Fi1osof 14 сентября 2014 1 28
Сегодня выкладываю новый модуль modRedirect. В целом считаю его с точки зрения полезности весьма сомнительным, но с точки зрения сложности - довольно коварным. Процесс написания его был что-то вроде нового исследования MODX-а.

Для начала цель: бывает так, что уже имеющийся документ переносится в другой раздел, или меняется его алиас, или меняется с обычного документа на контейнер, в общем что угодно, что в итоге приводит к тому, что УРЛ страницы меняется, а если это контейнер и поменялся его алиас, то меняются УРЛы и всех вложенных документов. Наверняка многие с этим сталкивались. И вот идея возникла написать такой модуль, чтобы он отслеживал эти меняющиеся УРЛы, записывал их в таблицу, и при запросе к несуществующей странице проверял наличие запрошенного адреса в таблице, и если находил, то редиректил бы на актуальную страницу 301-ым редиректом. Идея, собственно говоря, весьма простая, а вот реализовать это оказалось гораздо сложнее чем показалось изначально, и это даже при том, что еще не все 100% случаев изменения УРЛов отслеживаются... У меня это заняло часов пять, что по сути очень много. Под катом детали.

Итак, самая главная проблема во всем этом - невозможность вклиниться в метод modResource::save(). То есть если бы мы могли вклиниться непосредственно в момент сохранения конечного объекта документа, то мы могли бы перед сохранением проверить изменился ли у него УРЛ перед записью или нет, и если да, то выполнили бы нужные нам действия. А этого сделать нельзя. Можно только навесить плагин на событие сохранения документа в принципе, но это раньше, чем сам процесс записи изменения в БД, и помимо всего прочего, могут даже после этого сработать другие плагины, которые произведут еще какие-нибудь модификации с объектом документа. Здесь еще проблема в том, что если мы, к примеру, выполним
$o = $modx->getObject('modResource', $id);
$o->alias = 'new alias';
$o->save();

то здесь вообще никакие плагины не работают, так что на это мы вообще никак не можем среагировать.

Вторая проблема заключается в том, что при изменении алиаса раздела, поменяются УРЛы и всех вложенных документов, то есть изменения появятся не в одном документе, а во всех вложенных.

Вот, собственно, я и попытался написать модуль, который бы отслеживал хотя бы стандартные события изменений документов, и сохранял старые УРЛы для последующих редиректов, если документ не найден. Сейчас есть как минимум один вариант, когда он не спасает: когда вы создаете новый документ в документе, который не является контейнером (то есть isfolder != 1), то при сохранении родительский документ превращается в контейнер, и УРЛ этого родителя уже заканчивается на container_suffix, а не на .html, к примеру, и вот это изменение родителя не будет зафиксировано. Поэтому сначала меняете документ-родитель, установив ему галочку Контейнер (и для него тогда будет сохранен старый УРЛ), и только потом создаете дочерний документ.

В общем, предлагаю обсудить этот модуль, так как здесь довольно много интересного материала. Git-проект модуля: https://github.com/Fi1osof/modRedirect.
28 комментариев
T
TITAN-UZ 15 сентября 2014г в 08:45 #
Это как Seo strict urls
Fi1osof1
Fi1osof 15 сентября 2014г в 16:27 #
Под Рево он есть? Дайте ссылку на пакет.
T
TITAN-UZ 15 сентября 2014г в 18:07 #
Под рево есть только снипппет кривой
Fi1osof1
Fi1osof 15 сентября 2014г в 19:09 #
Ясно. Сниппет здесь вообще не спасает.
ilyautkin1
ilyautkin 15 сентября 2014г в 14:03 #
Где-то полгода назад столкнулся с необходимостью такого плагина. Вот моя реализация: https://github.com/ilyautkin/autoRedirector
Fi1osof1
Fi1osof 15 сентября 2014г в 16:43 #
Да, отличия конечно есть, но в целом принцип тот же. А ты как считаешь, это простая была задачка?
ilyautkin1
ilyautkin 16 сентября 2014г в 16:02 #
Не столько сложная, сколько большая - долго пришлось искать, в каком моменте можно вклиниться... Ну и это мой первый опыт с ExtJS, так что времени на разработку ушло уйма))
Fi1osof1
Fi1osof 16 сентября 2014г в 16:27 #
:)
S
Shatalov_Vadim 27 сентября 2014г в 09:44 #
Очень своевременно, давно искал что-то похожее... Спасибо!
Fi1osof1
Fi1osof 27 сентября 2014г в 17:49 #
Не за что :)
A
AlOshka 27 сентября 2014г в 19:00 #
Помнится мне, когда я хотел сделать такой же плагин, то также решил обработать все возможные события. Но натолкнулся на ворох багов, которые побороть не удалось.
Коль, ты на них не натыкался? Если да, то учитываешь как-нибудь?
Просто исправление этих багов - это серия пуллреквестов в modx репозиторий, которые я в своё время не осилил, а потом как-то и не вспоминал даже. Проще запулить небольшой коммит, чтобы в методе modResource::refreshURIs() или modResource::save() вызывалось какое-нибудь событие, которые решило бы все проблемы. Но не факт, что такой коммит примут разработчики modx'а.

А ещё, помнится мне, точно тогда же, на три дня позже, у нас с тобой развернулась полемика на эту тему, после чего ты мне доказывал, что такой плагин - на хрен не нужная хрень, аппелируя авторитетностью Носика, ибо seo. А сейчас вон оно как :-)
Fi1osof1
Fi1osof 27 сентября 2014г в 19:23 #
Коль, ты на них не натыкался? Если да, то учитываешь как-нибудь?

Нет, эти баги я не рассматривал и не учитывал (вполне допускаю, что они есть из-за неидеальности механизма). То есть мой плагин только следит за тем какой УРЛ был раньше, и если он изменился (а он не следит за механизмом изменения УРЛа), то сохраняет в БД старый УРЛ как есть и вместе с ним id документа. Далее (только в случае 404) плагин пытается найти запись с запрошенным УРЛом, и если найдено, то выполняет $modx->sendRedirect($modx->makeUrl($id)). То есть в целом плагину не важно что и как там обстоит с УРЛами.
На счет пуллреквестов в этом направлении - не вижу значительной проблемы. Вообще менять алиасы и перемещать документы - это злое зло. И заморозка УРЛов в помощь.
А ещё, помнится мне, точно тогда же, на три дня позже, у нас с тобой развернулась полемика на эту тему, после чего ты мне доказывал, что такой плагин - на хрен не нужная хрень, аппелируя авторитетностью Носика, ибо seo. А сейчас вон оно как :-)

Как я и писал в самом начале топика "В целом считаю его с точки зрения полезности весьма сомнительным", и по прежнему так считаю :)
S
Shatalov_Vadim 27 сентября 2014г в 22:40 #
Вопрос , это только у меня после установки плагина, не работает админка в опере?
Fi1osof1
Fi1osof 27 сентября 2014г в 22:43 #
Плагин не должен никак влиять на вашу админку. Там никаких JS-ов не устанавливается или типа того. У меня в опере все работает.
S
Shatalov_Vadim 27 сентября 2014г в 22:55 #
ладно поработаем в explorer , в хроме та же фигня. Заходишь в админку и после выбора ресурса для редактирования все зависает.
Fi1osof1
Fi1osof 27 сентября 2014г в 22:57 #
Так включайте логи, смотрите что и как там. Войдите в config.inc.php и пропишите ini_set('display_errors', 1);
Мой плагин здесь явно не при чем, тем более при попытке открытия страницы для редактирования. Значит там конкретно ошибки где-то лезут. Вы хоть разберитесь где и какие ошибки лезут.
v
vshatl 30 января 2015г в 13:54 #
Николай, здравствуйте. Плагин надо докручивать в ручную?
Fi1osof1
Fi1osof 30 января 2015г в 14:12 #
Добрый день.
В каком именно плане докручивать?
v
vshatl 30 января 2015г в 14:34 #
перенес товар из одной группы в другую… выдает ошибку 404… как бы не отработал плагин…
Fi1osof1
Fi1osof 30 января 2015г в 14:45 #
А какая версия ShopModxBox и modRedirect стоит? Если ShopModxBox версии менее 2.5.1, то может и не сработать. Проверьте код плагина modRedirect с гитхабовским.
Я сейчас на тестовом сайте проверил, у меня редиректится после переноса товара.
v
vshatl 30 января 2015г в 14:51 #
ShopModxBoxPatch 2.0.2 и modRedirect 1.0.0
Fi1osof1
Fi1osof 30 января 2015г в 14:58 #
А, ну у вас да, старая сборка, вы modRedirect устанавливали наверняка пакетом отдельно, а в опубликованном установочном бага была. Обновите код плагина с гитхаба. Новая версия установочного пакета modRedirect выйдет уже с актуальным кодом.
v
vshatl 30 января 2015г в 15:07 #
код обновил, но проблема не решилась… возможно из-за старой сборки ShopModxBox…
Fi1osof1
Fi1osof 30 января 2015г в 17:36 #
Нет, сборка не должна быть при чем, это самостоятельный плагин. Вы перемещаете документ как, просто в дереве документов перетаскиваете? Или как?
Fi1osof1
Fi1osof 30 января 2015г в 23:45 #
Вот какой вы код обновляли, если в плагине старый код был? Смотрите ревизию.
Сейчас все работает.
v
vshatl 30 января 2015г в 17:39 #
В настройках товара, родительский ресурс меняю…
Fi1osof1
Fi1osof 30 января 2015г в 17:42 #
Отправьте мне на почту n.lanets@modxclub.ru доступы в админку, я вечером гляну. Перепроверил, у меня все это работает.
v
vshatl 30 января 2015г в 17:51 #
ок
Авторизуйтесь или зарегистрируйтесь (можно через соцсети ), чтобы оставлять комментарии.