Current Path : /var/www/axolotl/data/www/voronezh.axolotls.ru/bitrix/modules/landing/lib/internals/ |
Current File : /var/www/axolotl/data/www/voronezh.axolotls.ru/bitrix/modules/landing/lib/internals/landing.php |
<?php namespace Bitrix\Landing\Internals; use \Bitrix\Main\Localization\Loc; use \Bitrix\Main\Entity; use \Bitrix\Landing\Landing; use \Bitrix\Landing\Manager; use \Bitrix\Landing\Rights; use \Bitrix\Landing\Role; use \Bitrix\Landing\TemplateRef; use \Bitrix\Landing\Landing\Cache; Loc::loadMessages(__FILE__); class LandingTable extends Entity\DataManager { /** * For save callbacks. */ const ACTION_TYPE_ADD = 'add'; /** * For save callbacks. */ const ACTION_TYPE_UPDATE = 'update'; /** * Stored fields for save separate. * @var array */ protected static $additionalFields = array(); /** * Returns DB table name for entity. * @return string */ public static function getTableName() { return 'b_landing'; } /** * Returns entity map definition. * @return array */ public static function getMap() { return array( 'ID' => new Entity\IntegerField('ID', array( 'primary' => true, 'autocomplete' => true, 'title' => 'ID' )), 'CODE' => new Entity\StringField('CODE', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANDING_CODE') )), 'INITIATOR_APP_CODE' => new Entity\StringField('INITIATOR_APP_CODE', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANDING_INITIATOR_APP_CODE') )), 'RULE' => new Entity\StringField('RULE', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_RULE') )), 'ACTIVE' => new Entity\StringField('ACTIVE', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANDING_ACTIVE'), 'default_value' => 'Y' )), 'DELETED' => new Entity\StringField('DELETED', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_SITE_DELETED'), 'default_value' => 'N' )), 'PUBLIC' => new Entity\StringField('PUBLIC', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANDING_PUBLIC'), 'default_value' => 'Y' )), 'SYS' => new Entity\StringField('SYS', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANDING_SYSTEM'), 'default_value' => 'N' )), 'VIEWS' => new Entity\IntegerField('VIEWS', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANDING_VIEWS'), 'default_value' => 0 )), 'TITLE' => new Entity\StringField('TITLE', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANDING_TITLE'), 'required' => true )), 'XML_ID' => new Entity\StringField('XML_ID', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_XML_ID') )), 'DESCRIPTION' => new Entity\StringField('DESCRIPTION', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_DESCRIPTION') )), 'TPL_ID' => new Entity\IntegerField('TPL_ID', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_TPL_ID') )), 'TPL_CODE' => new Entity\StringField('TPL_CODE', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_TPL_CODE') )), 'SITE_ID' => new Entity\IntegerField('SITE_ID', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_SITE_ID'), 'required' => true )), 'SITE' => new Entity\ReferenceField( 'SITE', 'Bitrix\Landing\Internals\SiteTable', array('=this.SITE_ID' => 'ref.ID') ), 'SITEMAP' => new Entity\StringField('SITEMAP', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANDING_SITEMAP'), 'default_value' => 'N' )), 'FOLDER' => new Entity\StringField('FOLDER', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_FOLDER'), 'default_value' => 'N' )), 'FOLDER_ID' => new Entity\IntegerField('FOLDER_ID', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_FOLDER_ID') )), 'SEARCH_CONTENT' => new Entity\StringField('SEARCH_CONTENT', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_SEARCH_CONTENT') )), 'VERSION' => new Entity\IntegerField('VERSION', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_VERSION'), 'default_value' => 5 )), 'CREATED_BY_ID' => new Entity\IntegerField('CREATED_BY_ID', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_CREATED_BY_ID'), 'required' => true )), 'CREATED_BY' => new Entity\ReferenceField( 'CREATED_BY', 'Bitrix\Main\UserTable', array('=this.CREATED_BY_ID' => 'ref.ID') ), 'MODIFIED_BY_ID' => new Entity\IntegerField('MODIFIED_BY_ID', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_MODIFIED_BY_ID'), 'required' => true )), 'MODIFIED_BY' => new Entity\ReferenceField( 'MODIFIED_BY', 'Bitrix\Main\UserTable', array('=this.MODIFIED_BY_ID' => 'ref.ID') ), 'DATE_CREATE' => new Entity\DatetimeField('DATE_CREATE', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_DATE_CREATE'), 'required' => true )), 'DATE_MODIFY' => new Entity\DatetimeField('DATE_MODIFY', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_DATE_MODIFY'), 'required' => true )), 'DATE_PUBLIC' => new Entity\DatetimeField('DATE_PUBLIC', array( 'title' => Loc::getMessage('LANDING_TABLE_FIELD_DATE_PUBLIC') )) ); } /** * Set additional access filter. * @param mixed $params ORM params. * @return mixed */ public static function setAccessFilter($params) { if ( isset($params['filter']['CHECK_PERMISSIONS']) && $params['filter']['CHECK_PERMISSIONS'] == 'N' ) { return $params; } // build filter $buildFilter = Rights::getAccessFilter(); if (empty($buildFilter)) { return $params; } // create runtime/filter keys if no exists if ( !isset($params['filter']) || !is_array($params['filter']) ) { $params['filter'] = []; } if ( !isset($params['runtime']) || !is_array($params['runtime']) ) { $params['runtime'] = []; } if ( !isset($params['group']) || !is_array($params['group']) ) { $params['group'] = []; } //$tasks = Rights::getAccessTasksReferences(); //$readCode = Rights::ACCESS_TYPES['read']; $extendedRights = Rights::isExtendedMode(); static $expectedRoles = null; if ($expectedRoles === null) { $expectedRoles = Role::getExpectedRoleIds(); } // create runtime fields $runtimeParams = [ '=this.SITE.ID' => 'ref.ENTITY_ID', '=ref.ENTITY_TYPE' => [ '?', Rights::ENTITY_TYPE_SITE ] /*'=ref.TASK_ID' => [ '?', $tasks[$readCode] ]*/ ]; if ($extendedRights) { $runtimeParams['=ref.ROLE_ID'] = [0]; } else { $runtimeParams['@ref.ROLE_ID'] = [implode(',', $expectedRoles)]; } $params['runtime'][] = new Entity\ReferenceField( 'RIGHTS', 'Bitrix\Landing\Internals\RightsTable', $runtimeParams, [ 'join_type' => 'LEFT' ] ); if (!$extendedRights) { $params['runtime'][] = new Entity\ReferenceField( 'RIGHTS_COMMON', 'Bitrix\Landing\Internals\RightsTable', [ '=ref.ENTITY_ID' => [0], '=ref.ENTITY_TYPE' => [ '?', Rights::ENTITY_TYPE_SITE ], /*'=ref.TASK_ID' => [ $tasks[$readCode] ],*/ '@ref.ROLE_ID' => [implode(',', $expectedRoles)] ], [ 'join_type' => 'LEFT' ] ); } $params['group'][] = 'SITE_ID'; // build filter $params['filter'][] = $buildFilter; return $params; } /** * Prepare change to save. * @param Entity\Event $event Event instance. * @param string $actionType Action type: add / update. * @return Entity\EventResult */ protected static function prepareChange(Entity\Event $event, $actionType) { $result = new Entity\EventResult(); $primary = $event->getParameter('primary'); $fields = $event->getParameter('fields'); $modifyFields = array(); $existFields = array(); $deleteMode = false; // get all fields, which we need if ($primary) { $res = self::getList([ 'select' => [ 'CODE', 'SITE_ID', 'FOLDER_ID', 'INITIATOR_APP_CODE', 'ID_INDEX' => 'SITE.LANDING_ID_INDEX' ], 'filter' => [ 'ID' => $primary['ID'], '=DELETED' => ['Y', 'N'] ] ]); $existFields = $res->fetch(); unset($res); } // check CODE mask if ( isset($fields['CODE']) && ( !isset($existFields['CODE']) || $existFields['CODE'] != $fields['CODE'] ) ) { if (preg_match('#^([\w]+)\_([\d]+)\_([\d]+)$#', $fields['CODE'], $matches)) { $result->setErrors(array( new Entity\EntityError( Loc::getMessage('LANDING_TABLE_ERROR_WRONG_CODE_FORMAT'), 'WRONG_CODE_FORMAT' ) )); return $result; } } // if page have't blocks of page's app, we clear this mark if (isset($fields['INITIATOR_APP_CODE'])) { $existFields['INITIATOR_APP_CODE'] = $fields['INITIATOR_APP_CODE']; } if ( $primary['ID'] && isset($existFields['INITIATOR_APP_CODE']) && $existFields['INITIATOR_APP_CODE'] ) { $res = BlockTable::getList([ 'select' => [ 'ID' ], 'filter' => [ 'LID' => $primary['ID'], '=DELETED' => 'N', '=INITIATOR_APP_CODE' => $existFields['INITIATOR_APP_CODE'] ] ]); if (!$res->fetch()) { $modifyFields['INITIATOR_APP_CODE'] = null; } unset($res); } // if delete, set unpublic always if (isset($fields['DELETED'])) { $deleteMode = true; $modifyFields['ACTIVE'] = 'N'; $fields['ACTIVE'] = 'N'; // disable main page deleting if ($fields['DELETED'] == 'Y' && $primary) { if ($existFields['ID_INDEX'] == $primary['ID']) { // disable only for a few pages in the site $sitesCheck = self::getList([ 'select' => [ 'ID' ], 'filter' => [ 'SITE_ID' => $existFields['SITE_ID'], '=DELETED' => 'N' ], 'limit' => 2 ])->fetchAll(); if (count($sitesCheck) > 1) { $result->setErrors([ new Entity\EntityError( Loc::getMessage('LANDING_TABLE_ERROR_LD_CANT_DELETE_MAIN'), 'CANT_DELETE_MAIN' ) ]); return $result; } } } } // get real site id, for check rights call upper level if (array_key_exists('SITE_ID', $fields)) { $res = \Bitrix\Landing\Site::getList(array( 'select' => array( 'ID' ), 'filter' => array( 'ID' => $fields['SITE_ID'] ) )); if (!$res->fetch()) { $result->setErrors(array( new Entity\EntityError( Loc::getMessage('LANDING_TABLE_ERROR_SITE_NOT_FOUND'), 'SITE_NOT_FOUND' ) )); return $result; } } else if ($existFields) { if ($existFields['SITE_ID']) { $fields['SITE_ID'] = $existFields['SITE_ID']; } else { $result->setErrors(array( new Entity\EntityError( Loc::getMessage('LANDING_TABLE_ERROR_SITE_NOT_FOUND'), 'SITE_NOT_FOUND' ) )); return $result; } } else { $fields['SITE_ID'] = 0; } // check rights if ($fields['SITE_ID'] && Rights::isOn()) { $rights = Rights::getOperationsForSite( $fields['SITE_ID'] ); // can create new landing in site if (!$primary) { if (!in_array(Rights::ACCESS_TYPES['edit'], $rights)) { $errMessage = Loc::getMessage( 'LANDING_TABLE_ERROR_LD_ACCESS_DENIED_ADD' ); $result->setErrors(array( new Entity\EntityError( $errMessage, 'ACCESS_DENIED' ) )); return $result; } } else { $freeAccessFields = [ 'CREATED_BY_ID', 'MODIFIED_BY_ID', 'DATE_CREATE', 'DATE_MODIFY', 'SITE_ID', 'PUBLIC' ]; if (in_array(Rights::ACCESS_TYPES['sett'], $rights)) { $freeAccessFields = $fields; $higherAccess = [ 'ACTIVE', 'DATE_PUBLIC', 'DELETED' ]; foreach ($higherAccess as $key) { if (isset($freeAccessFields[$key])) { unset($freeAccessFields[$key]); } } $freeAccessFields = array_keys($freeAccessFields); } if (in_array(Rights::ACCESS_TYPES['public'], $rights)) { $freeAccessFields[] = 'ACTIVE'; $freeAccessFields[] = 'DATE_PUBLIC'; } if (in_array(Rights::ACCESS_TYPES['delete'], $rights)) { $freeAccessFields[] = 'DELETED'; // allow unpublic in delete case if ($deleteMode) { $freeAccessFields[] = 'ACTIVE'; } } foreach ($fields as $key => $val) { if (!in_array($key, $freeAccessFields)) { $errMessage = Loc::getMessage( 'LANDING_TABLE_ERROR_LD_ACCESS_DENIED_' . $key ); if (!$errMessage) { $errMessage = Loc::getMessage( 'LANDING_TABLE_ERROR_LD_ACCESS_DENIED' ); } $result->setErrors(array( new Entity\EntityError( $errMessage, 'ACCESS_DENIED' ) )); return $result; } } } } // additional fields save after if (array_key_exists('ADDITIONAL_FIELDS', $fields)) { self::$additionalFields = $fields['ADDITIONAL_FIELDS']; $result->unsetFields(array('ADDITIONAL_FIELDS')); } else { self::$additionalFields = array(); } // slash in CODE is not allowed if ( array_key_exists('CODE', $fields) && mb_strpos($fields['CODE'], '/') !== false ) { $result->setErrors(array( new Entity\EntityError( Loc::getMessage('LANDING_TABLE_ERROR_SLASH_IS_NOT_ALLOWED'), 'SLASH_IS_NOT_ALLOWED' ) )); return $result; } // CODE can't be empty elseif ( array_key_exists('CODE', $fields) && $fields['CODE'] == '' ) { $result->setErrors(array( new Entity\EntityError( Loc::getMessage('LANDING_TABLE_ERROR_CANT_BE_EMPTY'), 'CANT_BE_EMPTY' ) )); return $result; } elseif ( $actionType == self::ACTION_TYPE_ADD && array_key_exists('TITLE', $fields) && (!array_key_exists('CODE', $fields) || trim($fields['CODE']) == '') ) { $fields['CODE'] = \CUtil::translit( trim($fields['TITLE']), LANGUAGE_ID, array( 'replace_space' => '', 'replace_other' => '' )); if (!$fields['CODE']) { $fields['CODE'] = randString(12); } $modifyFields['CODE'] = $fields['CODE']; } // check CODE unique in site group if (array_key_exists('CODE', $fields)) { // get site id if no exists if (!array_key_exists('SITE_ID', $fields) && $primary) { $site = self::getById($primary['ID'])->fetch(); $fields['SITE_ID'] = $site['SITE_ID']; } Landing::disableCheckDeleted(); $i = 0; do { $newCode = $fields['CODE'] . ($i++ > 0 ? $i : ''); $res = self::getList(array( 'select' => array( 'ID' ), 'filter' => array( '!ID' => $primary ? $primary['ID'] : 0, 'SITE_ID' => $fields['SITE_ID'], '=CODE' => $newCode, 'CHECK_PERMISSIONS' => 'N' ) )); } while ($res->fetch()); Landing::enableCheckDeleted(); $fields['CODE'] = $newCode; $modifyFields['CODE'] = $fields['CODE']; } $result->modifyFields($modifyFields); // all code blocks below promptly return result ! // check if folder_id is folder if ( array_key_exists('FOLDER_ID', $fields) && $fields['FOLDER_ID'] > 0 ) { $res = self::getList(array( 'select' => array( 'FOLDER' ), 'filter' => array( 'ID' => $fields['FOLDER_ID'], '=FOLDER' => 'Y', 'CHECK_PERMISSIONS' => 'N' ) )); if (!$res->fetch()) { $result->setErrors(array( new Entity\EntityError( Loc::getMessage('LANDING_TABLE_ERROR_ISNOT_FOLDER'), 'ISNOT_FOLDER' ) )); return $result; } } // subfolder disabled if ( array_key_exists('FOLDER', $fields) && $fields['FOLDER'] == 'Y' ) { if ($existFields['FOLDER_ID'] > 0) { $result->setErrors(array( new Entity\EntityError( Loc::getMessage('LANDING_TABLE_ERROR_SUBFOLDER_DISABLED'), 'SUBFOLDER_DISABLED' ) )); return $result; } } return $result; } /** * Get entity rows. * @param array $params Params array. * @return \Bitrix\Main\ORM\Query\Result */ public static function getList(array $params = array()) { if (Landing::checkDeleted()) { if ( !isset($params['filter']) || !is_array($params['filter']) ) { $params['filter'] = array(); } if ( !isset($params['filter']['DELETED']) && !isset($params['filter']['=DELETED']) ) { $params['filter']['=DELETED'] = 'N'; } if ( !isset($params['filter']['SITE.DELETED']) && !isset($params['filter']['=SITE.DELETED']) ) { $params['filter']['=SITE.DELETED'] = 'N'; } } if (isset($params['filter']['CHECK_PERMISSIONS'])) { unset($params['filter']['CHECK_PERMISSIONS']); } // strict filter by type $type = null; if (isset($params['filter']['SITE.TYPE'])) { $type = $params['filter']['SITE.TYPE']; unset($params['filter']['SITE.TYPE']); } if (isset($params['filter']['=SITE.TYPE'])) { $type = $params['filter']['=SITE.TYPE']; unset($params['filter']['=SITE.TYPE']); } $allowedTypes = \Bitrix\Landing\Site\Type::getFilterType(); $params['filter']['=SITE.TYPE'] = in_array($type, (array)$allowedTypes) ? $type : $allowedTypes; return parent::getList($params); } /** * Before add handler. * @param Entity\Event $event Event instance. * @return Entity\EventResult */ public static function OnBeforeAdd(Entity\Event $event) { return self::prepareChange($event, self::ACTION_TYPE_ADD); } /** * Before update handler. * @param Entity\Event $event Event instance. * @return Entity\EventResult */ public static function OnBeforeUpdate(Entity\Event $event) { return self::prepareChange($event, self::ACTION_TYPE_UPDATE); } /** * Before delete handler. * @param Entity\Event $event Event instance. * @return Entity\EventResult */ public static function OnBeforeDelete(Entity\Event $event) { $result = new Entity\EventResult(); $primary = $event->getParameter('primary'); if ($primary) { $res = self::getList([ 'select' => [ 'SITE_ID' ], 'filter' => [ 'ID' => $primary['ID'], 'CHECK_PERMISSIONS' => 'N', '=SITE.DELETED' => ['Y', 'N'], '=DELETED' => ['Y', 'N'] ] ]); if ($site = $res->fetch()) { // check delete access $hasAccess = Rights::hasAccessForSite( $site['SITE_ID'], Rights::ACCESS_TYPES['delete'] ); if (!$hasAccess) { $result->setErrors(array( new Entity\EntityError( Loc::getMessage('LANDING_TABLE_ERROR_LD_ACCESS_DENIED_DELETED'), 'ACCESS_DENIED' ) )); return $result; } } // check if it is folder $res = self::getList(array( 'select' => array( 'ID' ), 'filter' => array( 'FOLDER_ID' => $primary['ID'], 'CHECK_PERMISSIONS' => 'N', '=SITE.DELETED' => ['Y', 'N'], '=DELETED' => ['Y', 'N'] ), 'limit' => 1 )); if ($res->fetch()) { $result->setErrors(array( new Entity\EntityError( Loc::getMessage('LANDING_TABLE_ERROR_PAGE_FOLDER_NOT_EMPTY'), 'ERROR_PAGE_FOLDER_NOT_EMPTY' ) )); } } return $result; } /** * Save additional fields after add / update. * @param Entity\Event $event Event instance. * @return Entity\EventResult */ protected static function saveAdditionalFields(Entity\Event $event) { $result = new Entity\EventResult(); if (!empty(self::$additionalFields)) { $primary = $event->getParameter('primary'); Landing::saveAdditionalFields( $primary['ID'], self::$additionalFields ); } return $result; } /** * After add handler. * @param Entity\Event $event Event instance. * @return Entity\EventResult */ public static function OnAfterAdd(Entity\Event $event) { $primary = $event->getParameter('primary'); $fields = $event->getParameter('fields'); // set current landing as index, if this is single page if ($primary && isset($fields['SITE_ID'])) { $res = self::getList(array( 'select' => array( 'ID' ), 'filter' => array( 'SITE_ID' => $fields['SITE_ID'], 'CHECK_PERMISSIONS' => 'N' ), 'limit' => 2 )); if (count($res->fetchAll()) == 1) { Rights::setOff(); SiteTable::update($fields['SITE_ID'], array( 'LANDING_ID_INDEX' => $primary['ID'] )); Rights::setOn(); } } return self::saveAdditionalFields($event); } /** * After update handler. * @param Entity\Event $event Event instance. * @return Entity\EventResult */ public static function OnAfterUpdate(Entity\Event $event) { $primary = $event->getParameter('primary'); $fields = $event->getParameter('fields'); if ($primary) { Cache::clear($primary['ID']); } // for B24 we must update domain if ( array_key_exists('SITE_ID', $fields) && Manager::isB24() ) { \Bitrix\Landing\Site::update( $fields['SITE_ID'], array() ); } return self::saveAdditionalFields($event); } /** * After delete handler. * @param Entity\Event $event Event instance. * @return void */ public static function OnAfterDelete(Entity\Event $event) { $primary = $event->getParameter('primary'); if (isset($primary['ID'])) { Rights::setOff(); \Bitrix\Landing\File::deleteFromLanding($primary['ID']); \Bitrix\Landing\Syspage::deleteForLanding($primary['ID']); \Bitrix\Landing\Hook::deleteForLanding($primary['ID']); \Bitrix\Landing\TemplateRef::deleteArea($primary['ID']); \Bitrix\Landing\TemplateRef::setForLanding($primary['ID'], array()); \Bitrix\Landing\UrlRewrite::removeForLanding($primary['ID']); // if delete index page, make new page is index $res = \Bitrix\Landing\Site::getList(array( 'select' => array( 'ID' ), 'filter' => array( 'LANDING_ID_INDEX' => $primary['ID'] ) )); if ($site = $res->fetch()) { $res = Landing::getList(array( 'select' => array( 'ID' ), 'filter' => array( 'SITE_ID' => $site['ID'] ), 'order' => array( 'ID' => 'asc' ) )); while ($page = $res->fetch()) { if (!TemplateRef::landingIsArea($page['ID'])) { \Bitrix\Landing\Site::update( $site['ID'], array( 'LANDING_ID_INDEX' => $page['ID'] ) ); break; } } } Rights::setOn(); } } }