Make API endpoint a simple single-action class

[MAILPOET-4207]
This commit is contained in:
Jan Jakes
2022-04-12 13:11:52 +02:00
committed by Veljko V
parent 506b6e82fc
commit f7888480b4
3 changed files with 36 additions and 38 deletions

View File

@@ -2,16 +2,14 @@
namespace MailPoet\Automation\Engine\API; namespace MailPoet\Automation\Engine\API;
use MailPoet\Automation\Engine\API\Endpoints\SystemDatabaseEndpoint;
use MailPoet\Automation\Engine\API\Endpoints\WorkflowsEndpoint;
use MailPoet\Automation\Engine\Exceptions\Exception; use MailPoet\Automation\Engine\Exceptions\Exception;
use MailPoet\Automation\Engine\Hooks;
use MailPoet\Automation\Engine\WordPress; use MailPoet\Automation\Engine\WordPress;
use ReflectionClass;
use Throwable; use Throwable;
use WP_REST_Request;
class API { class API {
private const PREFIX = 'mailpoet/v1/automation'; private const PREFIX = 'mailpoet/v1/automation';
private const METHODS = ['get', 'post', 'put', 'delete'];
private const WP_REST_API_INIT_ACTION = 'rest_api_init'; private const WP_REST_API_INIT_ACTION = 'rest_api_init';
/** @var EndpointFactory */ /** @var EndpointFactory */
@@ -20,12 +18,6 @@ class API {
/** @var WordPress */ /** @var WordPress */
private $wordPress; private $wordPress;
/** @var array<string, class-string<Endpoint>> */
private $routes = [
'system/database' => SystemDatabaseEndpoint::class,
'workflows' => WorkflowsEndpoint::class,
];
public function __construct( public function __construct(
EndpointFactory $endpointFactory, EndpointFactory $endpointFactory,
WordPress $wordPress WordPress $wordPress
@@ -36,30 +28,45 @@ class API {
public function initialize(): void { public function initialize(): void {
$this->wordPress->addAction(self::WP_REST_API_INIT_ACTION, function () { $this->wordPress->addAction(self::WP_REST_API_INIT_ACTION, function () {
foreach ($this->routes as $route => $endpoint) { $this->wordPress->doAction(Hooks::API_INITIALIZE, [$this]);
$reflection = new ReflectionClass($endpoint);
foreach (self::METHODS as $method) {
if ($reflection->hasMethod($method) && $reflection->getMethod($method)->class === $endpoint) {
$this->registerRoute($route, $endpoint, $method);
}
}
}
}); });
} }
private function registerRoute(string $route, string $endpoint, string $method): void { public function registerGetRoute(string $route, string $endpoint): void {
$this->registerRoute($route, $endpoint, 'GET');
}
public function registerPostRoute(string $route, string $endpoint): void {
$this->registerRoute($route, $endpoint, 'POST');
}
public function registerPutRoute(string $route, string $endpoint): void {
$this->registerRoute($route, $endpoint, 'PUT');
}
public function registerPatchRoute(string $route, string $endpoint): void {
$this->registerRoute($route, $endpoint, 'PATCH');
}
public function registerDeleteRoute(string $route, string $endpoint): void {
$this->registerRoute($route, $endpoint, 'DELETE');
}
private function registerRoute(string $route, string $endpointClass, string $method): void {
$this->wordPress->registerRestRoute(self::PREFIX, $route, [ $this->wordPress->registerRestRoute(self::PREFIX, $route, [
'methods' => strtoupper($method), 'methods' => $method,
'callback' => function ($wpRequest) use ($endpoint, $method) { 'callback' => function (WP_REST_Request $wpRequest) use ($endpointClass) {
try { try {
$endpoint = $this->endpointFactory->createEndpoint($endpointClass);
$request = new Request($wpRequest); $request = new Request($wpRequest);
return $this->endpointFactory->createEndpoint($endpoint)->$method($request); return $endpoint->handle($request);
} catch (Throwable $e) { } catch (Throwable $e) {
return $this->convertToErrorResponse($e); return $this->convertToErrorResponse($e);
} }
}, },
'permission_callback' => function () { 'permission_callback' => function () use ($endpointClass) {
return $this->wordPress->currentUserCan('administrator'); $endpoint = $this->endpointFactory->createEndpoint($endpointClass);
return $endpoint->checkPermissions();
}, },
]); ]);
} }

View File

@@ -2,22 +2,12 @@
namespace MailPoet\Automation\Engine\API; namespace MailPoet\Automation\Engine\API;
use MailPoet\Automation\Engine\Exceptions; use function current_user_can;
abstract class Endpoint { abstract class Endpoint {
public function get(Request $request): Response { abstract public function handle(Request $request): Response;
throw Exceptions::apiMethodNotAllowed();
}
public function post(Request $request): Response { public function checkPermissions(): bool {
throw Exceptions::apiMethodNotAllowed(); return current_user_can('administrator');
}
public function put(Request $request): Response {
throw Exceptions::apiMethodNotAllowed();
}
public function delete(Request $request): Response {
throw Exceptions::apiMethodNotAllowed();
} }
} }

View File

@@ -4,6 +4,7 @@ namespace MailPoet\Automation\Engine;
class Hooks { class Hooks {
public const INITIALIZE = 'mailpoet/automation/initialize'; public const INITIALIZE = 'mailpoet/automation/initialize';
public const API_INITIALIZE = 'mailpoet/automation/api/initialize';
public const TRIGGER = 'mailpoet/automation/trigger'; public const TRIGGER = 'mailpoet/automation/trigger';
public const WORKFLOW_STEP = 'mailpoet/automation/workflow/step'; public const WORKFLOW_STEP = 'mailpoet/automation/workflow/step';
} }