Николай Ланец
31 июля 2013 г., 14:20

Самый простой кросс-контекстный роутер

Задача довольно тривиальная, а вот решение лично для меня на поверхности вообще не лежало…
Задача: у нас документы в разных контекстах лежат (не спрашивайте зачем). Так вот, нам надо организовать подмену УРЛов (то есть у нас своя маска УРЛов, и мы при обращении к сайту разбирая УРЛ точно знаем ID документа, который надо вывести), и нам надо вывести этот документ. Вопрос на засыпку: с какими трудностями мы можем столкнуться? Ответ: ни с какими!
В MODx есть функция — sendForward(); Но она очень замученная и далеко не для всего годится. В нашем же случае самый простой код выглядит вот так:
$modx->resource = $modx->getObject('modResource', $id); $modx->request->prepareResponse(); exit();
Все. При чем пофиг на текущий контексты и т.п. Вешаете свой плагин на OnPageNotFound и рулите какие документы выводить. Никакого редиректа, просто вывод документа абсолютно в штатном режиме.
UPD: на одном проекте делали хитрый роутинг под клиента, и выяснилось, что данный метод не укладывается в заложенный механизм MODX-кеширования, а именно: в момент выполнения modRequest::handleRequest MODX берет найденный документ из кеша, включая обработанный контент, ТВ-параметры и т.п., и только потом отправляет на обработку modRequest::prepareResponse(). А если мы напрямую его вызываем с полученным документом, то у нас нет его кеша и каждый раз страница отрабатывается с нуля. Чтобы все корректно работало, надо делать типа такого:
if(!empty($modx->resource)){ return; } if($modx->resourceMethod == "alias"){ $request = preg_replace('/^\/+/', '', $_SERVER['REQUEST_URI']); $q = $modx->newQuery('modResource'); $where = array( "uri" => $request, "deleted" => 0, ); $q->where($where); $q->select(array( "id", )); if($id = (int)$modx->getValue($q->prepare())){ $_REQUEST['id'] = $id; unset($_REQUEST['q']); $modx->handleRequest(); exit(); } }
Конечно же у вас могут быть свои отличные методы поиска айдишника запрошенного документа, но самое главное это сброс $_REQUEST['q'], установка id нужного документа $_REQUEST['id'] и повторная обработка запроса $modx->handleRequest(); Вот так будет все работать с кешем.

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