442 lines
15 KiB
PHP
442 lines
15 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
/**
|
||
|
|
* API Routes for Map Editor Plugin
|
||
|
|
*
|
||
|
|
* Provides CRUD operations for marker subpages
|
||
|
|
*/
|
||
|
|
|
||
|
|
return [
|
||
|
|
[
|
||
|
|
'pattern' => '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
|
||
|
|
];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
]
|
||
|
|
];
|