<?php
class onWidgetsPageIsAllowed extends cmsAction {
private $denied_type;
private $country;
private $strict = false;
public function run($allowed) {
// Если ранее в хуках уже сработал запрет
if (!$allowed) {
return false;
}
if (!$this->strict && $this->cms_user->is_admin) {
return $allowed;
}
$matched_pages = $this->cms_core->loadMatchedPages()->getMatchedPages();
if (!$matched_pages) {
return $allowed;
}
foreach ($matched_pages as $page) {
// проверяем доступ по группе
// если хотя бы для одной из страниц запрещено, закрываем доступ
if (!empty($page['groups']['view']) && !$this->cms_user->isInGroups($page['groups']['view'])) {
$allowed = false;
}
if (!empty($page['groups']['hide']) && $this->cms_user->isInGroups($page['groups']['hide'])) {
$allowed = false;
}
// прерываем перебор после первого запрета
if (!$allowed) {
$this->denied_type = 'group';
break;
}
// проверяем доступ по странам
if ((!empty($page['countries']['view']) && $page['countries']['view'] != [0]) || !empty($page['countries']['hide'])) {
$this->detectUserCountry();
if (!empty($page['countries']['view']) && $page['countries']['view'] != [0]) {
if (!$this->isInCountry($page['countries']['view'])) {
$allowed = false;
}
}
if (!empty($page['countries']['hide'])) {
if ($this->isInCountry($page['countries']['hide'])) {
$allowed = false;
}
}
}
if (!$allowed) {
$this->denied_type = 'country';
break;
}
}
if (!$allowed) {
$this->displayAccessError($page);
}
return $allowed;
}
private function displayAccessError($page) {
$this->cms_core->response->setStatusCode(403);
if ($page['controller']) {
if ($page['controller'] === 'content') {
$ctypes = cmsCore::getModel('content')->getContentTypes();
foreach ($ctypes as $_ctype) {
if (strpos($page['name'], $_ctype['name'] . '.') === 0) {
$page['title_subject'] = $_ctype['title'];
break;
}
}
}
cmsCore::loadControllerLanguage($page['controller']);
}
$page['title'] = !empty($page['title']) ?
$page['title'] :
sprintf(constant($page['title_const']), $page['title_subject']);
$this->cms_template->setContext($this);
$this->cms_template->setPageTitle(LANG_ACCESS_DENIED, $page['title']);
$this->cms_template->addBreadcrumb($page['title']);
$this->cms_template->addOutput($this->cms_template->render('access_error', [
'page' => $page,
'hint' => string_lang('LANG_ACCESS_' . $this->denied_type . '_HINT'),
'denied_type' => $this->denied_type
]));
}
/**
* @todo Надо переделать всё
* @return $this
*/
private function detectUserCountry() {
if ($this->country !== null) {
return $this;
}
if (!$this->isControllerInstalled('geo') || !$this->isControllerEnabled('geo')) {
return $this;
}
$geo = $this->controller_geo->getAutoDetectGeoByIp();
$this->country = $geo['country'];
return $this;
}
private function isInCountry($countries) {
if (empty($this->country['id'])) {
return true;
}
if (in_array(0, $countries)) {
return true;
}
return in_array($this->country['id'], $countries);
}
}