/** * {@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; }
/** * 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; }
/** * 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]); }
/** * 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); }
/** * 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} */ 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); } }
/** * 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(); }
/** * {@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); }; }
/** * Get or create instance of ConsoleApplication. * * @return Application */ public function application() { if (!empty($this->application)) { return $this->application; } $this->application = new Application('Spiral Console Toolkit', Core::VERSION); //Commands lookup empty($this->commands) && $this->findCommands(); foreach ($this->commands as $command) { try { $command = $this->container->get($command); if (method_exists($command, 'isAvailable') && !$command->isAvailable()) { continue; } } catch (\Exception $exception) { continue; } $this->application->add($command); } return $this->application; }
/** * Get or create instance of validation checker. * * @param string $name * @return Checker * @throws ValidationException */ protected function checker($name) { if (!isset($this->options['checkers'][$name])) { throw new ValidationException("Unable to create validation checker defined by '{$name}' name."); } return $this->container->get($this->options['checkers'][$name]); }
/** * 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); }
/** * @return array */ public function getFunctions() { return [new \Twig_SimpleFunction('spiral', function ($alias) { return $this->container->get($alias); }), new \Twig_SimpleFunction('dump', 'dump')]; }
/** * Create Definition using local composer.json file. Root directory will be resolved as location * of composer.json * * @param ContainerInterface $container * @param string $class Module class name. * @param string $composer Name of composer file. * @return DefinitionInterface * @throws ModuleException */ public static function fromComposer(ContainerInterface $container, $class, $composer = 'composer.json') { /** * We will fill name property little bit later. * * @var static $definition */ $definition = $container->get(static::class, ['class' => $class, 'name' => null]); //Let's look for composer file $location = $definition->location; while (!$definition->files->exists($location . FilesInterface::SEPARATOR . $composer)) { $location = dirname($location); if (empty(trim($location, '\\/.'))) { throw new ModuleException("Unable to locate composer.json file."); } } //We found root location $definition->location = $definition->files->normalizePath($location); $composer = json_decode($definition->files->read($location . FilesInterface::SEPARATOR . $composer), true); $definition->name = $composer['name']; if (!empty($composer['description'])) { $definition->description = $composer['description']; } if (!empty($composer['require'])) { $definition->dependencies = array_keys($composer['require']); } return $definition; }
/** * {@inheritdoc} * * @return Installer */ public static function getInstaller(ContainerInterface $container, DefinitionInterface $definition) { //Let's create default Installer return $container->get(Installer::class, ['moduleDirectory' => $definition->getLocation()]); }
/** * Core class will extend default spiral container and initiate set of directories. You must * provide application, libraries and root directories to constructor. * * @param array $directories Core directories list. Every directory must have / * at the end. * @param ContainerInterface $container * @param HippocampusInterface $memory */ public function __construct(array $directories, ContainerInterface $container, HippocampusInterface $memory = null) { $this->container = $container; /* * Default directories pattern, you can overwrite any directory you want in index file. */ $this->directories = $directories + ['framework' => dirname(__DIR__) . '/', 'public' => $directories['root'] . 'webroot/', 'config' => $directories['application'] . 'config/', 'views' => $directories['application'] . 'views/', 'runtime' => $directories['application'] . 'runtime/', 'cache' => $directories['application'] . 'runtime/cache/', 'resources' => $directories['application'] . 'resources/', 'locales' => $directories['application'] . 'resources/locales/']; //Every application needs timezone to be set, by default we are using UTC date_default_timezone_set($this->timezone); if (empty($memory)) { //Default memory implementation $memory = new Memory($this->directory('cache'), $container->get(FilesInterface::class)); } $this->memory = $memory; $this->bootloader = new BootloadManager($this->container, $this->memory); }
/** * Generate cached bindings schema. * * @param array $classes * @param ContainerInterface $container * @return array */ protected function generateSchema(array $classes, ContainerInterface $container) { $schema = ['snapshot' => $classes, 'bootloaders' => []]; foreach ($classes as $class) { $this->classes[] = $class; $initSchema = ['init' => true, 'boot' => false]; $bootloader = $container->get($class); if ($bootloader instanceof BootloaderInterface) { $initSchema['bindings'] = $bootloader->defineBindings(); $initSchema['singletons'] = $bootloader->defineSingletons(); $reflection = new \ReflectionClass($bootloader); //Can be booted based on it's configuration $initSchema['boot'] = (bool) $reflection->getConstant('BOOT'); $initSchema['init'] = $initSchema['boot']; //Let's initialize now $this->initBindings($container, $initSchema); } else { $initSchema['init'] = true; } //Need more checks here if ($initSchema['boot']) { $boot = new \ReflectionMethod($bootloader, 'boot'); $boot->invokeArgs($bootloader, $container->resolveArguments($boot)); } $schema['bootloaders'][$class] = $initSchema; } return $schema; }
/** * Internal helper used to create execute controller action using associated core instance. * * @param ContainerInterface $container * @param string $controller * @param string $action * @param array $parameters * @return mixed * @throws ClientException */ protected function callAction(ContainerInterface $container, $controller, $action, array $parameters = []) { if (empty($this->core)) { $this->core = $container->get(CoreInterface::class); } try { return $this->core->callAction($controller, $action, $parameters); } catch (ControllerException $exception) { $code = $exception->getCode(); if ($code == ControllerException::BAD_ACTION || $code == ControllerException::NOT_FOUND) { throw new ClientException(ClientException::NOT_FOUND, $exception->getMessage()); } throw new ClientException(ClientException::BAD_DATA, $exception->getMessage()); } }
/** * Shortcut to Container get method. * * @param string $alias * @return mixed|null|object * @throws InstanceException * @throws ArgumentException */ public function __get($alias) { return $this->container->get($alias); }