/** * **Return the Controller instance associated with a Request.** * * As several resolvers can exist for a single application, a resolver must * return false when it is not able to determine the controller. * * The resolver must only throw an exception when it should be able to load * controller but cannot because of some errors made by the developer. * * @param Request $request A Request instance * * @return callable|false A PHP callable representing the Controller, * or false if this resolver is not able to determine the controller. */ public function getController(Request $request) : callable { $controller = $request->attributes->get('_controller', NULL); if (!$this->callbackResolver->isValid($controller)) { return $this->controllerResolver->getController($request); } return $this->callbackResolver->convertCallback($controller); }
/** * Returns a callable given its string representation. * * @param string $name * * @return array A callable array * * @throws \InvalidArgumentException In case the method does not exist. */ public function resolveCallback($name) { if (!is_callable($callback = parent::resolveCallback($name))) { if (!class_exists($name) || !in_array(Middleware::class, class_implements($name))) { throw new \Exception($name . ' is not a valid middleware class'); } $callback = [$this->container->get($name), 'execute']; } return $callback; }
/** * @param string $name * @return array|callable */ public function convertCallback($name) { // original pattern if ($this->isValid($name)) { return parent::convertCallback($name); } // try to resolve callback from container try { return $this->resolver->resolve($name); } catch (NotCallableException $e) { throw new \InvalidArgumentException($e->getMessage()); } }
protected function addRoute(ControllerCollection $ctr, $name, array $config) { $config = new ArrayCollection($config); if (!($path = $config['path'])) { return; } if (!($defaults = $config['defaults'])) { return; } $defaults = new ArrayCollection($defaults); if (!($to = $defaults->remove('_controller'))) { return; } $route = $ctr->match($path, $to); $before = $defaults->remove('_before') ?: '::before'; $before = $this->resolveBefore($before); $route->before($before); $after = $defaults->remove('_after') ?: '::after'; $after = $this->resolveAfter($after); $route->after($after); foreach ($defaults as $key => $value) { $route->value($key, $value); } foreach ($config['requirements'] ?: [] as $variable => $callback) { $callback = $this->callbackResolver->resolveCallback($callback); $requirement = is_callable($callback) ? call_user_func($callback) : $callback; $route->assert($variable, $requirement); } if ($host = $config['host']) { $route->getRoute()->setHost($host); } if ($methods = $config['methods']) { $route->getRoute()->setMethods($methods); } if ($schemes = $config['schemes']) { $route->getRoute()->setSchemes($schemes); } $route->bind($name); }
/** * Returns a callable given its string representation. * * @param string $name * * @return array A callable array * * @throws \InvalidArgumentException In case the method does not exist. */ public function convertCallback($name) { if (preg_match(static::PAGE_PATTERN, $name)) { return function (Application $app, Request $request) use($name) { // setpath $path_info = $request->getPathInfo(); if (substr($path_info, -1) == '/') { $path_info .= 'index.php'; } $_SERVER['SCRIPT_NAME'] = str_replace('/index.php', '', $request->server->get('SCRIPT_NAME')) . $path_info . (substr($path_info, -1) == '/' ? 'index.php' : ''); $_SERVER['SCRIPT_FILENAME'] = dirname($request->server->get('SCRIPT_FILENAME')) . $path_info; // rtrim は PHP バージョン依存対策 $GLOBALS['_realdir'] = rtrim(realpath(rtrim(realpath(dirname($request->server->get('SCRIPT_FILENAME'))), '/\\') . '/'), '/\\') . '/'; $GLOBALS['_realdir'] = str_replace('\\', '/', $GLOBALS['_realdir']); $GLOBALS['_realdir'] = str_replace('//', '/', $GLOBALS['_realdir']); define('HTML_REALDIR', $GLOBALS['_realdir']); /** HTMLディレクトリからのDATAディレクトリの相対パス */ define('HTML2DATA_DIR', '../app/'); define('USE_FILENAME_DIR_INDEX', null); if (!defined('DATA_REALDIR')) { define('DATA_REALDIR', HTML_REALDIR . HTML2DATA_DIR); } // アプリケーション初期化処理 if (!defined('CACHE_REALDIR')) { /** キャッシュ生成ディレクトリ */ define('CACHE_REALDIR', DATA_REALDIR . "cache/eccube/"); } \Eccube\Framework\Helper\HandleErrorHelper::load(); // アプリケーション初期化処理 $objInit = new \Eccube\Framework\Initial(); $objInit->init(); // Page instance $objPage = new $name($app); if ($objPage instanceof \Eccube\Page\Admin\AbstractAdminPage) { define('ADMIN_FUNCTION', true); } else { define('FRONT_FUNCTION', true); } // 定数 SAFE が設定されている場合、DBアクセスを回避する。主に、エラー画面を意図する。 if (!defined('SAFE') || !SAFE) { // インストール中で無い場合、 if (!GcUtils::isInstallFunction()) { // インストールチェック Utils::sfInitInstall(); // セッション初期化・開始 $sessionFactory = SessionFactory::getInstance(); $sessionFactory->initSession(); /* * 管理画面の場合は認証行う. * 認証処理忘れ防止のため, \Eccube\Page\Admin::init() 等ではなく, ここでチェックする. */ SessionHelper::adminAuthorization(); } } // bufferを初期化する if ($objPage instanceof \Eccube\Page\Admin\AbstractAdminPage) { ob_start(); } else { // 絵文字変換 (除去) フィルターを組み込む。 ob_start(array('\\Eccube\\Framework\\MobileEmoji', 'handler')); if (Application::alias('eccube.display')->detectDevice() == DEVICE_TYPE_MOBILE) { // resize_image.phpは除外 if (!$objPage instanceof \Eccube\Page\ResizeImage) { /* @var $objMobile MobileHelper */ $objMobile = Application::alias('eccube.helper.mobile'); $objMobile->sfMobileInit(); } } } $objPage->init(); $objPage->process(); $response = ob_get_contents(); ob_end_clean(); return $response; }; } else { return parent::convertCallback($name); } }
/** * Converts: * * - Bolt\\Controller\\Frontend::hompeage to controller.frontend:homepage * - [Bolt\\Controller\\Frontend, homepage] to controller.frontend:homepage * * Those are then converted to valid callbacks with the controller object from application * * @param string $name * * @return array A callable array */ public function convertCallback($name) { if (is_array($name)) { list($cls, $method) = $name; if (is_array($method)) { $params = $method; $callback = $this->resolveCallback($cls); return function () use($callback, $params) { return call_user_func_array($callback, $params); }; } } elseif (strpos($name, '::') > 0) { $parts = explode('::', $name); $cls = reset($parts); $method = end($parts); } else { return parent::convertCallback($name); } if (isset($this->classmap[$cls])) { $service = $this->classmap[$cls]; return parent::convertCallback("{$service}:{$method}"); } return [$this->instantiateClass($cls), $method]; }