1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
userfield.php
См. документацию.
1<?php
8
9namespace Bitrix\Main;
10
11use Bitrix\Main\DB\SqlExpression;
12use Bitrix\Main\Localization\Loc;
13
33{
34 // to use in uts serialized fields
35 const MULTIPLE_DATE_FORMAT = 'Y-m-d';
36 const MULTIPLE_DATETIME_FORMAT = 'Y-m-d H:i:s';
37
38 public static function getMap()
39 {
40 return array(
41 'ID' => array(
42 'data_type' => 'integer',
43 'primary' => true,
44 'autocomplete' => true,
45 ),
46 'ENTITY_ID' => array(
47 'data_type' => 'string',
48 'title' => Loc::getMessage('MAIN_USER_FIELD_TABLE_ENTITY_ID_TITLE'),
49 ),
50 'FIELD_NAME' => array(
51 'data_type' => 'string',
52 'title' => Loc::getMessage('MAIN_USER_FIELD_TABLE_FIELD_NAME_TITLE'),
53 ),
54 'USER_TYPE_ID' => array(
55 'data_type' => 'string',
56 'title' => Loc::getMessage('MAIN_USER_FIELD_TABLE_USER_TYPE_ID_TITLE'),
57 ),
58 'XML_ID' => array(
59 'data_type' => 'string',
60 ),
61 'SORT' => array(
62 'data_type' => 'integer',
63 'title' => Loc::getMessage('MAIN_USER_FIELD_TABLE_SORT_TITLE'),
64 ),
65 'MULTIPLE' => array(
66 'data_type' => 'boolean',
67 'values' => array('N', 'Y'),
68 'title' => Loc::getMessage('MAIN_USER_FIELD_TABLE_MULTIPLE_TITLE'),
69 ),
70 'MANDATORY' => array(
71 'data_type' => 'boolean',
72 'values' => array('N', 'Y'),
73 'title' => Loc::getMessage('MAIN_USER_FIELD_TABLE_MANDATORY_TITLE'),
74 ),
75 'SHOW_FILTER' => array(
76 'data_type' => 'boolean',
77 'values' => array('N', 'Y'),
78 'title' => Loc::getMessage('MAIN_USER_FIELD_TABLE_SHOW_FILTER_TITLE'),
79 ),
80 'SHOW_IN_LIST' => array(
81 'data_type' => 'boolean',
82 'values' => array('N', 'Y'),
83 'title' => Loc::getMessage('MAIN_USER_FIELD_TABLE_SHOW_IN_LIST_TITLE'),
84 ),
85 'EDIT_IN_LIST' => array(
86 'data_type' => 'boolean',
87 'values' => array('N', 'Y'),
88 'title' => Loc::getMessage('MAIN_USER_FIELD_TABLE_EDIT_IN_LIST_TITLE'),
89 ),
90 'IS_SEARCHABLE' => array(
91 'data_type' => 'boolean',
92 'values' => array('N', 'Y'),
93 'title' => Loc::getMessage('MAIN_USER_FIELD_TABLE_IS_SEARCHABLE_TITLE'),
94 ),
95 'SETTINGS' => array(
96 'data_type' => 'text',
97 'serialized' => true,
98 'title' => Loc::getMessage('MAIN_USER_FIELD_TABLE_SETTINGS_TITLE'),
99 ),
100 );
101 }
102
103 public static function getLabelsReference(string $referenceName = null, string $languageId = null): ORM\Fields\Relations\Reference
104 {
105 if(!$referenceName)
106 {
107 $referenceName = 'LABELS';
108 }
109
110 $filter = [
111 '=this.ID' => 'ref.USER_FIELD_ID',
112 ];
113
114 if($languageId)
115 {
116 $filter['=ref.LANGUAGE_ID'] = new SqlExpression('?s', $languageId);
117 }
118
120 $referenceName,
121 UserFieldLangTable::class,
122 $filter
123 );
124 }
125
126 public static function getLabelFields(): array
127 {
128 return [
129 'LANGUAGE_ID',
130 'EDIT_FORM_LABEL',
131 'LIST_COLUMN_LABEL',
132 'LIST_FILTER_LABEL',
133 'ERROR_MESSAGE',
134 'HELP_MESSAGE',
135 ];
136 }
137
138 public static function getLabelsSelect(string $referenceName = null): array
139 {
140 if(!$referenceName)
141 {
142 $referenceName = 'LABELS';
143 }
144
145 $result = [];
146 foreach(static::getLabelFields() as $labelField)
147 {
148 $result[$labelField] = $referenceName . '.' . $labelField;
149 }
150
151 return $result;
152 }
153
154 public static function getFieldData(int $id): ?array
155 {
156 $labelFields = static::getLabelFields();
157 $field = [];
158 $list = static::getList([
159 'select' => array_merge(['*'], UserFieldTable::getLabelsSelect()),
160 'filter' => [
161 '=ID' => $id,
162 ],
163 'runtime' => [
164 static::getLabelsReference(),
165 ]
166 ]);
167 foreach($list as $data)
168 {
169 if(empty($field))
170 {
171 $field = $data;
172 unset(
173 $field['LANGUAGE_ID'],
174 $field['EDIT_FORM_LABEL'],
175 $field['LIST_COLUMN_LABEL'],
176 $field['LIST_FILTER_LABEL'],
177 $field['ERROR_MESSAGE'],
178 $field['HELP_MESSAGE'],
179 $field['UALIAS_0']
180 );
181 }
182
183 foreach($labelFields as $labelField)
184 {
185 $field[$labelField][$data['LANGUAGE_ID']] = $data[$labelField];
186 }
187 }
188
189 if(empty($field))
190 {
191 return null;
192 }
193
194 if($field['USER_TYPE_ID'] === 'enumeration')
195 {
196 $field['ENUM'] = [];
197 $enumEntity = new \CUserFieldEnum();
198 $enumList = $enumEntity->GetList(
199 [
200 'SORT' => 'ASC'
201 ], [
202 'USER_FIELD_ID' => $field['ID'],
203 ]
204 );
205 while($enum = $enumList->Fetch())
206 {
207 $field['ENUM'][] = $enum;
208 }
209 }
210
211 return $field;
212 }
213
220 public static function add(array $data)
221 {
222 throw new NotImplementedException('Use \CUserTypeEntity API instead.');
223 }
224
232 public static function update($primary, array $data)
233 {
234 throw new NotImplementedException('Use \CUserTypeEntity API instead.');
235 }
236
243 public static function delete($primary)
244 {
245 throw new NotImplementedException('Use \CUserTypeEntity API instead.');
246 }
247
255 public static function attachFields(ORM\Entity $entity, $ufId)
256 {
257 global $USER_FIELD_MANAGER;
258
259 $utsFields = array();
260 $utsFieldNames = array();
261
262 $utmFields = array();
263 $utmFieldNames = array();
264
265 $fields = $USER_FIELD_MANAGER->getUserFields($ufId);
266
267 foreach ($fields as $field)
268 {
269 if ($field['MULTIPLE'] === 'Y')
270 {
271 $utmFields[] = $field;
272 $utmFieldNames[$field['FIELD_NAME']] = true;
273 }
274 else
275 {
276 $utsFields[] = $field;
277 $utsFieldNames[$field['FIELD_NAME']] = true;
278 }
279 }
280
281 if (!empty($utsFields) || !empty($utmFields))
282 {
283 // create uts entity & put fields into it
284 $utsEntity = static::createUtsEntity($entity, $utsFields, $utmFields, $ufId);
285
286 // create reference to uts entity
287 $utsReference = new ORM\Fields\Relations\Reference('UTS_OBJECT', $utsEntity->getDataClass(), array(
288 '=this.ID' => 'ref.VALUE_ID'
289 ));
290
291 $entity->addField($utsReference);
292
293 // add UF_* aliases
294 foreach ($fields as $userfield)
295 {
296 $utsFieldName = $userfield['FIELD_NAME'];
297
299 $utsField = $utsEntity->getField($utsFieldName);
300
301 $aliasField = new ORM\Fields\UserTypeField(
302 $utsFieldName,
303 '%s',
304 'UTS_OBJECT.'.$utsFieldName,
305 array('data_type' => get_class($utsField))
306 );
307
308 $aliasField->configureValueField($utsField);
309
310 if ($userfield['MULTIPLE'] == 'Y')
311 {
312 $aliasField->configureMultiple();
313 }
314
315 $entity->addField($aliasField);
316 }
317
318
319 if (!empty($utsFields))
320 {
321 foreach ($utsFields as $utsField)
322 {
324 $utsEntityField = $utsEntity->getField($utsField['FIELD_NAME']);
325
326 foreach ($USER_FIELD_MANAGER->getEntityReferences($utsField, $utsEntityField) as $reference)
327 {
328 // rewrite reference from this.field to this.uts_object.field
329 $referenceDesc = static::rewriteUtsReference($reference->getReference());
330
331 $aliasReference = new ORM\Fields\Relations\Reference(
332 $reference->getName(),
333 $reference->getRefEntityName(),
334 $referenceDesc
335 );
336
337 $entity->addField($aliasReference);
338 }
339 }
340 }
341
342 if (!empty($utmFields))
343 {
344 // create utm entity & put base fields into it
345 $utmEntity = static::createUtmEntity($entity, $utmFields, $ufId);
346
347 // add UF_* aliases
348 foreach ($utmFieldNames as $utmFieldName => $true)
349 {
351 $utmField = $utmEntity->getField($utmFieldName);
352
353 $aliasField = new ORM\Fields\ExpressionField(
354 $utmFieldName.'_SINGLE',
355 '%s',
356 $utmEntity->getFullName().':PARENT_'.$utmFieldName.'.'.$utmField->getColumnName(),
357 array('data_type' => get_class($utmField))
358 );
359
360 $entity->addField($aliasField);
361 }
362 }
363 }
364 }
365
376 protected static function createUtsEntity(ORM\Entity $srcEntity, array $utsFields, array $utmFields, $ufId = null)
377 {
378 global $USER_FIELD_MANAGER;
379
380 // get namespace & class
382 $utsClassFull = static::getUtsEntityClassNameBySrcEntity($srcEntity);
383 $utsClassPath = explode('\\', ltrim($utsClassFull, '\\'));
384
385 $utsNamespace = join('\\', array_slice($utsClassPath, 0, -1));
386 $utsClass = end($utsClassPath);
387
388 // get table name
389 $utsTable = static::getUtsEntityTableNameBySrcEntity($srcEntity, $ufId);
390
391 // base fields
392 $fieldsMap = array(
393 'VALUE_ID' => array(
394 'data_type' => 'integer',
395 'primary' => true
396 ),
397 'PARENT' => array(
398 'data_type' => $srcEntity->getDataClass(),
399 'reference' => array(
400 '=this.VALUE_ID' => 'ref.ID'
401 )
402 )
403 );
404
405 // initialize entity
406 if (class_exists($utsNamespace."\\".$utsClass))
407 {
408 ORM\Entity::destroy($utsNamespace."\\".$utsClass);
409 $entity = ORM\Entity::getInstance($utsNamespace."\\".$utsClass);
410
411 foreach ($fieldsMap as $fieldName => $field)
412 {
413 $entity->addField($field, $fieldName);
414 }
415 }
416 else
417 {
418 $entity = ORM\Entity::compileEntity($utsClass, $fieldsMap, array(
419 'namespace' => $utsNamespace, 'table_name' => $utsTable
420 ));
421 }
422
423 foreach ($utsFields as $utsField)
424 {
425 $field = $USER_FIELD_MANAGER->getEntityField($utsField);
426 $entity->addField($field);
427
428 foreach ($USER_FIELD_MANAGER->getEntityReferences($utsField, $field) as $reference)
429 {
430 $entity->addField($reference);
431 }
432 }
433
434 foreach ($utmFields as $utmFieldMeta)
435 {
436 // better to get field from UtmEntity
437 $utmField = $USER_FIELD_MANAGER->getEntityField($utmFieldMeta);
438
439 // add serialized utm cache-fields
440 $cacheField = (new ORM\Fields\UserTypeUtsMultipleField($utmField->getName()))
441 ->configureUtmField($utmField);
442
443 static::setMultipleFieldSerialization($cacheField, $utmField);
444 $entity->addField($cacheField);
445 }
446
447 return $entity;
448 }
449
456 public static function setMultipleFieldSerialization(ORM\Fields\Field $entityField, $fieldAsType)
457 {
458 global $USER_FIELD_MANAGER;
459
460 if (!($fieldAsType instanceof ORM\Fields\Field))
461 {
462 $fieldAsType = $USER_FIELD_MANAGER->getEntityField($fieldAsType);
463 }
464
465 if ($fieldAsType instanceof ORM\Fields\DatetimeField)
466 {
467 if ($entityField instanceof ORM\Fields\ArrayField)
468 {
469 $entityField->configureSerializeCallback([__CLASS__, 'serializeMultipleDatetime']);
470 $entityField->configureUnserializeCallback([__CLASS__, 'unserializeMultipleDatetime']);
471 }
472 else
473 {
474 $entityField->addSaveDataModifier([__CLASS__, 'serializeMultipleDatetime']);
475 $entityField->addFetchDataModifier([__CLASS__, 'unserializeMultipleDatetime']);
476 }
477 }
478 elseif ($fieldAsType instanceof ORM\Fields\DateField)
479 {
480 if ($entityField instanceof ORM\Fields\ArrayField)
481 {
482 $entityField->configureSerializeCallback([__CLASS__, 'serializeMultipleDate']);
483 $entityField->configureUnserializeCallback([__CLASS__, 'unserializeMultipleDate']);
484 }
485 else
486 {
487 $entityField->addSaveDataModifier([__CLASS__, 'serializeMultipleDate']);
488 $entityField->addFetchDataModifier([__CLASS__, 'unserializeMultipleDate']);
489 }
490 }
491 else
492 {
493 if ($entityField instanceof ORM\Fields\ArrayField)
494 {
495 $entityField->configureSerializationPhp();
496 }
497 else
498 {
499 $entityField->setSerialized();
500 }
501 }
502 }
503
504 public static function rewriteUtsReference($referenceDesc)
505 {
506 $new = array();
507
508 foreach ($referenceDesc as $k => $v)
509 {
510 if (is_array($v))
511 {
512 $new[$k] = static::rewriteUtsReference($v);
513 }
514 else
515 {
516 $k = str_replace('this.', 'this.UTS_OBJECT.', $k);
517 $new[$k] = $v;
518 }
519 }
520
521 return $new;
522 }
523
524 protected static function getUtsEntityClassNameBySrcEntity(ORM\Entity $srcEntity)
525 {
526 return $srcEntity->getFullName().'UtsTable';
527 }
528
529 protected static function getUtsEntityTableNameBySrcEntity(ORM\Entity $srcEntity, $ufId = null)
530 {
531 return 'b_uts_'.mb_strtolower($ufId ?: $srcEntity->getUfId());
532 }
533
543 protected static function createUtmEntity(ORM\Entity $srcEntity, array $utmFields, $ufId = null)
544 {
545 global $USER_FIELD_MANAGER;
546
548 $utmClassFull = static::getUtmEntityClassNameBySrcEntity($srcEntity);
549 $utmClassPath = explode('\\', ltrim($utmClassFull, '\\'));
550
551 $utmNamespace = join('\\', array_slice($utmClassPath, 0, -1));
552 $utmClass = end($utmClassPath);
553
554 // get table name
555 $utmTable = static::getUtmEntityTableNameBySrcEntity($srcEntity, $ufId);
556
557 // collect fields
558 $fieldsMap = array(
559 'ID' => array(
560 'data_type' => 'integer',
561 'primary' => true,
562 'autocomplete' => true
563 ),
564 'VALUE_ID' => array(
565 'data_type' => 'integer',
566 'primary' => true
567 ),
568 'PARENT' => array(
569 'data_type' => $srcEntity->getDataClass(),
570 'reference' => array(
571 '=this.VALUE_ID' => 'ref.ID'
572 )
573 ),
574 'FIELD_ID' => array(
575 'data_type' => 'integer'
576 ),
577
578 // base values fields
579 'VALUE' => array(
580 'data_type' => 'text'
581 ),
582 'VALUE_INT' => array(
583 'data_type' => 'integer'
584 ),
585 'VALUE_DOUBLE' => array(
586 'data_type' => 'float'
587 ),
588 'VALUE_DATE' => array(
589 'data_type' => 'datetime'
590 )
591 );
592
593 // initialize entity
594 if (class_exists($utmNamespace."\\".$utmClass))
595 {
596 ORM\Entity::destroy($utmNamespace."\\".$utmClass);
597 $entity = ORM\Entity::getInstance($utmNamespace."\\".$utmClass);
598
599 foreach ($fieldsMap as $fieldName => $field)
600 {
601 $entity->addField($field, $fieldName);
602 }
603 }
604 else
605 {
606 $entity = ORM\Entity::compileEntity($utmClass, $fieldsMap, array(
607 'namespace' => $utmNamespace, 'table_name' => $utmTable
608 ));
609 }
610
611 // add utm fields being mapped on real column name
612 foreach ($utmFields as $utmField)
613 {
614 $field = $USER_FIELD_MANAGER->getEntityField($utmField);
615
616 if ($field instanceof ORM\Fields\IntegerField)
617 {
618 $columnName = 'VALUE_INT';
619 }
620 elseif ($field instanceof ORM\Fields\FloatField)
621 {
622 $columnName = 'VALUE_DOUBLE';
623 }
624 elseif ($field instanceof ORM\Fields\DateField)
625 {
626 $columnName = 'VALUE_DATE';
627 }
628 else
629 {
630 $columnName = 'VALUE';
631 }
632
633 $field->setColumnName($columnName);
634
635 $entity->addField($field);
636
637 foreach ($USER_FIELD_MANAGER->getEntityReferences($utmField, $field) as $reference)
638 {
639 $entity->addField($reference);
640 }
641
642 // add back-reference
643 $refField = new ORM\Fields\Relations\Reference(
644 'PARENT_'.$utmField['FIELD_NAME'],
645 $srcEntity->getDataClass(),
646 array('=this.VALUE_ID' => 'ref.ID', '=this.FIELD_ID' => array('?i', $utmField['ID']))
647 );
648
649 $entity->addField($refField);
650 }
651
652 return $entity;
653 }
654
655 protected static function getUtmEntityClassNameBySrcEntity(ORM\Entity $srcEntity)
656 {
657 return $srcEntity->getFullName().'UtmTable';
658 }
659
660 protected static function getUtmEntityTableNameBySrcEntity(ORM\Entity $srcEntity, $ufId = null)
661 {
662 return 'b_utm_'.mb_strtolower($ufId ?: $srcEntity->getUfId());
663 }
664
670 public static function serializeMultipleDatetime($value)
671 {
672 if (is_array($value) || $value instanceof \Traversable)
673 {
674 $tmpValue = array();
675
676 foreach ($value as $k => $singleValue)
677 {
679 $tmpValue[$k] = $singleValue->format(static::MULTIPLE_DATETIME_FORMAT);
680 }
681
682 return serialize($tmpValue);
683 }
684
685 return $value;
686 }
687
694 public static function unserializeMultipleDatetime($value)
695 {
696 if($value <> '')
697 {
698 $value = unserialize($value, ["allowed_classes" => false]);
699
700 foreach($value as &$singleValue)
701 {
702 try
703 {
704 //try new independent datetime format
705 $singleValue = new Type\DateTime($singleValue, static::MULTIPLE_DATETIME_FORMAT);
706 }
707 catch(ObjectException $e)
708 {
709 //try site format
710 $singleValue = new Type\DateTime($singleValue);
711 }
712 }
713 }
714
715 return $value;
716 }
717
723 public static function serializeMultipleDate($value)
724 {
725 if (is_array($value) || $value instanceof \Traversable)
726 {
727 $tmpValue = array();
728
729 foreach ($value as $k => $singleValue)
730 {
732 $tmpValue[$k] = $singleValue->format(static::MULTIPLE_DATE_FORMAT);
733 }
734
735 return serialize($tmpValue);
736 }
737
738 return $value;
739 }
740
747 public static function unserializeMultipleDate($value)
748 {
749 if($value <> '')
750 {
751 $value = unserialize($value, ["allowed_classes" => false]);
752
753 foreach($value as &$singleValue)
754 {
755 try
756 {
757 //try new independent datetime format
758 $singleValue = new Type\Date($singleValue, static::MULTIPLE_DATE_FORMAT);
759 }
760 catch(ObjectException $e)
761 {
762 //try site format
763 $singleValue = new Type\Date($singleValue);
764 }
765 }
766 }
767
768 return $value;
769 }
770}
static destroy($entity)
Определения entity.php:1248
static getInstance($entityName)
Определения entity.php:104
Определения date.php:9
static getMap()
Определения userfield.php:38
static unserializeMultipleDate($value)
Определения userfield.php:747
static getLabelsSelect(string $referenceName=null)
Определения userfield.php:138
static getUtsEntityClassNameBySrcEntity(ORM\Entity $srcEntity)
Определения userfield.php:524
static getLabelsReference(string $referenceName=null, string $languageId=null)
Определения userfield.php:103
const MULTIPLE_DATE_FORMAT
Определения userfield.php:35
const MULTIPLE_DATETIME_FORMAT
Определения userfield.php:36
static getUtmEntityTableNameBySrcEntity(ORM\Entity $srcEntity, $ufId=null)
Определения userfield.php:660
static getLabelFields()
Определения userfield.php:126
static setMultipleFieldSerialization(ORM\Fields\Field $entityField, $fieldAsType)
Определения userfield.php:456
static add(array $data)
Определения userfield.php:220
static rewriteUtsReference($referenceDesc)
Определения userfield.php:504
static unserializeMultipleDatetime($value)
Определения userfield.php:694
static getUtsEntityTableNameBySrcEntity(ORM\Entity $srcEntity, $ufId=null)
Определения userfield.php:529
static getFieldData(int $id)
Определения userfield.php:154
static getUtmEntityClassNameBySrcEntity(ORM\Entity $srcEntity)
Определения userfield.php:655
static update($primary, array $data)
Определения userfield.php:232
$data['IS_AVAILABLE']
Определения .description.php:13
$new
Определения file_edit.php:48
</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
$entity
$filter
Определения iblock_catalog_list.php:54
Определения ufield.php:9
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$k
Определения template_pdf.php:567
$fields
Определения yandex_run.php:501