404 статус для существующих страниц
Актуально для версии 18.
Для некоторых страниц, например для страниц настроек или комментариев, может понадобиться выводить 404 страницу.
В исходном коде системы есть стандартная точка вызова systemPrepare, описание которой я не нашел в документации. На мой взгляд это самое удачное место для внедрения кастомного обработчика.
Перехватка события (файл events.php в папке classes/modules/content шаблона, или custom_events.php в системной папке модуля):
new umiEventListener('systemPrepare', 'content', 'after_system_prepared');
Права на доступ к макросу (permissions.php или permissions_custom.php):
$permissions= Array(
'content' => array('after_system_prepared')
);
Сам макрос (в class.php или custom.php):
public function after_system_prepared(iUmiEventPoint $oEventPoint) {
if ($oEventPoint->getMode() === "after") {
$cmsController = cmsController::getInstance();
$page_id = $cmsController->getCurrentElementId();
if (!$page_id or !$this->isStatus404($page_id))
return true;
// задаем данные, как для несуществующей страницы
$cmsController->setCurrentElementId(false);
$cmsController->setCurrentModule('content');
$cmsController->setCurrentMethod('content');
}
return true;
}
В методе isStatus404 определяем, какие страницы скрываются от отображения на сайте:
public function isStatus404($pageId = false) {
if (!$pageId)
return true;
$hierarchy = umiHierarchy::getInstance();
$page = $hierarchy->getElement($pageId);
$status = (bool) $page->getValue('status404');
if ($status)
return true;
$parents = $hierarchy->getAllParents($pageId);
$pages = new selector('pages');
$pages->where('id')->equals($parents);
$pages->option('return')->value('status404');
foreach ($pages->result as $item) {
if ($item['status404'])
return true;
}
return false;
}
В данном случае у типа данных "Раздел сайта" есть поле status404, при включении которого будет скрываться данная страница и все ее подстраницы.
Также будет логичным скрыть такие страницы из xml-карты сайта. Для этого можно воспользоваться этой статьей.