'map-editor/pages/(:all)/markers', 'method' => 'GET', 'auth' => false, // Allow Panel session auth 'action' => function (string $pageId) { try { // Get user from session (Panel context) $user = kirby()->user(); // For Panel requests, we trust the session is valid // The Panel itself already requires authentication if (!$user && !kirby()->option('debug', false)) { return [ 'status' => 'error', 'message' => 'Unauthorized', 'code' => 401 ]; } // Get the map page $mapPage = kirby()->page($pageId); if (!$mapPage) { return [ 'status' => 'error', 'message' => 'Map page not found', 'code' => 404 ]; } // Check if user can read the page if (!$mapPage->isReadable()) { return [ 'status' => 'error', 'message' => 'Forbidden', 'code' => 403 ]; } // Get all marker subpages, listed only, sorted by num $markerPages = $mapPage ->children() ->listed() ->filterBy('intendedTemplate', 'marker') ->sortBy('num', 'asc'); // Format markers for response $markers = []; foreach ($markerPages as $marker) { $markers[] = [ 'id' => $marker->id(), 'slug' => $marker->slug(), 'title' => $marker->title()->value(), 'position' => [ 'lat' => (float) $marker->latitude()->value(), 'lon' => (float) $marker->longitude()->value() ], 'num' => $marker->num(), 'panelUrl' => (string) $marker->panel()->url() ]; } return [ 'status' => 'success', 'data' => [ 'markers' => $markers ] ]; } catch (Exception $e) { return [ 'status' => 'error', 'message' => $e->getMessage(), 'code' => 500 ]; } } ], [ 'pattern' => 'map-editor/pages/(:all)/markers', 'method' => 'POST', 'auth' => false, // Allow Panel session auth 'action' => function (string $pageId) { try { // Get user from session (Panel context) $user = kirby()->user(); // For Panel requests, we trust the session is valid if (!$user && !kirby()->option('debug', false)) { return [ 'status' => 'error', 'message' => 'Unauthorized', 'code' => 401 ]; } // Note: CSRF verification skipped for Panel session requests // The Panel session itself is already authenticated and secure // Get the map page $mapPage = kirby()->page($pageId); if (!$mapPage) { return [ 'status' => 'error', 'message' => 'Map page not found', 'code' => 404 ]; } // Check if user can create children if (!$mapPage->permissions()->can('create')) { return [ 'status' => 'error', 'message' => 'Forbidden', 'code' => 403 ]; } // Get position from request body // Use data() instead of body() - Kirby automatically parses JSON $data = kirby()->request()->data(); if (!isset($data['position']['lat']) || !isset($data['position']['lon'])) { return [ 'status' => 'error', 'message' => 'Position (lat, lon) is required', 'code' => 400 ]; } $lat = (float) $data['position']['lat']; $lon = (float) $data['position']['lon']; // Validate coordinates if ($lat < -90 || $lat > 90 || $lon < -180 || $lon > 180) { return [ 'status' => 'error', 'message' => 'Invalid coordinates', 'code' => 400 ]; } // Get existing markers to determine next num $existingMarkers = $mapPage ->children() ->filterBy('intendedTemplate', 'marker'); $nextNum = $existingMarkers->count() + 1; // Generate unique slug $slug = 'marker-' . time(); // Create the new marker page $newMarker = $mapPage->createChild([ 'slug' => $slug, 'template' => 'marker', 'content' => [ 'title' => 'Marqueur ' . $nextNum, 'latitude' => $lat, 'longitude' => $lon ] ]); // Publish the page as listed with the correct num $newMarker->changeStatus('listed', $nextNum); return [ 'status' => 'success', 'data' => [ 'marker' => [ 'id' => $newMarker->id(), 'slug' => $newMarker->slug(), 'title' => $newMarker->title()->value(), 'position' => [ 'lat' => $lat, 'lon' => $lon ], 'num' => $newMarker->num(), 'panelUrl' => '/panel/pages/' . $newMarker->id() ] ] ]; } catch (Exception $e) { return [ 'status' => 'error', 'message' => $e->getMessage(), 'code' => 500 ]; } } ], [ 'pattern' => 'map-editor/pages/(:all)/markers/(:all)', 'method' => 'PATCH', 'auth' => false, // Allow Panel session auth 'action' => function (string $pageId, string $markerId) { try { // Get user from session (Panel context) $user = kirby()->user(); if (!$user && !kirby()->option('debug', false)) { return [ 'status' => 'error', 'message' => 'Unauthorized', 'code' => 401 ]; } // Note: CSRF verification skipped for Panel session requests // The Panel session itself is already authenticated and secure // Get the marker page $marker = kirby()->page($markerId); if (!$marker) { return [ 'status' => 'error', 'message' => 'Marker not found', 'code' => 404 ]; } // Check if user can update the page if (!$marker->permissions()->can('update')) { return [ 'status' => 'error', 'message' => 'Forbidden', 'code' => 403 ]; } // Get position from request body $data = kirby()->request()->data(); if (!isset($data['position']['lat']) || !isset($data['position']['lon'])) { return [ 'status' => 'error', 'message' => 'Position (lat, lon) is required', 'code' => 400 ]; } $lat = (float) $data['position']['lat']; $lon = (float) $data['position']['lon']; // Validate coordinates if ($lat < -90 || $lat > 90 || $lon < -180 || $lon > 180) { return [ 'status' => 'error', 'message' => 'Invalid coordinates', 'code' => 400 ]; } // Update the marker position $marker->update([ 'latitude' => $lat, 'longitude' => $lon ]); return [ 'status' => 'success', 'data' => [ 'marker' => [ 'id' => $marker->id(), 'slug' => $marker->slug(), 'title' => $marker->title()->value(), 'position' => [ 'lat' => $lat, 'lon' => $lon ], 'num' => $marker->num(), 'panelUrl' => '/panel/pages/' . $marker->id() ] ] ]; } catch (Exception $e) { return [ 'status' => 'error', 'message' => $e->getMessage(), 'code' => 500 ]; } } ], [ 'pattern' => 'map-editor/pages/(:all)/markers/(:all)', 'method' => 'DELETE', 'auth' => false, // Allow Panel session auth 'action' => function (string $pageId, string $markerId) { try { // Get user from session (Panel context) $user = kirby()->user(); if (!$user && !kirby()->option('debug', false)) { return [ 'status' => 'error', 'message' => 'Unauthorized', 'code' => 401 ]; } // Note: CSRF verification skipped for Panel session requests // The Panel session itself is already authenticated and secure // Get the marker page $marker = kirby()->page($markerId); if (!$marker) { return [ 'status' => 'error', 'message' => 'Marker not found', 'code' => 404 ]; } // Check if user can delete the page if (!$marker->permissions()->can('delete')) { return [ 'status' => 'error', 'message' => 'Forbidden', 'code' => 403 ]; } // Delete the marker page $marker->delete(true); // true = force delete return [ 'status' => 'success', 'data' => [ 'message' => 'Marker deleted successfully' ] ]; } catch (Exception $e) { return [ 'status' => 'error', 'message' => $e->getMessage(), 'code' => 500 ]; } } ], [ 'pattern' => 'map-editor/pages/(:all)/position', 'method' => 'PATCH', 'auth' => false, // Allow Panel session auth 'action' => function (string $pageId) { try { // Get user from session (Panel context) $user = kirby()->user(); if (!$user && !kirby()->option('debug', false)) { return [ 'status' => 'error', 'message' => 'Unauthorized', 'code' => 401 ]; } // Note: CSRF verification skipped for Panel session requests // The Panel session itself is already authenticated and secure // Get the page (marker page in single mode) $page = kirby()->page($pageId); if (!$page) { return [ 'status' => 'error', 'message' => 'Page not found', 'code' => 404 ]; } // Check if user can update the page if (!$page->permissions()->can('update')) { return [ 'status' => 'error', 'message' => 'Forbidden', 'code' => 403 ]; } // Get coordinates from request body $data = kirby()->request()->data(); if (!isset($data['latitude']) || !isset($data['longitude'])) { return [ 'status' => 'error', 'message' => 'Latitude and longitude are required', 'code' => 400 ]; } $lat = (float) $data['latitude']; $lon = (float) $data['longitude']; // Validate coordinates if ($lat < -90 || $lat > 90 || $lon < -180 || $lon > 180) { return [ 'status' => 'error', 'message' => 'Invalid coordinates', 'code' => 400 ]; } // Update the page position $page->update([ 'latitude' => $lat, 'longitude' => $lon ]); return [ 'status' => 'success', 'data' => [ 'latitude' => $lat, 'longitude' => $lon ] ]; } catch (Exception $e) { return [ 'status' => 'error', 'message' => $e->getMessage(), 'code' => 500 ]; } } ] ];