diff --git a/api/v1/index.php b/api/v1/index.php index 10f6f00dac..fce4db8c4e 100644 --- a/api/v1/index.php +++ b/api/v1/index.php @@ -29,5 +29,4 @@ require_once('../../bootstrap.php'); -$app = new \Espo\Core\Application(); -$app->runApi(); +(new \Espo\Core\Application())->run('api'); diff --git a/api/v1/portal-access/index.php b/api/v1/portal-access/index.php index 0cd1872434..73519a2dd6 100644 --- a/api/v1/portal-access/index.php +++ b/api/v1/portal-access/index.php @@ -35,5 +35,4 @@ if (!empty($_GET['portalId'])) { $portalId = explode('/', $_SERVER['REQUEST_URI'])[count(explode('/', $_SERVER['SCRIPT_NAME'])) - 1]; } -$app = new \Espo\Core\Portal\Application($portalId); -$app->runApi(); +(new \Espo\Core\Portal\Application($portalId))->run('api'); diff --git a/application/Espo/Core/Application.php b/application/Espo/Core/Application.php index 17b3232a9d..7a14cadc68 100644 --- a/application/Espo/Core/Application.php +++ b/application/Espo/Core/Application.php @@ -29,22 +29,11 @@ namespace Espo\Core; -use Espo\Core\Exceptions\{ - Error, -}; - use Espo\Core\{ ContainerConfiguration, InjectableFactory, Container, ApplicationUser, - Authentication\Authentication, - Api\Auth as ApiAuth, - Api\ErrorOutput as ApiErrorOutput, - Api\RequestWrapper, - Api\ResponseWrapper, - Api\RouteProcessor, - Utils\Route, Utils\Autoload, Utils\Config, Utils\Metadata, @@ -57,17 +46,6 @@ use Espo\Core\{ Loaders\Metadata as MetadataLoader, }; -use Psr\Http\{ - Message\ResponseInterface as Response, - Message\ServerRequestInterface as Request, - Server\RequestHandlerInterface as RequestHandler, -}; - -use Slim\{ - App as SlimApp, - Factory\AppFactory as SlimAppFactory, -}; - use ReflectionClass; /** @@ -77,10 +55,6 @@ class Application { protected $container; - protected $slim = null; - - protected $log; - protected $loaderClassNames = [ 'config' => ConfigLoader::class, 'log' => LogLoader::class, @@ -103,63 +77,6 @@ class Application $this->container = new Container(ContainerConfiguration::class, $this->loaderClassNames); } - /** - * Run REST API. - */ - public function runApi() - { - $slim = $this->createSlimApp(); - $slim->addRoutingMiddleware(); - - $crudList = array_keys($this->getConfig()->get('crud')); - - $routeList = $this->getRouteList(); - - foreach ($routeList as $item) { - $method = strtolower($item['method']); - $route = $item['route']; - - if (!in_array($method, $crudList) && $method !== 'options') { - $this->getLog()->error("Route: Method '{$method}' does not exist. Check the route '{$route}'."); - continue; - } - - $slim->$method( - $route, - function (Request $request, Response $response, array $args) use ($item, $slim) { - $requestWrapped = new RequestWrapper($request, $slim->getBasePath()); - $responseWrapped = new ResponseWrapper($response); - - try { - $authRequired = !($item['noAuth'] ?? false); - - $apiAuth = new ApiAuth($this->createAuthentication(), $authRequired); - $apiAuth->process($requestWrapped, $responseWrapped); - - if (!$apiAuth->isResolved()) { - return $responseWrapped->getResponse(); - } - if ($apiAuth->isResolvedUseNoAuth()) { - $this->setupSystemUser(); - } - - $routeProcessor = $this->getInjectableFactory()->create(RouteProcessor::class); - $routeProcessor->process($item['route'], $item['params'], $requestWrapped, $responseWrapped, $args); - } catch (\Exception $exception) { - (new ApiErrorOutput($requestWrapped))->process( - $responseWrapped, $exception, false, $item, $args - ); - } - - return $responseWrapped->getResponse(); - } - ); - } - - $slim->addErrorMiddleware(false, true, true); - $slim->run(); - } - /** * Run an application through a specific runner. * You can find runner classes in `Espo\Core\ApplicationRunners`. @@ -255,20 +172,6 @@ class Application return $this->container->get('config'); } - protected function createSlimApp() : SlimApp - { - $slim = SlimAppFactory::create(); - $slim->setBasePath(Route::detectBasePath()); - return $slim; - } - - protected function createAuthentication(bool $allowAnyAccess = false) : Authentication - { - return $this->getInjectableFactory()->createWith(Authentication::class, [ - 'allowAnyAccess' => $allowAnyAccess, - ]); - } - protected function initAutoloads() { $autoload = $this->getInjectableFactory()->create(Autoload::class); @@ -287,11 +190,6 @@ class Application } } - protected function getRouteList() : array - { - return $this->getInjectableFactory()->create(Route::class)->getFullList(); - } - /** * Set a base path of an index file related to the application directory. Used for a portal. */ diff --git a/application/Espo/Core/ApplicationRunners/Api.php b/application/Espo/Core/ApplicationRunners/Api.php new file mode 100644 index 0000000000..a532536d23 --- /dev/null +++ b/application/Espo/Core/ApplicationRunners/Api.php @@ -0,0 +1,135 @@ +injectableFactory = $injectableFactory; + $this->applicationUser = $applicationUser; + $this->config = $config; + } + + public function run() + { + $slim = SlimAppFactory::create(); + $slim->setBasePath(Route::detectBasePath()); + $slim->addRoutingMiddleware(); + + $crudList = array_keys($this->config->get('crud')); + + $routeList = $this->getRouteList(); + + foreach ($routeList as $item) { + $method = strtolower($item['method']); + $route = $item['route']; + + if (!in_array($method, $crudList) && $method !== 'options') { + $GLOBALS['log']->error("Route: Method '{$method}' does not exist. Check the route '{$route}'."); + continue; + } + + $slim->$method( + $route, + function (Psr7Request $request, Psr7Response $response, array $args) use ($item, $slim) { + $requestWrapped = new RequestWrapper($request, $slim->getBasePath()); + $responseWrapped = new ResponseWrapper($response); + + try { + $authRequired = !($item['noAuth'] ?? false); + + $authentication = $this->injectableFactory->create(Authentication::class); + + $apiAuth = new ApiAuth($authentication, $authRequired); + $apiAuth->process($requestWrapped, $responseWrapped); + + if (!$apiAuth->isResolved()) { + return $responseWrapped->getResponse(); + } + if ($apiAuth->isResolvedUseNoAuth()) { + $this->applicationUser->setupSystemUser(); + } + + $routeProcessor = $this->injectableFactory->create(RouteProcessor::class); + $routeProcessor->process($item['route'], $item['params'], $requestWrapped, $responseWrapped, $args); + } catch (Exception $exception) { + (new ApiErrorOutput($requestWrapped))->process( + $responseWrapped, $exception, false, $item, $args + ); + } + + return $responseWrapped->getResponse(); + } + ); + } + + $slim->addErrorMiddleware(false, true, true); + $slim->run(); + } + + protected function getRouteList() : array + { + return $this->injectableFactory->create(Route::class)->getFullList(); + } +} diff --git a/application/Espo/Core/Portal/Application.php b/application/Espo/Core/Portal/Application.php index 33cbabaa6f..1a9fa235c5 100644 --- a/application/Espo/Core/Portal/Application.php +++ b/application/Espo/Core/Portal/Application.php @@ -94,22 +94,6 @@ class Application extends BaseApplication return $this->portal; } - protected function getRouteList() : array - { - $routeList = parent::getRouteList(); - - foreach ($routeList as $i => $route) { - if (isset($route['route'])) { - if ($route['route']{0} !== '/') { - $route['route'] = '/' . $route['route']; - } - $route['route'] = '/{portalId}' . $route['route']; - } - $routeList[$i] = $route; - } - return $routeList; - } - protected function getRunnerClassName(string $runnerName) : ?string { $className = 'Espo\\Core\\Portal\\ApplicationRunners\\' . ucfirst($runnerName); diff --git a/application/Espo/Core/Portal/ApplicationRunners/Api.php b/application/Espo/Core/Portal/ApplicationRunners/Api.php new file mode 100644 index 0000000000..5aa306291c --- /dev/null +++ b/application/Espo/Core/Portal/ApplicationRunners/Api.php @@ -0,0 +1,53 @@ + $route) { + if (isset($route['route'])) { + if ($route['route']{0} !== '/') { + $route['route'] = '/' . $route['route']; + } + $route['route'] = '/{portalId}' . $route['route']; + } + $routeList[$i] = $route; + } + return $routeList; + } +}