#18 - membership

This commit was merged in pull request #23.
This commit is contained in:
Martin Slachta
2026-06-17 11:15:09 +02:00
parent df5f9b1df4
commit c754e18a82
25 changed files with 885 additions and 35 deletions
@@ -0,0 +1,183 @@
<?php
class RsvMembershipProgramController {
use RsvPagedResponseTrait;
private string $namespace = 'reservations/v1';
private string $resource_name = 'membership-program';
private static function schema(): array {
return [
'type' => 'object',
'properties' => [
'id' => ['type' => 'integer', 'readonly' => true],
'name' => ['type' => 'string', 'required' => true, 'minLength' => 1],
'active' => ['type' => 'boolean', 'default' => true],
],
];
}
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, 'delete'],
'permission_callback' => [RsvRestPolicy::class, 'admin'],
],
]);
register_rest_route($this->namespace, '/' . $this->resource_name . '/(?P<id>\d+)/keys', [
[
'methods' => 'GET',
'callback' => [$this, 'index_keys'],
'permission_callback' => [RsvRestPolicy::class, 'admin'],
],
[
'methods' => 'POST',
'callback' => [$this, 'add_key'],
'permission_callback' => [RsvRestPolicy::class, 'admin'],
],
]);
register_rest_route($this->namespace, '/' . $this->resource_name . '/(?P<id>\d+)/keys/(?P<key_id>\d+)', [
[
'methods' => 'DELETE',
'callback' => [$this, 'delete_key'],
'permission_callback' => [RsvRestPolicy::class, 'admin'],
],
]);
}
public function index(WP_REST_Request $request): WP_REST_Response {
[$skip, $limit] = self::paging($request);
$repo = new RsvMembershipProgramRepository();
$programs = array_map(fn($p) => $p->to_array(), $repo->all($limit, $skip));
return $this->paged_response($programs, $repo->count_all());
}
public function create(WP_REST_Request $request): WP_REST_Response {
$params = $request->get_json_params();
$name = $params['name'] ?? '';
$active = $params['active'] ?? true;
if (trim($name) === '') {
throw new InvalidArgumentException('Name is required.');
}
$repo = new RsvMembershipProgramRepository();
$id = $repo->add($name, $active);
return new WP_REST_Response(RsvMembershipProgram::from_array(['id' => $id, 'name' => $name, 'active' => $active])->to_array(), 201);
}
public function show(WP_REST_Request $request): WP_REST_Response {
$id = (int) $request->get_param('id');
$repo = new RsvMembershipProgramRepository();
$program = $repo->get($id);
if ($program === null) {
return new WP_REST_Response(['error' => 'Not found'], 404);
}
return new WP_REST_Response($program, 200);
}
public function update(WP_REST_Request $request): WP_REST_Response {
$id = (int) $request->get_param('id');
$params = $request->get_json_params();
$name = $params['name'] ?? '';
$active = $params['active'] ?? true;
if (trim($name) === '') {
throw new InvalidArgumentException('Name is required.');
}
$repo = new RsvMembershipProgramRepository();
if ($repo->get($id) === null) {
return new WP_REST_Response(['error' => 'Not found'], 404);
}
$repo->update($id, $name, $active);
return new WP_REST_Response(['id' => $id, 'name' => $name, 'active' => $active], 200);
}
public function delete(WP_REST_Request $request): WP_REST_Response {
$id = (int) $request->get_param('id');
$repo = new RsvMembershipProgramRepository();
if ($repo->get($id) === null) {
return new WP_REST_Response(['error' => 'Not found'], 404);
}
$repo->delete($id);
return new WP_REST_Response(['ok' => true], 200);
}
public function index_keys(WP_REST_Request $request): WP_REST_Response {
[$skip, $limit] = self::paging($request);
$program_id = (int) $request->get_param('id');
$repo = new RsvMembershipProgramRepository();
if ($repo->get($program_id) === null) {
return new WP_REST_Response(['error' => 'Program not found'], 404);
}
$keys = array_map(fn($k) => $k->to_array(), $repo->keys($program_id, $limit, $skip));
return $this->paged_response($keys, $repo->count_keys($program_id));
}
public function add_key(WP_REST_Request $request): WP_REST_Response {
$program_id = (int) $request->get_param('id');
$params = $request->get_json_params();
$key_value = $params['key_value'] ?? '';
if (trim($key_value) === '') {
throw new InvalidArgumentException('Key value is required.');
}
$repo = new RsvMembershipProgramRepository();
if ($repo->get($program_id) === null) {
return new WP_REST_Response(['error' => 'Program not found'], 404);
}
$key_id = $repo->add_key($program_id, $key_value);
return new WP_REST_Response(['id' => $key_id, 'program_id' => $program_id, 'key_value' => $key_value], 201);
}
public function delete_key(WP_REST_Request $request): WP_REST_Response {
$program_id = (int) $request->get_param('id');
$key_id = (int) $request->get_param('key_id');
$repo = new RsvMembershipProgramRepository();
if ($repo->get($program_id) === null) {
return new WP_REST_Response(['error' => 'Program not found'], 404);
}
$repo->delete_key($key_id);
return new WP_REST_Response(['ok' => true], 200);
}
}