public function _get_callback() { if ($this->_callback) { return $this->_callback; } else { $this->_callback = get_callable($this->_callback_str); if ($this->_callback === false) { throw new ViewDoesNotExist(sprintf("Could not import %s.", $this->_callback_str)); } return $this->_callback; } }
/** * @param $name * @return mixed * @throws \RuntimeException * @throws \Exception */ public function get($name) { static $depth = 0; static $allNames = array(); if (!isset($this->services[$name])) { throw new \Exception('Service by name ' . $name . ' was not located in this ServiceLocator'); } if ($depth > 99) { throw new \RuntimeException('Recursion detected when trying to resolve these services: ' . implode(', ', $allNames)); } if ($this->services[$name] instanceof \Closure && !isset($this->instantiated[$name])) { $depth++; $allNames[] = $name; /** @var $factory \Closure */ $factory = $this->services[$name]; $factoryCallable = get_callable($factory); $this->services[$name] = invoke($factoryCallable, $this, $this); $this->instantiated[$name] = true; // allow closure wrapped in a closure $depth--; } if ($depth === 0) { while ($allNames) { $aName = array_pop($allNames); if (isset($this->initializers[$aName . '+'])) { $depth++; /** @var $initializer \Closure */ $initializer = $this->initializers[$aName . '+']; if (version_compare(PHP_VERSION, '5.4.0')) { $initializer = $initializer->bindTo($this, __CLASS__); } $initializer($this->services[$aName]); $depth--; } if ($this->initializers['+']) { foreach ($this->initializers['+'] as $initializer) { if (version_compare(PHP_VERSION, '5.4.0')) { $initializer = $initializer->bindTo($this, __CLASS__); } $initializer($this->services[$aName]); } } unset($this->services[$aName . '+']); } } return $this->services[$name]; }
/** * @return mixed|null * @throws \RuntimeException * @throws \Exception */ public function run() { $this->initialize(); // default error handling if (!isset($this->callbacks['Application.Error'])) { $this->addFeature(new Feature\BasicErrorHandler()); } /** @var $router Router */ $router = $this->serviceLocator->get('Router'); $this->trigger('Application.PreRoute'); try { $routeMatch = $router->route(); $this->serviceLocator->set('RouteMatch', $routeMatch, true); } catch (\Exception $e) { return $this->trigger('Application.Error', array('type' => self::ERROR_EXCEPTION, 'exception' => $e)); } $this->trigger('Application.PostRoute'); if ($routeMatch == null) { /** @var $router Router */ $router = $this->serviceLocator->get('Router'); $routeMatch = $router->getLastRouteMatch(); if (!$routeMatch) { return $this->trigger('Application.Error', array('type' => self::ERROR_UNROUTABLE)); } } elseif (!$routeMatch instanceof Router\RouteMatch) { throw new \InvalidArgumentException('Provided RouteMatch must be of type P\\Router\\RouteMatch'); } $route = $routeMatch->getRoute(); if (!$route instanceof Router\RouteInterface) { throw new \RuntimeException('Matched route must implement MiniP\\ApplicationRoute\\ApplicationRouteInterface'); } $this->trigger('Application.PreDispatch'); try { $routeSource = $router->getSource(); $dispatchParams = $routeMatch->getParameters(); if ($routeSource instanceof Router\HttpSource) { $dispatchParams['HttpUri'] = $routeSource['uri']; $dispatchParams['HttpMethod'] = $routeSource['method']; } $this->applicationState->pushScope('Application.Dispatch', $dispatchParams); try { $callable = get_callable($route->getDispatchable(), $this->applicationState); } catch (\Exception $e) { $this->applicationState->popScope(); return $this->trigger('Application.Error', array('type' => self::ERROR_UNDISPATCHABLE)); } $result = invoke($callable, $this->applicationState, null, false); $this->applicationState->setResult($result); $this->applicationState->popScope(); } catch (\Exception $e) { $this->applicationState->popScope(); return $this->trigger('Application.Error', array('type' => self::ERROR_EXCEPTION, 'exception' => $e)); } $this->trigger('Application.PostDispatch'); }