Your IP : 18.191.135.39
<?php
/**
* Bitrix Framework
* @package bitrix
* @subpackage main
* @copyright 2001-2014 Bitrix
*/
namespace Bitrix\Main;
use Bitrix\Main\Entity;
use Bitrix\Main\Type;
/**
* Entity representation of UserFields.
* @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
)
);
}
/**
* @param array $data
*
* @return Entity\AddResult|void
* @throws NotImplementedException
*/
public static function add(array $data)
{
throw new NotImplementedException('Use \CUserTypeEntity API instead.');
}
/**
* @param mixed $primary
* @param array $data
*
* @return Entity\UpdateResult|void
* @throws NotImplementedException
*/
public static function update($primary, array $data)
{
throw new NotImplementedException('Use \CUserTypeEntity API instead.');
}
/**
* @param mixed $primary
*
* @return Entity\DeleteResult|void
* @throws NotImplementedException
*/
public static function delete($primary)
{
throw new NotImplementedException('Use \CUserTypeEntity API instead.');
}
/**
* @param Entity\Base $entity
* @param $ufId
*
* @throws ArgumentException
*/
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)
{
/** @var Entity\ScalarField $utsEntityField */
$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);
}
}
}
}
/**
* @param Entity\Base $srcEntity
* @param array $utsFields
* @param array $utmFields
*
* @return Entity\Base
* @throws ArgumentException
*/
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
if (class_exists($utsNamespace."\\".$utsClass))
{
Entity\Base::destroy($utsNamespace."\\".$utsClass);
$entity = Entity\Base::getInstance($utsNamespace."\\".$utsClass);
foreach ($fieldsMap as $fieldName => $field)
{
$entity->addField($field, $fieldName);
}
}
else
{
$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 serialized 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
*
* @throws ArgumentException
*/
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());
}
/**
* @param Entity\Base $srcEntity
* @param array $utmFields
*
* @return Entity\Base
* @throws ArgumentException
*/
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);
// collect 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
if (class_exists($utmNamespace."\\".$utmClass))
{
Entity\Base::destroy($utmNamespace."\\".$utmClass);
$entity = Entity\Base::getInstance($utmNamespace."\\".$utmClass);
foreach ($fieldsMap as $fieldName => $field)
{
$entity->addField($field, $fieldName);
}
}
else
{
$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
* @throws ObjectException
*/
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
* @throws ObjectException
*/
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;
}
}