Fi1osof
14 сент. 2014 г., 15:12

modRedirect

Сегодня выкладываю новый модуль 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.
Это как Seo strict urls
Где-то полгода назад столкнулся с необходимостью такого плагина. Вот моя реализация: https://github.com/ilyautkin/autoRedirector
Под Рево он есть? Дайте ссылку на пакет.
Да, отличия конечно есть, но в целом принцип тот же. А ты как считаешь, это простая была задачка?
Под рево есть только снипппет кривой
Ясно. Сниппет здесь вообще не спасает.
Не столько сложная, сколько большая - долго пришлось искать, в каком моменте можно вклиниться... Ну и это мой первый опыт с ExtJS, так что времени на разработку ушло уйма))
Очень своевременно, давно искал что-то похожее... Спасибо!
Помнится мне, когда я хотел сделать такой же плагин, то также решил обработать все возможные события. Но натолкнулся на ворох багов, которые побороть не удалось. Коль, ты на них не натыкался? Если да, то учитываешь как-нибудь? Просто исправление этих багов - это серия пуллреквестов в modx репозиторий, которые я в своё время не осилил, а потом как-то и не вспоминал даже. Проще запулить небольшой коммит, чтобы в методе modResource::refreshURIs() или modResource::save() вызывалось какое-нибудь событие, которые решило бы все проблемы. Но не факт, что такой коммит примут разработчики modx'а.
А ещё, помнится мне, точно тогда же, на три дня позже, у нас с тобой развернулась полемика на эту тему, после чего ты мне доказывал, что такой плагин - на хрен не нужная хрень, аппелируя авторитетностью Носика, ибо seo. А сейчас вон оно как :-)
Коль, ты на них не натыкался? Если да, то учитываешь как-нибудь?
Нет, эти баги я не рассматривал и не учитывал (вполне допускаю, что они есть из-за неидеальности механизма). То есть мой плагин только следит за тем какой УРЛ был раньше, и если он изменился (а он не следит за механизмом изменения УРЛа), то сохраняет в БД старый УРЛ как есть и вместе с ним id документа. Далее (только в случае 404) плагин пытается найти запись с запрошенным УРЛом, и если найдено, то выполняет $modx->sendRedirect($modx->makeUrl($id)). То есть в целом плагину не важно что и как там обстоит с УРЛами. На счет пуллреквестов в этом направлении - не вижу значительной проблемы. Вообще менять алиасы и перемещать документы - это злое зло. И заморозка УРЛов в помощь.
А ещё, помнится мне, точно тогда же, на три дня позже, у нас с тобой развернулась полемика на эту тему, после чего ты мне доказывал, что такой плагин - на хрен не нужная хрень, аппелируя авторитетностью Носика, ибо seo. А сейчас вон оно как :-)
Как я и писал в самом начале топика "В целом считаю его с точки зрения полезности весьма сомнительным", и по прежнему так считаю :)
Вопрос , это только у меня после установки плагина, не работает админка в опере?
Плагин не должен никак влиять на вашу админку. Там никаких JS-ов не устанавливается или типа того. У меня в опере все работает.
ладно поработаем в explorer , в хроме та же фигня. Заходишь в админку и после выбора ресурса для редактирования все зависает.
Так включайте логи, смотрите что и как там. Войдите в config.inc.php и пропишите ini_set('display_errors', 1); Мой плагин здесь явно не при чем, тем более при попытке открытия страницы для редактирования. Значит там конкретно ошибки где-то лезут. Вы хоть разберитесь где и какие ошибки лезут.
Николай, здравствуйте. Плагин надо докручивать в ручную?
Добрый день. В каком именно плане докручивать?
перенес товар из одной группы в другую… выдает ошибку 404… как бы не отработал плагин…
А какая версия ShopModxBox и modRedirect стоит? Если ShopModxBox версии менее 2.5.1, то может и не сработать. Проверьте код плагина modRedirect с гитхабовским. Я сейчас на тестовом сайте проверил, у меня редиректится после переноса товара.
ShopModxBoxPatch 2.0.2 и modRedirect 1.0.0
А, ну у вас да, старая сборка, вы modRedirect устанавливали наверняка пакетом отдельно, а в опубликованном установочном бага была. Обновите код плагина с гитхаба. Новая версия установочного пакета modRedirect выйдет уже с актуальным кодом.
код обновил, но проблема не решилась… возможно из-за старой сборки ShopModxBox…
Нет, сборка не должна быть при чем, это самостоятельный плагин. Вы перемещаете документ как, просто в дереве документов перетаскиваете? Или как?
В настройках товара, родительский ресурс меняю…
Отправьте мне на почту n.lanets@modxclub.ru доступы в админку, я вечером гляну. Перепроверил, у меня все это работает.
Вот какой вы код обновляли, если в плагине старый код был? Смотрите ревизию. Сейчас все работает.

Добавить комментарий