UrlManager

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
Аватара пользователя
Unsiker
Сообщения: 57
Зарегистрирован: 2012.05.02, 12:17

UrlManager

Сообщение Unsiker »

Подскажите, можна ли как то сделать, возможность одинаково обрабатывать правила?

Код: Выделить всё

http://domain.loc/r=test/about
http://domain.loc/test/about
 
Тоесть в зависимости urlFormat (path или get) использовать один и тот же набор правил.

P.S.: Конфигурация

Код: Выделить всё

'urlManager'=>array(
    'urlFormat'=>'path',
    'showScriptName'=>false,
    'rules'=>array(
        'test/<view:[-a-zA-Z0-9_]*>'=>'site/pages', 
    ),
),
 
Контролера test не существует, при таком наборе правил url domain.loc/test/about - рабочий, а /?r=test/about - нет
Последний раз редактировалось Unsiker 2013.01.24, 21:09, всего редактировалось 1 раз.
Огонь!
Nafania
Сообщения: 1227
Зарегистрирован: 2011.01.31, 13:12

Re: UrlManager

Сообщение Nafania »

/?r=test/about не?
Аватара пользователя
Unsiker
Сообщения: 57
Зарегистрирован: 2012.05.02, 12:17

Re: UrlManager

Сообщение Unsiker »

Nafania писал(а):/?r=test/about не?
Нет, это просто опечатка.
Тут проблема куда глубже. Если я указываю 'urlFormat'=>'get', то правила вообще не учитываются, а очень бы хотелось
Огонь!
Nafania
Сообщения: 1227
Зарегистрирован: 2011.01.31, 13:12

Re: UrlManager

Сообщение Nafania »

Чего-то я не пойму, чего вы хотите. Это два взаимоисключающих правила, а вы хотите чтобы они вместе работали?
URLs managed via CUrlManager can be in one of the following two formats, by setting urlFormat property:

'path' format: /path/to/EntryScript.php/name1/value1/name2/value2...
'get' format: /path/to/EntryScript.php?name1=value1&name2=value2...
Аватара пользователя
Unsiker
Сообщения: 57
Зарегистрирован: 2012.05.02, 12:17

Re: UrlManager

Сообщение Unsiker »

Nafania писал(а):Чего-то я не пойму, чего вы хотите. Это два взаимоисключающих правила, а вы хотите чтобы они вместе работали?
URLs managed via CUrlManager can be in one of the following two formats, by setting urlFormat property:

'path' format: /path/to/EntryScript.php/name1/value1/name2/value2...
'get' format: /path/to/EntryScript.php?name1=value1&name2=value2...
А хочется третьего, так сказать микс из path и get
Огонь!
Аватара пользователя
Unsiker
Сообщения: 57
Зарегистрирован: 2012.05.02, 12:17

Re: UrlManager

Сообщение Unsiker »

Как говорится надо, значит сделаем!

Покритикуйте такой подход для решения задачи
В конфиге указываем

Код: Выделить всё

'urlManager'=> array(
    'class'=>'application.components.EUrlManager',
    'urlFormat'=>'param', 
    'urlSuffix'=>'.html',
    'showScriptName'=>false,
    'rules'=>array(
        'test/<tid:\d+>'=>'home/index', 
    ),
)
Далее наследуемся от CUrlManager и переопределяем/добавляем

Код: Выделить всё

<?php
class EUrlManager extends CUrlManager
{
    const PARAM_FORMAT='param';
    private $_urlFormat=self::GET_FORMAT;
    public $rules=array();
    private $_rules=array();

    public function init()
    {
        parent::init();
        $this->processRules();
    }

    protected function processRules()
    {
        if(empty($this->rules) || $this->getUrlFormat()===self::GET_FORMAT)
            return;
        if($this->cacheID!==false && ($cache=Yii::app()->getComponent($this->cacheID))!==null)
        {
            $hash=md5(serialize($this->rules));
            if(($data=$cache->get(self::CACHE_KEY))!==false && isset($data[1]) && $data[1]===$hash)
            {
                $this->_rules=$data[0];
                return;
            }
        }
        foreach($this->rules as $pattern=>$route)
            $this->_rules[]=$this->createUrlRule($route,$pattern);
        if(isset($cache))
            $cache->set(self::CACHE_KEY,array($this->_rules,$hash));
    }

    protected function createUrlDefault($route,$params,$ampersand)
    {
        if($this->getUrlFormat()===self::PARAM_FORMAT)
        {
            $url=$this->getBaseUrl();
            if(!$this->showScriptName)
                $url.='/';
            if($route!=='')
            {
                $url.='?'.$this->routeVar.'='.$route.$this->urlSuffix;
                if(($query=$this->createPathInfo($params,'=',$ampersand))!=='')
                    $url.=$ampersand.$query;
            }
            else if(($query=$this->createPathInfo($params,'=',$ampersand))!=='')
                $url.='?'.$query;
            return $url;
        }    
         else
             return parent::createUrlDefault($route,$params,$ampersand);    
    }

    public function parseUrl($request)
    {
        if($this->getUrlFormat()===self::PARAM_FORMAT)
        {
            if(isset($_GET[$this->routeVar]))
            {
                $rawPathInfo = $_GET[$this->routeVar];
                $pathInfo=$this->removeUrlSuffix($rawPathInfo,$this->urlSuffix);

            
                
                foreach($this->_rules as $i=>$rule)
                {
                    if(is_array($rule))
                        $this->_rules[$i]=$rule=Yii::createComponent($rule);
                    if(($r=$rule->parseUrl($this,$request,$pathInfo,$rawPathInfo))!==false)
                        return $r;
                }
                if($this->useStrictParsing)
                    throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
                        array('{route}'=>$pathInfo)));
                else
                    return $pathInfo;
            }
            else 
                return ''; 
            

            

        } 
        else
            return parent::parseUrl($request);
    }

    public function getUrlFormat()
    {
        return $this->_urlFormat;
    }

    public function setUrlFormat($value)
    {
        if($value===self::PATH_FORMAT || $value===self::GET_FORMAT || $value===self::PARAM_FORMAT )
            $this->_urlFormat=$value;
        else
            throw new CException(Yii::t('yii','CUrlManager.UrlFormat must be either "path", "get" or "param".'));
    }

}
В результате можем использовать

Код: Выделить всё

http://domain.loc/r=test/about //'urlFormat'=>'param', 
http://domain.loc/test/about // 'urlFormat'=>'path', 
 
Огонь!
Ответить