From 675756d64b4bc893b56f3cf35a6498edbea87496 Mon Sep 17 00:00:00 2001 From: dozer111 Date: Thu, 21 Jun 2018 12:33:12 +0300 Subject: [PATCH] исправление микроразметки на blog/index 1 --- frontend/views/blog/_article.php | 14 +++++++++----- frontend/views/blog/index.php | 10 ++++++++-- frontend/widgets/SeoLinks.php | 346 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 363 insertions(+), 7 deletions(-) create mode 100644 frontend/widgets/SeoLinks.php diff --git a/frontend/views/blog/_article.php b/frontend/views/blog/_article.php index da080db..0e01324 100755 --- a/frontend/views/blog/_article.php +++ b/frontend/views/blog/_article.php @@ -27,7 +27,7 @@ $imageHeight=240;
-
+
@@ -48,9 +48,10 @@ $imageHeight=240;
- - created_at);?>"/> - + + +
comments)?>
views?>
@@ -64,6 +65,8 @@ $imageHeight=240; +
@@ -77,7 +80,8 @@ $imageHeight=240;
- + diff --git a/frontend/views/blog/index.php b/frontend/views/blog/index.php index 3a7a86c..c2bd918 100755 --- a/frontend/views/blog/index.php +++ b/frontend/views/blog/index.php @@ -6,7 +6,7 @@ use yii\web\View; use yii\widgets\ActiveForm; use yii\widgets\ListView; - +use frontend\widgets\SeoLinks; /** * @var View $this * @var ActiveDataProvider $dataProvider @@ -94,4 +94,10 @@
- \ No newline at end of file + + $dataProvider->pagination, + 'seo' => $seo, + ] +) ?> \ No newline at end of file diff --git a/frontend/widgets/SeoLinks.php b/frontend/widgets/SeoLinks.php new file mode 100644 index 0000000..7d4edea --- /dev/null +++ b/frontend/widgets/SeoLinks.php @@ -0,0 +1,346 @@ + parent::run + * При наследовании у меня выдавалось по 2 одинаковых link prev/link next + * Поэтому ядро виджета я вернул в исходное состояние, поменял use во всех местах на свой, мой является + * как минимум на 50% дописанным/переписанным вариантом для линии + * ====================================================================================================================| + */ + +namespace frontend\widgets; + +use Yii; +use common\components\Substringer; +use yii\helpers\Url; +use yii\base\Widget; +use yii\data\Pagination; +use yii\helpers\VarDumper as d; + +class SeoLinks extends Widget +{ + + /** + * @var null | Pagination + * @var null | \common\components\SeoComponent + */ + public $pagination = null; + + public $canonical = true; + + public $firstpageWithoutParameter = false; + + public $seo = null; + /** + * @inheritdoc + */ + + /** + * ============================================================================================================| + * Правка от Саши + * 1) Если есть параметры в урле, Canonical должен вести на страницу без параметров, + * за исключением Пагинации и сортировки. И next/prev чтобы были без этих параметров + * Пример страницы + * https://www.linija-svitla.ua/catalog/ulichnoe-osveshchenie?page_num=3&fcatlist=3268%2C&sort=test_test&3269%2C3270%2C3272%2C3273%2C3274%2C3275&page=50&per-page=18 + * ************************************************************************************************************ + * 2) link prev со 2й страницы должен ссылатся на первую, НО , + * a) там должна отсутствовать пагинация б) должна остатся сортировка + * Прим + * Было https://www.linija-svitla.ua/catalog/ulichnoe-osveshchenie?page=1&per=page=18&sort=title_asc + * Стало https://www.linija-svitla.ua/catalog/ulichnoe-osveshchenie?sort=title_asc + * ============================================================================================================| + * 3) При 301 редирректе от НеЧПУ продуктам/фильтрам к ЧПУ, теги prev/next ссылаются на старые НеЧПУ + * страницы + * ============================================================================================================| + */ + public function run() + { + + # 0 изменяем ссылку, оставляя в ней только пагинацию и сортировку + $firstRegex = '/(\??|&?)page=\d{1,5}&per-page=\d{1,5}/'; + $secondRegex = '/(\?|&)sort=[a-zA-z_]+/'; + $requiredDelimiter = '?'; + $firstConcatenateSymbol = '?'; + $secondConcatenateSymbol = '&'; + + $links = $this->pagination->getLinks(); + + if ($this->canonical and ($this->seo->getRobots() != 'noindex,nofollow' and $this->seo->getRobots() != 'noindex,follow' and $this->seo->getRobots() != 'noindex, nofollow' and $this->seo->getRobots() != 'noindex, follow') + ) { + # 0 + $cannonicalLink = Substringer::changeStringByRegex( + Yii::$app->request->getAbsoluteUrl(), + $firstRegex, + $secondRegex, + $requiredDelimiter, + $firstConcatenateSymbol, + $secondConcatenateSymbol + ); + # 1 В канониклах должна присутствовать только пагинация, удаляю всё, что не есть пагинацией + if ((strpos($cannonicalLink, '?page'))) { + $cannonicalLink = Substringer::simpleStringSubstring($cannonicalLink, '&sort'); + } else { + $cannonicalLink = Substringer::changeStringByRegex( + Yii::$app->request->getAbsoluteUrl(), + $firstRegex, + $secondRegex, + $requiredDelimiter, + $firstConcatenateSymbol, + $secondConcatenateSymbol + ); + $cannonicalLink = Substringer::simpleStringSubstring($cannonicalLink, '&sort'); + /** + * Сейчас ссылка имеет вид: www.siteName.com?page=X&per-page=X + */ + + # 1.1 Если в результате у нас остается URL вида www.siteName.com? + # обрезаем этот ? + if (strpos($cannonicalLink, '?') && !strpos($cannonicalLink, '?page')) { + $cannonicalLink = stristr($cannonicalLink, '?', true); + } + + # 1.2 если ссылка содержит в себе пагинацию, НО она по каким-то причинам не первая, + # удаляем все GET параметры до неё, и заменяем & на ? + if (strpos($cannonicalLink, '?page') !== false) { + $cannonicalLinkRigth = stristr($cannonicalLink, '&page'); + $cannonicalLinkRigth = substr($cannonicalLinkRigth, 1); + $cannonicalLinkRigth = '?' . $cannonicalLinkRigth; + + $cannonicalLink = stristr($cannonicalLink, '?', true); + $cannonicalLink .= $cannonicalLinkRigth; + } + + } + # если нашем очищенном каноникле есть ? в конце(www.siteName.com?page=X&per-page=X?), убираем его + $cannonicalLink = ($cannonicalLink[strlen($cannonicalLink) - 1] !== '?') ? $cannonicalLink : rtrim( + $cannonicalLink, + '?' + ); + + # 1.3 в каноникле должна сохранятся очередность нужных GET параметров + # берём финальную ссылку и если нужно, перерисовываем её + $seoCuttedLink = $this->changeLinksToRequestView($cannonicalLink, Yii::$app->request->getAbsoluteUrl()); + $this->view->registerLinkTag( + [ + 'rel' => 'canonical', + 'href' => $cannonicalLink, + ] + ); + } + + /** + * ========================================================================================================= + * То же самое для тега next + * ========================================================================================================= + */ + + if (key_exists('next', $links)) { + #2.1 Обрезаем ссылку справа по заданным GET regexp-ам + $nextPageGetQueryString = stristr( + Substringer::changeStringByRegex( + $links['next'], + $firstRegex, + $secondRegex, + $requiredDelimiter, + $firstConcatenateSymbol, + $secondConcatenateSymbol + ), + '?' + ); + # 2.2 сливаем левую и правую часть + $nextLinkTitle = Substringer::simpleStringSubstring( + Yii::$app->request->url, + '?' + ) . $nextPageGetQueryString; + + # 2.3 перестраиваем сслыку согласно входящему стилю + $nextLinkTitle = $this->changeLinksToRequestView($nextLinkTitle, Yii::$app->request->url); + + $this->view->registerLinkTag( + [ + 'rel' => 'next', + 'href' => $nextLinkTitle, + ] + ); + } + + if ($this->firstpageWithoutParameter and $this->pagination->page == 1) { + if (key_exists('prev', $links)) { + $link = stristr(\Yii::$app->request->url, '?', true); + /** + * @var \artbox\catalog\models\Filter $filter + */ + $filter = \Yii::$app->get('filter')->filterObj; + if (key_exists($link, $filter->getReplacedFilters())) { + $link = $filter->getReplacedFilters()[$link]; + } + + $seoCuttedLink = $this->changeLinksToRequestView($link, Yii::$app->request->url); + $this->view->registerLinkTag( + [ + 'rel' => 'prev', + 'href' => $seoCuttedLink, + + ] + ); + } + } else { + if (key_exists('prev', $links)) { + + # правка 3 Я не ломаю старых наработок, а просто прокидываю новый(если был редирект) URL prev для + // предыдущих правок + $prevPageGetQueryString = stristr( + Substringer::changeStringByRegex( + $links['prev'], + $firstRegex, + $secondRegex, + $requiredDelimiter, + $firstConcatenateSymbol, + $secondConcatenateSymbol + ), + '?' + ); + $prevLinkTitle = Substringer::simpleStringSubstring( + Yii::$app->request->url, + '?' + ) . $prevPageGetQueryString; + # правка 2 + $seoStringStart = $prevLinkTitle; + $seoCuttedLink = $seoStringStart; + $seoCuttedLink = Substringer::changeStringByRegex( + $seoCuttedLink, + $firstRegex, + $secondRegex, + $requiredDelimiter, + $firstConcatenateSymbol, + $secondConcatenateSymbol + ); + + if (strpos($seoStringStart, '?page=1')) { + + /** + * Правка для категории/блога + * У них разное к-во страниц, поэтому на замену конкретной срезки URL(?page=1&per-page=18) как было раньше, + * я буду автоматически пересматривать currentPageSizeParam для странички + */ + $perPageParam = false; + + # если в $seoCuttredLink уже есть пагинация, то паршу строку и достаю реальное к-во записей для страницы + if (strpos($seoCuttedLink, 'per-page')) { + $perPageParam = parse_str($seoCuttedLink, $params); + $perPageParam = (isset ($params['per-page'])) ? $params['per-page'] : false; + } + # или же ставлю размер как в frontend/views/category, + # потому что большая часть кода здесь заточена именно под currentPerPageSizeParam=18 + $perPageParam = ($perPageParam === false) ? 18 : $perPageParam; + $seoCuttedLink = str_replace('?page=1&per-page=' . $perPageParam, '?', $seoCuttedLink); + $seoCuttedLink = str_replace('&', '', $seoCuttedLink); + $strlen = mb_strlen($seoCuttedLink); + if ($seoCuttedLink[$strlen - 1] == '?') { + $seoCuttedLink = str_replace('?', '', $seoCuttedLink); + } + + } else { + $seoCuttedLink = $seoStringStart; + } + + # правка 2 + + if (strpos($seoCuttedLink, '?sort')) { + if (strpos($seoCuttedLink, '&page=1')) { + $seoCuttedLink = Substringer::simpleStringSubstring($seoCuttedLink, '&page=1&per-page'); + } + + } + + $seoCuttedLink = Substringer::changeStringByRegex( + $seoCuttedLink, + $firstRegex, + $secondRegex, + $requiredDelimiter, + $firstConcatenateSymbol, + $secondConcatenateSymbol + ); + # поправляем URL выдачи, если он после всего имеет такой вид: + if (preg_match('/\d+sort=/', $seoCuttedLink) != false) { + $seoCuttedLinkRigth = stristr($seoCuttedLink, 'sort='); + $seoCuttedLink = stristr($seoCuttedLink, 'sort=', true) . '&' . $seoCuttedLinkRigth; + } + # то же самое, если в пагинации URL пропущен & ==> www.site.com?page=Xper-page=X + if (preg_match('/\d+per-page=/', $seoCuttedLink) != false) { + $seoCuttedLinkRigth = stristr($seoCuttedLink, 'per-page='); + $seoCuttedLink = stristr($seoCuttedLink, 'per-page=', true) . '&' . $seoCuttedLinkRigth; + } + + $seoCuttedLink = $this->changeLinksToRequestView($seoCuttedLink, Yii::$app->request->url); + + $this->view->registerLinkTag( + [ + 'rel' => 'prev', + 'href' => $seoCuttedLink, + ] + ); + } + } + + parent::run(); + } + + /** + * @param string $link + * @param string $requestUrl + * ========================================================================================================= + * Метод, который берет строку(URL), и преобразовывает его в вид, в котором он поступал. Написан для тегов + * next/prev/cannonical + * ========================================================================================================= + * К нам приходит сюда(в данный виджет) URL, из которого нужно сформировать данные 3 линка. По всем Саниным + * правкам, они должны быть в одном из форматов: + * + новенькийЧпу?page=X&per-page=X&sort=param_val + * + новенькийЧпу?sort=param_val&page=X&per-page=X + * Метод берет текущий URL, смотрит какая из 2 вариаций пришла, и не меняя уже написанной логики + * возвращает обработанную конечтную строку,идентичную входящей + *Если в текущем URL отсутствует погинация, НО присутствует сортировка, + * делает ссылку типа www.siteName.com?sort=var_param&page=X&per-page=X + * ========================================================================================================= + * + * @return string + */ + private function changeLinksToRequestView(string $link, string $requestUrl) + { + $positionSort = (strpos($requestUrl, 'sort=') !== false) ? strpos($requestUrl, 'sort=') : 0; + $positionPagination = (strpos($requestUrl, 'page=') !== false) ? strpos($requestUrl, 'page=') : 0; + + $regex1 = '/(\??|&?)page=\d{1,5}&per-page=\d{1,5}/'; + $regex2 = '/(\??|&)sort=[a-zA-z_]+&?/'; + + /* + * У нас 5 вариантов: + * sort>page ===> пагинация идёт первой + * sort перввая сортировка + * !sort + * !page + * !sort !page + */ + $option = $positionSort - $positionPagination; + if ($option > 0 && $positionPagination != 0)// первая пагинация + { + $link = Substringer::changeStringByRegex($link, $regex1, $regex2, '?', '?', '&'); + } elseif ($option > 0 && $positionPagination == 0)//есть сортировка, но нету пагинации + { + $link = Substringer::changeStringByRegex($link, $regex2, $regex1, '?', '?', '&'); + } elseif ($option < 0)// page>sort + { + $link = Substringer::changeStringByRegex($link, $regex2, $regex1, '?', '?', '&'); + } else // нету ни сортировки, ни пагинации + { + $link = Substringer::changeStringByRegex($link, $regex2, $regex1, '?', '?', '&'); + } + $result = $link; + return $result; + } +} + -- libgit2 0.21.4