Вывод тикетов пользователя

Сегодня задали вопрос: -а как выводить тикеты определённого пользователя, типа как персональный блог?
Ну, тут минимум 2 варианта: 1. Создать отдельный раздел для юзера. 2. Выделять тикеты юзера из общей кучи.
Первый вариант отметаем сразу по ряду причин: - Нужно дать право юзеру на создание разделов. - Нужно проверять, сколько он их создал (должно же быть не больше одного). - Нужно назначать политики доступа так, чтобы туда мог написать только юзер. - Куча ненужных никому разделов в админке - Еще всякие непредвиденные сложности.
Если вы будуте создавать каждому юзеру блог самостоятельно в админке руками - еще куда ни шло. Но это не удобно + если юзеров много, то админка разрастётся до неприличных размеров.
Поэтому, мы пойдем вторым путём - выводом тикетов юзера по уникальному url. Я предлагаю site_name/section_name/user_name/.
Первым делом, нам нужно подготовить getPage к фильтрации по юзеру. Пиишем сниппет-обёртку getPageWrapper:

if (!empty($_REQUEST['username'])) {
    $username = trim($_REQUEST['username']);
    if ($user = $modx->getObject('modUser', array('username' => $username))) {
        $uid = $user->get('id');
    }
    else {$uid = 0;}
    $scriptProperties['where'] = '{"createdby":'.$uid.'}';
}

return $modx->runSnippet('getPage', $scriptProperties);
В разделе всех тикетов заменяем вызов getPage на getPageWrapper. Теперь, если в массиве $_REQUEST передать username существующего юзера - то выведутся только его тикеты.
Уже можно обращаться к странице site_name/section_name/?username=k07n. Обратите внимание, мы заодно нашли решение распространённого вопроса - а как передать через $_GET данные в getPage? Ничего сложного.
В принципе, всё. Можно делать ссылки на блог юзера и при переходе туда, будут выводиться только его статьи. Но это не красиво, мы ведь хотим дружественные url, да?
Эта задача также решается довольно просто. Пишем плагин redirectToUser:

if ($modx->event->name == 'OnPageNotFound') {
    $request = $_REQUEST['q'].'/';
    preg_match('/(.*?)\/(.*?)(?:\/|\.html)/', $request, $matches); // выбираем имя секции и юзера
    //echo '<pre>';print_r($matches);die; // Можно активировать для отладке
    if (!empty($matches[1]) && !empty($matches[2])) {
        $q = array(
            'alias' => $matches[1]
            ,'class_key' => 'TicketsSection'
            ,'deleted' => 0
            ,'published' => 1
        );
        // Ищем секцию тикетов и выводим её вместе с параметром фильтрации по юзеру
        if ($section = $modx->getObject('TicketsSection', $q)) {
            $section_id = $section->get('id');
            $_REQUEST['username'] = $matches[2];

            $modx->sendForward($section_id);
        }
    }
}
Плагин сработает, если не найдена страница по указанному адресу, затем попытается выделить из адреса запроса имя секции тикетов и юзера. Если секцию тикетов существует, то плагин загрузит ее, поместив в $_REQUEST имя юзера, чтобы обёртка getPage добавила его в условие выборки.
Если где-то в этом процессе произойдет сбой\несоответствие, то работа плагина остановится и вы получите стандартную страницу 404, которая и должна выводиться в таком случае. Конечно, вы можете добавить собственные дополнительные услоия\проверки и расширить мой пример как угодно.
Задача решена. С этого момента у меня в разделе вопросов можно кликать на имя юзера и получать все его тикеты. Например: http://bezumkin.ru/user/topics/bezumkin/.
Данный пример является класическим роутером дружественных url. Приблительно так же работают и friendly urls самого MODX.