Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/iblock/lib/ |
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/iblock/lib/iblocktable.php |
<?php namespace Bitrix\Iblock; use Bitrix\Iblock\ORM\ElementEntity; use Bitrix\Iblock\ORM\ElementV1Table; use Bitrix\Iblock\ORM\ElementV2Table; use Bitrix\Iblock\ORM\Fields\PropertyOneToMany; use Bitrix\Iblock\ORM\Fields\PropertyReference; use Bitrix\Main\Entity; use Bitrix\Main\Localization\Loc; use Bitrix\Main\ORM\Data\DataManager; use Bitrix\Main\ORM\Event; use Bitrix\Main\ORM\EventResult; use Bitrix\Main\ORM\Fields\BooleanField; use Bitrix\Main\ORM\Fields\Relations\CascadePolicy; use Bitrix\Main\ORM\Fields\Relations\ManyToMany; use Bitrix\Main\ORM\Fields\Relations\OneToMany; use Bitrix\Main\ORM\Fields\Relations\Reference; use Bitrix\Main\ORM\Fields\StringField; use Bitrix\Main\ORM\Query\Join; use Bitrix\Main\ORM\Query\Query; use Bitrix\Main\Type\DateTime; use CIBlockProperty; /** * Class IblockTable * * Fields: * <ul> * <li> ID int mandatory * <li> TIMESTAMP_X datetime * <li> IBLOCK_TYPE_ID string(50) mandatory * <li> CODE string(50) optional * <li> NAME string(255) mandatory * <li> ACTIVE bool optional default 'Y' * <li> SORT int optional default 500 * <li> LIST_PAGE_URL string(255) optional * <li> DETAIL_PAGE_URL string(255) optional * <li> SECTION_PAGE_URL string(255) optional * <li> CANONICAL_PAGE_URL string(255) optional * <li> PICTURE int optional * <li> DESCRIPTION text optional * <li> DESCRIPTION_TYPE enum ('text', 'html') optional default 'text' * <li> XML_ID string(255) optional * <li> TMP_ID string(40) optional <b>internal use only</b> * <li> INDEX_ELEMENT bool optional default 'Y' * <li> INDEX_SECTION bool optional default 'N' * <li> WORKFLOW bool optional default 'Y' * <li> BIZPROC bool optional default 'N' * <li> SECTION_CHOOSER enum ('L', 'D' or 'P') optional default 'L' * <li> LIST_MODE enum ('S' or 'C') optional default '' * <li> RIGHTS_MODE enum ('S' or 'E') optional default 'S' * <li> SECTION_PROPERTY bool optional default 'N' * <li> PROPERTY_INDEX enum ('N', 'Y', 'I') optional default 'N' * <li> VERSION enum (1 or 2) optional default 1 * <li> LAST_CONV_ELEMENT int optional default 0 <b>internal use only</b> * <li> SOCNET_GROUP_ID int optional <b>internal use only</b> * <li> EDIT_FILE_BEFORE string(255) optional * <li> EDIT_FILE_AFTER string(255) optional * <li> TYPE reference to {@link \Bitrix\Iblock\TypeTable} * </ul> * * @package Bitrix\Iblock * * DO NOT WRITE ANYTHING BELOW THIS * * <<< ORMENTITYANNOTATION * @method static EO_Iblock_Query query() * @method static EO_Iblock_Result getByPrimary($primary, array $parameters = []) * @method static EO_Iblock_Result getById($id) * @method static EO_Iblock_Result getList(array $parameters = []) * @method static EO_Iblock_Entity getEntity() * @method static \Bitrix\Iblock\Iblock createObject($setDefaultValues = true) * @method static \Bitrix\Iblock\EO_Iblock_Collection createCollection() * @method static \Bitrix\Iblock\Iblock wakeUpObject($row) * @method static \Bitrix\Iblock\EO_Iblock_Collection wakeUpCollection($rows) */ class IblockTable extends DataManager { const PROPERTY_STORAGE_COMMON = 1; const PROPERTY_STORAGE_SEPARATE = 2; const RIGHTS_SIMPLE = 'S'; const RIGHTS_EXTENDED = 'E'; const PROPERTY_INDEX_DISABLE = 'N'; const PROPERTY_INDEX_ENABLE = 'Y'; const PROPERTY_INDEX_INVALID = 'I'; const LIST_MODE_SEPARATE = 'S'; const LIST_MODE_COMBINED = 'C'; const SECTION_CHOOSER_SELECT = 'L'; const SECTION_CHOOSER_DROPDOWNS = 'D'; const SECTION_CHOOSER_PATH = 'P'; /* deprecated constants */ const SELECT = self::SECTION_CHOOSER_SELECT; const DROPDOWNS = self::SECTION_CHOOSER_DROPDOWNS; const PATH = self::SECTION_CHOOSER_PATH; const SIMPLE = self::RIGHTS_SIMPLE; const EXTENDED = self::RIGHTS_EXTENDED; const SEPARATE = self::LIST_MODE_SEPARATE; const COMBINED = self::LIST_MODE_COMBINED; const INVALID = self::PROPERTY_INDEX_INVALID; const DATA_CLASS_NAMESPACE = 'Bitrix\Iblock\Elements'; const DATA_CLASS_PREFIX = 'Element'; /** * Returns DB table name for entity * * @return string */ public static function getTableName() { return 'b_iblock'; } public static function getObjectClass() { return Iblock::class; } /** * Returns entity map definition. * * @return array * @throws \Bitrix\Main\SystemException */ public static function getMap() { return array( 'ID' => array( 'data_type' => 'integer', 'primary' => true, 'autocomplete' => true, 'title' => Loc::getMessage('IBLOCK_ENTITY_ID_FIELD'), ), 'TIMESTAMP_X' => array( 'data_type' => 'datetime', 'default_value' => function() { return new DateTime(); } , 'title' => Loc::getMessage('IBLOCK_ENTITY_TIMESTAMP_X_FIELD'), ), 'IBLOCK_TYPE_ID' => array( 'data_type' => 'string', 'required' => true, 'title' => Loc::getMessage('IBLOCK_ENTITY_IBLOCK_TYPE_ID_FIELD'), 'validation' => array(__CLASS__, 'validateIblockTypeId'), ), 'LID' => array( 'data_type' => 'string', 'validation' => array(__CLASS__, 'validateLid'), ), 'CODE' => array( 'data_type' => 'string', 'title' => Loc::getMessage('IBLOCK_ENTITY_CODE_FIELD'), 'validation' => array(__CLASS__, 'validateCode'), ), (new StringField('API_CODE')) ->configureSize(50), (new BooleanField('REST_ON')) ->configureValues('N', 'Y') ->configureDefaultValue('N'), 'NAME' => array( 'data_type' => 'string', 'required' => true, 'title' => Loc::getMessage('IBLOCK_ENTITY_NAME_FIELD'), 'validation' => array(__CLASS__, 'validateName'), ), 'ACTIVE' => array( 'data_type' => 'boolean', 'values' => array('N','Y'), 'title' => Loc::getMessage('IBLOCK_ENTITY_ACTIVE_FIELD'), ), 'SORT' => array( 'data_type' => 'integer', 'title' => Loc::getMessage('IBLOCK_ENTITY_SORT_FIELD'), ), 'LIST_PAGE_URL' => array( 'data_type' => 'string', 'title' => Loc::getMessage('IBLOCK_ENTITY_LIST_PAGE_URL_FIELD'), 'validation' => array(__CLASS__, 'validateListPageUrl'), ), 'DETAIL_PAGE_URL' => array( 'data_type' => 'string', 'title' => Loc::getMessage('IBLOCK_ENTITY_DETAIL_PAGE_URL_FIELD'), 'validation' => array(__CLASS__, 'validateDetailPageUrl'), ), 'SECTION_PAGE_URL' => array( 'data_type' => 'string', 'title' => Loc::getMessage('IBLOCK_ENTITY_SECTION_PAGE_URL_FIELD'), 'validation' => array(__CLASS__, 'validateSectionPageUrl'), ), 'CANONICAL_PAGE_URL' => array( 'data_type' => 'string', 'title' => Loc::getMessage('IBLOCK_ENTITY_CANONICAL_PAGE_URL_FIELD'), 'validation' => array(__CLASS__, 'validateCanonicalPageUrl'), ), 'PICTURE' => array( 'data_type' => 'integer', 'title' => Loc::getMessage('IBLOCK_ENTITY_PICTURE_FIELD'), ), 'DESCRIPTION' => array( 'data_type' => 'string', 'title' => Loc::getMessage('IBLOCK_ENTITY_DESCRIPTION_FIELD'), ), 'DESCRIPTION_TYPE' => array( 'data_type' => 'enum', 'values' => array('text', 'html'), 'title' => Loc::getMessage('IBLOCK_ENTITY_DESCRIPTION_TYPE_FIELD'), ), 'XML_ID' => array( 'data_type' => 'string', 'title' => Loc::getMessage('IBLOCK_ENTITY_XML_ID_FIELD'), 'validation' => array(__CLASS__, 'validateXmlId'), ), 'TMP_ID' => array( 'data_type' => 'string', 'title' => Loc::getMessage('IBLOCK_ENTITY_TMP_ID_FIELD'), 'validation' => array(__CLASS__, 'validateTmpId'), ), 'INDEX_ELEMENT' => array( 'data_type' => 'boolean', 'values' => array('N','Y'), 'title' => Loc::getMessage('IBLOCK_ENTITY_INDEX_ELEMENT_FIELD'), ), 'INDEX_SECTION' => array( 'data_type' => 'boolean', 'values' => array('N','Y'), 'title' => Loc::getMessage('IBLOCK_ENTITY_INDEX_SECTION_FIELD'), ), 'WORKFLOW' => array( 'data_type' => 'boolean', 'values' => array('N','Y'), 'title' => Loc::getMessage('IBLOCK_ENTITY_WORKFLOW_FIELD'), ), 'BIZPROC' => array( 'data_type' => 'boolean', 'values' => array('N','Y'), 'title' => Loc::getMessage('IBLOCK_ENTITY_BIZPROC_FIELD'), ), 'SECTION_CHOOSER' => array( 'data_type' => 'enum', 'values' => array( self::SECTION_CHOOSER_SELECT, self::SECTION_CHOOSER_DROPDOWNS, self::SECTION_CHOOSER_PATH ), 'default_value' => self::SECTION_CHOOSER_SELECT, 'title' => Loc::getMessage('IBLOCK_ENTITY_SECTION_CHOOSER_FIELD'), ), 'LIST_MODE' => array( 'data_type' => 'enum', 'values' => array(self::LIST_MODE_COMBINED, self::LIST_MODE_SEPARATE), 'default_value' => self::LIST_MODE_COMBINED, 'title' => Loc::getMessage('IBLOCK_ENTITY_LIST_MODE_FIELD'), ), 'RIGHTS_MODE' => array( 'data_type' => 'enum', 'values' => array(self::RIGHTS_SIMPLE, self::RIGHTS_EXTENDED), 'default_value' => self::RIGHTS_SIMPLE, 'title' => Loc::getMessage('IBLOCK_ENTITY_RIGHTS_MODE_FIELD'), ), 'SECTION_PROPERTY' => array( 'data_type' => 'boolean', 'values' => array('N','Y'), 'title' => Loc::getMessage('IBLOCK_ENTITY_SECTION_PROPERTY_FIELD'), ), 'PROPERTY_INDEX' => array( 'data_type' => 'enum', 'values' => array(self::PROPERTY_INDEX_DISABLE, self::PROPERTY_INDEX_ENABLE, self::PROPERTY_INDEX_INVALID), 'default' => self::PROPERTY_INDEX_DISABLE, 'title' => Loc::getMessage('IBLOCK_ENTITY_PROPERTY_INDEX_FIELD'), ), 'VERSION' => array( 'data_type' => 'enum', 'values' => array(self::PROPERTY_STORAGE_COMMON, self::PROPERTY_STORAGE_SEPARATE), 'default_value' => self::PROPERTY_STORAGE_COMMON, 'title' => Loc::getMessage('IBLOCK_ENTITY_VERSION_FIELD'), ), 'LAST_CONV_ELEMENT' => array( 'data_type' => 'integer', 'title' => Loc::getMessage('IBLOCK_ENTITY_LAST_CONV_ELEMENT_FIELD'), ), 'SOCNET_GROUP_ID' => array( 'data_type' => 'integer', 'title' => Loc::getMessage('IBLOCK_ENTITY_SOCNET_GROUP_ID_FIELD'), ), 'EDIT_FILE_BEFORE' => array( 'data_type' => 'string', 'title' => Loc::getMessage('IBLOCK_ENTITY_EDIT_FILE_BEFORE_FIELD'), 'validation' => array(__CLASS__, 'validateEditFileBefore'), ), 'EDIT_FILE_AFTER' => array( 'data_type' => 'string', 'title' => Loc::getMessage('IBLOCK_ENTITY_EDIT_FILE_AFTER_FIELD'), 'validation' => array(__CLASS__, 'validateEditFileAfter'), ), 'TYPE' => array( 'data_type' => 'Bitrix\Iblock\Type', 'reference' => array('=this.IBLOCK_TYPE_ID' => 'ref.ID'), ), new OneToMany('PROPERTIES', PropertyTable::class, 'IBLOCK') ); } /** * @param int|Iblock $iblockApiCode * * @return ElementEntity|false * @throws \Bitrix\Main\ArgumentException * @throws \Bitrix\Main\ObjectPropertyException * @throws \Bitrix\Main\SystemException */ public static function compileEntity($iblockApiCode) { // get iblock if ($iblockApiCode instanceof Iblock) { $iblock = $iblockApiCode; $iblock->fillApiCode(); } else { $iblock = IblockTable::getList([ 'select' => ['ID', 'API_CODE'], 'filter' => Query::filter()->where('API_CODE', $iblockApiCode) ])->fetchObject(); } if (!$iblock || empty($iblock->getApiCode())) { return false; } // class info $iblockNamespace = static::DATA_CLASS_NAMESPACE; $iblockDataClassName = $iblock->getEntityDataClassName(); if ($iblockDataClassName == '') { return false; } // check if already compiled $iblockDataClass = $iblock->getEntityDataClass(); if (class_exists($iblockDataClass, false)) { return $iblockDataClass::getEntity(); } // fill some necessary info $iblock->fill(['VERSION', 'PROPERTIES']); // iblock personal entity $parentDataClass = $iblock->getVersion() == 1 ? ElementV1Table::class : ElementV2Table::class; /** @var ElementEntity $elementEntity */ $elementEntity = \Bitrix\Main\ORM\Entity::compileEntity( $iblockDataClassName, [], [ 'namespace' => $iblockNamespace, 'parent' => $parentDataClass, ] ); // set iblock to the entity $elementEntity->setIblock($iblock); // set relation with sections SectionElementTable::getEntity()->addField( (new Reference('REGULAR_ELEMENT_'.$iblock->getId(), $elementEntity, Join::on('this.IBLOCK_ELEMENT_ID', 'ref.ID')->whereNull('this.ADDITIONAL_PROPERTY_ID'))) ); $elementEntity->addField((new ManyToMany('SECTIONS', SectionTable::class)) ->configureMediatorEntity(SectionElementTable::class) ->configureLocalReference('REGULAR_ELEMENT_'.$iblock->getId()) ->configureRemoteReference('IBLOCK_SECTION') ); //$baseTypeList = \Bitrix\Iblock\Helpers\Admin\Property::getBaseTypeList(true); $userTypeList = CIBlockProperty::GetUserType(); // get properties foreach ($iblock->getProperties() as $property) { if (empty($property->getCode())) { continue; } // build property entity with base fields $propertyValueEntity = $property->getValueEntity($elementEntity); // add custom fields if (!empty($property->getUserType()) && !empty($userTypeList[$property->getUserType()]['GetORMFields'])) { call_user_func($userTypeList[$property->getUserType()]['GetORMFields'], $propertyValueEntity, $property); } // add relations with property entity $niceColumnName = $property->getCode(); if ($property->getMultiple()) { // classic OneToMany $elementRefName = 'SRC_ELEMENT'; // ref from prop entity to src element $propertyValueEntity->addField( (new Reference( $elementRefName, $elementEntity, Join::on('this.IBLOCK_ELEMENT_ID', 'ref.ID') ->where('this.IBLOCK_PROPERTY_ID', $property->getId()) )) ->configureJoinType(Join::TYPE_INNER) ); // OneToMany from src element to prop entity $elementEntity->addField( (new PropertyOneToMany($niceColumnName, $propertyValueEntity, $elementRefName)) ->configureJoinType(Join::TYPE_LEFT) ->configureIblockElementProperty($property) ->configureCascadeDeletePolicy( CascadePolicy::FOLLOW ) ); } else { // classic ref $joinType = Join::TYPE_INNER; $joinFilter = Join::on('this.ID', 'ref.IBLOCK_ELEMENT_ID'); if ($iblock->getVersion() == 1) { // additional clause for shared value table in v1.0 $joinType = Join::TYPE_LEFT; $joinFilter->where('ref.IBLOCK_PROPERTY_ID', $property->getId()); } // ref from src element to prop entity $elementEntity->addField( (new PropertyReference($niceColumnName, $propertyValueEntity, $joinFilter)) ->configureJoinType($joinType) ->configureIblockElementProperty($property) ->configureCascadeDeletePolicy( CascadePolicy::NO_ACTION // will be removed together in onAfterDelete ) ); } } return $elementEntity; } /** * @throws \Bitrix\Main\ArgumentException * @throws \Bitrix\Main\ObjectPropertyException * @throws \Bitrix\Main\SystemException */ public static function compileAllEntities() { foreach (static::getList(['select' => ['ID', 'API_CODE']])->fetchCollection() as $iblock) { static::compileEntity($iblock); } } /** * Returns validators for IBLOCK_TYPE_ID field. * * @return array */ public static function validateIblockTypeId() { return array( new Entity\Validator\Length(null, 50), ); } /** * Returns validators for LID field. * * @return array */ public static function validateLid() { return array( new Entity\Validator\Length(null, 2), ); } /** * Returns validators for CODE field. * * @return array */ public static function validateCode() { return array( new Entity\Validator\Length(null, 50), ); } /** * Returns validators for NAME field. * * @return array */ public static function validateName() { return array( new Entity\Validator\Length(null, 255), ); } /** * Returns validators for LIST_PAGE_URL field. * * @return array */ public static function validateListPageUrl() { return array( new Entity\Validator\Length(null, 255), ); } /** * Returns validators for DETAIL_PAGE_URL field. * * @return array */ public static function validateDetailPageUrl() { return array( new Entity\Validator\Length(null, 255), ); } /** * Returns validators for SECTION_PAGE_URL field. * * @return array */ public static function validateSectionPageUrl() { return array( new Entity\Validator\Length(null, 255), ); } /** * Returns validators for CANONICAL_PAGE_URL field. * * @return array */ public static function validateCanonicalPageUrl() { return array( new Entity\Validator\Length(null, 255), ); } /** * Returns validators for XML_ID field. * * @return array */ public static function validateXmlId() { return array( new Entity\Validator\Length(null, 255), ); } /** * Returns validators for TMP_ID field. * * @return array */ public static function validateTmpId() { return array( new Entity\Validator\Length(null, 40), ); } /** * Returns validators for EDIT_FILE_BEFORE field. * * @return array */ public static function validateEditFileBefore() { return array( new Entity\Validator\Length(null, 255), ); } /** * Returns validators for EDIT_FILE_AFTER field. * * @return array */ public static function validateEditFileAfter() { return array( new Entity\Validator\Length(null, 255), ); } /** * Default onAfterAdd handler. Absolutely necessary. * * @param Event $event Current data for add. * @return void */ public static function onAfterAdd(Event $event) { $primary = $event->getParameter('primary'); \CIBlock::CleanCache($primary['ID']); } /** * Default onBeforeAdd handler. Absolutely necessary. * * @param Event $event Current data for add. * @return EventResult */ public static function onBeforeAdd(Event $event): EventResult { $result = new EventResult; $fields = $event->getParameter('fields'); if (!isset($fields['TIMESTAMP_X'])) { $result->modifyFields([ 'TIMESTAMP_X' => new DateTime(), ]); } return $result; } /** * Default onBeforeUpdate handler. Absolutely necessary. * * @param Event $event Current data for update. * @return EventResult */ public static function onBeforeUpdate(Event $event): EventResult { $result = new EventResult; $fields = $event->getParameter('fields'); if (!isset($fields['TIMESTAMP_X'])) { $result->modifyFields([ 'TIMESTAMP_X' => new DateTime(), ]); } return $result; } /** * Default onAfterUpdate handler. Absolutely necessary. * * @param Event $event Current data for add. * @return void */ public static function onAfterUpdate(Event $event) { $primary = $event->getParameter('primary'); \CIBlock::CleanCache($primary['ID']); } /** * Default onAfterDelete handler. Absolutely necessary. * * @param Event $event Current data for add. * @return void */ public static function onAfterDelete(Event $event) { $primary = $event->getParameter('primary'); \CIBlock::CleanCache($primary['ID']); } }