Класс Route который позволит регистрировать маршруты REST API в WordPress
Задача
Реализуйте класс Route который позволит регистрировать маршруты REST API в WordPress с использованием функций-посредников (Middleware). Требуемый интерфейс:
Route::register(
string $namespace,
array $routes,
array $middlewares = []
);
$namespace — пространство имён REST в WordPress.
$routes — ассоциативный массив, где ключ — это шаблон пути маршрута REST API, а значение — массив параметров для конечной точки. Пример:
$routes = [
'/post/(?P<id>\d+)' => [
'methods' => 'GET',
'callback' => function (WP_REST_Request $request) {
//...
}
]
];
$middlewares — массив функций-посредников, которые выполняются последовательно перед каждым зарегистрированным обработчиком маршрута. Могут использоваться для авторизации, преобразования параметров запроса, запуска параллельных процессов и т. п. Пример:
$middlewares = [
function($data, $next) {
if (authorize_user($data)) {
return $next($data);
} else {
return "You are not authorized";
}
},
function($data, $next) {
log_activity($data);
return $next($data);
}
];
Для простоты считайте, что массивы $routes и $middlewares всегда состоят только из валидных элементов.
Реализация
Выполнен как плагин, должен располагаться по адресу: /wp-content/plugins/dw_route.php
<?php
/*
* Plugin Name: Disweb Route
* Plugin URI: https://disweb.ru
* Description:
* Version: 1.0
* Author: DisWEB
* Author URI: https://disweb.ru
*/
namespace Disweb;
// begin: Script
class Route
{
public static $ar = [];
public function __construct()
{
\add_action('rest_api_init', [$this, 'init'], 10);
}
public function init()
{
foreach (self::$ar as $k => $v)
{
foreach ($v['routes'] as $route => $args)
{
$args['permission_callback'] = function ($request) use ($k) {
Route::middlewares($request, $k);
return true;
};
\register_rest_route($v['namespace'], $route, $args);
}
}
}
public static function middlewares($request, $k)
{
foreach (self::$ar[$k]['middlewares'] as $middlewares)
{
$uniqid = uniqid();
$res = $middlewares($request, function ($request) use ($uniqid) {
return $uniqid;
});
if ($uniqid != $res)
{
die($res);
}
}
}
public static function register(
string $namespace,
array $routes,
array $middlewares = []
)
{
self::$ar[] = [
'namespace' => $namespace,
'routes' => $routes,
'middlewares' => $middlewares,
];
}
}
new Route();
// end: Script
// ***************************************************
/*
URL:
https://example.com/wp-json/yt/v1/post/543
https://example.com/wp-json/yt/v1/test_sr/543
RESULT:
{"status":"ok","request":{"id":"543","test":"md-1"}}
URL:
https://example.com/wp-json/yt/v1/post2/543
https://example.com/wp-json/yt/v1/test_sr2/543
RESULT:
Not found data!
*/
// begin: Example
Route::register('yt/v1', [
'/post/(?P<id>\d+)' => [
'methods' => 'GET',
'callback' => function (\WP_REST_Request $request) {
return [
'status' => 'ok',
'request' => $request->get_params(),
];
}
],
'/test_sr/(?P<id>\d+)' => [
'methods' => 'GET',
'callback' => function (\WP_REST_Request $request) {
return [
'status' => 'ok',
'request' => $request->get_params(),
];
}
],
], [
function ($data, $next) {
$data->set_param('test', 'md-1');
return $next($data);
},
function ($data, $next) {
return $next($data);
return "Not found data!";
},
]);
Route::register('yt/v1', [
'/post2/(?P<id>\d+)' => [
'methods' => 'GET',
'callback' => function (\WP_REST_Request $request) {
return [
'status' => 'ok',
'request' => $request->get_params(),
];
}
],
'/test_sr2/(?P<id>\d+)' => [
'methods' => 'GET',
'callback' => function (\WP_REST_Request $request) {
return [
'status' => 'ok',
'request' => $request->get_params(),
];
}
],
], [
function ($data, $next) {
$data->set_param('test', 'md-2');
$data->set_param('test2', 'md-2');
return $next($data);
},
function ($data, $next) {
//return $next($data);
return "Not found data!";
},
]);
// end: Example
В реализации для middleware передаваться будет только объект. Строковые, массивы и т.д. передаваться не будут.