/** * {@inheritdoc} */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response, \Closure $next) { $cookies = $request->getCookieParams(); $outerID = null; if (isset($cookies[self::COOKIE])) { if ($this->store()->isStarted()) { $outerID = $this->store()->getID(); } //Mounting ID retrieved from cookies $this->store()->setID($cookies[self::COOKIE]); } $response = $next(); if (empty($this->store) && $this->container->hasInstance(SessionStore::class)) { //Store were started by itself $this->store = $this->container->get(SessionStore::class); } if (!empty($this->store) && ($this->store->isStarted() || $this->store->isDestroyed())) { $response = $this->setCookie($request, $response, $this->store, $cookies); } //Restoring original session, not super efficient operation if (!empty($outerID)) { $this->store->setID($outerID); } return $response; }
/** * Initiate set of modifiers. * * @return ModifierInterface[] */ protected function getModifiers() { foreach ($this->modifiers as $index => $modifier) { if (!is_object($modifier)) { //Initiating using container $this->modifiers[$index] = $this->container->make($modifier, ['environment' => $this->environment]); } } return $this->modifiers; }
/** * Configure logger handlers. * * @param Logger $logger */ public function configureLogger(Logger $logger) { if (!isset($this->config['loggers'][$logger->getName()])) { //Nothing to configure return; } foreach ($this->config['loggers'][$logger->getName()] as $logLevel => $handler) { $logger->setHandler($logLevel, $this->container->construct($handler['class'], ['options' => $handler])); } }
/** * {@inheritdoc} */ public function __invoke(Request $request, Response $response, callable $next) { $this->initSession($request); $scope = $this->container->replace(SessionInterface::class, $this->session); try { $response = $next($request->withAttribute('session', $this->session), $response); } finally { $this->container->restore($scope); } return $this->commitSession($request, $response); }
/** * Get active instance of ServerRequestInterface. * * @return ServerRequestInterface */ public function request() { //Check if we still pointing to right request if ($this->request !== $this->container->get(ServerRequestInterface::class)) { $this->request = null; //Our parameter bags has expired $this->bagInstances = []; //Update instance $this->request = $this->container->get(ServerRequestInterface::class); } return $this->request; }
/** * {@inheritdoc} */ public function getValue($dependency) { if (!isset($this->dependencies[$dependency])) { throw new EnvironmentException("Undefined environment variable '{$dependency}'."); } $source = $this->dependencies[$dependency]; if (is_array($source) && is_string($source[0])) { //Let's resolve using container $source[0] = $this->container->get($source[0]); $this->dependencies[$dependency] = $source; } return call_user_func($source); }
/** * Get or create encrypter instance. * * @return EncrypterInterface */ protected function encrypter() { if (empty($this->encrypter)) { $this->encrypter = $this->container->get(EncrypterInterface::class); } return $this->encrypter; }
/** * {@inheritdoc} */ public function __invoke(Request $request, Response $response, callable $next) { $context = $this->createContext($request); $scope = $this->container->replace(ContextInterface::class, $context); try { $response = $next($request->withAttribute('auth', $context), $response); } finally { $this->container->restore($scope); } if ($context->hasToken()) { $response = $this->updateToken($request, $response, $context); } elseif ($context->hasUser()) { $response = $this->createToken($request, $response, $context); } return $response; }
/** * {@inheritdoc} * * @param \SessionHandler $handler Custom session handler. */ public function start(\SessionHandler $handler = null) { if ($this->started) { return true; } //We don't need cookies ini_set('session.use_cookies', false); !empty($this->id) && session_id($this->id); if (empty($handler)) { $defaultHandler = $this->config['handler']; if ($defaultHandler != self::NATIVE_HANDLER) { $config = $this->config['handlers'][$this->config['handler']]; $benchmark = $this->benchmark('handler', $this->config['handler']); $handler = $this->handler = $this->container->construct($config['class'], ['options' => $config, 'lifetime' => $this->config['lifetime']]); $this->benchmark($benchmark); } } !empty($handler) && session_set_save_handler($handler, true); try { $benchmark = $this->benchmark('start'); session_start(); $this->benchmark($benchmark); $this->id = session_id(); $this->started = true; $this->destroyed = false; } catch (\ErrorException $exception) { throw new SessionException($exception->getMessage(), $exception->getCode()); } return true; }
/** * {@inheritdoc} */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response) { $scope = $this->container->replace(RouterInterface::class, $this); try { $route = $this->findRoute($request); if (empty($route)) { //Unable to locate route throw new ClientException(ClientException::NOT_FOUND); } //IoC container context $response = $route->withContainer($this->container)->perform($request->withAttribute('route', $route), $response); } finally { $this->container->restore($scope); } return $response; }
/** * @final For my own reasons (i have some ideas), please use SaturableInterface and init method. * @param InputManager $input * @param ContainerInterface $container */ public final function __construct(InputManager $input, ContainerInterface $container) { $this->input = $input; foreach ($this->schema as $field => $source) { list($source, $origin) = $this->parseSource($field, $source); if (!method_exists($input, $source)) { throw new FilterException("Undefined source '{$source}'."); } //Receiving value as result of InputManager method $this->setField($field, call_user_func([$input, $source], $origin), true); } if (method_exists($this, SaturableInterface::SATURATE_METHOD) && !$this instanceof SaturableInterface) { $method = new \ReflectionMethod($this, SaturableInterface::SATURATE_METHOD); //Executing init method call_user_func_array([$this, SaturableInterface::SATURATE_METHOD], $container->resolveArguments($method)); } }
/** * Get instance of compiler associated with specified namespace and view. * * @param string $namespace * @param string $view * @param string $engine Selected engine name. * @return CompilerInterface|null * @throws ContainerException */ private function compiler($namespace, $view, &$engine = null) { $filename = $this->getFilename($namespace, $view, $engine); if (empty($this->config['engines'][$engine]['compiler'])) { return null; } return $this->container->get($this->config['engines'][$engine]['compiler'], ['views' => $this, 'config' => $this->config['engines'][$engine], 'namespace' => $namespace, 'view' => $view, 'filename' => $filename]); }
/** * @param Debugger $debugger * @param ORM $orm * @param ContainerInterface $container * @param ClassLocator $locator */ public function perform(Debugger $debugger, ORM $orm, ContainerInterface $container, ClassLocator $locator) { //We don't really need location errors here $locator->setLogger(new NullLogger()); $benchmark = $debugger->benchmark($this, 'update'); $builder = $orm->schemaBuilder($locator); //To make builder available for other commands (in sequence) $container->bind(get_class($builder), $builder); if (!$this->option('sync')) { $this->writeln("<comment>Silent mode on, no databases to be altered.</comment>"); } $orm->updateSchema($builder, $this->option('sync')); $elapsed = number_format($debugger->benchmark($this, $benchmark), 3); $countModels = count($builder->getRecords()); $this->write("<info>ORM Schema has been updated: <comment>{$elapsed} s</comment>"); $this->writeln(", found records: <comment>{$countModels}</comment></info>"); }
/** * Execute endpoint and return it's result. * * @param ServerRequestInterface $request * @param ResponseInterface $response * @return mixed */ protected function execute(ServerRequestInterface $request, ResponseInterface $response) { if ($this->target instanceof \Closure) { $reflection = new \ReflectionFunction($this->target); return $reflection->invokeArgs($this->container->resolveArguments($reflection, compact('request', 'response'))); } //Calling pipeline target (do we need reflection here?) return call_user_func($this->target, $request, $response); }
/** * Default endpoint. * * @return callable|null */ protected function endpoint() { if (!is_string($this->endpoint)) { //Presumably callable return $this->endpoint; } //Specified as class name return $this->container->get($this->endpoint); }
/** * {@inheritdoc} */ protected function createEndpoint(ContainerInterface $container) { if (is_object($this->target) || is_array($this->target)) { return $this->target; } if (is_string($this->target) && strpos($this->target, self::SEPARATOR) === false) { //Endpoint return $container->get($this->target); } $route = $this; return function () use($container, $route) { list($controller, $action) = explode(self::SEPARATOR, $route->target); if ($action == self::DYNAMIC_ACTION) { $action = $route->matches['action']; } return $route->callAction($container, $controller, $action, $route->matches); }; }
/** * {@inheritdoc} */ public function __invoke(Request $request, Response $response, callable $next) { $outputLevel = ob_get_level(); try { /** * Debug: exceptions and clientExceptions are isolated in this middleware. */ return $next($request, $response); } catch (ClientException $exception) { while (ob_get_level() > $outputLevel) { //Flushing all unclosed buffers ob_end_clean(); } //Logging client error $this->logError($request, $exception); $writer = $this->container->get(ErrorWriter::class); return $writer->writeException($request, $response, $exception); } }
/** * Create processors list based on compiler configuration. * * @return ProcessorInterface[] * @throws ContainerException */ public function getProcessors() { if (!empty($this->processors)) { return $this->processors; } foreach ($this->config['processors'] as $processor => $options) { $this->processors[] = $this->container->get($processor, ['views' => $this->views, 'compiler' => $this, 'options' => $options]); } return $this->processors; }
/** * {@inheritdoc} * * @throws CacheException */ public function createInjection(\ReflectionClass $class, $context) { if (!$class->isInstantiable()) { return $this->store(); } $store = $this->container->construct($class->getName(), ['cache' => $this]); if (!$store->isAvailable()) { throw new CacheException("Unable to use store '" . get_class($store) . "', driver is unavailable."); } return $store; }
/** * {@inheritdoc} */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response) { //Open router scope $outerRouter = $this->container->replace(self::class, $this); if (empty($this->activeRoute = $this->findRoute($request, $this->basePath))) { throw new ClientException(ClientException::NOT_FOUND); } //Default routes will understand about keepOutput $response = $this->activeRoute->perform($request->withAttribute('route', $this->activeRoute), $response, $this->container); //Close router scope $this->container->restore($outerRouter); return $response; }
/** * {@inheritdoc} */ public function server($server, array $options = []) { if (isset($this->servers[$server])) { return $this->servers[$server]; } if (!empty($options)) { $this->config['servers'][$server] = $options; } if (!array_key_exists($server, $this->config['servers'])) { throw new StorageException("Undefined storage server '{$server}'."); } $config = $this->config['servers'][$server]; return $this->servers[$server] = $this->container->construct($config['class'], $config); }
/** * Get driver by it's name. * * @param string $name * @param array $config Custom driver options and class. * @return Driver * @throws DatabaseException */ public function driver($name, array $config = []) { if (isset($this->drivers[$name])) { return $this->drivers[$name]; } if (empty($config)) { if (!isset($this->config['connections'][$name])) { throw new DatabaseException("Unable to create Driver, no presets for '{$name}' found."); } $config = $this->config['connections'][$name]; } $this->drivers[$name] = $this->container->construct($config['driver'], compact('name', 'config')); return $this->drivers[$name]; }
/** * Refresh modules configuration file with only existed modules and their configurations. * Should be called every time new module gets registered or removed. */ private function updateConfig() { foreach ($this->modules as $name => $module) { if (!class_exists($module['class'])) { //Module got removed unset($this->modules[$name]); } } /** * We are going to store information about modules into component configuration * * @var ConfigWriter $configWriter */ $configWriter = $this->container->get(ConfigWriter::class, ['name' => 'modules', 'method' => ConfigWriter::FULL_OVERWRITE]); //Writing (make sure we are inside environment with right permissions) $configWriter->setConfig($this->modules)->writeConfig(); }
/** * Execute console command using it's name. * * @param string $command * @param array|InputInterface $parameters * @param OutputInterface $output * @return CommandOutput * @throws ConsoleException */ public function command($command, $parameters = [], OutputInterface $output = null) { $input = is_object($parameters) ? $parameters : new ArrayInput(compact('command') + $parameters); $output = !empty($output) ? $output : new BufferedOutput(); $outerOutput = $this->container->replace(OutputInterface::class, $output); $outerInput = $this->container->replace(InputInterface::class, $input); //Go $code = self::CODE_UNDEFINED; try { $code = $this->application()->find($command)->run($input, $output); } catch (\Exception $exception) { $this->application->renderException($exception, $output); } finally { $this->container->restore($outerInput); $this->container->restore($outerOutput); } return new CommandOutput($code, $output); }
/** * @param string $controller * @param string $action * @param array $parameters * @return mixed * @throws ControllerException */ protected function execute($controller, $action, array $parameters) { $benchmark = $this->benchmark('callAction', $controller . '::' . ($action ?: '~default~')); $scope = $this->container->replace(Vault::class, $this); $this->controller = $controller; try { //Initiating controller with all required dependencies $object = $this->container->make($this->config->controllers()[$controller]); if (!$object instanceof ControllerInterface) { throw new ControllerException("Invalid '{$controller}', ControllerInterface not implemented.", ControllerException::NOT_FOUND); } return $object->callAction($action, $parameters); } finally { $this->benchmark($benchmark); $this->container->restore($scope); $this->controller = ''; } }
/** * {@inheritdoc} * * @return MigrationInterface[] */ public function getMigrations() { $migrations = []; foreach ($this->getFiles() as $filename => $definition) { if (!class_exists($definition['class'], false)) { //Can happen sometimes require_once $filename; } elseif (isset($migrations[$filename])) { $this->logger()->warning("Migration '{class}' already presented in loaded classes.", $definition); continue; } /** * @var MigrationInterface $migration */ $migration = $this->container->construct($definition['class']); //Status $migration->setState($this->getStatus($definition)); $migrations[$filename] = $migration; } return $migrations; }
/** * Get engine by it's type. * * @param string $engine * @param bool $reload If true engine will receive new instance of loader and enviroment. * @return EngineInterface */ public function engine($engine, $reload = false) { if (!isset($this->engines[$engine])) { $parameters = $this->config->engineParameters($engine); $parameters['loader'] = $this->loader($engine); $parameters['environment'] = $this->environment(); //We have to create an engine $benchmark = $this->benchmark('engine', $engine); try { $this->engines[$engine] = $this->container->make($this->config->engineClass($engine), $parameters); } finally { $this->benchmark($benchmark); } $reload = true; } //Configuring engine if ($reload) { $this->engines[$engine]->setLoader($this->loader($engine)); $this->engines[$engine]->setEnvironment($this->environment()); } return $this->engines[$engine]; }
/** * Create instance of relation schema based on relation type and given definition (declared in * record). Resolve using container to support any possible relation type. You can create your * own relations, loaders and schemas by altering ORM config. * * @param mixed $type * @param SchemaBuilder $builder * @param RecordSchema $record * @param string $name * @param array $definition * @return Schemas\RelationInterface */ public function relationSchema($type, SchemaBuilder $builder, RecordSchema $record, $name, array $definition) { if (!isset($this->config['relations'][$type]['schema'])) { throw new ORMException("Undefined relation schema '{$type}'."); } return $this->container->construct($this->config['relations'][$type]['schema'], compact('builder', 'record', 'name', 'definition')); }
/** * Get instance of ODM SchemaBuilder. * * @param TokenizerInterface $tokenizer * @return SchemaBuilder */ public function schemaBuilder(TokenizerInterface $tokenizer = null) { return $this->container->construct(SchemaBuilder::class, ['odm' => $this, 'config' => $this->config['schemas'], 'tokenizer' => $tokenizer]); }
/** * Execute statement or fetch result from cache and return cached query iterator. * * @param int $lifetime Cache lifetime in seconds. * @param string $query * @param array $parameters Parameters to be binded into query. * @param string $key Cache key to be used to store query result. * @param StoreInterface $store Cache store to store result in, if null default store will * be used. * @return CachedResult * @throws DriverException * @throws QueryException */ public function cached($lifetime, $query, array $parameters = [], $key = '', StoreInterface $store = null) { $store = !empty($store) ? $store : $this->container->get(CacheInterface::class)->store(); if (empty($key)) { //Trying to build unique query id based on provided options and environment. $key = md5(serialize([$query, $parameters, $this->name, $this->tablePrefix])); } $data = $store->remember($key, $lifetime, function () use($query, $parameters) { return $this->query($query, $parameters)->fetchAll(); }); return new CachedResult($store, $key, $query, $parameters, $data); }