Собственные ссылки в yii2. Как?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Аватара пользователя
mihail_dev
Сообщения: 243
Зарегистрирован: 2013.07.17, 00:51
Откуда: Молдова
Контактная информация:

Re: Собственные ссылки в yii2. Как?

Сообщение mihail_dev »

я по тестирую! за выходные выложу!
Изображение
Matthew
Сообщения: 23
Зарегистрирован: 2015.05.22, 19:28

Re: Собственные ссылки в yii2. Как?

Сообщение Matthew »

mihail_dev писал(а):я по тестирую! за выходные выложу!
Спасибо, с нетерпением жду.
Аватара пользователя
mihail_dev
Сообщения: 243
Зарегистрирован: 2013.07.17, 00:51
Откуда: Молдова
Контактная информация:

Re: Собственные ссылки в yii2. Как?

Сообщение mihail_dev »

после проведения ряда тестов выявлена проблема с кэшированием самого урлмэнеджера

для того чтоб убедится что всё работает можно просто в конфиге прописать

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

'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'cache' => false,
            'rules'=> [
                //  'register' => 'user/index',
                ['class' => 'app\components\PagesUrlRule'],
            ],
        ],
для нормальной работы надо добавить в класс функцию wakeup которая будет подтягивать данные после восстановления класса из кэша

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

public function __wakeup()
    {
        $this->init();
    } 

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

<?php
namespace frontend\components\Pages;
use frontend\models\Pages\Pages;
use yii\caching\DbDependency;
use yii\web\CompositeUrlRule;
use yii\web\UrlRuleInterface;
use yii\base\InvalidConfigException;

/**
 * Class PagesUrlRule
 *
 * @package frontend\components\Pages
 */
class PagesUrlRule extends CompositeUrlRule{

    public $cacheComponent = 'cache';

    public $cacheID = 'PagesUrlRules';

    public $ruleConfig = ['class' => 'yii\web\UrlRule'];

    /**
     * Creates the URL rules that should be contained within this composite rule.
     *
     * @return \yii\web\UrlRuleInterface[] the URL rules
     * @throws \yii\base\InvalidConfigException
     */
    protected function createRules()
    {
        $cache = \Yii::$app->get($this->cacheComponent)->get($this->cacheID);
        if(!empty($cache))
            return $cache;

        $pages = Pages::find()->asArray(true)->all();


        $rules = [];
        foreach ($pages as $page) {

            $rule = [
                'pattern' => ltrim($page['alias'], '/'),
                'route' => ltrim($page['route'], '/'),
            ];


            $rule = \Yii::createObject(array_merge($this->ruleConfig, $rule));
            if (!$rule instanceof UrlRuleInterface) {
                throw new InvalidConfigException('URL rule class must implement UrlRuleInterface.');
            }
            $rules[] = $rule;
        }

        $cd= new DbDependency();
        $cd->sql='SELECT SUM(id) FROM '.Pages::tableName();

        \Yii::$app->get($this->cacheComponent)->set($this->cacheID, $rules, 0, $cd);

        return $rules;
    }
    
    public function __wakeup()
    {
        $this->init();
    }

} 
да ещё одна правка SELECT SUM(id) FROM
Изображение
Matthew
Сообщения: 23
Зарегистрирован: 2015.05.22, 19:28

Re: Собственные ссылки в yii2. Как?

Сообщение Matthew »

mihail_dev писал(а):после проведения ряда тестов выявлена проблема с кэшированием самого урлмэнеджера
Да, заработало. Пару вопросов в догонку:

1) Как теперь при обновлении в базе правила, чистить кэш? (чтобы новое правило заработало)

Очень волнует довести дело до конца:)
Аватара пользователя
mihail_dev
Сообщения: 243
Зарегистрирован: 2013.07.17, 00:51
Откуда: Молдова
Контактная информация:

Re: Собственные ссылки в yii2. Как?

Сообщение mihail_dev »

блин не понял немного вопроса
там есть правило

кэш не надо чистить там есть правила обновления кэша

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

        $cd= new DbDependency();
        $cd->sql='SELECT SUM(id) FROM '.Pages::tableName();

        \Yii::$app->get($this->cacheComponent)->set($this->cacheID, $rules, 0, $cd);
но оно не сработает если обновить правило
для этого в базу лучше внести ещё одно поле дату последнего обновления и изменить правило хранения кэша

допустим добавить поле last_update

и заменить правило на

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

        $cd= new DbDependency();
        $cd->sql='SELECT MAX(last_update) FROM '.Pages::tableName();

        \Yii::$app->get($this->cacheComponent)->set($this->cacheID, $rules, 0, $cd);
Изображение
Matthew
Сообщения: 23
Зарегистрирован: 2015.05.22, 19:28

Re: Собственные ссылки в yii2. Как?

Сообщение Matthew »

mihail_dev писал(а):прочти доку https://github.com/yiisoft/yii2/blob/ma ... pbehavior-
Смотри, допустим или обновляю или ДОБАВЛЯЮ правило. Нужно обновить кэш как-то.
Еще проблемка возникла.
/registration => user/index работает! Но не должно если есть такой алиас работать user/index. А оно работает.
Если в 'urlManager' добавить 'enableStrictParsing' => true то работает ТОЛЬКО алиас /registration. А доступ ко всем контроллерам получить невозможно.
Аватара пользователя
mihail_dev
Сообщения: 243
Зарегистрирован: 2013.07.17, 00:51
Откуда: Молдова
Контактная информация:

Re: Собственные ссылки в yii2. Как?

Сообщение mihail_dev »

по поводу Смотри, допустим или обновляю или ДОБАВЛЯЮ правило. Нужно обновить кэш как-то.

в классе есть зависимость так что если ты добавишь или обновишь правило кэш должен обновится
если ты следовал доработкам по кэшу которые я ранее тебе предложил сделать

по поводу строгости и блокировки

можно добавь универсальное правило допустим
'<m>/<c>/<a>' => '<m>/<c>/<a>',
'<c>/<a>' => '<c>/<a>'

не вижу всей картины что ты хочешь получить
если строго следовать правилам то конечно всё что не в правилах будет игнориться

и честно не пойму почему тебе так надо закрыть доступ через user/index

если в шабах ты используешь конструктор ссылок то все ссылки изменятся согласно твоим правилам и в плане сео всё будет тип топ
если же надо убивать ссылки на контроллеры то тут надо дорабатывать сам урлМанаджер чтоб он при инициализации правил выдирал все руты и создавал на них блокирующее правило
Изображение
Matthew
Сообщения: 23
Зарегистрирован: 2015.05.22, 19:28

Re: Собственные ссылки в yii2. Как?

Сообщение Matthew »

mihail_dev писал(а): ...

не вижу всей картины что ты хочешь получить
если строго следовать правилам то конечно всё что не в правилах будет игнориться

и честно не пойму почему тебе так надо закрыть доступ через user/index

если в шабах ты используешь конструктор ссылок то все ссылки изменятся согласно твоим правилам и в плане сео всё будет тип топ
если же надо убивать ссылки на контроллеры то тут надо дорабатывать сам урлМанаджер чтоб он при инициализации правил выдирал все руты и создавал на них блокирующее правило
Вот что я хочу получить:
Все должно стандартно работать. За исключением: Если для controller/action есть в базе алиас, то должно делать редирект на алиас. Если для введенного controller/action нет в базе алиаса, то открыть стандартно.
Пример:
В базе допустим лежит только: registration (алиас) -> user/registration (контроллер/действие)
При открытии /registration , получаем user/registration. При открытии user/registration делается редирект на /registration.
При открытии user/login (для такого сочетания нет алиаса) открыть user/login (стандартно).

Для чего это? Для того, чтобы не было дублей станиц. Чтобы по двум различным ссылкам, алиасу и контроллер/действие, не открывался один и тот же контент. Поэтому если для контроллер/действие есть алиас, то при открытии контроллер/действие редирект нужно делать на алиас, а не отдавать контент.
Аватара пользователя
mihail_dev
Сообщения: 243
Зарегистрирован: 2013.07.17, 00:51
Откуда: Молдова
Контактная информация:

Re: Собственные ссылки в yii2. Как?

Сообщение mihail_dev »

вот класс проверки аллиасов

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

<?php
namespace app\components;


use yii\web\CompositeUrlRule;

class StrictParseRequest extends CompositeUrlRule
{
    public $ruleConfig = ['class' => 'yii\web\UrlRule'];
    public $onlyGET = true;

    /**
     * @inheritdoc
     */
    protected function createRules()
    {
        $verb = null;
        if($this->onlyGET)
            $verb = 'GET';

        return [
            \Yii::createObject(array_merge($this->ruleConfig, [
                'pattern' => '<m>/<c>/<a>',
                'route' => '<m>/<c>/<a>',
                'verb' => $verb
            ])),
            \Yii::createObject(array_merge($this->ruleConfig, [
                'pattern' => '<c>/<a>',
                'route' => '<c>/<a>',
                'verb' => $verb
            ]))
        ];
    }

    /**
     * @inheritdoc
     */
    public function __wakeup()
    {
        $this->init();
    }

    /**
     * @inheritdoc
     */
    public function parseRequest($manager, $request){
        $result = parent::parseRequest($manager, $request);

        if(empty($result))
            return $result;

        $url = array_merge(["/".$result[0]], $result[1], $request->getQueryParams());

        $canonical = $manager->createUrl($url);

        if($request->url != $canonical){
            \Yii::$app->response->redirect($canonical, 301);
        }

        return $result;
    }
}
 
в конфиге это правило должно быть последним!!!!

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

'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            //'cache' => false,
            'rules'=> [
                ['class' => 'app\components\PagesUrlRule'],
                ['class' => 'app\components\StrictParseRequest'],
            ],
        ],
 
Изображение
Matthew
Сообщения: 23
Зарегистрирован: 2015.05.22, 19:28

Re: Собственные ссылки в yii2. Как?

Сообщение Matthew »

mihail_dev писал(а):вот класс проверки аллиасов
Отлично! Все работает! Спасибо огромное, тема в 3 страницы завершена.)
Ответить