Your IP : 3.22.235.243
<?php
/**
* Bitrix Framework
* @package bitrix
* @subpackage main
* @copyright 2001-2016 Bitrix
*/
namespace Bitrix\Main\ORM;
use Bitrix\Main;
use Bitrix\Main\ORM\Data\DataManager;
use Bitrix\Main\ORM\Fields\ExpressionField;
use Bitrix\Main\ORM\Fields\Field;
use Bitrix\Main\ORM\Fields\Relations\Reference;
use Bitrix\Main\ORM\Fields\ScalarField;
use Bitrix\Main\ORM\Objectify\EntityObject;
use Bitrix\Main\ORM\Objectify\Collection;
use Bitrix\Main\ORM\Query\Query;
use Bitrix\Main\Text\StringHelper;
/**
* Base entity
*/
class Entity
{
/** @var DataManager */
protected $className;
protected
$module,
$name,
$connectionName,
$dbTableName,
$primary,
$autoIncrement;
protected
$uf_id,
$isUts,
$isUtm;
/** @var Field[] */
protected $fields;
protected $fieldsMap;
/** @var UField[] */
protected $u_fields;
/** @var string Unique code */
protected $code;
protected $references;
/** @var static[] dataClass => entity */
protected static $instances;
/** @var array ufId => dataClass */
protected static $ufIdIndex = [];
/** @var bool */
protected $isClone = false;
const DEFAULT_OBJECT_PREFIX = 'EO_';
/**
* Returns entity object
*
* @param $entityName
*
* @return Entity
* @throws Main\ArgumentException
* @throws Main\SystemException
*/
public static function get($entityName)
{
return static::getInstance($entityName);
}
/**
* Checks if entity exists
*
* @param $entityName
*
* @return bool
*/
public static function has($entityName)
{
$entityClass = static::normalizeEntityClass($entityName);
return class_exists($entityClass);
}
/**
* @static
*
* @param string $entityName
*
* @return Entity
* @throws Main\ArgumentException
* @throws Main\SystemException
*/
public static function getInstance($entityName)
{
$entityName = static::normalizeEntityClass($entityName);
return self::getInstanceDirect($entityName);
}
/**
* @param DataManager|string $className
*
* @return mixed
* @throws Main\ArgumentException
* @throws Main\SystemException
*/
protected static function getInstanceDirect($className)
{
if (empty(self::$instances[$className]))
{
/** @var Entity $entity */
$entityClass = $className::getEntityClass();
// in case of calling Table class was not ended with entity initialization
if (empty(self::$instances[$className]))
{
$entity = new $entityClass;
$entity->initialize($className);
$entity->postInitialize();
// call user-defined postInitialize
$className::postInitialize($entity);
self::$instances[$className] = $entity;
}
}
return self::$instances[$className];
}
/**
* Fields factory
*
* @param string $fieldName
* @param array|Field $fieldInfo
*
* @return Field
* @throws Main\ArgumentException
* @throws Main\SystemException
*/
public function initializeField($fieldName, $fieldInfo)
{
if ($fieldInfo instanceof Field)
{
$field = $fieldInfo;
// rewrite name
if (!empty($fieldName) && !is_numeric($fieldName))
{
$field->setName($fieldName);
}
}
elseif (is_array($fieldInfo))
{
if (!empty($fieldInfo['reference']))
{
if (is_string($fieldInfo['data_type']) && strpos($fieldInfo['data_type'], '\\') === false)
{
// if reference has no namespace, then it'is in the same namespace
$fieldInfo['data_type'] = $this->getNamespace().$fieldInfo['data_type'];
}
//$refEntity = Base::getInstance($fieldInfo['data_type']."Table");
$field = new Reference($fieldName, $fieldInfo['data_type'], $fieldInfo['reference'], $fieldInfo);
}
elseif (!empty($fieldInfo['expression']))
{
$expression = array_shift($fieldInfo['expression']);
$buildFrom = $fieldInfo['expression'];
$field = new ExpressionField($fieldName, $expression, $buildFrom, $fieldInfo);
}
elseif (!empty($fieldInfo['USER_TYPE_ID']))
{
$field = new UField($fieldInfo);
}
else
{
$fieldClass = StringHelper::snake2camel($fieldInfo['data_type']) . 'Field';
$fieldClass = '\\Bitrix\\Main\\Entity\\'.$fieldClass;
if (strlen($fieldInfo['data_type']) && class_exists($fieldClass))
{
$field = new $fieldClass($fieldName, $fieldInfo);
}
elseif (strlen($fieldInfo['data_type']) && class_exists($fieldInfo['data_type']))
{
$fieldClass = $fieldInfo['data_type'];
$field = new $fieldClass($fieldName, $fieldInfo);
}
else
{
throw new Main\ArgumentException(sprintf(
'Unknown data type "%s" found for `%s` field in %s Entity.',
$fieldInfo['data_type'], $fieldName, $this->getName()
));
}
}
}
else
{
throw new Main\ArgumentException(sprintf('Unknown field type `%s`',
is_object($fieldInfo) ? get_class($fieldInfo) : gettype($fieldInfo)
));
}
$field->setEntity($this);
$field->postInitialize();
return $field;
}
public function initialize($className)
{
/** @var $className DataManager */
$this->className = $className;
/** @var DataManager $className */
$this->connectionName = $className::getConnectionName();
$this->dbTableName = $className::getTableName();
$this->fieldsMap = $className::getMap();
$this->uf_id = $className::getUfId();
$this->isUts = $className::isUts();
$this->isUtm = $className::isUtm();
// object & collection classes
// Loader::registerObjectClass($className::getObjectClass(), $className);
// Loader::registerCollectionClass($className::getCollectionClass(), $className);
}
/**
* Reinitializing entity object for another Table class.
* Can be useful for complex inheritance with cloning.
*
* @param $className
*
* @throws Main\SystemException
*/
public function reinitialize($className)
{
// reset class
$this->className = static::normalizeEntityClass($className);
$classPath = explode('\\', ltrim($this->className, '\\'));
$this->name = substr(end($classPath), 0, -5);
}
/**
* @throws Main\ArgumentException
* @throws Main\SystemException
*/
public function postInitialize()
{
// basic properties
$classPath = explode('\\', ltrim($this->className, '\\'));
$this->name = substr(end($classPath), 0, -5);
// default db table name
if (is_null($this->dbTableName))
{
$_classPath = array_slice($classPath, 0, -1);
$this->dbTableName = 'b_';
foreach ($_classPath as $i => $_pathElem)
{
if ($i == 0 && $_pathElem == 'Bitrix')
{
// skip bitrix namespace
continue;
}
if ($i == 1 && $_pathElem == 'Main')
{
// also skip Main module
continue;
}
$this->dbTableName .= strtolower($_pathElem).'_';
}
// add class
if ($this->name !== end($_classPath))
{
$this->dbTableName .= StringHelper::camel2snake($this->name);
}
else
{
$this->dbTableName = substr($this->dbTableName, 0, -1);
}
}
$this->primary = array();
$this->references = array();
// attributes
foreach ($this->fieldsMap as $fieldName => &$fieldInfo)
{
$this->addField($fieldInfo, $fieldName);
}
if (!empty($this->fieldsMap) && empty($this->primary))
{
throw new Main\SystemException(sprintf('Primary not found for %s Entity', $this->name));
}
// attach userfields
if (empty($this->uf_id))
{
// try to find ENTITY_ID by map
$userTypeManager = Main\Application::getUserTypeManager();
if($userTypeManager instanceof \CUserTypeManager)
{
$entityList = $userTypeManager->getEntityList();
$ufId = is_array($entityList) ? array_search($this->className, $entityList) : false;
if ($ufId !== false)
{
$this->uf_id = $ufId;
}
}
}
if (!empty($this->uf_id))
{
// attach uf fields and create uts/utm entities
Main\UserFieldTable::attachFields($this, $this->uf_id);
// save index
static::$ufIdIndex[$this->uf_id] = $this->className;
}
}
/**
* Returns class of Object for current entity.
*
* @return EntityObject|string
*/
public function getObjectClass()
{
$dataManagerClass = $this->className;
return static::normalizeName($dataManagerClass::getObjectClass());
}
/**
* Returns class name of Object for current entity.
*
* @return EntityObject|string
*/
public function getObjectClassName()
{
$dataManagerClass = $this->className;
return $dataManagerClass::getObjectClassName();
}
public static function getDefaultObjectClassName($entityName)
{
$className = $entityName;
if ($className == '')
{
// entity without name
$className = 'NNM_Object';
}
$className = static::DEFAULT_OBJECT_PREFIX.$className;
return $className;
}
/**
* @return Collection|string
*/
public function getCollectionClass()
{
$dataClass = $this->getDataClass();
return static::normalizeName($dataClass::getCollectionClass());
}
/**
* @return Collection|string
*/
public function getCollectionClassName()
{
$dataClass = $this->getDataClass();
return $dataClass::getCollectionClassName();
}
public static function getDefaultCollectionClassName($entityName)
{
$className = static::DEFAULT_OBJECT_PREFIX.$entityName.'_Collection';
return $className;
}
/**
* @param bool $setDefaultValues
*
* @return null Actual type should be annotated by orm:annotate
*/
public function createObject($setDefaultValues = true)
{
$objectClass = $this->getObjectClass();
return new $objectClass($setDefaultValues);
}
/**
* @return null Actual type should be annotated by orm:annotate
*/
public function createCollection()
{
$collectionClass = $this->getCollectionClass();
return new $collectionClass($this);
}
/**
* @see EntityObject::wakeUp()
*
* @param $row
*
* @return null Actual type should be annotated by orm:annotate
* @throws Main\ArgumentException
* @throws Main\SystemException
*/
public function wakeUpObject($row)
{
$objectClass = $this->getObjectClass();
return $objectClass::wakeUp($row);
}
/**
* @see Collection::wakeUp()
*
* @param $rows
*
* @return null Actual type should be annotated by orm:annotate
* @throws Main\ArgumentException
* @throws Main\SystemException
*/
public function wakeUpCollection($rows)
{
$collectionClass = $this->getCollectionClass();
return $collectionClass::wakeUp($rows);
}
/**
* @param Field $field
*
* @return bool
* @throws Main\ArgumentException
* @throws Main\SystemException
*/
protected function appendField(Field $field)
{
if (isset($this->fields[StringHelper::strtoupper($field->getName())]) && !$this->isClone)
{
trigger_error(sprintf(
'Entity `%s` already has Field with name `%s`.', $this->getFullName(), $field->getName()
), E_USER_WARNING);
return false;
}
if ($field instanceof Reference)
{
// references cache
$this->references[$field->getRefEntityName()][] = $field;
}
$this->fields[StringHelper::strtoupper($field->getName())] = $field;
if ($field instanceof ScalarField && $field->isPrimary())
{
$this->primary[] = $field->getName();
if($field->isAutocomplete())
{
$this->autoIncrement = $field->getName();
}
}
// add reference field for UField iblock_section
if ($field instanceof UField && $field->getTypeId() == 'iblock_section')
{
$refFieldName = $field->getName().'_BY';
if ($field->isMultiple())
{
$localFieldName = $field->getValueFieldName();
}
else
{
$localFieldName = $field->getName();
}
$newFieldInfo = array(
'data_type' => 'Bitrix\Iblock\Section',
'reference' => array($localFieldName, 'ID')
);
$newRefField = new Reference($refFieldName, $newFieldInfo['data_type'], $newFieldInfo['reference'][0], $newFieldInfo['reference'][1]);
$newRefField->setEntity($this);
$this->fields[StringHelper::strtoupper($refFieldName)] = $newRefField;
}
return true;
}
/**
* @param array|Field $fieldInfo
* @param null|string $fieldName
*
* @return Field|false
* @throws Main\ArgumentException
* @throws Main\SystemException
*/
public function addField($fieldInfo, $fieldName = null)
{
$field = $this->initializeField($fieldName, $fieldInfo);
return $this->appendField($field) ? $field : false;
}
public function getReferencesCountTo($refEntityName)
{
if (array_key_exists($key = strtolower($refEntityName), $this->references))
{
return count($this->references[$key]);
}
return 0;
}
public function getReferencesTo($refEntityName)
{
if (array_key_exists($key = strtolower($refEntityName), $this->references))
{
return $this->references[$key];
}
return array();
}
// getters
public function getFields()
{
return $this->fields;
}
/**
* @param $name
*
* @return Field|ScalarField
* @throws Main\ArgumentException
*/
public function getField($name)
{
if ($this->hasField($name))
{
return $this->fields[StringHelper::strtoupper($name)];
}
throw new Main\ArgumentException(sprintf(
'%s Entity has no `%s` field.', $this->getName(), $name
));
}
public function hasField($name)
{
return isset($this->fields[StringHelper::strtoupper($name)]);
}
/**
* @return ScalarField[]
*/
public function getScalarFields()
{
$scalarFields = array();
foreach ($this->getFields() as $field)
{
if ($field instanceof ScalarField)
{
$scalarFields[$field->getName()] = $field;
}
}
return $scalarFields;
}
/**
* @deprecated
*
* @param $name
*
* @return UField
* @throws Main\ArgumentException
* @throws Main\SystemException
*/
public function getUField($name)
{
if ($this->hasUField($name))
{
return $this->u_fields[$name];
}
throw new Main\ArgumentException(sprintf(
'%s Entity has no `%s` userfield.', $this->getName(), $name
));
}
/**
* @deprecated
*
* @param $name
*
* @return bool
* @throws Main\SystemException
*/
public function hasUField($name)
{
if (is_null($this->u_fields))
{
$this->u_fields = array();
if($this->uf_id <> '')
{
/** @var \CUserTypeManager $USER_FIELD_MANAGER */
global $USER_FIELD_MANAGER;
foreach($USER_FIELD_MANAGER->getUserFields($this->uf_id) as $info)
{
$this->u_fields[$info['FIELD_NAME']] = new UField($info);
$this->u_fields[$info['FIELD_NAME']]->setEntity($this);
// add references for ufield (UF_DEPARTMENT_BY)
if($info['USER_TYPE_ID'] == 'iblock_section')
{
$info['FIELD_NAME'] .= '_BY';
$this->u_fields[$info['FIELD_NAME']] = new UField($info);
$this->u_fields[$info['FIELD_NAME']]->setEntity($this);
}
}
}
}
return isset($this->u_fields[$name]);
}
public function getName()
{
return $this->name;
}
public function getFullName()
{
return substr($this->className, 0, -5);
}
public function getNamespace()
{
return substr($this->className, 0, strrpos($this->className, '\\') + 1);
}
public function getModule()
{
if($this->module === null)
{
// \Bitrix\Main\Site -> "main"
// \Partner\Module\Thing -> "partner.module"
// \Thing -> ""
$parts = explode("\\", $this->className);
if($parts[1] == "Bitrix")
$this->module = strtolower($parts[2]);
elseif(!empty($parts[1]) && isset($parts[2]))
$this->module = strtolower($parts[1].".".$parts[2]);
else
$this->module = "";
}
return $this->module;
}
/**
* @return DataManager|string
*/
public function getDataClass()
{
return $this->className;
}
/**
* @return Main\DB\Connection
* @throws Main\SystemException
*/
public function getConnection()
{
/** @var Main\DB\Connection $conn */
$conn = Main\Application::getInstance()->getConnectionPool()->getConnection($this->connectionName);
return $conn;
}
public function getDBTableName()
{
return $this->dbTableName;
}
public function getPrimary()
{
return count($this->primary) == 1 ? $this->primary[0] : $this->primary;
}
public function getPrimaryArray()
{
return $this->primary;
}
public function getAutoIncrement()
{
return $this->autoIncrement;
}
public function isUts()
{
return $this->isUts;
}
public function isUtm()
{
return $this->isUtm;
}
public function getUfId()
{
return $this->uf_id;
}
/**
* @param Query $query
*
* @return Query
*/
public function setDefaultScope($query)
{
$dataClass = $this->className;
return $dataClass::setDefaultScope($query);
}
public static function isExists($name)
{
return class_exists(static::normalizeEntityClass($name));
}
/**
* @param $entityName
*
* @return string|DataManager
*/
public static function normalizeEntityClass($entityName)
{
if (strtolower(substr($entityName, -5)) !== 'table')
{
$entityName .= 'Table';
}
if (substr($entityName, 0, 1) !== '\\')
{
$entityName = '\\'.$entityName;
}
return $entityName;
}
public static function getEntityClassParts($class)
{
$class = static::normalizeEntityClass($class);
$lastPos = strrpos($class, '\\');
if($lastPos === 0)
{
//global namespace
$namespace = "";
}
else
{
$namespace = substr($class, 1, $lastPos - 1);
}
$name = substr($class, $lastPos + 1, -5);
return compact('namespace', 'name');
}
public function getCode()
{
if ($this->code === null)
{
$this->code = '';
// get absolute path to class
$class_path = explode('\\', strtoupper(ltrim($this->className, '\\')));
// cut class name to leave namespace only
$class_path = array_slice($class_path, 0, -1);
// cut Bitrix namespace
if (count($class_path) && $class_path[0] === 'BITRIX')
{
$class_path = array_slice($class_path, 1);
}
// glue module name
if (!empty($class_path))
{
$this->code = join('_', $class_path).'_';
}
// glue entity name
$this->code .= strtoupper(StringHelper::camel2snake($this->getName()));
}
return $this->code;
}
public function getLangCode()
{
return $this->getCode().'_ENTITY';
}
public function getTitle()
{
$dataClass = $this->getDataClass();
$title = $dataClass::getTitle();
if ($title === null)
{
$title = Main\Localization\Loc::getMessage($this->getLangCode());
}
return $title;
}
/**
* @deprecated Use Bitrix\StringHelper::camel2snake instead
*
* @param $str
*
* @return string
*/
public static function camel2snake($str)
{
return StringHelper::camel2snake($str);
}
/**
* @deprecated Use Bitrix\StringHelper::snake2camel instead
*
* @param $str
*
* @return mixed
*/
public static function snake2camel($str)
{
return StringHelper::snake2camel($str);
}
public static function normalizeName($entityName)
{
if (substr($entityName, 0, 1) !== '\\')
{
$entityName = '\\'.$entityName;
}
if (strtolower(substr($entityName, -5)) === 'table')
{
$entityName = substr($entityName, 0, -5);
}
return $entityName;
}
public function __clone()
{
$this->isClone = true;
// reset entity in fields
foreach ($this->fields as $field)
{
$field->resetEntity();
$field->setEntity($this);
}
}
/**
* @param Query $query
* @param null $entity_name
*
* @return Entity
* @throws Main\ArgumentException
* @throws Main\SystemException
*/
public static function getInstanceByQuery(Query $query, &$entity_name = null)
{
if ($entity_name === null)
{
$entity_name = 'Tmp'.randString().'x';
}
elseif (!preg_match('/^[a-z0-9_]+$/i', $entity_name))
{
throw new Main\ArgumentException(sprintf(
'Invalid entity name `%s`.', $entity_name
));
}
$query_string = '('.$query->getQuery().')';
$query_chains = $query->getChains();
$replaced_aliases = array_flip($query->getReplacedAliases());
// generate fieldsMap
$fieldsMap = array();
foreach ($query->getSelect() as $k => $v)
{
// convert expressions to regular field, clone in case of regular scalar field
if (is_array($v))
{
// expression
$fieldsMap[$k] = array('data_type' => $v['data_type']);
}
else
{
if ($v instanceof ExpressionField)
{
$fieldDefinition = $v->getName();
// better to initialize fields as objects after entity is created
$dataType = Field::getOldDataTypeByField($query_chains[$fieldDefinition]->getLastElement()->getValue());
$fieldsMap[$fieldDefinition] = array('data_type' => $dataType);
}
else
{
$fieldDefinition = is_numeric($k) ? $v : $k;
/** @var Field $field */
$field = $query_chains[$fieldDefinition]->getLastElement()->getValue();
if ($field instanceof ExpressionField)
{
$dataType = Field::getOldDataTypeByField($query_chains[$fieldDefinition]->getLastElement()->getValue());
$fieldsMap[$fieldDefinition] = array('data_type' => $dataType);
}
else
{
/** @var ScalarField[] $fieldsMap */
$fieldsMap[$fieldDefinition] = clone $field;
$fieldsMap[$fieldDefinition]->setName($fieldDefinition);
$fieldsMap[$fieldDefinition]->setColumnName($fieldDefinition);
$fieldsMap[$fieldDefinition]->resetEntity();
}
}
}
if (isset($replaced_aliases[$k]))
{
if (is_array($fieldsMap[$k]))
{
$fieldsMap[$k]['column_name'] = $replaced_aliases[$k];
}
elseif ($fieldsMap[$k] instanceof ScalarField)
{
/** @var ScalarField[] $fieldsMap */
$fieldsMap[$k]->setColumnName($replaced_aliases[$k]);
}
}
}
// generate class content
$eval = 'class '.$entity_name.'Table extends '.DataManager::class.' {'.PHP_EOL;
$eval .= 'public static function getMap() {'.PHP_EOL;
$eval .= 'return '.var_export(['TMP_ID' => ['data_type' => 'integer', 'primary' => true, 'auto_generated' => true]], true).';'.PHP_EOL;
$eval .= '}';
$eval .= 'public static function getTableName() {'.PHP_EOL;
$eval .= 'return '.var_export($query_string, true).';'.PHP_EOL;
$eval .= '}';
$eval .= '}';
eval($eval);
$entity = self::getInstance($entity_name);
foreach ($fieldsMap as $k => $v)
{
$entity->addField($v, $k);
}
return $entity;
}
/**
* @param string $entityName
* @param null|array[]|Field[] $fields
* @param array $parameters [namespace, table_name, uf_id, parent, parent_map, default_scope]
*
* @return Entity
*
* @throws Main\ArgumentException
* @throws Main\SystemException
*/
public static function compileEntity($entityName, $fields = null, $parameters = array())
{
$classCode = '';
$classCodeEnd = '';
if (strtolower(substr($entityName, -5)) !== 'table')
{
$entityName .= 'Table';
}
// validation
if (!preg_match('/^[a-z0-9_]+$/i', $entityName))
{
throw new Main\ArgumentException(sprintf(
'Invalid entity className `%s`.', $entityName
));
}
/** @var DataManager $fullEntityName */
$fullEntityName = $entityName;
// namespace configuration
if (!empty($parameters['namespace']) && $parameters['namespace'] !== '\\')
{
$namespace = $parameters['namespace'];
if (!preg_match('/^[a-z0-9_\\\\]+$/i', $namespace))
{
throw new Main\ArgumentException(sprintf(
'Invalid namespace name `%s`', $namespace
));
}
$classCode = $classCode."namespace {$namespace} "."{";
$classCodeEnd = '}'.$classCodeEnd;
$fullEntityName = '\\'.$namespace.'\\'.$fullEntityName;
}
$parentClass = !empty($parameters['parent']) ? $parameters['parent'] : DataManager::class;
// build entity code
$classCode = $classCode."class {$entityName} extends \\".$parentClass." {";
$classCodeEnd = '}'.$classCodeEnd;
if (!empty($parameters['table_name']))
{
$classCode .= 'public static function getTableName(){return '.var_export($parameters['table_name'], true).';}';
}
if (!empty($parameters['uf_id']))
{
$classCode .= 'public static function getUfId(){return '.var_export($parameters['uf_id'], true).';}';
}
if (!empty($parameters['default_scope']))
{
$classCode .= 'public static function setDefaultScope($query){'.$parameters['default_scope'].'}';
}
if (isset($parameters['parent_map']) && $parameters['parent_map'] == false)
{
$classCode .= 'public static function getMap(){return [];}';
}
if(isset($parameters['object_parent']) && is_a($parameters['object_parent'], EntityObject::class, true))
{
$classCode .= 'public static function getObjectParentClass(){return '.var_export($parameters['object_parent'], true).';}';
}
// create entity
eval($classCode.$classCodeEnd);
$entity = $fullEntityName::getEntity();
// add fields
if (!empty($fields))
{
foreach ($fields as $fieldName => $field)
{
$entity->addField($field, $fieldName);
}
}
return $entity;
}
/**
* @return string[] Array of SQL queries
* @throws Main\SystemException
*/
public function compileDbTableStructureDump()
{
$fields = $this->getScalarFields();
/** @var Main\DB\MysqlCommonConnection $connection */
$connection = $this->getConnection();
$autocomplete = [];
$unique = [];
foreach ($fields as $field)
{
if ($field->isAutocomplete())
{
$autocomplete[] = $field->getName();
}
if ($field->isUnique())
{
$unique[] = $field->getName();
}
}
// start collecting queries
$connection->disableQueryExecuting();
// create table
$connection->createTable($this->getDBTableName(), $fields, $this->getPrimaryArray(), $autocomplete);
// create indexes
foreach ($unique as $fieldName)
{
$connection->createIndex($this->getDBTableName(), $fieldName, [$fieldName], null,
Main\DB\MysqlCommonConnection::INDEX_UNIQUE);
}
// stop collecting queries
$connection->enableQueryExecuting();
return $connection->getDisabledQueryExecutingDump();
}
/**
* @param $dataClass
*
* @return EntityObject|string
*/
public static function compileObjectClass($dataClass)
{
$dataClass = static::normalizeEntityClass($dataClass);
$classParts = static::getEntityClassParts($dataClass);
if (class_exists($dataClass::getObjectClass(), false)
&& is_subclass_of($dataClass::getObjectClass(), EntityObject::class))
{
// class is already defined
return $dataClass::getObjectClass();
}
$baseObjectClass = '\\'.$dataClass::getObjectParentClass();
$objectClassName = static::getDefaultObjectClassName($classParts['name']);
$eval = "";
if($classParts['namespace'] <> '')
{
$eval .= "namespace {$classParts['namespace']} {";
}
$eval .= "class {$objectClassName} extends {$baseObjectClass} {";
$eval .= "static public \$dataClass = '{$dataClass}';";
$eval .= "}"; // end class
if($classParts['namespace'] <> '')
{
$eval .= "}"; // end namespace
}
eval($eval);
return $dataClass::getObjectClass();
}
/**
* @param $dataClass
*
* @return Collection|string
*/
public static function compileCollectionClass($dataClass)
{
$dataClass = static::normalizeEntityClass($dataClass);
$classParts = static::getEntityClassParts($dataClass);
if (class_exists($dataClass::getCollectionClass(), false)
&& is_subclass_of($dataClass::getCollectionClass(), Collection::class))
{
// class is already defined
return $dataClass::getCollectionClass();
}
$baseCollectionClass = '\\'.$dataClass::getCollectionParentClass();
$collectionClassName = static::getDefaultCollectionClassName($classParts['name']);
$eval = "";
if($classParts['namespace'] <> '')
{
$eval .= "namespace {$classParts['namespace']} {";
}
$eval .= "class {$collectionClassName} extends {$baseCollectionClass} {";
$eval .= "static public \$dataClass = '{$dataClass}';";
$eval .= "}"; // end class
if($classParts['namespace'] <> '')
{
$eval .= "}"; // end namespace
}
eval($eval);
return $dataClass::getCollectionClass();
}
/**
* Creates table according to Fields collection
*
* @return void
* @throws Main\SystemException
*/
public function createDbTable()
{
foreach ($this->compileDbTableStructureDump() as $sqlQuery)
{
$this->getConnection()->query($sqlQuery);
}
}
/**
* @param Entity|string $entity
*
* @return bool
*/
public static function destroy($entity)
{
if ($entity instanceof Entity)
{
$entityName = $entity->getDataClass();
}
else
{
$entityName = static::normalizeEntityClass($entity);
}
if (isset(self::$instances[$entityName]))
{
unset(self::$instances[$entityName]);
DataManager::unsetEntity($entityName);
return true;
}
return false;
}
public static function onUserTypeChange($userfield, $id = null)
{
// resolve UF ENTITY_ID
if (!empty($userfield['ENTITY_ID']))
{
$ufEntityId = $userfield['ENTITY_ID'];
}
elseif (!empty($id))
{
$usertype = new \CUserTypeEntity();
$userfield = $usertype->GetList([], ["ID" => $id])->Fetch();
if ($userfield)
{
$ufEntityId = $userfield['ENTITY_ID'];
}
}
if (empty($ufEntityId))
{
throw new Main\ArgumentException('Invalid ENTITY_ID');
}
// find orm entity with uf ENTITY_ID
if (!empty(static::$ufIdIndex[$ufEntityId]))
{
if (!empty(static::$instances[static::$ufIdIndex[$ufEntityId]]))
{
// clear for further reinitialization
static::destroy(static::$instances[static::$ufIdIndex[$ufEntityId]]);
}
}
}
/**
* Reads data from cache.
*
* @param int $ttl TTL.
* @param string $cacheId The cache ID.
* @param bool $countTotal Whether to read total count from the cache.
*
* @return Main\DB\ArrayResult|null
* @throws Main\SystemException
*/
public function readFromCache($ttl, $cacheId, $countTotal = false)
{
if($ttl > 0)
{
$cache = Main\Application::getInstance()->getManagedCache();
$cacheDir = $this->getCacheDir();
$count = null;
if($countTotal)
{
if ($cache->read($ttl, $cacheId.".total", $cacheDir))
{
$count = $cache->get($cacheId.".total");
}
else
{
// invalidate cache
return null;
}
}
if($cache->read($ttl, $cacheId, $cacheDir))
{
$result = new Main\DB\ArrayResult($cache->get($cacheId));
if($count !== null)
{
$result->setCount($count);
}
return $result;
}
}
return null;
}
/**
* @param Main\DB\Result $result A query result to cache.
* @param string $cacheId The cache ID.
* @param bool $countTotal Whether to write total count to the cache.
*
* @return Main\DB\ArrayResult
* @throws Main\ObjectPropertyException
* @throws Main\SystemException
*/
public function writeToCache(Main\DB\Result $result, $cacheId, $countTotal = false)
{
$rows = $result->fetchAll();
$arrayResult = new Main\DB\ArrayResult($rows);
$cache = Main\Application::getInstance()->getManagedCache();
$cache->set($cacheId, $rows);
if($countTotal)
{
$count = $result->getCount();
$cache->set($cacheId.".total", $count);
$arrayResult->setCount($count);
}
return $arrayResult;
}
/**
* Returns cache TTL for the entity, possibly limited by the .settings.php:
* 'cache_flags' => array('value'=> array(
* "b_group_max_ttl" => 200,
* "b_group_min_ttl" => 100,
* ))
* Maximum is a higher-priority.
* @param int $ttl Preferable TTL
* @return int Calculated TTL
*/
public function getCacheTtl($ttl)
{
$table = $this->getDBTableName();
$cacheFlags = Main\Config\Configuration::getValue("cache_flags");
if(isset($cacheFlags[$table."_min_ttl"]))
{
$ttl = (int)max($ttl, $cacheFlags[$table."_min_ttl"]);
}
if(isset($cacheFlags[$table."_max_ttl"]))
{
$ttl = (int)min($ttl, $cacheFlags[$table."_max_ttl"]);
}
return $ttl;
}
protected function getCacheDir()
{
return "orm_".$this->getDBTableName();
}
/**
* Cleans all cache entries for the entity.
*/
public function cleanCache()
{
if($this->getCacheTtl(100) > 0)
{
//cache might be disabled in .settings.php via *_max_ttl = 0 option
$cache = Main\Application::getInstance()->getManagedCache();
$cache->cleanDir($this->getCacheDir());
}
}
/**
* Sets a flag indicating full text index support for a field.
*
* @deprecated Does nothing, mysql 5.6 has fulltext always enabled.
* @param string $field
* @param bool $mode
*/
public function enableFullTextIndex($field, $mode = true)
{
}
/**
* Returns true if full text index is enabled for a field.
*
* @deprecated Always returns true, mysql 5.6 has fulltext always enabled.
* @param string $field
* @return bool
*/
public function fullTextIndexEnabled($field)
{
return true;
}
}