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

Задача довольно тривиальная, а вот решение лично для меня на поверхности вообще не лежало…

Задача: у нас документы в разных контекстах лежат (не спрашивайте зачем). Так вот, нам надо организовать подмену УРЛов (то есть у нас своя маска УРЛов, и мы при обращении к сайту разбирая УРЛ точно знаем 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['q'], установка id нужного документа _REQUEST['id'] и повторная обработка запроса $modx->handleRequest(); Вот так будет все работать с кешем.