88 lines
3.7 KiB
PHP
88 lines
3.7 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
use Reservair\Database\DbException;
|
||
|
|
use Reservair\Logger\Logger;
|
||
|
|
|
||
|
|
function rsv_define_rest_api(): void {
|
||
|
|
// Exception handler for all reservations/v1 endpoints.
|
||
|
|
// Runs before WordPress calls the callback, so no try/catch is needed
|
||
|
|
// in individual controller methods.
|
||
|
|
add_filter('rest_dispatch_request', function ($result, WP_REST_Request $request, string $route, array $handler) {
|
||
|
|
if ($result !== null) {
|
||
|
|
return $result;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!str_starts_with($route, '/reservations/v1/') && $route !== '/reservations/v1') {
|
||
|
|
return $result;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
return call_user_func($handler['callback'], $request);
|
||
|
|
} catch (DbException $e) {
|
||
|
|
Logger::error($e);
|
||
|
|
return new WP_REST_Response(['error' => 'A database error occurred.'], 500);
|
||
|
|
} catch (InvalidArgumentException $e) {
|
||
|
|
return new WP_REST_Response(['error' => $e->getMessage()], 400);
|
||
|
|
} catch (\Throwable $e) {
|
||
|
|
Logger::error($e);
|
||
|
|
return new WP_REST_Response(['error' => 'An unexpected error occurred.'], 500);
|
||
|
|
}
|
||
|
|
}, 10, 4);
|
||
|
|
|
||
|
|
// -------------------------------------------------------------------------
|
||
|
|
// Routes
|
||
|
|
// -------------------------------------------------------------------------
|
||
|
|
|
||
|
|
register_rest_route('reservations/v1', '/google-callback', [
|
||
|
|
'methods' => 'GET',
|
||
|
|
'callback' => 'rsv_google_oauth_callback',
|
||
|
|
// Public: OAuth redirect from Google; the handler validates the returned code.
|
||
|
|
'permission_callback' => [RsvRestPolicy::class, 'open'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
register_rest_route('reservations/v1', '/google-calendar-hook', [
|
||
|
|
'methods' => 'POST',
|
||
|
|
'callback' => 'rsv_google_calendar_webhook',
|
||
|
|
// Public webhook: authorised by matching the secret channel id carried in
|
||
|
|
// the request headers (validated inside rsv_google_calendar_webhook).
|
||
|
|
'permission_callback' => [RsvRestPolicy::class, 'open'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
register_rest_route('reservations/v1', '/google-calendars', [
|
||
|
|
'methods' => 'GET',
|
||
|
|
'callback' => function () {
|
||
|
|
$service = new RsvGoogleCalendarService();
|
||
|
|
if (!$service->is_google_connected()) {
|
||
|
|
return new WP_REST_Response(['error' => 'Not connected to Google Calendar'], 403);
|
||
|
|
}
|
||
|
|
return new WP_REST_Response($service->list_calendars(), 200);
|
||
|
|
},
|
||
|
|
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
register_rest_route('reservations/v1', '/timetable/(?P<id>\d+)/google-calendar', [
|
||
|
|
'methods' => 'PUT',
|
||
|
|
'callback' => function (WP_REST_Request $request) {
|
||
|
|
$id = (int) $request->get_param('id');
|
||
|
|
$calendar_id = $request->get_json_params()['calendar_id'] ?? null;
|
||
|
|
|
||
|
|
$service = new RsvTimetableService();
|
||
|
|
if (!$service->get($id)) {
|
||
|
|
return new WP_REST_Response(['error' => 'Timetable not found'], 404);
|
||
|
|
}
|
||
|
|
|
||
|
|
$service->set_google_calendar_id($id, $calendar_id ?: null);
|
||
|
|
return new WP_REST_Response(['ok' => true], 200);
|
||
|
|
},
|
||
|
|
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
(new RsvReservationController())->register_routes();
|
||
|
|
(new RsvTimetableDefinitionController())->register_routes();
|
||
|
|
(new RsvTimetableAvailabilityController())->register_routes();
|
||
|
|
(new RsvTimetableCapacityController())->register_routes();
|
||
|
|
(new RsvTimetableReservationController())->register_routes();
|
||
|
|
(new RsvFormController())->register_routes();
|
||
|
|
(new RsvFormDefinitionController())->register_routes();
|
||
|
|
}
|