Сначала я сделал плагинчик для того, чтобы можно было ресурсы переносить из раздела в раздел безболезненно и добавлять дочерние ресурсы (у контейнеров префикс URL меняется).
Теперь решил поднатужится и сделать максимально автоматизированную систему, которая позволит не только переносить ресурсы, но и менять им псевдонимы, не беспокоясь о редиректах.
Схема и проблемы (теория)
Изначально идеей было сохранять все варианты uri ресурса в отдельную таблицу. Однако пришлось бы на каждом новом сайте создавать таблицу, прописывать схему и пр. Я же хотел, чтобы на каждый новый сайт этот функционал добавлялся как можно проще.
Думаю, как будет время, соберу пакет, который будет сам создавать таблицу и пр.
Пока решил сделать по-другому: при изменении псевдонима создается ресурс, которому устанавливается старый uri.
Тут появляется проблема — если мы захотим поменять псевдоним обратно, вылезет ошибка, так как такой uri уже используется. Я пытался отловить этот момент, чтобы перезаписывать uri второстепенного ресурса. Но здесь видно, что в момент выполнения функции checkFriendlyAlias не вызывается никаких событий (и до этой функции тоже).
Поэтому было решено отключить «проверку на дублирование uri во всех контекстах» (в настройках системы) и создать для второстепенных ресурсов свой контекст.
Сам код и комментарии
И так, сначала по событию OnBeforeDocFormSave мы записываем в сессию текущий uri:
<?php switch ($modx->event->name) { case "OnBeforeDocFormSave": if ($mode == 'upd') { $uri = $resource->uri; $_SESSION[$id."-uri"] = $uri; } break; }После сохранения (событие OnDocFormSave) мы смотрим, изменился ли uri ресурса и если да, то создаем второстепенный ресурс в отдельном контексте:
<?php switch ($modx->event->name) { case "OnDocFormSave": if ($mode == 'upd') { if ($old_uri == $uri) {break;} else { $context = "redirector"; // наш контекст $uri = $resource->uri; // текущий uri $old_uri = $_SESSION[$id."-uri"]; // uri, записанный в сессию // Чтобы дерево ресурсов не разрасталось и админка не тормозила // ставим show_in_tree => 0 $redirectorParams = array( "show_in_tree" => 0 , "published" => 1 , "uri_override" => 1 , "context_key" => $context ); $redirectorParams["uri"] = $old_uri; // Записываем старый uri $redirectorParams["longtitle"] = $id; // Указываем, куда редиректить $response = $modx->runProcessor('resource/create', $redirectorParams); $redirectorId = $response->response['object']['id']; $redirector = $modx->getObject("modResource", $redirectorId); $redirector->set("pagetitle", $redirectorId); $redirector->set("alias", $redirectorId); $redirector->save(); break; } } }Если мы сначала поменяли псевдоним, а потом решили вернуть его обратно, просто меняем uri ресурсов местами:
<?php if ($redirector = $modx->getObject("modResource", $redirectorParams)) { $redirector->set("uri",$old_uri); $redirector->save(); break; }Ну и правила для редиректов (события OnPageNotFound):
<?php case "OnPageNotFound": $url = $_SERVER['REQUEST_URI']; $uri = str_replace($modx->getOption("site_url"),"",$url); if (substr($uri, 0, 1) == "/") $uri = substr($uri, 1); $redirector = $modx->getObject('modResource', array("uri" => $uri)); if ($redirector) { $modx->sendRedirect($modx->makeUrl($redirector->get('longtitle')), array('responseCode' => 'HTTP/1.1 301 Moved Permanently')); } // Если ресурс не редактировался (например, его просто перетащили в дереве) // (это тот самый маленький плагин из прошлой статьи) if (substr($url, -5) == ".html") $url = substr($url, 0, -5); if (substr($url, -1) == "/") $url = substr($url, 0, -1); $url = str_replace($modx->getOption("site_url"),"",$url); $url_array = explode('/', $url); $alias = array_pop($url_array); $res = $modx->getObject('modResource', array("alias" => $alias)); if ($res) $modx->sendRedirect($modx->makeUrl($res->get('id')), array('responseCode' => 'HTTP/1.1 301 Moved Permanently')); break; }
Инструкция, как запустить на своем сайте
- Выключаем в настройках системы global_duplicate_uri_check («Проверять на дублирование URI во всех контекстах»)
- Создаем контекст redirector
- Создаем плагин и включаем в нем события OnBeforeDocFormSave, OnDocFormSave и OnPageNotFound
- Вставляем в плагин код по ссылке.
G+ Оригинал статьи community.modx-cms.ru/blog/tips_and_tricks/9559.html
0 комментариев