initial
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
const RSV_REST_API_BASE = 'reservations/';
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
class RsvFormController {
|
||||
private $namespace;
|
||||
private $resource_name;
|
||||
|
||||
public function __construct() {
|
||||
$this->namespace = 'reservations/v1';
|
||||
$this->resource_name = 'form';
|
||||
}
|
||||
|
||||
public function register_routes(): void {
|
||||
register_rest_route($this->namespace, '/' . $this->resource_name . '/(?P<id>[^/]+)', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'handle'],
|
||||
// Public: site visitors submit reservation forms. The handler validates
|
||||
// the form definition and payload before persisting anything.
|
||||
'permission_callback' => [RsvRestPolicy::class, 'open']
|
||||
]);
|
||||
}
|
||||
|
||||
function handle(WP_REST_Request $request) {
|
||||
$submitter = new RsvFormSubmission();
|
||||
$submit_result = $submitter->submit($request->get_param("id"), $request->get_json_params());
|
||||
|
||||
if(isset($submit_result['success']) && $submit_result['success'] === true) {
|
||||
return new WP_REST_Response($submit_result, 200);
|
||||
}
|
||||
|
||||
return new WP_REST_Response($submit_result, 400);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
use Reservair\Logger\Logger;
|
||||
|
||||
|
||||
class RsvFormDefinitionController {
|
||||
use RsvPagedResponseTrait;
|
||||
private string $namespace = 'reservations/v1';
|
||||
private string $resource_name = 'form-definition';
|
||||
|
||||
private static function schema(): array {
|
||||
return [
|
||||
'type' => 'object',
|
||||
'properties' => [
|
||||
'form_id' => ['type' => 'integer', 'readonly' => true],
|
||||
'name' => ['type' => 'string', 'required' => true, 'minLength' => 1],
|
||||
'definition' => [
|
||||
'type' => 'object',
|
||||
'required' => false,
|
||||
'properties' => [
|
||||
'email_key' => ['type' => 'string', 'required' => false],
|
||||
'elements' => ['type' => 'array', 'default' => []],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function register_routes(): void {
|
||||
register_rest_route($this->namespace, '/' . $this->resource_name, [
|
||||
[
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'index'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
],
|
||||
[
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'create'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
'args' => self::input_args(self::schema()),
|
||||
],
|
||||
]);
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->resource_name . '/(?P<id>\d+)', [
|
||||
[
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'show'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
],
|
||||
[
|
||||
'methods' => 'PUT',
|
||||
'callback' => [$this, 'update'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
'args' => self::input_args(self::schema()),
|
||||
],
|
||||
[
|
||||
'methods' => 'DELETE',
|
||||
'callback' => [$this, 'destroy'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
function index(WP_REST_Request $request): WP_REST_Response {
|
||||
[$skip, $limit] = self::paging($request);
|
||||
$repo = new RsvFormDefinitionRepository();
|
||||
return $this->paged_response($repo->get_all($limit, $skip), $repo->count_all());
|
||||
}
|
||||
|
||||
function show(WP_REST_Request $request): WP_REST_Response {
|
||||
$row = (new RsvFormDefinitionRepository())->get((int) $request->get_param('id'));
|
||||
|
||||
if ($row === null) {
|
||||
return new WP_REST_Response(['error' => 'Not found'], 404);
|
||||
}
|
||||
|
||||
return new WP_REST_Response($row, 200);
|
||||
}
|
||||
|
||||
function create(WP_REST_Request $request): WP_REST_Response {
|
||||
try {
|
||||
$id = (new RsvFormDefinitionRepository())->add(
|
||||
$request->get_param('name'),
|
||||
$request->get_param('definition') ?? []
|
||||
);
|
||||
} catch(Throwable $e) {
|
||||
Logger::error($e);
|
||||
return new WP_REST_Response(['error' => 'An error occurred.'], 500);
|
||||
}
|
||||
|
||||
return new WP_REST_Response(['id' => $id], 201);
|
||||
}
|
||||
|
||||
function destroy(WP_REST_Request $request): WP_REST_Response {
|
||||
$id = (int) $request->get_param('id');
|
||||
$repo = new RsvFormDefinitionRepository();
|
||||
|
||||
if ($repo->get($id) === null) {
|
||||
return new WP_REST_Response(['error' => 'Not found'], 404);
|
||||
}
|
||||
|
||||
$repo->delete($id);
|
||||
|
||||
return new WP_REST_Response(null, 204);
|
||||
}
|
||||
|
||||
function update(WP_REST_Request $request): WP_REST_Response {
|
||||
$id = (int) $request->get_param('id');
|
||||
$repo = new RsvFormDefinitionRepository();
|
||||
|
||||
if ($repo->get($id) === null) {
|
||||
return new WP_REST_Response(['error' => 'Not found'], 404);
|
||||
}
|
||||
|
||||
$repo->update($id, $request->get_param('name'), $request->get_param('definition'));
|
||||
|
||||
return new WP_REST_Response(null, 204);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
trait RsvPagedResponseTrait {
|
||||
private function paged_response(array $data, ?int $total = null): WP_REST_Response {
|
||||
return new WP_REST_Response([
|
||||
'total' => $total ?? count($data),
|
||||
'data' => $data,
|
||||
], 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read pagination from the request as [skip, limit]. limit is clamped to
|
||||
* 1..100 and defaults to 20; skip defaults to 0.
|
||||
*
|
||||
* @return array{0:int,1:int}
|
||||
*/
|
||||
private static function paging(WP_REST_Request $request): array {
|
||||
$skip = max(0, (int) $request->get_param('skip'));
|
||||
$limit = (int) $request->get_param('limit');
|
||||
$limit = $limit > 0 ? min($limit, 100) : 20;
|
||||
return [$skip, $limit];
|
||||
}
|
||||
|
||||
/** Extract writable (non-readonly) properties from a schema for use as route args. */
|
||||
private static function input_args(array $schema): array {
|
||||
return array_filter(
|
||||
$schema['properties'],
|
||||
fn(array $prop): bool => empty($prop['readonly'])
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
|
||||
class RsvReservationController {
|
||||
use RsvPagedResponseTrait;
|
||||
|
||||
private $namespace;
|
||||
private $resource_name;
|
||||
|
||||
public function __construct() {
|
||||
$this->namespace = 'reservations/v1';
|
||||
$this->resource_name = 'reservation';
|
||||
}
|
||||
|
||||
public function register_routes(): void {
|
||||
register_rest_route($this->namespace, '/' . $this->resource_name, [
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'get_all'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin']
|
||||
]);
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->resource_name . '/(?P<id>\d+)', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'get'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin']
|
||||
]);
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->resource_name, [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'create'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin']
|
||||
]);
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->resource_name . '/(?P<id>\d+)/accept', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'accept_by_id'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
]);
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->resource_name . '/(?P<id>\d+)/refuse', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'refuse_by_id'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
]);
|
||||
}
|
||||
|
||||
function get_all(WP_REST_Request $request) {
|
||||
[$skip, $limit] = self::paging($request);
|
||||
$service = new RsvReservationService();
|
||||
return $this->paged_response((array) $service->get_all($limit, $skip), $service->count_all());
|
||||
}
|
||||
|
||||
function get(WP_REST_Request $request): WP_REST_Response {
|
||||
$service = new RsvReservationService();
|
||||
$detail = $service->get_detail((int) $request->get_param('id'));
|
||||
|
||||
if ($detail === null) {
|
||||
return new WP_REST_Response(['error' => 'Not found'], 404);
|
||||
}
|
||||
|
||||
return new WP_REST_Response($detail, 200);
|
||||
}
|
||||
|
||||
function create(WP_REST_Request $request) {
|
||||
$service = new RsvReservationService();
|
||||
$body = $request->get_json_params();
|
||||
return $service->create(RsvReservation::from_array($body));
|
||||
}
|
||||
|
||||
function accept_by_id(WP_REST_Request $request): WP_REST_Response {
|
||||
try {
|
||||
(new RsvTimetableReservationService())->accept_by_reservation_id((int) $request->get_param('id'));
|
||||
return new WP_REST_Response(['status' => 'accepted'], 200);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
return new WP_REST_Response(['error' => $e->getMessage()], 404);
|
||||
}
|
||||
}
|
||||
|
||||
function refuse_by_id(WP_REST_Request $request): WP_REST_Response {
|
||||
try {
|
||||
(new RsvTimetableReservationService())->refuse_by_reservation_id((int) $request->get_param('id'));
|
||||
return new WP_REST_Response(['status' => 'refused'], 200);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
return new WP_REST_Response(['error' => $e->getMessage()], 404);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorization policy for the reservations/v1 REST API.
|
||||
*
|
||||
* Every route's `permission_callback` references one of these tiers so the
|
||||
* intended audience is visible at the route definition:
|
||||
*
|
||||
* - admin(): requires the manage_reservations capability (see RsvCapabilities).
|
||||
* - open(): genuinely public, OR a capability URL whose secret is validated
|
||||
* inside the handler itself (confirmation codes, the Google webhook,
|
||||
* the OAuth callback). Any `open()` route that is not fully public
|
||||
* MUST authorise its caller from the request.
|
||||
*/
|
||||
final class RsvRestPolicy {
|
||||
/** Administrative endpoints: managing timetables, capacities, forms, reservations. */
|
||||
public static function admin(): bool|WP_Error {
|
||||
if ( current_user_can( RsvCapabilities::MANAGE ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return new WP_Error(
|
||||
'rsv_forbidden',
|
||||
__( 'Sorry, you are not allowed to do that.', 'reservair' ),
|
||||
// 401 when logged out, 403 when logged in but under-privileged.
|
||||
[ 'status' => rest_authorization_required_code() ]
|
||||
);
|
||||
}
|
||||
|
||||
/** Public endpoints, and capability URLs validated inside the handler. */
|
||||
public static function open(): bool {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Reservair\Logger\Logger;
|
||||
|
||||
class RsvTimetableAvailabilityController {
|
||||
private string $namespace = 'reservations/v1';
|
||||
|
||||
public function register_routes(): void {
|
||||
register_rest_route($this->namespace, '/timetable/(?P<id>\d+)/availability', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'show'],
|
||||
// Public: the booking widget reads availability for anonymous visitors.
|
||||
'permission_callback' => [RsvRestPolicy::class, 'open'],
|
||||
'args' => [
|
||||
'date' => ['type' => 'string', 'required' => true, 'format' => 'date'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(WP_REST_Request $request): WP_REST_Response {
|
||||
$id = (int) $request->get_param('id');
|
||||
$service = new RsvTimetableService();
|
||||
$timetable = $service->get($id);
|
||||
|
||||
if ($timetable === null || $timetable->id === null) {
|
||||
return new WP_REST_Response(['error' => 'Timetable not found'], 404);
|
||||
}
|
||||
|
||||
try {
|
||||
$availability = $service->get_availability_on_date($id, $timetable->block_size, new DateTime($request->get_param('date')));
|
||||
} catch (Throwable $e) {
|
||||
Logger::error($e);
|
||||
return new WP_REST_Response(['error' => $e->getMessage()], 400);
|
||||
}
|
||||
|
||||
return new WP_REST_Response($availability, 200);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
|
||||
class RsvTimetableCapacityController {
|
||||
use RsvPagedResponseTrait;
|
||||
private string $namespace = 'reservations/v1';
|
||||
private string $resource_name = 'timetable/(?P<id>\d+)/capacity';
|
||||
|
||||
public function register_routes(): void {
|
||||
register_rest_route($this->namespace, '/' . $this->resource_name, [
|
||||
[
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'get_all'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
],
|
||||
[
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'create'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
// 'args' => self::input_args(RsvTimetableCapacity::schema()),
|
||||
],
|
||||
]);
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->resource_name . '/(?P<capacity_id>\d+)', [
|
||||
[
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'get'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
],
|
||||
[
|
||||
'methods' => 'PUT',
|
||||
'callback' => [$this, 'update'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
'args' => self::input_args(RsvTimetableCapacity::schema()),
|
||||
],
|
||||
[
|
||||
'methods' => 'DELETE',
|
||||
'callback' => [$this, 'delete'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function get_all(WP_REST_Request $request): WP_REST_Response {
|
||||
[$skip, $limit] = self::paging($request);
|
||||
$timetable_id = (int) $request->get_param('id');
|
||||
$service = new RsvTimetableCapacityRepository();
|
||||
return $this->paged_response(
|
||||
$service->get_all($timetable_id, $limit, $skip),
|
||||
$service->count_all($timetable_id)
|
||||
);
|
||||
}
|
||||
|
||||
public function get(WP_REST_Request $request): WP_REST_Response {
|
||||
return new WP_REST_Response(
|
||||
(new RsvTimetableCapacityRepository())->get((int) $request->get_param('capacity_id')),
|
||||
200
|
||||
);
|
||||
}
|
||||
|
||||
public function create(WP_REST_Request $request): WP_REST_Response {
|
||||
$items = $request->get_json_params();
|
||||
$timetable_id = (int) $request->get_param('id');
|
||||
|
||||
$ids = [];
|
||||
|
||||
foreach($items as $item) {
|
||||
$capacity = new RsvTimetableCapacity(
|
||||
null,
|
||||
$timetable_id,
|
||||
(int) $item['capacity'],
|
||||
(int) $item['min_lead_time_minutes'],
|
||||
new DateTime($item['date']),
|
||||
(int) $item['start_time'],
|
||||
(int) $item['end_time'],
|
||||
(int) $item['repeat_period_in_days'],
|
||||
(int) $item['repeat_times'],
|
||||
(bool) $item['requires_confirmation'],
|
||||
);
|
||||
|
||||
$ids[] = (new RsvTimetableCapacityRepository())->create($capacity);
|
||||
}
|
||||
|
||||
return new WP_REST_Response(
|
||||
['ids' => $ids],
|
||||
201
|
||||
);
|
||||
}
|
||||
|
||||
public function update(WP_REST_Request $request): WP_REST_Response {
|
||||
$capacity = new RsvTimetableCapacity(
|
||||
(int) $request->get_param('capacity_id'),
|
||||
(int) $request->get_param('id'),
|
||||
(int) $request->get_param('capacity'),
|
||||
(int) $request->get_param('min_lead_time_minutes'),
|
||||
new DateTime($request->get_param('date')),
|
||||
(int)$request->get_param('start_time'),
|
||||
(int)$request->get_param('end_time'),
|
||||
(int) $request->get_param('repeat_period_in_days'),
|
||||
(int) $request->get_param('repeat_times'),
|
||||
(bool) $request->get_param('requires_confirmation'),
|
||||
);
|
||||
|
||||
$capacity_id = (int) $request->get_param('capacity_id');
|
||||
(new RsvTimetableCapacityRepository())->update($capacity_id, $capacity);
|
||||
|
||||
return new WP_REST_Response(['id' => $capacity_id], 200);
|
||||
}
|
||||
|
||||
public function delete(WP_REST_Request $request): WP_REST_Response {
|
||||
(new RsvTimetableCapacityRepository())->delete((int) $request->get_param('capacity_id'));
|
||||
return new WP_REST_Response(null, 204);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
|
||||
class RsvTimetableDefinitionController {
|
||||
use RsvPagedResponseTrait;
|
||||
private string $namespace = 'reservations/v1';
|
||||
private string $resource_name = 'timetable';
|
||||
|
||||
public function register_routes(): void {
|
||||
register_rest_route($this->namespace, '/' . $this->resource_name, [
|
||||
[
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'index'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
],
|
||||
[
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'create'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
'args' => self::input_args(RsvTimetable::schema()),
|
||||
],
|
||||
]);
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->resource_name . '/(?P<id>\d+)', [
|
||||
[
|
||||
'methods' => 'PATCH',
|
||||
'callback' => [$this, 'update'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
'args' => self::input_args(RsvTimetable::schema()),
|
||||
],
|
||||
[
|
||||
'methods' => 'DELETE',
|
||||
'callback' => [$this, 'destroy'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function index(WP_REST_Request $request): WP_REST_Response {
|
||||
[$skip, $limit] = self::paging($request);
|
||||
$service = new RsvTimetableService();
|
||||
return $this->paged_response($service->get_all($limit, $skip), $service->count_all());
|
||||
}
|
||||
|
||||
public function create(WP_REST_Request $request): WP_REST_Response {
|
||||
$service = new RsvTimetableService();
|
||||
$id = $service->create(new RsvTimetable([
|
||||
'name' => $request->get_param('name'),
|
||||
'block_size' => (int) $request->get_param('block_size'),
|
||||
'maintainer_email' => $request->get_param('maintainer_email'),
|
||||
]));
|
||||
|
||||
return new WP_REST_Response(['id' => $id], 201);
|
||||
}
|
||||
|
||||
public function update(WP_REST_Request $request): WP_REST_Response {
|
||||
$id = (int) $request->get_param('id');
|
||||
$service = new RsvTimetableService();
|
||||
$body = $request->get_json_params();
|
||||
|
||||
$timetable = $service->get($id);
|
||||
if ($timetable === null) {
|
||||
return new WP_REST_Response(['error' => 'Not found'], 404);
|
||||
}
|
||||
|
||||
if (array_key_exists('name', $body)) $timetable->name = $body['name'];
|
||||
if (array_key_exists('block_size', $body)) $timetable->block_size = (int) $body['block_size'];
|
||||
if (array_key_exists('maintainer_email', $body)) $timetable->maintainer_email = $body['maintainer_email'] ?: null;
|
||||
if (array_key_exists('google_calendar_id', $body)) $timetable->google_calendar_id = $body['google_calendar_id'] ?: null;
|
||||
|
||||
$service->update($id, $timetable);
|
||||
|
||||
return new WP_REST_Response(['id' => $id], 200);
|
||||
}
|
||||
|
||||
public function destroy(WP_REST_Request $request): WP_REST_Response {
|
||||
$id = (int) $request->get_param('id');
|
||||
$service = new RsvTimetableService();
|
||||
|
||||
if ($service->get($id) === null) {
|
||||
return new WP_REST_Response(['error' => 'Not found'], 404);
|
||||
}
|
||||
|
||||
$service->delete($id);
|
||||
|
||||
return new WP_REST_Response(null, 204);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
class RsvTimetableReservationController {
|
||||
use RsvPagedResponseTrait;
|
||||
|
||||
private $namespace = 'reservations/v1';
|
||||
private $resource_name = '/timetable/(?P<id>\d+)/reservation';
|
||||
|
||||
public function register_routes(): void {
|
||||
register_rest_route($this->namespace, $this->resource_name, [
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'by_timetable'],
|
||||
'permission_callback' => [RsvRestPolicy::class, 'admin'],
|
||||
]);
|
||||
|
||||
register_rest_route($this->namespace, '/timetable-reservation/accept/(?P<code>[a-zA-Z0-9]+)', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'accept'],
|
||||
// Capability URL: authorised by the secret confirmation code, which
|
||||
// accept() validates against the database before changing state.
|
||||
'permission_callback' => [RsvRestPolicy::class, 'open'],
|
||||
]);
|
||||
|
||||
register_rest_route($this->namespace, '/timetable-reservation/refuse/(?P<code>[a-zA-Z0-9]+)', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'refuse'],
|
||||
// Capability URL: authorised by the secret confirmation code, which
|
||||
// refuse() validates against the database before changing state.
|
||||
'permission_callback' => [RsvRestPolicy::class, 'open'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function by_timetable(WP_REST_Request $request): WP_REST_Response {
|
||||
[$skip, $limit] = self::paging($request);
|
||||
$timetable_id = (int) $request->get_param('id');
|
||||
$service = new RsvTimetableReservationService();
|
||||
return $this->paged_response(
|
||||
$service->get_by_timetable($timetable_id, $limit, $skip),
|
||||
$service->count_by_timetable($timetable_id)
|
||||
);
|
||||
}
|
||||
|
||||
function accept(WP_REST_Request $request) {
|
||||
try {
|
||||
$service = new RsvTimetableReservationService();
|
||||
$service->accept($request->get_param('code'));
|
||||
return new WP_REST_Response(['status' => 'accepted'], 200);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
return new WP_REST_Response(['error' => 'Invalid or expired confirmation code.'], 404);
|
||||
}
|
||||
}
|
||||
|
||||
function refuse(WP_REST_Request $request) {
|
||||
try {
|
||||
$service = new RsvTimetableReservationService();
|
||||
$service->refuse($request->get_param('code'));
|
||||
return new WP_REST_Response(['status' => 'refused'], 200);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
return new WP_REST_Response(['error' => 'Invalid or expired confirmation code.'], 404);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user