listeners[] = $events->attach(MvcEvent::EVENT_BOOTSTRAP, [$this, 'onBootstrap'], 10000); } /** * Prepares the view layer * * Overriding, as several operations are omitted in the console view * algorithms, as well as to ensure we pick up the Console variants * of several listeners and strategies. * * @param MvcEvent $event * @return void */ public function onBootstrap($event) { $application = $event->getApplication(); $services = $application->getServiceManager(); $events = $application->getEventManager(); $sharedEvents = $events->getSharedManager(); $this->config = $this->loadConfig($services->get('config')); $this->services = $services; $routeNotFoundStrategy = $services->get('ConsoleRouteNotFoundStrategy'); $exceptionStrategy = $services->get('ConsoleExceptionStrategy'); $mvcRenderingStrategy = $services->get('ConsoleDefaultRenderingStrategy'); $createViewModelListener = new CreateViewModelListener(); $injectViewModelListener = new InjectViewModelListener(); $injectParamsListener = new InjectNamedConsoleParamsListener(); $this->registerMvcRenderingStrategies($events); $this->registerViewStrategies(); // @codingStandardsIgnoreStart $routeNotFoundStrategy->attach($events); $exceptionStrategy->attach($events); $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$injectViewModelListener, 'injectViewModel'], -100); $events->attach(MvcEvent::EVENT_RENDER_ERROR, [$injectViewModelListener, 'injectViewModel'], -100); $mvcRenderingStrategy->attach($events); $sharedEvents->attach(DispatchableInterface::class, MvcEvent::EVENT_DISPATCH, [$injectParamsListener, 'injectNamedParams'], 1000); $sharedEvents->attach(DispatchableInterface::class, MvcEvent::EVENT_DISPATCH, [$createViewModelListener, 'createViewModelFromArray'], -80); $sharedEvents->attach(DispatchableInterface::class, MvcEvent::EVENT_DISPATCH, [$createViewModelListener, 'createViewModelFromString'], -80); $sharedEvents->attach(DispatchableInterface::class, MvcEvent::EVENT_DISPATCH, [$createViewModelListener, 'createViewModelFromNull'], -80); $sharedEvents->attach(DispatchableInterface::class, MvcEvent::EVENT_DISPATCH, [$injectViewModelListener, 'injectViewModel'], -100); // @codingStandardsIgnoreEnd } /** * Retrieves the View instance * * @return View */ public function getView() { if ($this->view) { return $this->view; } $this->view = $this->services->get(View::class); return $this->view; } /** * Extract view manager configuration from the application's configuration * * @param array|ArrayAccess $configService * @return array|ArrayAccess */ private function loadConfig($configService) { $config = []; // override when console config is provided, otherwise use the standard definition if (isset($configService['console']['view_manager'])) { $config = $configService['console']['view_manager']; } elseif (isset($configService['view_manager'])) { $config = $configService['view_manager']; } return ($config instanceof ArrayAccess || is_array($config)) ? $config : []; } /** * Register additional mvc rendering strategies * * If there is a "mvc_strategies" key of the view manager configuration, loop * through it. Pull each as a service from the service manager, and, if it * is a ListenerAggregate, attach it to the view, at priority 100. This * latter allows each to trigger before the default mvc rendering strategy, * and for them to trigger in the order they are registered. * * @param EventManagerInterface $events * @return void */ private function registerMvcRenderingStrategies(EventManagerInterface $events) { if (! isset($this->config['mvc_strategies'])) { return; } $mvcStrategies = $this->config['mvc_strategies']; if (is_string($mvcStrategies)) { $mvcStrategies = [$mvcStrategies]; } if (! is_array($mvcStrategies) && ! $mvcStrategies instanceof Traversable) { return; } foreach ($mvcStrategies as $mvcStrategy) { if (! is_string($mvcStrategy)) { continue; } $listener = $this->services->get($mvcStrategy); if (! $listener instanceof ListenerAggregateInterface) { continue; } $listener->attach($events, 100); } } /** * Register additional view strategies * * If there is a "strategies" key of the view manager configuration, loop * through it. Pull each as a service from the service manager, and, if it * is a ListenerAggregate, attach it to the view, at priority 100. This * latter allows each to trigger before the default strategy, and for them * to trigger in the order they are registered. * * @return void */ private function registerViewStrategies() { if (! isset($this->config['strategies'])) { return; } $strategies = $this->config['strategies']; if (is_string($strategies)) { $strategies = [$strategies]; } if (! is_array($strategies) && ! $strategies instanceof Traversable) { return; } $view = $this->getView(); $events = $view->getEventManager(); foreach ($strategies as $strategy) { if (! is_string($strategy)) { continue; } $listener = $this->services->get($strategy); if ($listener instanceof ListenerAggregateInterface) { $listener->attach($events, 100); } } } }