runners refactoring

This commit is contained in:
Yuri Kuznetsov
2021-03-28 17:45:39 +03:00
parent e89ca133cd
commit ee24ab8f6e
15 changed files with 167 additions and 45 deletions

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -0,0 +1,94 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Core\Application;
/**
* Parameters for an application runner.
*/
class RunnerParams
{
private $data;
private function __construct()
{
}
/**
* Get a parameter value.
*
* @return ?mixed
*/
public function get(string $name)
{
return $this->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();
}
}

View File

@@ -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 {

View File

@@ -39,7 +39,7 @@ use Espo\Core\{
*/
class Client implements Runner
{
protected $clientManager;
private $clientManager;
public function __construct(ClientManager $clientManager)
{

View File

@@ -44,7 +44,7 @@ class Command implements Runner
use Cli;
use SetupSystemUser;
protected $commandManager;
private $commandManager;
public function __construct(ConsoleCommandManager $commandManager)
{

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -41,7 +41,7 @@ class Rebuild implements Runner
{
use Cli;
protected $dataManager;
private $dataManager;
public function __construct(DataManager $dataManager)
{

View File

@@ -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(

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -39,11 +39,13 @@ $app = new Application();
if (!$app->isInstalled()) {
header("Location: install/");
exit;
}
if (!empty($_GET['entryPoint'])) {
$app->run(EntryPoint::class);
exit;
}

View File

@@ -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);