'id', 'page' => 'page', 'per-page' => 'per_page', 'book_id' => 'book_id', 'q' => 'q', 'tag' => 'tag', ]; public function __construct(Languages $languages, array $config = []) { $this->languages = $languages; parent::__construct($config); } /** * @param \yii\web\Request $request * * @return array|bool * @throws \artbox\core\exceptions\AliasOverwriteException * @throws \yii\base\ExitException * @throws \yii\base\InvalidConfigException */ public function parseRequest($request) { $redirect = $this->checkRedirect($request->url); if ($redirect !== null) { \Yii::$app->response->redirect("/" . $redirect->value, 301); } $request = $this->parseLanguage($request); $path = $request->pathInfo; if (strlen($path) && $path[strlen($path) - 1] == '/' # && $path[strlen($path)-2]=='/' ) { throw new NotFoundHttpException(); } /** * @var Alias $alias */ $alias = Alias::find() ->where( [ 'value' => trim($request->pathInfo, '/'), ] ) ->andWhere( [ 'language_id' => $this->languages->getCurrent()->id, ] ) ->one(); $this->invalidParams(\Yii::$app->request->queryParams); if ($alias !== null) { $params = Json::decode($alias->route); $route = array_shift($params); /** * @todo REFACTOR AS SOO AS POSIBLE! * remove service locator, and implement Dependency Injection * @var \artbox\core\components\SeoComponent $seo */ $seo = \Yii::$app->get('seo'); $seo->setAlias($alias); return [ $route, $params, ]; } return parent::parseRequest($request); } /** * @param array|string $params * * @return string */ public function createUrl($params) { if ($this->hideDefaultLanguagePrefix && ($this->languages->getCurrent()->url == $this->languages->getDefault()->url)) { $prefix = ''; } else { $prefix = '/' . $this->languages->getCurrent()->url; } if (isset($params['alias'])) { if ($params['alias'] instanceof Alias) { return $prefix . '/' . $params['alias']->value; } elseif (is_array($params['alias'])) { return $prefix . '/' . $params['alias']['value']; } } return $prefix . parent::createUrl($params); } /** * @param $request * * @return mixed * @throws \yii\base\ExitException * @throws \yii\base\InvalidConfigException */ protected function parseLanguage(Request $request) { $split = explode('/', $request->pathInfo); if (in_array($split[0], array_keys($this->languages->getActive()))) { if ($this->hideDefaultLanguagePrefix && ($split[0] == $this->languages->getDefault()->url)) { unset($split[0]); \Yii::$app->response->redirect('/' . implode('/', $split), 301) ->send(); \Yii::$app->end(); } else { $this->languages->setCurrent($split[0]); unset($split[0]); $request->setPathInfo(implode('/', $split)); } } else { if ($this->hideDefaultLanguagePrefix) { $this->languages->setCurrentDefault(); } else { \Yii::$app->response->redirect( '/' . $this->languages->getDefault()->url . '/' . implode('/', $split), 301 ) ->send(); \Yii::$app->end(); } } return $request; } /** * Looks for rule in table(column) * `redirect.from` if findes - * redirects to `redirect.to` * * @param string $url */ protected function checkRedirect(string $url) { $url1 = parse_url($url); $string = '{"0":"' . ltrim($url1['path'], "/") . '"'; if (isset($url1['query'])) { parse_str($url1['query'], $url1['query']); $string .= (isset($url1['query']['id'])) ? ',"id":' . $url1['query']['id'] : ''; } $string .= '}'; $alias = Alias::find() ->where(['like', 'route', $string]) ->limit(1) ->one(); return $alias; } protected function invalidParams($requestParams) { foreach ($requestParams as $key => $param) { if (!array_key_exists($key, $this->params)) { throw new NotFoundHttpException(); } } } }