Просмотр во фронте собственных не опубликованных страниц без права видеть неопубликованные страницы в принципе
В MODX есть один довольно неприятный подводный камень — есть настройка политик безопасности view_unpublished (Видеть неопубликованные документы), но нет возможности дать пользователю видеть конкретно его страницы, даже если они не опубликованы. То есть или все (давать право видеть в принципе не опубликованные, что понятно по ряду причин не круто), или не ясно как извращаться.
Это особенно важно, если у вас, к примеру, какая-то небольшая социалочка или типа того, когда сторонние пользователи создают свои собственные документы, но есть премодерация и эти документы изначально не опубликованые. Конечно можно сделать фейковую страницу для просмотра таких не опубликованных страниц, но это годится только для мелких проектов и когда всего один-два шаблона выводов таких страниц. Еже ли проект крупный, и для просмотра страницы важно, чтобы страница отображалась ровно так, как она отображалась бы, если бы была опубликована (с учетом шаблона, ее места в структуре и т.п.), то тут уже такой номер не пройдет. Надо именно дать возможность пользователям видеть их документы, даже если они не опубликованы.
Проблема в том, что если у пользователя нет прав видеть неопубликованные страницы, то modRequest в принципе исключает не опубликованные страницы еще на уровне SQL-запроса условием published = 1. Если modRequest не находит запрошенный по УРЛу документ, он отбрасывает $modx->sendErrorPage(), который в свою очередь вызывает событие OnPageNotFound, на который мы можем навесить плагин и рулить не найденные страницы, но проблема в том, что мы там могли бы перенаправить $modx->sendForward($id) только на опубликованную страницу. С неопубликованной страницей такой номер не пройдет. Я исследовал различные варианты решения этой проблемы и для себя нашел только один вариант — переопределение реквест-класса. Благо, что проблем с этим нет. Делаем так:
- Создаем свой пакет и добавляем его в
ExtensionPackages. Если данный шаг не понятен, можно сделать еще проще: если не установлен пакетmodxSite, устанавливаем его. - В папке
core/components/{component}/model/{package}создаем свой файл, к примеруmyrequest.class.php - В нем прописываем код (особое внимание обратите на то, что маска файла обязана быть такой:
strtolower($className).class.php). Например, если у вас класс называетсяMyRequest, то файл должен называтьсяmyrequest.class.php
<?php
class myRequest extends modRequest{
public function getResource($method, $identifier, array $options = array()) {
$resource = parent::getResource($method, $identifier, $options);
if(!$resource){
// Доступ к собственным ресурсам, даже если они не опубликованы
if(
$this->modx->user->id
AND is_numeric($this->modx->resourceIdentifier)
){
$resource = $this->modx->getObject('modResource', array(
"id" => $this->modx->resourceIdentifier,
"createdby" => $this->modx->user->id,
));
}
}
return $resource;
}
}
- В системных настройках создаем новую настройку
modRequest.classсо значением имени вашего класса (в нашем случаеmyRequest).
Всё. Теперь при запросе страницы, наш переопределенный класс будет сначала получить объект ресурса от родительского класса, а если не получит, будет пытаться в БД получить документ с таким ID и текущим пользователем. Получив объект ресурса MODX не проверяет опубликован он или нет. Есть — ОК, выводим. Конечно же здесь и прочую свою логику можно дописать.