LanguageRequest.php 4.06 KB
<?php
    
    namespace artbox\core\components;
    
    use artbox\core\models\Language;
    use yii\base\InvalidConfigException;
    use yii\log\Logger;
    use yii\web\Request;
    
    class LanguageRequest extends Request
    {
        /**
         * Language model $url field for current request.
         *
         * @var string
         */
        private $languageUrl;
    
        /**
         * Get $languageUrl from current Request Url.
         *
         * @return string
         */
        public function getLanguageUrl()
        {
            if ($this->languageUrl === null) {
                $this->languageUrl = $this->getUrl();
                
                $url_list = explode('/', $this->languageUrl);
    
                $language_url = isset($url_list[ 1 ]) ? $url_list[ 1 ] : null;
                if ($paramsPos = strpos($language_url, '?')) {
                    $language_url = substr($language_url, 0, $paramsPos);
                }
                
                $is_language = Language::setCurrent($language_url);
                if (!$is_language && !$this->isAjax) {
                    if (strpos($language_url, '.') === false && count(Language::getActive()) !== 1) {
                        \Yii::$app->response->redirect('/' . Language::getCurrent()->url . $this->url, 302, false);
                    } else {
                        \Yii::getLogger()
                            ->log(
                                "Url $language_url has extension '.' symbol in name. No language redirect applied.",
                                Logger::LEVEL_INFO,
                                'artbox'
                            );
                    }
                }
    
                if ($language_url !== null && $language_url === Language::getCurrent()->url && strpos(
                        $this->languageUrl,
                        Language::getCurrent()->url
                    ) === 1
                ) {
                    $this->languageUrl = substr($this->languageUrl, strlen(Language::getCurrent()->url) + 1);
                    if (count(Language::getActive()) === 1 && !$this->isAjax) {
                        \Yii::$app->response->redirect('/', 302, false);
                    }
                }
            }
            return $this->languageUrl;
        }
    
        /**
         * @inheritdoc
         */
        protected function resolvePathInfo()
        {
            $pathInfo = $this->getLanguageUrl();
    
            if (( $pos = strpos($pathInfo, '?') ) !== false) {
                $pathInfo = substr($pathInfo, 0, $pos);
            }
            
            $pathInfo = urldecode($pathInfo);
    
            if (!preg_match(
                '%^(?:
            [\x09\x0A\x0D\x20-\x7E]              
            | [\xC2-\xDF][\x80-\xBF]             
            | \xE0[\xA0-\xBF][\x80-\xBF]       
            | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}
            | \xED[\x80-\x9F][\x80-\xBF]       
            | \xF0[\x90-\xBF][\x80-\xBF]{2}    
            | [\xF1-\xF3][\x80-\xBF]{3}        
            | \xF4[\x80-\x8F][\x80-\xBF]{2}    
            )*$%xs',
                $pathInfo
            )
            ) {
                $pathInfo = utf8_encode($pathInfo);
            }
            
            $scriptUrl = $this->getScriptUrl();
            $baseUrl = $this->getBaseUrl();
    
            if (strpos($pathInfo, $scriptUrl) === 0) {
                $pathInfo = substr($pathInfo, strlen($scriptUrl));
            } elseif ($baseUrl === '' || strpos($pathInfo, $baseUrl) === 0) {
                $pathInfo = substr($pathInfo, strlen($baseUrl));
            } elseif (isset($_SERVER[ 'PHP_SELF' ]) && strpos($_SERVER[ 'PHP_SELF' ], $scriptUrl) === 0) {
                $pathInfo = substr($_SERVER[ 'PHP_SELF' ], strlen($scriptUrl));
            } else {
                throw new InvalidConfigException('Unable to determine the path info of the current request.');
            }
    
            if ($pathInfo === '/') {
                $pathInfo = substr($pathInfo, 1);
            }
            
            return (string) $pathInfo;
        }
    }