1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
entity.php
См. документацию.
1<?php
2
9
10namespace Bitrix\Main\ORM;
11
12use Bitrix\Main;
13use Bitrix\Main\ORM\Data\DataManager;
14use Bitrix\Main\ORM\Fields\ExpressionField;
15use Bitrix\Main\ORM\Fields\Field;
16use Bitrix\Main\ORM\Fields\Relations\Reference;
17use Bitrix\Main\ORM\Fields\ScalarField;
18use Bitrix\Main\ORM\Objectify\EntityObject;
19use Bitrix\Main\ORM\Objectify\Collection;
20use Bitrix\Main\ORM\Query\Query;
21use Bitrix\Main\Text\StringHelper;
22
26class Entity
27{
29 protected $className;
30
31 protected
38
39 protected
43
45 protected $fields;
46
47 protected $fieldsMap;
48
50 protected $u_fields;
51
53 protected $code;
54
55 protected $references;
56
58 protected static $instances;
59
61 protected static $ufIdIndex = [];
62
64 protected $isClone = false;
65
66 const DEFAULT_OBJECT_PREFIX = 'EO_';
67
77 public static function get($entityName)
78 {
79 return static::getInstance($entityName);
80 }
81
89 public static function has($entityName)
90 {
91 $entityClass = static::normalizeEntityClass($entityName);
92 return class_exists($entityClass);
93 }
94
104 public static function getInstance($entityName)
105 {
106 $entityName = static::normalizeEntityClass($entityName);
107
108 return self::getInstanceDirect($entityName);
109 }
110
118 protected static function getInstanceDirect($className)
119 {
120 if (empty(self::$instances[$className]))
121 {
123 $entityClass = $className::getEntityClass();
124
125 // in case of calling Table class was not ended with entity initialization
126 if (empty(self::$instances[$className]))
127 {
128 $entity = new $entityClass;
129 $entity->initialize($className);
130 $entity->postInitialize();
131
132 // call user-defined postInitialize
133 $className::postInitialize($entity);
134
135 self::$instances[$className] = $entity;
136 }
137 }
138
139 return self::$instances[$className];
140 }
141
152 public function initializeField($fieldName, $fieldInfo)
153 {
154 if ($fieldInfo instanceof Field)
155 {
156 $field = $fieldInfo;
157
158 // rewrite name
159 if (!empty($fieldName) && !is_numeric($fieldName))
160 {
161 $field->setName($fieldName);
162 }
163 }
164 elseif (is_array($fieldInfo))
165 {
166 if (!empty($fieldInfo['reference']))
167 {
168 if (is_string($fieldInfo['data_type']) && !str_contains($fieldInfo['data_type'], '\\'))
169 {
170 // if reference has no namespace, then it's in the same namespace
171 $fieldInfo['data_type'] = $this->getNamespace().$fieldInfo['data_type'];
172 }
173
174 //$refEntity = Base::getInstance($fieldInfo['data_type']."Table");
175 $field = new Reference($fieldName, $fieldInfo['data_type'], $fieldInfo['reference'], $fieldInfo);
176 }
177 elseif (!empty($fieldInfo['expression']))
178 {
179 $expression = array_shift($fieldInfo['expression']);
180 $buildFrom = $fieldInfo['expression'];
181
182 $field = new ExpressionField($fieldName, $expression, $buildFrom, $fieldInfo);
183 }
184 elseif (!empty($fieldInfo['USER_TYPE_ID']))
185 {
186 $field = new UField($fieldInfo);
187 }
188 else
189 {
190 $fieldClass = StringHelper::snake2camel($fieldInfo['data_type']) . 'Field';
191 $fieldClass = '\\Bitrix\\Main\\Entity\\'.$fieldClass;
192
193 if (strlen($fieldInfo['data_type']) && class_exists($fieldClass))
194 {
195 $field = new $fieldClass($fieldName, $fieldInfo);
196 }
197 elseif (strlen($fieldInfo['data_type']) && class_exists($fieldInfo['data_type']))
198 {
199 $fieldClass = $fieldInfo['data_type'];
200 $field = new $fieldClass($fieldName, $fieldInfo);
201 }
202 else
203 {
204 throw new Main\ArgumentException(sprintf(
205 'Unknown data type "%s" found for `%s` field in %s Entity.',
206 $fieldInfo['data_type'], $fieldName, $this->getName()
207 ));
208 }
209 }
210 }
211 else
212 {
213 throw new Main\ArgumentException(sprintf('Unknown field type `%s`',
214 is_object($fieldInfo) ? get_class($fieldInfo) : gettype($fieldInfo)
215 ));
216 }
217
218 $field->setEntity($this);
219 $field->postInitialize();
220
221 return $field;
222 }
223
224 public function initialize($className)
225 {
227 $this->className = $className;
228
230 $this->connectionName = $className::getConnectionName();
231 $this->dbTableName = $className::getTableName();
232 $this->fieldsMap = $className::getMap();
233 $this->uf_id = $className::getUfId();
234 $this->isUts = $className::isUts();
235 $this->isUtm = $className::isUtm();
236
237 // object & collection classes
238 // Loader::registerObjectClass($className::getObjectClass(), $className);
239 // Loader::registerCollectionClass($className::getCollectionClass(), $className);
240 }
241
248 public function reinitialize($className)
249 {
250 // reset class
251 $this->className = static::normalizeEntityClass($className);
252
253 $classPath = explode('\\', ltrim($this->className, '\\'));
254 $this->name = substr(end($classPath), 0, -5);
255 }
256
261 public function postInitialize()
262 {
263 // basic properties
264 $classPath = explode('\\', ltrim($this->className, '\\'));
265 $this->name = substr(end($classPath), 0, -5);
266
267 // default db table name
268 if (is_null($this->dbTableName))
269 {
270 $_classPath = array_slice($classPath, 0, -1);
271
272 $this->dbTableName = 'b_';
273
274 foreach ($_classPath as $i => $_pathElem)
275 {
276 if ($i == 0 && $_pathElem == 'Bitrix')
277 {
278 // skip bitrix namespace
279 continue;
280 }
281
282 if ($i == 1 && $_pathElem == 'Main')
283 {
284 // also skip Main module
285 continue;
286 }
287
288 $this->dbTableName .= strtolower($_pathElem).'_';
289 }
290
291 // add class
292 if ($this->name !== end($_classPath))
293 {
294 $this->dbTableName .= StringHelper::camel2snake($this->name);
295 }
296 else
297 {
298 $this->dbTableName = substr($this->dbTableName, 0, -1);
299 }
300 }
301
302 $this->primary = array();
303 $this->references = array();
304
305 // attributes
306 foreach ($this->fieldsMap as $fieldName => &$fieldInfo)
307 {
308 $this->addField($fieldInfo, $fieldName);
309 }
310
311 if (!empty($this->fieldsMap) && empty($this->primary))
312 {
313 throw new Main\SystemException(sprintf('Primary not found for %s Entity', $this->name));
314 }
315
316 // attach userfields
317 if (empty($this->uf_id))
318 {
319 // try to find ENTITY_ID by map
320 $userTypeManager = Main\Application::getUserTypeManager();
321 if($userTypeManager instanceof \CUserTypeManager)
322 {
323 $entityList = $userTypeManager->getEntityList();
324 $ufId = is_array($entityList) ? array_search($this->className, $entityList) : false;
325 if ($ufId !== false)
326 {
327 $this->uf_id = $ufId;
328 }
329 }
330 }
331
332 if (!empty($this->uf_id))
333 {
334 // attach uf fields and create uts/utm entities
335 Main\UserFieldTable::attachFields($this, $this->uf_id);
336
337 // save index
338 static::$ufIdIndex[$this->uf_id] = $this->className;
339 }
340 }
341
347 public function getObjectClass()
348 {
349 $dataManagerClass = $this->className;
350 return static::normalizeName($dataManagerClass::getObjectClass());
351 }
352
358 public function getObjectClassName()
359 {
360 $dataManagerClass = $this->className;
361 return $dataManagerClass::getObjectClassName();
362 }
363
364 public static function getDefaultObjectClassName($entityName)
365 {
366 $className = $entityName;
367
368 if ($className == '')
369 {
370 // entity without name
371 $className = 'NNM_Object';
372 }
373
374 $className = static::DEFAULT_OBJECT_PREFIX.$className;
375
376 return $className;
377 }
378
382 public function getCollectionClass()
383 {
384 $dataClass = $this->getDataClass();
385 return static::normalizeName($dataClass::getCollectionClass());
386 }
387
391 public function getCollectionClassName()
392 {
393 $dataClass = $this->getDataClass();
394 return $dataClass::getCollectionClassName();
395 }
396
397 public static function getDefaultCollectionClassName($entityName)
398 {
399 $className = static::DEFAULT_OBJECT_PREFIX.$entityName.'_Collection';
400
401 return $className;
402 }
403
409 public function createObject($setDefaultValues = true)
410 {
411 $objectClass = $this->getObjectClass();
412 return new $objectClass($setDefaultValues);
413 }
414
418 public function createCollection()
419 {
420 $collectionClass = $this->getCollectionClass();
421 return new $collectionClass($this);
422 }
423
433 public function wakeUpObject($row)
434 {
435 $objectClass = $this->getObjectClass();
436 return $objectClass::wakeUp($row);
437 }
438
448 public function wakeUpCollection($rows)
449 {
450 $collectionClass = $this->getCollectionClass();
451 return $collectionClass::wakeUp($rows);
452 }
453
461 protected function appendField(Field $field)
462 {
463 if (isset($this->fields[StringHelper::strtoupper($field->getName())]) && !$this->isClone)
464 {
465 trigger_error(sprintf(
466 'Entity `%s` already has Field with name `%s`.', $this->getFullName(), $field->getName()
467 ), E_USER_WARNING);
468
469 return false;
470 }
471
472 if ($field instanceof Reference)
473 {
474 // references cache
475 $this->references[$field->getRefEntityName()][] = $field;
476 }
477
478 $this->fields[StringHelper::strtoupper($field->getName())] = $field;
479
480 if ($field instanceof ScalarField && $field->isPrimary())
481 {
482 $this->primary[] = $field->getName();
483
484 if($field->isAutocomplete())
485 {
486 $this->autoIncrement = $field->getName();
487 }
488 }
489
490 // add reference field for UField iblock_section
491 if ($field instanceof UField && $field->getTypeId() == 'iblock_section')
492 {
493 $refFieldName = $field->getName().'_BY';
494
495 if ($field->isMultiple())
496 {
497 $localFieldName = $field->getValueFieldName();
498 }
499 else
500 {
501 $localFieldName = $field->getName();
502 }
503
504 $newFieldInfo = array(
505 'data_type' => 'Bitrix\Iblock\Section',
506 'reference' => array($localFieldName, 'ID'),
507 );
508
509 $newRefField = new Reference($refFieldName, $newFieldInfo['data_type'], $newFieldInfo['reference'][0], $newFieldInfo['reference'][1]);
510 $newRefField->setEntity($this);
511
512 $this->fields[StringHelper::strtoupper($refFieldName)] = $newRefField;
513 }
514
515 return true;
516 }
517
526 public function addField($fieldInfo, $fieldName = null)
527 {
528 $field = $this->initializeField($fieldName, $fieldInfo);
529
530 return $this->appendField($field) ? $field : false;
531 }
532
533 public function getReferencesCountTo($refEntityName)
534 {
535 if (array_key_exists($key = strtolower($refEntityName), $this->references))
536 {
537 return count($this->references[$key]);
538 }
539
540 return 0;
541 }
542
543
544 public function getReferencesTo($refEntityName)
545 {
546 if (array_key_exists($key = strtolower($refEntityName), $this->references))
547 {
548 return $this->references[$key];
549 }
550
551 return array();
552 }
553
554 // getters
555 public function getFields()
556 {
557 return $this->fields;
558 }
559
566 public function getField($name)
567 {
568 if ($this->hasField($name))
569 {
570 return $this->fields[StringHelper::strtoupper($name)];
571 }
572
573 throw new Main\ArgumentException(sprintf(
574 '%s Entity has no `%s` field.', $this->getName(), $name
575 ));
576 }
577
578 public function hasField($name)
579 {
580 return isset($this->fields[StringHelper::strtoupper($name)]);
581 }
582
586 public function getScalarFields()
587 {
588 $scalarFields = array();
589
590 foreach ($this->getFields() as $field)
591 {
592 if ($field instanceof ScalarField)
593 {
594 $scalarFields[$field->getName()] = $field;
595 }
596 }
597
598 return $scalarFields;
599 }
600
610 public function getUField($name)
611 {
612 if ($this->hasUField($name))
613 {
614 return $this->u_fields[$name];
615 }
616
617 throw new Main\ArgumentException(sprintf(
618 '%s Entity has no `%s` userfield.', $this->getName(), $name
619 ));
620 }
621
630 public function hasUField($name)
631 {
632 if (is_null($this->u_fields))
633 {
634 $this->u_fields = array();
635
636 if($this->uf_id <> '')
637 {
639 global $USER_FIELD_MANAGER;
640
641 foreach($USER_FIELD_MANAGER->getUserFields($this->uf_id) as $info)
642 {
643 $this->u_fields[$info['FIELD_NAME']] = new UField($info);
644 $this->u_fields[$info['FIELD_NAME']]->setEntity($this);
645
646 // add references for ufield (UF_DEPARTMENT_BY)
647 if($info['USER_TYPE_ID'] == 'iblock_section')
648 {
649 $info['FIELD_NAME'] .= '_BY';
650 $this->u_fields[$info['FIELD_NAME']] = new UField($info);
651 $this->u_fields[$info['FIELD_NAME']]->setEntity($this);
652 }
653 }
654 }
655 }
656
657 return isset($this->u_fields[$name]);
658 }
659
660 public function getName()
661 {
662 return $this->name;
663 }
664
665 public function getFullName()
666 {
667 return substr($this->className, 0, -5);
668 }
669
670 public function getNamespace()
671 {
672 return substr($this->className, 0, strrpos($this->className, '\\') + 1);
673 }
674
675 public function getModule()
676 {
677 if($this->module === null)
678 {
679 // \Bitrix\Main\Site -> "main"
680 // \Partner\Module\Thing -> "partner.module"
681 // \Thing -> ""
682 $parts = explode("\\", $this->className);
683 if($parts[1] == "Bitrix")
684 $this->module = strtolower($parts[2]);
685 elseif(!empty($parts[1]) && isset($parts[2]))
686 $this->module = strtolower($parts[1].".".$parts[2]);
687 else
688 $this->module = "";
689 }
690 return $this->module;
691 }
692
696 public function getDataClass()
697 {
698 return $this->className;
699 }
700
704 public function getConnection()
705 {
707 $conn = Main\Application::getInstance()->getConnectionPool()->getConnection($this->connectionName);
708 return $conn;
709 }
710
711 public function getDBTableName()
712 {
713 return $this->dbTableName;
714 }
715
716 public function getPrimary()
717 {
718 return count($this->primary) == 1 ? $this->primary[0] : $this->primary;
719 }
720
721 public function getPrimaryArray()
722 {
723 return $this->primary;
724 }
725
729 public function getAutoIncrement()
730 {
731 return $this->autoIncrement;
732 }
733
734 public function isUts()
735 {
736 return $this->isUts;
737 }
738
739 public function isUtm()
740 {
741 return $this->isUtm;
742 }
743
744 public function getUfId()
745 {
746 return $this->uf_id;
747 }
748
754 public function setDefaultScope($query)
755 {
756 $dataClass = $this->className;
757 return $dataClass::setDefaultScope($query);
758 }
759
760 public static function isExists($name)
761 {
762 return class_exists(static::normalizeEntityClass($name));
763 }
764
770 public static function normalizeEntityClass($entityName)
771 {
772 if (strtolower(substr($entityName, -5)) !== 'table')
773 {
774 $entityName .= 'Table';
775 }
776
777 if (!str_starts_with($entityName, '\\'))
778 {
779 $entityName = '\\'.$entityName;
780 }
781
782 return $entityName;
783 }
784
785 public static function getEntityClassParts($class)
786 {
787 $class = static::normalizeEntityClass($class);
788 $lastPos = strrpos($class, '\\');
789
790 if($lastPos === 0)
791 {
792 //global namespace
793 $namespace = "";
794 }
795 else
796 {
797 $namespace = substr($class, 1, $lastPos - 1);
798 }
799 $name = substr($class, $lastPos + 1, -5);
800
801 return compact('namespace', 'name');
802 }
803
804 public function getCode()
805 {
806 if ($this->code === null)
807 {
808 $this->code = '';
809
810 // get absolute path to class
811 $class_path = explode('\\', strtoupper(ltrim($this->className, '\\')));
812
813 // cut class name to leave namespace only
814 $class_path = array_slice($class_path, 0, -1);
815
816 // cut Bitrix namespace
817 if (count($class_path) && $class_path[0] === 'BITRIX')
818 {
819 $class_path = array_slice($class_path, 1);
820 }
821
822 // glue module name
823 if (!empty($class_path))
824 {
825 $this->code = join('_', $class_path).'_';
826 }
827
828 // glue entity name
829 $this->code .= strtoupper(StringHelper::camel2snake($this->getName()));
830 }
831
832 return $this->code;
833 }
834
835 public function getLangCode()
836 {
837 return $this->getCode().'_ENTITY';
838 }
839
840 public function getTitle()
841 {
842 $dataClass = $this->getDataClass();
843 $title = $dataClass::getTitle();
844
845 if ($title === null)
846 {
848 }
849
850 return $title;
851 }
852
860 public static function camel2snake($str)
861 {
862 return StringHelper::camel2snake($str);
863 }
864
872 public static function snake2camel($str)
873 {
874 return StringHelper::snake2camel($str);
875 }
876
877 public static function normalizeName($entityName)
878 {
879 if (!str_starts_with($entityName, '\\'))
880 {
881 $entityName = '\\'.$entityName;
882 }
883
884 if (strtolower(substr($entityName, -5)) === 'table')
885 {
886 $entityName = substr($entityName, 0, -5);
887 }
888
889 return $entityName;
890 }
891
892 public function __clone()
893 {
894 $this->isClone = true;
895
896 // reset entity in fields
897 foreach ($this->fields as $field)
898 {
899 $field->resetEntity();
900 $field->setEntity($this);
901 }
902 }
903
912 public static function getInstanceByQuery(Query $query, &$entity_name = null)
913 {
914 if ($entity_name === null)
915 {
916 $entity_name = 'Tmp'.randString().'x';
917 }
918 elseif (!preg_match('/^[a-z0-9_]+$/i', $entity_name))
919 {
920 throw new Main\ArgumentException(sprintf(
921 'Invalid entity name `%s`.', $entity_name
922 ));
923 }
924
925 $query_string = '('.$query->getQuery().')';
926 $query_chains = $query->getChains();
927
928 $replaced_aliases = array_flip($query->getReplacedAliases());
929
930 // generate fieldsMap
931 $fieldsMap = array();
932
933 foreach ($query->getSelect() as $k => $v)
934 {
935 // convert expressions to regular field, clone in case of regular scalar field
936 if (is_array($v))
937 {
938 // expression
939 $fieldsMap[$k] = array('data_type' => $v['data_type']);
940 }
941 else
942 {
943 if ($v instanceof ExpressionField)
944 {
945 $fieldDefinition = $v->getName();
946
947 // better to initialize fields as objects after entity is created
948 $dataType = Field::getOldDataTypeByField($query_chains[$fieldDefinition]->getLastElement()->getValue());
949 $fieldsMap[$fieldDefinition] = array('data_type' => $dataType);
950 }
951 else
952 {
953 $fieldDefinition = is_numeric($k) ? $v : $k;
954
956 $field = $query_chains[$fieldDefinition]->getLastElement()->getValue();
957
958 if ($field instanceof ExpressionField)
959 {
960 $dataType = Field::getOldDataTypeByField($query_chains[$fieldDefinition]->getLastElement()->getValue());
961 $fieldsMap[$fieldDefinition] = array('data_type' => $dataType);
962 }
963 else
964 {
966 $fieldsMap[$fieldDefinition] = clone $field;
967 $fieldsMap[$fieldDefinition]->setName($fieldDefinition);
968 $fieldsMap[$fieldDefinition]->setColumnName($fieldDefinition);
969 $fieldsMap[$fieldDefinition]->resetEntity();
970 }
971 }
972 }
973
974 if (isset($replaced_aliases[$k]))
975 {
976 if (is_array($fieldsMap[$k]))
977 {
978 $fieldsMap[$k]['column_name'] = $replaced_aliases[$k];
979 }
980 elseif ($fieldsMap[$k] instanceof ScalarField)
981 {
983 $fieldsMap[$k]->setColumnName($replaced_aliases[$k]);
984 }
985 }
986 }
987
988 // generate class content
989 $eval = 'class '.$entity_name.'Table extends '.DataManager::class.' {'.PHP_EOL;
990 $eval .= 'public static function getMap() {'.PHP_EOL;
991 $eval .= 'return '.var_export(['TMP_ID' => ['data_type' => 'integer', 'primary' => true, 'auto_generated' => true]], true).';'.PHP_EOL;
992 $eval .= '}';
993 $eval .= 'public static function getTableName() {'.PHP_EOL;
994 $eval .= 'return '.var_export($query_string, true).';'.PHP_EOL;
995 $eval .= '}';
996 $eval .= '}';
997
998 eval($eval);
999
1000 $entity = self::getInstance($entity_name);
1001
1002 foreach ($fieldsMap as $k => $v)
1003 {
1004 $entity->addField($v, $k);
1005 }
1006
1007 return $entity;
1008 }
1009
1020 public static function compileEntity($entityName, $fields = null, $parameters = array())
1021 {
1022 $classCode = '';
1023 $classCodeEnd = '';
1024
1025 if (strtolower(substr($entityName, -5)) !== 'table')
1026 {
1027 $entityName .= 'Table';
1028 }
1029
1030 // validation
1031 if (!preg_match('/^[a-z0-9_]+$/i', $entityName))
1032 {
1033 throw new Main\ArgumentException(sprintf(
1034 'Invalid entity className `%s`.', $entityName
1035 ));
1036 }
1037
1039 $fullEntityName = $entityName;
1040
1041 // namespace configuration
1042 if (!empty($parameters['namespace']) && $parameters['namespace'] !== '\\')
1043 {
1044 $namespace = $parameters['namespace'];
1045
1046 if (!preg_match('/^[a-z0-9_\\\\]+$/i', $namespace))
1047 {
1048 throw new Main\ArgumentException(sprintf(
1049 'Invalid namespace name `%s`', $namespace
1050 ));
1051 }
1052
1053 $classCode = $classCode."namespace {$namespace} "."{";
1054 $classCodeEnd = '}'.$classCodeEnd;
1055
1056 $fullEntityName = '\\'.$namespace.'\\'.$fullEntityName;
1057 }
1058
1059 $parentClass = !empty($parameters['parent']) ? $parameters['parent'] : DataManager::class;
1060
1061 // build entity code
1062 $classCode = $classCode."class {$entityName} extends \\".$parentClass." {";
1063 $classCodeEnd = '}'.$classCodeEnd;
1064
1065 if (!empty($parameters['table_name']))
1066 {
1067 $classCode .= 'public static function getTableName(){return '.var_export($parameters['table_name'], true).';}';
1068 }
1069
1070 if (!empty($parameters['uf_id']))
1071 {
1072 $classCode .= 'public static function getUfId(){return '.var_export($parameters['uf_id'], true).';}';
1073 }
1074
1075 if (!empty($parameters['default_scope']))
1076 {
1077 $classCode .= 'public static function setDefaultScope($query){'.$parameters['default_scope'].'}';
1078 }
1079
1080 if (isset($parameters['parent_map']) && !$parameters['parent_map'])
1081 {
1082 $classCode .= 'public static function getMap(){return [];}';
1083 }
1084
1085 if(isset($parameters['object_parent']) && is_a($parameters['object_parent'], EntityObject::class, true))
1086 {
1087 $classCode .= 'public static function getObjectParentClass(){return '.var_export($parameters['object_parent'], true).';}';
1088 }
1089
1090 // create entity
1091 eval($classCode.$classCodeEnd);
1092
1093 $entity = $fullEntityName::getEntity();
1094
1095 // add fields
1096 if (!empty($fields))
1097 {
1098 foreach ($fields as $fieldName => $field)
1099 {
1100 $entity->addField($field, $fieldName);
1101 }
1102 }
1103
1104 return $entity;
1105 }
1106
1111 public function compileDbTableStructureDump()
1112 {
1113 $fields = $this->getScalarFields();
1114
1116 $connection = $this->getConnection();
1117
1118 $autocomplete = [];
1119 $unique = [];
1120
1121 foreach ($fields as $field)
1122 {
1123 if ($field->isAutocomplete())
1124 {
1125 $autocomplete[] = $field->getName();
1126 }
1127
1128 if ($field->isUnique())
1129 {
1130 $unique[] = $field->getName();
1131 }
1132 }
1133
1134 // start collecting queries
1135 $connection->disableQueryExecuting();
1136
1137 // create table
1138 $connection->createTable($this->getDBTableName(), $fields, $this->getPrimaryArray(), $autocomplete);
1139
1140 // create indexes
1141 foreach ($unique as $fieldName)
1142 {
1143 $connection->createIndex($this->getDBTableName(), $fieldName, [$fieldName], null,
1144 Main\DB\Connection::INDEX_UNIQUE);
1145 }
1146
1147 // stop collecting queries
1148 $connection->enableQueryExecuting();
1149
1150 return $connection->getDisabledQueryExecutingDump();
1151 }
1152
1158 public static function compileObjectClass($dataClass)
1159 {
1160 $dataClass = static::normalizeEntityClass($dataClass);
1161 $classParts = static::getEntityClassParts($dataClass);
1162
1163 if (class_exists($dataClass::getObjectClass(), false)
1164 && is_subclass_of($dataClass::getObjectClass(), EntityObject::class))
1165 {
1166 // class is already defined
1167 return $dataClass::getObjectClass();
1168 }
1169
1170 $baseObjectClass = '\\'.$dataClass::getObjectParentClass();
1171 $objectClassName = static::getDefaultObjectClassName($classParts['name']);
1172
1173 $eval = "";
1174 if($classParts['namespace'] <> '')
1175 {
1176 $eval .= "namespace {$classParts['namespace']} {";
1177 }
1178 $eval .= "class {$objectClassName} extends {$baseObjectClass} {";
1179 $eval .= "static public \$dataClass = '{$dataClass}';";
1180 $eval .= "}"; // end class
1181 if($classParts['namespace'] <> '')
1182 {
1183 $eval .= "}"; // end namespace
1184 }
1185
1186 eval($eval);
1187
1188 return $dataClass::getObjectClass();
1189 }
1190
1196 public static function compileCollectionClass($dataClass)
1197 {
1198 $dataClass = static::normalizeEntityClass($dataClass);
1199 $classParts = static::getEntityClassParts($dataClass);
1200
1201 if (class_exists($dataClass::getCollectionClass(), false)
1202 && is_subclass_of($dataClass::getCollectionClass(), Collection::class))
1203 {
1204 // class is already defined
1205 return $dataClass::getCollectionClass();
1206 }
1207
1208 $baseCollectionClass = '\\'.$dataClass::getCollectionParentClass();
1209 $collectionClassName = static::getDefaultCollectionClassName($classParts['name']);
1210
1211 $eval = "";
1212 if($classParts['namespace'] <> '')
1213 {
1214 $eval .= "namespace {$classParts['namespace']} {";
1215 }
1216 $eval .= "class {$collectionClassName} extends {$baseCollectionClass} {";
1217 $eval .= "static public \$dataClass = '{$dataClass}';";
1218 $eval .= "}"; // end class
1219 if($classParts['namespace'] <> '')
1220 {
1221 $eval .= "}"; // end namespace
1222 }
1223
1224 eval($eval);
1225
1226 return $dataClass::getCollectionClass();
1227 }
1228
1235 public function createDbTable()
1236 {
1237 foreach ($this->compileDbTableStructureDump() as $sqlQuery)
1238 {
1239 $this->getConnection()->query($sqlQuery);
1240 }
1241 }
1242
1248 public static function destroy($entity)
1249 {
1250 if ($entity instanceof Entity)
1251 {
1252 $entityName = $entity->getDataClass();
1253 }
1254 else
1255 {
1256 $entityName = static::normalizeEntityClass($entity);
1257 }
1258
1259 if (isset(self::$instances[$entityName]))
1260 {
1261 unset(self::$instances[$entityName]);
1262 DataManager::unsetEntity($entityName);
1263
1264 return true;
1265 }
1266
1267 return false;
1268 }
1269
1270 public static function onUserTypeChange($userfield, $id = null)
1271 {
1272 // resolve UF ENTITY_ID
1273 if (!empty($userfield['ENTITY_ID']))
1274 {
1275 $ufEntityId = $userfield['ENTITY_ID'];
1276 }
1277 elseif (!empty($id))
1278 {
1279 $usertype = new \CUserTypeEntity();
1280 $userfield = $usertype->GetList([], ["ID" => $id])->Fetch();
1281
1282 if ($userfield)
1283 {
1284 $ufEntityId = $userfield['ENTITY_ID'];
1285 }
1286 }
1287
1288 if (empty($ufEntityId))
1289 {
1290 throw new Main\ArgumentException('Invalid ENTITY_ID');
1291 }
1292
1293 // find orm entity with uf ENTITY_ID
1294 if (!empty(static::$ufIdIndex[$ufEntityId]))
1295 {
1296 if (!empty(static::$instances[static::$ufIdIndex[$ufEntityId]]))
1297 {
1298 // clear for further reinitialization
1299 static::destroy(static::$instances[static::$ufIdIndex[$ufEntityId]]);
1300 }
1301 }
1302 }
1303
1313 public function readFromCache($ttl, $cacheId, $countTotal = false)
1314 {
1315 if($ttl > 0)
1316 {
1317 $cache = Main\Application::getInstance()->getManagedCache();
1318 $cacheDir = $this->getCacheDir();
1319
1320 $count = null;
1321 if($countTotal)
1322 {
1323 if ($cache->read($ttl, $cacheId.".total", $cacheDir))
1324 {
1325 $count = $cache->get($cacheId.".total");
1326 }
1327 else
1328 {
1329 // invalidate cache
1330 return null;
1331 }
1332 }
1333 if($cache->read($ttl, $cacheId, $cacheDir))
1334 {
1335 $result = new Main\DB\ArrayResult($cache->get($cacheId));
1336 if($count !== null)
1337 {
1338 $result->setCount($count);
1339 }
1340 return $result;
1341 }
1342 }
1343 return null;
1344 }
1345
1355 public function writeToCache(Main\DB\Result $result, $cacheId, $countTotal = false)
1356 {
1357 $rows = $result->fetchAll();
1358 $arrayResult = new Main\DB\ArrayResult($rows);
1359
1360 $cache = Main\Application::getInstance()->getManagedCache();
1361 $cache->set($cacheId, $rows);
1362
1363 if($countTotal)
1364 {
1365 $count = $result->getCount();
1366 $cache->set($cacheId.".total", $count);
1367 $arrayResult->setCount($count);
1368 }
1369 return $arrayResult;
1370 }
1371
1382 public function getCacheTtl($ttl)
1383 {
1384 if (!$this->className::isCacheable())
1385 {
1386 // cache is disabled in the tablet
1387 return 0;
1388 }
1389
1390 $table = $this->getDBTableName();
1391 $cacheFlags = Main\Config\Configuration::getValue("cache_flags");
1392 if(isset($cacheFlags[$table."_min_ttl"]))
1393 {
1394 $ttl = (int)max($ttl, $cacheFlags[$table."_min_ttl"]);
1395 }
1396 if(isset($cacheFlags[$table."_max_ttl"]))
1397 {
1398 $ttl = (int)min($ttl, $cacheFlags[$table."_max_ttl"]);
1399 }
1400 return $ttl;
1401 }
1402
1403 protected function getCacheDir()
1404 {
1405 return "orm_".$this->getDBTableName();
1406 }
1407
1411 public function cleanCache()
1412 {
1413 if($this->getCacheTtl(100) > 0)
1414 {
1415 //cache might be disabled in .settings.php via *_max_ttl = 0 option
1416 $cache = Main\Application::getInstance()->getManagedCache();
1417 $cache->cleanDir($this->getCacheDir());
1418 }
1419 }
1420
1428 public function enableFullTextIndex($field, $mode = true)
1429 {
1430 }
1431
1439 public function fullTextIndexEnabled($field)
1440 {
1441 return true;
1442 }
1443}
$connection
Определения actionsdefinitions.php:38
$count
Определения admin_tab.php:4
static getUserTypeManager()
Определения application.php:714
static getInstance()
Определения application.php:98
static getValue($name)
Определения configuration.php:24
static getMessage($code, $replace=null, $language=null)
Определения loc.php:30
$primary
Определения entity.php:36
getUField($name)
Определения entity.php:610
static normalizeEntityClass($entityName)
Определения entity.php:770
getUfId()
Определения entity.php:744
static $instances
Определения entity.php:58
$dbTableName
Определения entity.php:35
getPrimaryArray()
Определения entity.php:721
readFromCache($ttl, $cacheId, $countTotal=false)
Определения entity.php:1313
getNamespace()
Определения entity.php:670
getFullName()
Определения entity.php:665
static destroy($entity)
Определения entity.php:1248
static onUserTypeChange($userfield, $id=null)
Определения entity.php:1270
static compileObjectClass($dataClass)
Определения entity.php:1158
getCollectionClassName()
Определения entity.php:391
getName()
Определения entity.php:660
static normalizeName($entityName)
Определения entity.php:877
getCacheTtl($ttl)
Определения entity.php:1382
static $ufIdIndex
Определения entity.php:61
getModule()
Определения entity.php:675
appendField(Field $field)
Определения entity.php:461
writeToCache(Main\DB\Result $result, $cacheId, $countTotal=false)
Определения entity.php:1355
setDefaultScope($query)
Определения entity.php:754
$u_fields
Определения entity.php:50
static getDefaultObjectClassName($entityName)
Определения entity.php:364
isUtm()
Определения entity.php:739
getObjectClassName()
Определения entity.php:358
getLangCode()
Определения entity.php:835
static isExists($name)
Определения entity.php:760
static snake2camel($str)
Определения entity.php:872
postInitialize()
Определения entity.php:261
initializeField($fieldName, $fieldInfo)
Определения entity.php:152
static getEntityClassParts($class)
Определения entity.php:785
createDbTable()
Определения entity.php:1235
hasField($name)
Определения entity.php:578
getObjectClass()
Определения entity.php:347
fullTextIndexEnabled($field)
Определения entity.php:1439
$code
Определения entity.php:53
cleanCache()
Определения entity.php:1411
$autoIncrement
Определения entity.php:37
static camel2snake($str)
Определения entity.php:860
$connectionName
Определения entity.php:34
isUts()
Определения entity.php:734
static getDefaultCollectionClassName($entityName)
Определения entity.php:397
reinitialize($className)
Определения entity.php:248
createObject($setDefaultValues=true)
Определения entity.php:409
static getInstance($entityName)
Определения entity.php:104
wakeUpCollection($rows)
Определения entity.php:448
getTitle()
Определения entity.php:840
getCollectionClass()
Определения entity.php:382
$isUts
Определения entity.php:41
static has($entityName)
Определения entity.php:89
getDataClass()
Определения entity.php:696
static compileCollectionClass($dataClass)
Определения entity.php:1196
$fields
Определения entity.php:45
$name
Определения entity.php:33
getCode()
Определения entity.php:804
getScalarFields()
Определения entity.php:586
enableFullTextIndex($field, $mode=true)
Определения entity.php:1428
$module
Определения entity.php:32
const DEFAULT_OBJECT_PREFIX
Определения entity.php:66
$references
Определения entity.php:55
addField($fieldInfo, $fieldName=null)
Определения entity.php:526
$fieldsMap
Определения entity.php:47
$className
Определения entity.php:29
__clone()
Определения entity.php:892
getPrimary()
Определения entity.php:716
getDBTableName()
Определения entity.php:711
$isUtm
Определения entity.php:42
wakeUpObject($row)
Определения entity.php:433
$uf_id
Определения entity.php:40
getField($name)
Определения entity.php:566
createCollection()
Определения entity.php:418
getAutoIncrement()
Определения entity.php:729
$isClone
Определения entity.php:64
getReferencesTo($refEntityName)
Определения entity.php:544
getCacheDir()
Определения entity.php:1403
getFields()
Определения entity.php:555
getReferencesCountTo($refEntityName)
Определения entity.php:533
$str
Определения commerceml2.php:63
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
global $USER_FIELD_MANAGER
Определения attempt.php:6
$result
Определения get_property_values.php:14
$query
Определения get_search.php:11
$entity
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
if($NS['step']==6) if( $NS[ 'step']==7) if(COption::GetOptionInt('main', 'disk_space', 0) > 0) $info
Определения backup.php:924
$name
Определения menu_edit.php:35
getValue()
Определения Param.php:141
Определения arrayresult.php:2
Определения ufield.php:9
Определения chain.php:3
$table
Определения mysql_to_pgsql.php:36
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
$i
Определения factura.php:643
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$title
Определения pdf.php:123
$rows
Определения options.php:264
$k
Определения template_pdf.php:567
$fields
Определения yandex_run.php:501