/bitrix/modules/main/lib/userfield.php
PHP | 529 lines | 415 code | 60 blank | 54 comment | 15 complexity | f2ab4c8ac92e7290bc3daf29774f79c6 MD5 | raw file
- <?php
- /**
- * Bitrix Framework
- * @package bitrix
- * @subpackage main
- * @copyright 2001-2014 Bitrix
- */
- namespace Bitrix\Main;
- use Bitrix\Main\Entity;
- use Bitrix\Main\Type;
- /**
- * Class description
- * @package bitrix
- * @subpackage main
- */
- class UserFieldTable extends Entity\DataManager
- {
- // to use in uts serialized fields
- const MULTIPLE_DATE_FORMAT = 'Y-m-d';
- const MULTIPLE_DATETIME_FORMAT = 'Y-m-d H:i:s';
- public static function getMap()
- {
- return array(
- 'ID' => array(
- 'data_type' => 'integer',
- 'primary' => true,
- 'autocomplete' => true,
- ),
- 'ENTITY_ID' => array(
- 'data_type' => 'string'
- ),
- 'FIELD_NAME' => array(
- 'data_type' => 'string'
- ),
- 'USER_TYPE_ID' => array(
- 'data_type' => 'string'
- ),
- 'XML_ID' => array(
- 'data_type' => 'string'
- ),
- 'SORT' => array(
- 'data_type' => 'integer'
- ),
- 'MULTIPLE' => array(
- 'data_type' => 'boolean',
- 'values' => array('N', 'Y')
- ),
- 'MANDATORY' => array(
- 'data_type' => 'boolean',
- 'values' => array('N', 'Y')
- ),
- 'SHOW_FILTER' => array(
- 'data_type' => 'boolean',
- 'values' => array('N', 'Y')
- ),
- 'SHOW_IN_LIST' => array(
- 'data_type' => 'boolean',
- 'values' => array('N', 'Y')
- ),
- 'EDIT_IN_LIST' => array(
- 'data_type' => 'boolean',
- 'values' => array('N', 'Y')
- ),
- 'IS_SEARCHABLE' => array(
- 'data_type' => 'boolean',
- 'values' => array('N', 'Y')
- ),
- 'SETTINGS' => array(
- 'data_type' => 'text',
- 'serialized' => true
- )
- );
- }
- public static function add(array $data)
- {
- throw new NotImplementedException('Use \CUserTypeEntity API instead.');
- }
- public static function update($primary, array $data)
- {
- throw new NotImplementedException('Use \CUserTypeEntity API instead.');
- }
- public static function delete($primary)
- {
- throw new NotImplementedException('Use \CUserTypeEntity API instead.');
- }
- public static function attachFields(Entity\Base $entity, $ufId)
- {
- global $USER_FIELD_MANAGER;
- $utsFields = array();
- $utsFieldNames = array();
- $utmFields = array();
- $utmFieldNames = array();
- $fields = $USER_FIELD_MANAGER->getUserFields($ufId);
- foreach ($fields as $field)
- {
- if ($field['MULTIPLE'] === 'Y')
- {
- $utmFields[] = $field;
- $utmFieldNames[$field['FIELD_NAME']] = true;
- }
- else
- {
- $utsFields[] = $field;
- $utsFieldNames[$field['FIELD_NAME']] = true;
- }
- }
- if (!empty($utsFields) || !empty($utmFields))
- {
- // create uts entity & put fields into it
- $utsEntity = static::createUtsEntity($entity, $utsFields, $utmFields);
- // create reference to uts entity
- $utsReference = new Entity\ReferenceField('UTS_OBJECT', $utsEntity->getDataClass(), array(
- '=this.ID' => 'ref.VALUE_ID'
- ));
- $entity->addField($utsReference);
- // add UF_* aliases
- foreach ($fields as $userfield)
- {
- $utsFieldName = $userfield['FIELD_NAME'];
- /** @var Entity\ScalarField $utsField */
- $utsField = $utsEntity->getField($utsFieldName);
- $aliasField = new Entity\ExpressionField(
- $utsFieldName,
- '%s',
- 'UTS_OBJECT.'.$utsFieldName,
- array('data_type' => get_class($utsField))
- );
- if ($userfield['MULTIPLE'] == 'Y')
- {
- static::setMultipleFieldSerialization($aliasField, $userfield);
- }
- $entity->addField($aliasField);
- }
- if (!empty($utsFields))
- {
- foreach ($utsFields as $utsField)
- {
- $utsEntityField = $utsEntity->getField($utsField['FIELD_NAME']);
- foreach ($USER_FIELD_MANAGER->getEntityReferences($utsField, $utsEntityField) as $reference)
- {
- // rewrite reference from this.field to this.uts_object.field
- $referenceDesc = static::rewriteUtsReference($reference->getReference());
- $aliasReference = new Entity\ReferenceField(
- $reference->getName(),
- $reference->getRefEntityName(),
- $referenceDesc
- );
- $entity->addField($aliasReference);
- }
- }
- }
- if (!empty($utmFields))
- {
- // create utm entity & put base fields into it
- $utmEntity = static::createUtmEntity($entity, $utmFields);
- // add UF_* aliases
- foreach ($utmFieldNames as $utmFieldName => $true)
- {
- /** @var Entity\ScalarField $utmField */
- $utmField = $utmEntity->getField($utmFieldName);
- $aliasField = new Entity\ExpressionField(
- $utmFieldName.'_SINGLE',
- '%s',
- $utmEntity->getFullName().':PARENT_'.$utmFieldName.'.'.$utmField->getColumnName(),
- array('data_type' => get_class($utmField))
- );
- $entity->addField($aliasField);
- }
- }
- }
- }
- protected static function createUtsEntity(Entity\Base $srcEntity, array $utsFields, array $utmFields)
- {
- global $USER_FIELD_MANAGER;
- // get namespace & class
- /** @var Entity\DataManager $utsClassFull */
- $utsClassFull = static::getUtsEntityClassNameBySrcEntity($srcEntity);
- $utsClassPath = explode('\\', ltrim($utsClassFull, '\\'));
- $utsNamespace = join('\\', array_slice($utsClassPath, 0, -1));
- $utsClass = end($utsClassPath);
- // get table name
- $utsTable = static::getUtsEntityTableNameBySrcEntity($srcEntity);
- // base fields
- $fieldsMap = array(
- 'VALUE_ID' => array(
- 'data_type' => 'integer',
- 'primary' => true
- ),
- 'PARENT' => array(
- 'data_type' => $srcEntity->getDataClass(),
- 'reference' => array(
- '=this.VALUE_ID' => 'ref.ID'
- )
- )
- );
- // initialize entity
- $entity = Entity\Base::compileEntity($utsClass, $fieldsMap, array(
- 'namespace' => $utsNamespace, 'table_name' => $utsTable
- ));
- foreach ($utsFields as $utsField)
- {
- $field = $USER_FIELD_MANAGER->getEntityField($utsField);
- $entity->addField($field);
- foreach ($USER_FIELD_MANAGER->getEntityReferences($utsField, $field) as $reference)
- {
- $entity->addField($reference);
- }
- }
- foreach ($utmFields as $utmField)
- {
- // add seriazed utm cache-fields
- $cacheField = new Entity\TextField($utmField['FIELD_NAME']);
- static::setMultipleFieldSerialization($cacheField, $utmField);
- $entity->addField($cacheField);
- }
- return $entity;
- }
- /**
- * @param Entity\Field $entityField
- * @param Entity\Field|array $fieldAsType
- */
- public static function setMultipleFieldSerialization(Entity\Field $entityField, $fieldAsType)
- {
- global $USER_FIELD_MANAGER;
- if (!($fieldAsType instanceof Entity\Field))
- {
- $fieldAsType = $USER_FIELD_MANAGER->getEntityField($fieldAsType);
- }
- if ($fieldAsType instanceof Entity\DatetimeField)
- {
- $entityField->addSaveDataModifier(array(__CLASS__, 'serializeMultipleDatetime'));
- $entityField->addFetchDataModifier(array(__CLASS__, 'unserializeMultipleDatetime'));
- }
- elseif ($fieldAsType instanceof Entity\DateField)
- {
- $entityField->addSaveDataModifier(array(__CLASS__, 'serializeMultipleDate'));
- $entityField->addFetchDataModifier(array(__CLASS__, 'unserializeMultipleDate'));
- }
- else
- {
- $entityField->setSerialized();
- }
- }
- public static function rewriteUtsReference($referenceDesc)
- {
- $new = array();
- foreach ($referenceDesc as $k => $v)
- {
- if (is_array($v))
- {
- $new[$k] = static::rewriteUtsReference($v);
- }
- else
- {
- $k = str_replace('this.', 'this.UTS_OBJECT.', $k);
- $new[$k] = $v;
- }
- }
- return $new;
- }
- protected static function getUtsEntityClassNameBySrcEntity(Entity\Base $srcEntity)
- {
- return $srcEntity->getFullName().'UtsTable';
- }
- protected static function getUtsEntityTableNameBySrcEntity(Entity\Base $srcEntity)
- {
- return 'b_uts_'.strtolower($srcEntity->getUfId());
- }
- protected static function createUtmEntity(Entity\Base $srcEntity, array $utmFields)
- {
- global $USER_FIELD_MANAGER;
- /** @var Entity\DataManager $utmClassFull */
- $utmClassFull = static::getUtmEntityClassNameBySrcEntity($srcEntity);
- $utmClassPath = explode('\\', ltrim($utmClassFull, '\\'));
- $utmNamespace = join('\\', array_slice($utmClassPath, 0, -1));
- $utmClass = end($utmClassPath);
- // get table name
- $utmTable = static::getUtmEntityTableNameBySrcEntity($srcEntity);
- // coolect fields
- $fieldsMap = array(
- 'ID' => array(
- 'data_type' => 'integer',
- 'primary' => true,
- 'autocomplete' => true
- ),
- 'VALUE_ID' => array(
- 'data_type' => 'integer',
- 'primary' => true
- ),
- 'PARENT' => array(
- 'data_type' => $srcEntity->getDataClass(),
- 'reference' => array(
- '=this.VALUE_ID' => 'ref.ID'
- )
- ),
- 'FIELD_ID' => array(
- 'data_type' => 'integer'
- ),
- // base values fields
- 'VALUE' => array(
- 'data_type' => 'text'
- ),
- 'VALUE_INT' => array(
- 'data_type' => 'integer'
- ),
- 'VALUE_DOUBLE' => array(
- 'data_type' => 'float'
- ),
- 'VALUE_DATE' => array(
- 'data_type' => 'datetime'
- )
- );
- // initialize entity
- $entity = Entity\Base::compileEntity($utmClass, $fieldsMap, array(
- 'namespace' => $utmNamespace, 'table_name' => $utmTable
- ));
- // add utm fields being mapped on real column name
- foreach ($utmFields as $utmField)
- {
- $field = $USER_FIELD_MANAGER->getEntityField($utmField);
- if ($field instanceof Entity\IntegerField)
- {
- $columnName = 'VALUE_INT';
- }
- elseif ($field instanceof Entity\FloatField)
- {
- $columnName = 'VALUE_DOUBLE';
- }
- elseif ($field instanceof Entity\DateField || $field instanceof Entity\DatetimeField)
- {
- $columnName = 'VALUE_DATE';
- }
- else
- {
- $columnName = 'VALUE';
- }
- $field->setColumnName($columnName);
- $entity->addField($field);
- foreach ($USER_FIELD_MANAGER->getEntityReferences($utmField, $field) as $reference)
- {
- $entity->addField($reference);
- }
- // add back-reference
- $refField = new Entity\ReferenceField(
- 'PARENT_'.$utmField['FIELD_NAME'],
- $srcEntity->getDataClass(),
- array('=this.VALUE_ID' => 'ref.ID', '=this.FIELD_ID' => array('?i', $utmField['ID']))
- );
- $entity->addField($refField);
- }
- return $entity;
- }
- protected static function getUtmEntityClassNameBySrcEntity(Entity\Base $srcEntity)
- {
- return $srcEntity->getFullName().'UtmTable';
- }
- protected static function getUtmEntityTableNameBySrcEntity(Entity\Base $srcEntity)
- {
- return 'b_utm_'.strtolower($srcEntity->getUfId());
- }
- /**
- * @param Type\DateTime[] $value
- *
- * @return string
- */
- public static function serializeMultipleDatetime($value)
- {
- if (is_array($value) || $value instanceof \Traversable)
- {
- $tmpValue = array();
- foreach ($value as $k => $singleValue)
- {
- /** @var Type\DateTime $singleValue */
- $tmpValue[$k] = $singleValue->format(static::MULTIPLE_DATETIME_FORMAT);
- }
- return serialize($tmpValue);
- }
- return $value;
- }
- /**
- * @param string $value
- *
- * @return array
- */
- public static function unserializeMultipleDatetime($value)
- {
- if (strlen($value))
- {
- $value = unserialize($value);
- foreach ($value as &$singleValue)
- {
- try
- {
- //try new independent datetime format
- $singleValue = new Type\DateTime($singleValue, static::MULTIPLE_DATETIME_FORMAT);
- }
- catch (ObjectException $e)
- {
- //try site format
- $singleValue = new Type\DateTime($singleValue);
- }
- }
- }
- return $value;
- }
- /**
- * @param Type\Date[] $value
- *
- * @return string
- */
- public static function serializeMultipleDate($value)
- {
- if (is_array($value) || $value instanceof \Traversable)
- {
- $tmpValue = array();
- foreach ($value as $k => $singleValue)
- {
- /** @var Type\Date $singleValue */
- $tmpValue[$k] = $singleValue->format(static::MULTIPLE_DATE_FORMAT);
- }
- return serialize($tmpValue);
- }
- return $value;
- }
- /**
- * @param string $value
- *
- * @return array
- */
- public static function unserializeMultipleDate($value)
- {
- if (strlen($value))
- {
- $value = unserialize($value);
- foreach ($value as &$singleValue)
- {
- try
- {
- //try new independent datetime format
- $singleValue = new Type\Date($singleValue, static::MULTIPLE_DATE_FORMAT);
- }
- catch (ObjectException $e)
- {
- //try site format
- $singleValue = new Type\Date($singleValue);
- }
- }
- }
- return $value;
- }
- }