From ee24ab8f6e60da19a3fb4908f8eda7dc2ccb5617 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Sun, 28 Mar 2021 17:45:39 +0300 Subject: [PATCH] runners refactoring --- api/v1/portal-access/index.php | 7 +- application/Espo/Core/Application.php | 16 +++- .../Espo/Core/Application/RunnerParams.php | 94 +++++++++++++++++++ .../Espo/Core/ApplicationRunners/Api.php | 11 ++- .../Espo/Core/ApplicationRunners/Client.php | 2 +- .../Espo/Core/ApplicationRunners/Command.php | 2 +- .../Core/ApplicationRunners/EntryPoint.php | 20 ++-- .../Espo/Core/ApplicationRunners/Job.php | 11 ++- .../Core/ApplicationRunners/PortalClient.php | 18 ++-- .../Espo/Core/ApplicationRunners/Rebuild.php | 2 +- application/Espo/Core/Job/JobTask.php | 7 +- .../Core/Portal/ApplicationRunners/Client.php | 4 +- application/Espo/Core/Portal/Utils/Url.php | 11 +++ index.php | 2 + portal/index.php | 5 +- 15 files changed, 167 insertions(+), 45 deletions(-) create mode 100644 application/Espo/Core/Application/RunnerParams.php diff --git a/api/v1/portal-access/index.php b/api/v1/portal-access/index.php index 4e16cd2c72..6d631214b1 100644 --- a/api/v1/portal-access/index.php +++ b/api/v1/portal-access/index.php @@ -32,12 +32,9 @@ require_once('../../../bootstrap.php'); use Espo\Core\{ Portal\Application, Portal\ApplicationRunners\Api, + Portal\Utils\Url, }; -if (!empty($_GET['portalId'])) { - $portalId = $_GET['portalId']; -} else { - $portalId = explode('/', $_SERVER['REQUEST_URI'])[count(explode('/', $_SERVER['SCRIPT_NAME'])) - 1]; -} +$portalId = Url::detectPortalIdForApi(); (new Application($portalId))->run(Api::class); diff --git a/application/Espo/Core/Application.php b/application/Espo/Core/Application.php index a872d67ce5..bd58429393 100644 --- a/application/Espo/Core/Application.php +++ b/application/Espo/Core/Application.php @@ -33,6 +33,8 @@ use Espo\Core\{ Container\ContainerBuilder, InjectableFactory, Container, + Application\Runner, + Application\RunnerParams, ApplicationUser, Utils\Autoload, Utils\Config, @@ -42,7 +44,6 @@ use Espo\Core\{ }; use ReflectionClass; -use StdClass; /** * A central access point of the application. @@ -66,9 +67,12 @@ class Application } /** - * Run a specific application runner. + * Run an application runner. + * + * @param $className A runner class name. + * @param $params Runner parameters. Will be passed to a runner's constructor. */ - public function run(string $className, ?StdClass $params = null) : void + public function run(string $className, ?RunnerParams $params = null) : void { if (!$className || !class_exists($className)) { $this->getLog()->error("Application runner '{$className}' does not exist."); @@ -89,9 +93,13 @@ class Application } $runner = $this->getInjectableFactory()->createWith($className, [ - 'params' => $params, + 'params' => $params ?? RunnerParams::fromNothing(), ]); + if (!$runner instanceof Runner) { + die("Class should implement Runner interface."); + } + $runner->run(); } diff --git a/application/Espo/Core/Application/RunnerParams.php b/application/Espo/Core/Application/RunnerParams.php new file mode 100644 index 0000000000..db4cba7555 --- /dev/null +++ b/application/Espo/Core/Application/RunnerParams.php @@ -0,0 +1,94 @@ +data[$name] ?? null; + } + + /** + * Whether a parameter is set. + */ + public function has(string $name) : bool + { + return array_key_exists($name, $this->data); + } + + /** + * Clone with a parameter value. + * + * @param ?mixed $value + */ + public function with(string $name, $value) : self + { + $obj = clone $this; + + $obj->data[$name] = $value; + + return $obj; + } + + /** + * Create from an array. + */ + public static function fromArray(array $data) : self + { + $obj = new self(); + + $obj->data = $data; + + return $obj; + } + + /** + * Create an empty instance. + */ + public static function fromNothing() : self + { + return new self(); + } +} diff --git a/application/Espo/Core/ApplicationRunners/Api.php b/application/Espo/Core/ApplicationRunners/Api.php index e6fff460e3..722683220c 100644 --- a/application/Espo/Core/ApplicationRunners/Api.php +++ b/application/Espo/Core/ApplicationRunners/Api.php @@ -107,7 +107,7 @@ class Api implements Runner $slim->run(); } - private function addRoute(SlimApp $slim, array $item) + private function addRoute(SlimApp $slim, array $item) : void { $method = strtolower($item['method']); $route = $item['route']; @@ -168,8 +168,10 @@ class Api implements Runner return $params; } - private function processRequest(array $item, RequestWrapper $requestWrapped, ResponseWrapper $responseWrapped) - { + private function processRequest( + array $item, RequestWrapper $requestWrapped, ResponseWrapper $responseWrapped + ) : void { + try { $authRequired = !($item['noAuth'] ?? false); @@ -204,7 +206,8 @@ class Api implements Runner private function handleException( Throwable $exception, RequestWrapper $requestWrapped, ResponseWrapper $responseWrapped, string $route - ) { + ) : void { + $errorOutput = new ApiErrorOutput($requestWrapped, $route); try { diff --git a/application/Espo/Core/ApplicationRunners/Client.php b/application/Espo/Core/ApplicationRunners/Client.php index 960212db5a..5eb2d4bc8e 100644 --- a/application/Espo/Core/ApplicationRunners/Client.php +++ b/application/Espo/Core/ApplicationRunners/Client.php @@ -39,7 +39,7 @@ use Espo\Core\{ */ class Client implements Runner { - protected $clientManager; + private $clientManager; public function __construct(ClientManager $clientManager) { diff --git a/application/Espo/Core/ApplicationRunners/Command.php b/application/Espo/Core/ApplicationRunners/Command.php index c4f73d9333..09721e9ed1 100644 --- a/application/Espo/Core/ApplicationRunners/Command.php +++ b/application/Espo/Core/ApplicationRunners/Command.php @@ -44,7 +44,7 @@ class Command implements Runner use Cli; use SetupSystemUser; - protected $commandManager; + private $commandManager; public function __construct(ConsoleCommandManager $commandManager) { diff --git a/application/Espo/Core/ApplicationRunners/EntryPoint.php b/application/Espo/Core/ApplicationRunners/EntryPoint.php index 17830dd6d7..6d2f00c161 100644 --- a/application/Espo/Core/ApplicationRunners/EntryPoint.php +++ b/application/Espo/Core/ApplicationRunners/EntryPoint.php @@ -31,6 +31,7 @@ namespace Espo\Core\ApplicationRunners; use Espo\Core\{ Application\Runner, + Application\RunnerParams, Exceptions\Error, EntryPoint\EntryPointManager, ApplicationUser, @@ -52,7 +53,6 @@ use Slim\{ Psr7\Response, }; -use StdClass; use Exception; /** @@ -84,7 +84,7 @@ class EntryPoint implements Runner ApplicationUser $applicationUser, AuthTokenManager $authTokenManager, AuthBuilderFactory $authBuilderFactory, - ?StdClass $params = null + ?RunnerParams $params = null ) { $this->authenticationFactory = $authenticationFactory; $this->entryPointManager = $entryPointManager; @@ -94,7 +94,7 @@ class EntryPoint implements Runner $this->authTokenManager = $authTokenManager; $this->authBuilderFactory = $authBuilderFactory; - $this->params = $params ?? (object) []; + $this->params = $params ?? RunnerParams::fromNothing(); } public function run() : void @@ -108,9 +108,9 @@ class EntryPoint implements Runner throw new Error("Only GET requests allowed for entry points."); } - $entryPoint = $this->params->entryPoint ?? $requestWrapped->getQueryParam('entryPoint'); + $entryPoint = $this->params->get('entryPoint') ?? $requestWrapped->getQueryParam('entryPoint'); - $final = $this->params->final ?? false; + $final = $this->params->get('final') ?? false; if (!$entryPoint) { throw new Error(); @@ -136,7 +136,7 @@ class EntryPoint implements Runner (new ResponseEmitter())->emit($responseWrapped->getResponse()); } - protected function processRequest( + private function processRequest( string $entryPoint, RequestWrapper $requestWrapped, ResponseWrapper $responseWrapped, @@ -181,7 +181,7 @@ class EntryPoint implements Runner } } - protected function detectPortalId(RequestWrapper $requestWrapped) : ?string + private function detectPortalId(RequestWrapper $requestWrapped) : ?string { if ($requestWrapped->hasQueryParam('portalId')) { return $requestWrapped->getQueryParam('portalId'); @@ -202,15 +202,17 @@ class EntryPoint implements Runner return null; } - protected function runThroughPortal(string $portalId, string $entryPoint) : void + private function runThroughPortal(string $portalId, string $entryPoint) : void { $app = new PortalApplication($portalId); $app->setClientBasePath($this->clientManager->getBasePath()); - $app->run(EntryPoint::class, (object) [ + $params = RunnerParams::fromArray([ 'entryPoint' => $entryPoint, 'final' => true, ]); + + $app->run(EntryPoint::class, $params); } } diff --git a/application/Espo/Core/ApplicationRunners/Job.php b/application/Espo/Core/ApplicationRunners/Job.php index df99a98a64..e6d7d973a7 100644 --- a/application/Espo/Core/ApplicationRunners/Job.php +++ b/application/Espo/Core/ApplicationRunners/Job.php @@ -31,11 +31,10 @@ namespace Espo\Core\ApplicationRunners; use Espo\Core\{ Application\Runner, + Application\RunnerParams, Job\JobManager, }; -use StdClass; - /** * Runs a job by ID. A job record should exist in database. */ @@ -44,11 +43,11 @@ class Job implements Runner use Cli; use SetupSystemUser; - protected $params; + private $params; private $jobManager; - public function __construct(JobManager $jobManager, StdClass $params) + public function __construct(JobManager $jobManager, RunnerParams $params) { $this->jobManager = $jobManager; @@ -57,6 +56,8 @@ class Job implements Runner public function run() : void { - $this->jobManager->runJobById($this->params->id); + $id = $this->params->get('id'); + + $this->jobManager->runJobById($id); } } diff --git a/application/Espo/Core/ApplicationRunners/PortalClient.php b/application/Espo/Core/ApplicationRunners/PortalClient.php index 6003d1511a..fa4f7505a0 100644 --- a/application/Espo/Core/ApplicationRunners/PortalClient.php +++ b/application/Espo/Core/ApplicationRunners/PortalClient.php @@ -31,6 +31,7 @@ namespace Espo\Core\ApplicationRunners; use Espo\Core\{ Application\Runner, + Application\RunnerParams, Exceptions\NotFound, Utils\ClientManager, Utils\Config, @@ -48,7 +49,6 @@ use Slim\{ Psr7\Response, }; -use StdClass; use Exception; /** @@ -56,27 +56,27 @@ use Exception; */ class PortalClient implements Runner { - protected $params; + private $params; - protected $clientManager; + private $clientManager; - protected $config; + private $config; - public function __construct(ClientManager $clientManager, Config $config, ?StdClass $params = null) + public function __construct(ClientManager $clientManager, Config $config, ?RunnerParams $params = null) { $this->clientManager = $clientManager; $this->config = $config; - $this->params = $params ?? (object) []; + $this->params = $params ?? RunnerParams::fromNothing(); } public function run() : void { - $id = $this->params->id ?? + $id = $this->params->get('id') ?? Url::detectPortalId() ?? $this->config->get('defaultPortalId'); - $basePath = $this->params->basePath ?? $this->clientManager->getBasePath(); + $basePath = $this->params->get('basePath') ?? $this->clientManager->getBasePath(); $requestWrapped = new RequestWrapper( ServerRequestCreatorFactory::create()->createServerRequestFromGlobals() @@ -108,7 +108,7 @@ class PortalClient implements Runner $application->run(PortalPortalClient::class); } - protected function processError(RequestWrapper $request, ResponseWrapper $response, Exception $exception) + private function processError(RequestWrapper $request, ResponseWrapper $response, Exception $exception) : void { (new ApiErrorOutput($request))->process($response, $exception, true); diff --git a/application/Espo/Core/ApplicationRunners/Rebuild.php b/application/Espo/Core/ApplicationRunners/Rebuild.php index 61d23f96d6..95e9627273 100644 --- a/application/Espo/Core/ApplicationRunners/Rebuild.php +++ b/application/Espo/Core/ApplicationRunners/Rebuild.php @@ -41,7 +41,7 @@ class Rebuild implements Runner { use Cli; - protected $dataManager; + private $dataManager; public function __construct(DataManager $dataManager) { diff --git a/application/Espo/Core/Job/JobTask.php b/application/Espo/Core/Job/JobTask.php index 9d02904742..c72cf46ac0 100644 --- a/application/Espo/Core/Job/JobTask.php +++ b/application/Espo/Core/Job/JobTask.php @@ -32,6 +32,7 @@ namespace Espo\Core\Job; use Espo\Core\{ Application, ApplicationRunners\Job as JobRunner, + Application\RunnerParams, }; use Spatie\Async\Task as AsyncTask; @@ -55,12 +56,12 @@ class JobTask extends AsyncTask { $app = new Application(); - $data = (object) [ + $params = RunnerParams::fromArray([ 'id' => $this->jobId, - ]; + ]); try { - $app->run(JobRunner::class, $data); + $app->run(JobRunner::class, $params); } catch (Throwable $e) { $GLOBALS['log']->error( diff --git a/application/Espo/Core/Portal/ApplicationRunners/Client.php b/application/Espo/Core/Portal/ApplicationRunners/Client.php index ea4236ebb0..a4989173a8 100644 --- a/application/Espo/Core/Portal/ApplicationRunners/Client.php +++ b/application/Espo/Core/Portal/ApplicationRunners/Client.php @@ -40,9 +40,9 @@ use Espo\Core\{ */ class Client implements Runner { - protected $clientManager; + private $clientManager; - protected $applicationState; + private $applicationState; public function __construct(ClientManager $clientManager, ApplicationState $applicationState) { diff --git a/application/Espo/Core/Portal/Utils/Url.php b/application/Espo/Core/Portal/Utils/Url.php index 51bda285ad..ef89bd3f59 100644 --- a/application/Espo/Core/Portal/Utils/Url.php +++ b/application/Espo/Core/Portal/Utils/Url.php @@ -31,6 +31,17 @@ namespace Espo\Core\Portal\Utils; class Url { + public static function detectPortalIdForApi() : ?string + { + if (!empty($_GET['portalId'])) { + return $_GET['portalId']; + } + + $url = $_SERVER['REQUEST_URI']; + + return explode('/', $url)[count(explode('/', $_SERVER['SCRIPT_NAME'])) - 1] ?? null; + } + public static function detectPortalId() : ?string { $portalId = $_SERVER['ESPO_PORTAL_ID'] ?? null; diff --git a/index.php b/index.php index 4ddf7b3226..0843edc0b7 100644 --- a/index.php +++ b/index.php @@ -39,11 +39,13 @@ $app = new Application(); if (!$app->isInstalled()) { header("Location: install/"); + exit; } if (!empty($_GET['entryPoint'])) { $app->run(EntryPoint::class); + exit; } diff --git a/portal/index.php b/portal/index.php index bd15da965f..004de2edc7 100644 --- a/portal/index.php +++ b/portal/index.php @@ -31,6 +31,7 @@ include "../bootstrap.php"; use Espo\Core\{ Application, + Application\RunnerParams, ApplicationRunners\EntryPoint, ApplicationRunners\PortalClient, Portal\Utils\Url, @@ -58,6 +59,8 @@ if (!empty($_GET['entryPoint'])) { exit; } -$app->run(PortalClient::class, (object) [ +$params = RunnerParams::fromArray([ 'basePath' => $basePath, ]); + +$app->run(PortalClient::class, $params);