Мой вариант UrlManager анти дубль :)

Обсуждение документации второй версии фреймворка. Переводы Cookbook и авторские рецепты.
Ответить
developer-av
Сообщения: 3
Зарегистрирован: 2015.11.24, 12:00

Мой вариант UrlManager анти дубль :)

Сообщение developer-av »

Добрый день, расширил класс UrlManager и постарался убрать дубли страниц.
Может кому-то пригодится, а может кто-то что-то и посоветует :)
Что умеет класс:
  • убирает дубли вида index.php/controller/action (если showScriptName => false)
  • Если у вас есть rules для метода, то стандартный url будет редиректиться(301) на "правильный url"
  • если withoutWww =>true то будет редирект(301) с www на без www
  • если SlashTheEnd => true то редирект(301) на url со слешем в конце, если не определен suffix для роута
Все правила применяются в один редирект.

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

<?php

namespace app\components;

use Yii;
use yii\web\UrlManager;
use yii\helpers\Url;
use yii\caching\Cache;

class MyUrlManager extends UrlManager {

    /**
     * @var boolean когда true redirect с www на без www
     */
    public $withoutWww = false;
    /**
     * @var boolean когда true redirect с без / в конце на /
     */
    public $SlashTheEnd = true;

    public function parseRequest($request) {
        if ($this->suffix == '' && $this->SlashTheEnd == true)
            $this->suffix = '/';
        $this->indexFix();
        if ($this->enablePrettyUrl) {
            $pathInfo = $request->getPathInfo();
            /* @var $rule UrlRule */
            foreach ($this->rules as $rule) {
                if (($result = $rule->parseRequest($this, $request)) !== false) {
                    $this->doubleUrlFix($result);
                    $url = $this->wwwFix();
                    return $result;
                }
            }

            if ($this->enableStrictParsing) {
                return false;
            }

            Yii::trace('No matching URL rules. Using default URL parsing logic.', __METHOD__);

            $suffix = (string) $this->suffix;
            if ($suffix !== '' && $pathInfo !== '') {
                $n = strlen($this->suffix);
                if (substr_compare($pathInfo, $this->suffix, -$n, $n) === 0) {
                    $pathInfo = substr($pathInfo, 0, -$n);
                    if ($pathInfo === '') {
//                         suffix alone is not allowed
                        return false;
                    }
                } else {
                    // suffix doesn't match
                    $this->doubleUrlFix([$pathInfo, []]);
                    return false;
                }
            }

            $url = [$pathInfo, []];
            $this->doubleUrlFix($url);
            $url = $this->wwwFix();
            return $url;
        } else {
            Yii::trace('Pretty URL not enabled. Using default URL parsing logic.', __METHOD__);
            $route = $request->getQueryParam($this->routeParam, '');
            if (is_array($route)) {
                $route = '';
            }
            return [(string) $route, []];
        }
    }

    /**
     * Редирект на без www
     * @param string $url
     * @return string|bool $url|redirect
     */
    public function wwwFix($url = false) {
        if (strpos(Yii::$app->request->hostInfo, 'www.') !== false && $this->withoutWww == true) {
            if ($url) {
                return str_replace('www.', '', Yii::$app->request->hostInfo) . $url;
            } else {
                $url = str_replace('www.', '', Yii::$app->request->hostInfo) . Yii::$app->request->url;
                Yii::$app->getResponse()->redirect($url, 301);
                header('HTTP/1.1 301 Moved Permanently');
                header('Location: ' . $url);
                Yii::$app->end();
            }
        } else {
            return $url;
        }
    }

    /**
     * Убирает дубли страниц
     * @param type $url
     * @param type $r
     */
    private function doubleUrlFix($url) {
        $url[0] = trim($url[0], '/');
        $url = Url::to(array_merge(['/' . $url[0]], array_merge($url[1], Yii::$app->request->get())));
        if ($url != Url::to()) {
            $url = $this->wwwFix($url);
            Yii::$app->getResponse()->redirect($url, 301);
            header('HTTP/1.1 301 Moved Permanently');
            header('Location: ' . $url);
            Yii::$app->end();
        }
    }

    /**
     * убирает дубли через index.php
     */
    public function indexFix() {
        if (strpos(Yii::$app->request->url, Yii::$app->request->scriptUrl) !== FALSE && $this->showScriptName == false) {
            $url = str_replace(Yii::$app->request->scriptUrl, '', Yii::$app->request->url);
            if (strpos($url, '/') !== 0) {
                $url = '/' . $url;
            }
            $this->doubleUrlFix([$url, []]);
            $url = $this->wwwFix($url);
            Yii::$app->getResponse()->redirect($url, 301);
            header('HTTP/1.1 301 Moved Permanently');
            header('Location: ' . $url);
            Yii::$app->end();
        }
    }

}
P.S. Может кто-то скажет почему иногда редирект Yii не срабатывает?)
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Мой вариант UrlManager анти дубль :)

Сообщение zelenin »

код отформатируйте по psr
developer-av
Сообщения: 3
Зарегистрирован: 2015.11.24, 12:00

Re: Мой вариант UrlManager анти дубль :)

Сообщение developer-av »

Если можно, уточните что тут не по PSR.
На Yii2 недавно, раньше писал исключительно для себя и не парился "не нужным бредом".
Сейчас понял что нужен levelUp, так что буду благодарен за помощь.
P.S. PSR уже читал не один раз, но не понял что конкретно не вписывается в него из компонента.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Мой вариант UrlManager анти дубль :)

Сообщение zelenin »

скобочки переносятся на след. строку - это сильно бросается.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Мой вариант UrlManager анти дубль :)

Сообщение zelenin »

в PhpStorm есть встроенный кодстайл psr + форматирование кода по сочетанию клавиш.
developer-av
Сообщения: 3
Зарегистрирован: 2015.11.24, 12:00

Re: Мой вариант UrlManager анти дубль :)

Сообщение developer-av »

Хм, спасибо учту. Странно что в NetBeans нормально не форматирует :)
Аватара пользователя
zabachok
Сообщения: 522
Зарегистрирован: 2013.12.16, 14:38

Re: Мой вариант UrlManager анти дубль :)

Сообщение zabachok »

NetBeans нормально форматирует. Ctrl+Shift+F. Только надо форматтер настроить по пср.
2b||!2b Just read the instructions
Ответить