ConfigLoader::class, 'log' => LogLoader::class, 'fileManager' => FileManagerLoader::class, 'dataManager' => DataManagerLoader::class, 'metadata' => MetadataLoader::class, ]; public function __construct() { date_default_timezone_set('UTC'); $this->initContainer(); $this->initAutoloads(); $this->initPreloads(); } protected function initContainer() { $this->container = new Container(ContainerConfiguration::class, $this->loaderClassNames); } public function run(string $name = 'default') { $this->routeHooks(); $this->initRoutes(); $this->getSlim()->run(); } public function runClient() { $this->container->get('clientManager')->display(); exit; } public function runEntryPoint(string $entryPoint, array $data = [], bool $final = false) { if (empty($entryPoint)) { throw new Error(); } $slim = $this->getSlim(); $container = $this->container; $slim->any('.*', function() {}); $injectableFactory = $container->get('injectableFactory'); $classFinder = $container->get('classFinder'); $entryPointManager = new EntryPointManager($injectableFactory, $classFinder); try { $authRequired = $entryPointManager->checkAuthRequired($entryPoint); $authNotStrict = $entryPointManager->checkNotStrictAuth($entryPoint); if ($authRequired && !$authNotStrict) { if (!$final && $portalId = $this->detectPortalId()) { $app = new PortalApplication($portalId); $app->setBasePath($this->getBasePath()); $app->runEntryPoint($entryPoint, $data, true); exit; } } $auth = new Auth($this->container, $authNotStrict); $apiAuth = new ApiAuth($auth, $authRequired, true); $slim->add($apiAuth); $request = $slim->request(); $slim->hook('slim.before.dispatch', function () use ($entryPointManager, $entryPoint, $request, $data) { $entryPointManager->run($entryPoint, $request, $data); }); $slim->run(); } catch (\Exception $e) { try { $container->get('output')->processError($e->getMessage(), $e->getCode(), true, $e); } catch (\Slim\Exception\Stop $e) {} } } public function runCron() { if ($this->getConfig()->get('cronDisabled')) { $GLOBALS['log']->warning("Cron is not run because it's disabled with 'cronDisabled' param."); return; } $auth = $this->createAuth(); $auth->useNoAuth(); $cronManager = $this->container->get('cronManager'); $cronManager->run(); } public function runDaemon() { $maxProcessNumber = $this->getConfig()->get('daemonMaxProcessNumber'); $interval = $this->getConfig()->get('daemonInterval'); $timeout = $this->getConfig()->get('daemonProcessTimeout'); $phpExecutablePath = $this->getConfig()->get('phpExecutablePath'); if (!$phpExecutablePath) { $phpExecutablePath = (new \Symfony\Component\Process\PhpExecutableFinder)->find(); } if (!$maxProcessNumber || !$interval) { $GLOBALS['log']->error("Daemon config params are not set."); return; } $processList = []; while (true) { $toSkip = false; $runningCount = 0; foreach ($processList as $i => $process) { if ($process->isRunning()) { $runningCount++; } else { unset($processList[$i]); } } $processList = array_values($processList); if ($runningCount >= $maxProcessNumber) { $toSkip = true; } if (!$toSkip) { $process = new \Symfony\Component\Process\Process([$phpExecutablePath, 'cron.php']); $process->setTimeout($timeout); $process->run(); $processList[] = $process; } sleep($interval); } } public function runJob(string $id) { $auth = $this->createAuth(); $auth->useNoAuth(); $cronManager = $this->container->get('cronManager'); $cronManager->runJobById($id); } public function runRebuild() { $dataManager = $this->container->get('dataManager'); $dataManager->rebuild(); } public function runClearCache() { $dataManager = $this->container->get('dataManager'); $dataManager->clearCache(); } public function runCommand(string $command) { $auth = $this->createAuth(); $auth->useNoAuth(); $consoleCommandManager = $this->container->get('consoleCommandManager'); return $consoleCommandManager->run($command); } public function isInstalled() : bool { $config = $this->getConfig(); if (file_exists($config->getConfigPath()) && $config->get('isInstalled')) { return true; } return false; } public function getContainer() : Container { return $this->container; } protected function getSlim() { if (!$this->slim) { $this->slim = $this->container->get('slim'); } return $this->slim; } protected function getMetadata() { if (!$this->metadata) { $this->metadata = $this->container->get('metadata'); } return $this->metadata; } protected function createAuth() { return new Auth($this->container); } protected function getConfig() { return $this->container->get('config'); } protected function createApiAuth(Auth $auth) : ApiAuth { return new ApiAuth($auth); } protected function routeHooks() { $container = $this->container; $slim = $this->getSlim(); try { $auth = $this->createAuth(); } catch (\Exception $e) { $container->get('output')->processError($e->getMessage(), $e->getCode(), false, $e); } $apiAuth = $this->createApiAuth($auth); $this->getSlim()->add($apiAuth); $this->getSlim()->hook('slim.before.dispatch', function () use ($slim, $container) { $route = $slim->router()->getCurrentRoute(); $conditions = $route->getConditions(); $response = $slim->response(); $response->headers->set('Content-Type', 'application/json'); if (isset($conditions['useController']) && $conditions['useController'] == false) { return; } $routeOptions = call_user_func($route->getCallable()); $routeKeys = is_array($routeOptions) ? array_keys($routeOptions) : []; if (!in_array('controller', $routeKeys, true)) { return $container->get('output')->render($routeOptions); } $params = $route->getParams(); $data = $slim->request()->getBody(); foreach ($routeOptions as $key => $value) { if (strstr($value, ':')) { $paramName = str_replace(':', '', $value); $value = $params[$paramName]; } $controllerParams[$key] = $value; } $params = array_merge($params, $controllerParams); $controllerName = ucfirst($controllerParams['controller']); if (!empty($controllerParams['action'])) { $actionName = $controllerParams['action']; } else { $httpMethod = strtolower($slim->request()->getMethod()); $crudList = $container->get('config')->get('crud'); $actionName = $crudList[$httpMethod] ?? null; if (!$actionName) { throw new Error("No action for {$httpMethod} request."); } } try { $controllerManager = $this->container->get('controllerManager'); $result = $controllerManager->process( $controllerName, $actionName, $params, $data, $slim->request(), $slim->response() ); $container->get('output')->render($result); } catch (\Exception $e) { $container->get('output')->processError($e->getMessage(), $e->getCode(), false, $e); } }); $this->getSlim()->hook('slim.after.router', function () use (&$slim) { $response = $slim->response(); if (!$response->headers->has('Content-Type')) { $response->headers->set('Content-Type', 'application/json'); } $response->headers->set('Expires', '0'); $response->headers->set('Last-Modified', gmdate("D, d M Y H:i:s") . " GMT"); $response->headers->set('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'); $response->headers->set('Pragma', 'no-cache'); }); } protected function getRouteList() { $routes = new Route($this->getConfig(), $this->getMetadata(), $this->container->get('fileManager')); return $routes->getAll(); } protected function initRoutes() { $crudList = array_keys($this->getConfig()->get('crud')); foreach ($this->getRouteList() as $route) { $method = strtolower($route['method']); if (!in_array($method, $crudList) && $method !== 'options') { $GLOBALS['log']->error( 'Route: Method ['.$method.'] does not exist. Please check your route ['.$route['route'].']' ); continue; } $currentRoute = $this->getSlim()->$method($route['route'], function() use ($route) { return $route['params']; }); if (isset($route['conditions'])) { $currentRoute->conditions($route['conditions']); } } } protected function initAutoloads() { $autoload = new Autoload($this->getConfig(), $this->getMetadata(), $this->container->get('fileManager')); $autoload->register(); } protected function initPreloads() { foreach ($this->getMetadata()->get(['app', 'containerServices']) ?? [] as $name => $defs) { if ($defs['preload'] ?? false) { $this->container->get($name); } } } public function setBasePath(string $basePath) { $this->container->get('clientManager')->setBasePath($basePath); } public function getBasePath() : string { return $this->container->get('clientManager')->getBasePath(); } public function detectPortalId() : ?string { if (!empty($_GET['portalId'])) { return $_GET['portalId']; } if (!empty($_COOKIE['auth-token'])) { $token = $this->container->get('entityManager') ->getRepository('AuthToken')->where(['token' => $_COOKIE['auth-token']])->findOne(); if ($token && $token->get('portalId')) { return $token->get('portalId'); } } return null; } public function setupSystemUser() { $user = $this->container->get('entityManager')->getEntity('User', 'system'); $user->set('isAdmin', true); // TODO remove in 5.7 $user->set('type', 'system'); $this->container->set('user', $user); $this->container->get('entityManager')->setUser($user); } }