Bitrix-D7 22.2
Загрузка...
Поиск...
Не найдено
entitypropertyvalue.php
См. документацию.
1<?php
2
3namespace Bitrix\Sale;
4
6use Bitrix\Main\Entity\ReferenceField;
10use Bitrix\Main;
12
18{
20 protected $property = null;
21
25 abstract protected static function getEntityType(): string;
26
30 abstract protected static function getPropertyClassName(): string;
31
40 abstract protected static function createPropertyValueObject(
41 array $property = null,
42 array $value = [],
43 array $relation = null
45
50 abstract protected static function getOnSavedEventName(): string;
51
52 protected static function extractPaySystemIdList(Entity $entity)
53 {
54 return [];
55 }
56
57 protected static function extractDeliveryIdList(Entity $entity)
58 {
59 return [];
60 }
61
62 protected static function extractTpLandingIdList(Entity $entity) : array
63 {
64 return [];
65 }
66
74 protected static function loadFromDb(Entity $entity): array
75 {
76 $propertyValues = [];
77 $propertyValuesMap = [];
78
79 if ($entity->getId() > 0)
80 {
81 $dbRes = static::getList(
82 [
83 'select' => ['ID', 'NAME', 'VALUE', 'CODE', 'ORDER_PROPS_ID'],
84 'filter' => [
85 'ENTITY_ID' => $entity->getId(),
86 'ENTITY_TYPE' => static::getEntityType()
87 ]
88 ]
89 );
90 while ($row = $dbRes->fetch())
91 {
92 $propertyValues[$row['ID']] = $row;
93 $propertyValuesMap[$row['ORDER_PROPS_ID']] = $row['ID'];
94 }
95 }
96
98 $propertyClassName = static::getPropertyClassName();
99
100 $getListParams = [
101 'select' => [
102 'ID',
103 'PERSON_TYPE_ID',
104 'NAME',
105 'TYPE',
106 'REQUIRED',
107 'DEFAULT_VALUE',
108 'SORT',
109 'USER_PROPS',
110 'IS_LOCATION',
111 'PROPS_GROUP_ID',
112 'DESCRIPTION',
113 'IS_EMAIL',
114 'IS_PROFILE_NAME',
115 'IS_PAYER',
116 'IS_LOCATION4TAX',
117 'IS_FILTERED',
118 'CODE',
119 'IS_ZIP',
120 'IS_PHONE',
121 'IS_ADDRESS',
122 'IS_ADDRESS_FROM',
123 'IS_ADDRESS_TO',
124 'ACTIVE',
125 'UTIL',
126 'INPUT_FIELD_LOCATION',
127 'MULTIPLE',
128 'SETTINGS',
129 'ENTITY_TYPE'
130 ],
131 'filter' => static::constructPropertyFilter($entity),
132 'runtime' => static::getRelationRuntimeFields(),
133 'order' => ['SORT' => 'ASC'],
134 ];
135
136 $dbRes = $propertyClassName::getList($getListParams);
137 $properties = [];
138 $propRelation = [];
139
140 while ($row = $dbRes->fetch())
141 {
142 $properties[$row['ID']] = $row;
143 $propRelation[$row['ID']] = [];
144 }
145
146 $dbRes = OrderPropsRelationTable::getList(
147 [
148 'select' => [
149 'PROPERTY_ID',
150 'ENTITY_ID',
151 'ENTITY_TYPE'
152 ],
153 'filter' => [
154 'PROPERTY_ID' => array_keys($properties)
155 ]
156 ]
157 );
158
159 while ($row = $dbRes->fetch())
160 {
161 $propRelation[$row['PROPERTY_ID']][] = $row;
162 }
163
164 return [$properties, $propertyValues, $propRelation, $propertyValuesMap];
165 }
166
170 public function needDeleteOnRefresh() : bool
171 {
172 $property = $this->getPropertyObject();
173
174 return $property ? !empty($property->getRelations()) : false;
175 }
176
177 protected static function constructPropertyFilter(Entity $entity) : array
178 {
179 $filter = [
180 '=ENTITY_TYPE' => static::getEntityType()
181 ];
182
183 if ($entity->getPersonTypeId() > 0)
184 {
185 $filter['=PERSON_TYPE_ID'] = $entity->getPersonTypeId();
186 }
187
188 $subFilter = [
189 'LOGIC' => 'OR',
190 static::constructPropertyRelatedEntitiesFilter($entity)
191 ];
192
193 if ($entity->getId() > 0)
194 {
195 $dbRes = static::getList([
196 'select' => ['ORDER_PROPS_ID'],
197 'filter' => [
198 '=ENTITY_ID' => $entity->getId(),
199 '=ENTITY_TYPE' => static::getEntityType()
200 ]
201 ]);
202
203 while ($row = $dbRes->fetch())
204 {
205 $subFilter['@ID'][] = $row['ORDER_PROPS_ID'];
206 }
207 }
208
209 $filter[] = $subFilter;
210
211 return $filter;
212 }
213
214 protected static function hasPresetForLanding(Entity $entity) : bool
215 {
216 $tpLandingList = static::extractTpLandingIdList($entity);
217
218 if ($tpLandingList)
219 {
220 $dbRes = Internals\OrderPropsRelationTable::getList([
221 'filter' => [
222 '@ENTITY_ID' => $tpLandingList,
223 '=ENTITY_TYPE' => 'L'
224 ],
225 'limit' => 1
226 ]);
227
228 return (bool)$dbRes->fetch();
229 }
230
231 return false;
232 }
233
238 protected static function constructPropertyRelatedEntitiesFilter(Entity $entity): array
239 {
240 $result = [];
241
242 $psFilter = ['=RELATION_PS.ENTITY_ID' => null];
243
244 if ($paySystemList = static::extractPaySystemIdList($entity))
245 {
246 $psFilter['LOGIC'] = 'OR';
247 $psFilter['@RELATION_PS.ENTITY_ID'] = $paySystemList;
248 }
249
250 $result[] = $psFilter;
251 $dlvFilter = ['=RELATION_DLV.ENTITY_ID' => null];
252
253 if ($deliveryList = static::extractDeliveryIdList($entity))
254 {
255 $dlvFilter['LOGIC'] = 'OR';
256 $dlvFilter['@RELATION_DLV.ENTITY_ID'] = $deliveryList;
257 }
258
259 $result[] = $dlvFilter;
260
261 if (self::hasPresetForLanding($entity))
262 {
263 $result[] = [
264 'LOGIC' => 'OR',
265 '!RELATION_PS.ENTITY_ID' => null,
266 '!RELATION_DLV.ENTITY_ID' => null,
267 ];
268
269 $result = [
270 'LOGIC' => 'OR',
271 '@RELATION_TP_LANDING.ENTITY_ID' => static::extractTpLandingIdList($entity),
272 $result,
273 ];
274 }
275 else
276 {
277 $result = [
278 '=RELATION_TP_LANDING.ENTITY_ID' => null,
279 $result,
280 ];
281 }
282
283 return $result;
284 }
285
286 protected static function getRelationRuntimeFields(): array
287 {
288 return [
289 new ReferenceField(
290 'RELATION_PS',
291 '\Bitrix\Sale\Internals\OrderPropsRelation',
292 [
293 '=this.ID' => 'ref.PROPERTY_ID',
294 'ref.ENTITY_TYPE' => new SqlExpression('?', 'P')
295 ],
296 'left_join'
297 ),
298 new ReferenceField(
299 'RELATION_DLV',
300 '\Bitrix\Sale\Internals\OrderPropsRelation',
301 [
302 '=this.ID' => 'ref.PROPERTY_ID',
303 'ref.ENTITY_TYPE' => new SqlExpression('?', 'D')
304 ],
305 'left_join'
306 ),
307 new Main\Entity\ReferenceField(
308 'RELATION_TP_LANDING',
309 '\Bitrix\Sale\Internals\OrderPropsRelation',
310 [
311 '=this.ID' => 'ref.PROPERTY_ID',
312 'ref.ENTITY_TYPE' => new Main\DB\SqlExpression('?', 'L')
313 ],
314 'left_join'
315 )
316 ];
317 }
318
328 protected static function createPropertyValuesObjects(
329 array $properties,
330 array $propertyValues,
331 array $propRelation,
332 array $propertyValuesMap): array
333 {
334 $result = [];
335
336 foreach ($properties as $property)
337 {
338 $id = $property['ID'];
339
340 if (isset($propertyValuesMap[$id]))
341 {
342 $fields = $propertyValues[$propertyValuesMap[$id]];
343 unset($propertyValues[$propertyValuesMap[$id]]);
344 unset($propertyValuesMap[$id]);
345 }
346 else
347 {
348 if ($property['ACTIVE'] === 'N')
349 {
350 continue;
351 }
352
353 $fields = [];
354 }
355
356 $result[$id] = static::createPropertyValueObject($property, $fields, $propRelation[$id]);
357 }
358
359 foreach ($propertyValues as $propertyValue)
360 {
361 $result[$propertyValue['ORDER_PROPS_ID']] = static::createPropertyValueObject(null, $propertyValue);
362 }
363
364 return $result;
365 }
366
370 protected static function getFieldsMap()
371 {
372 return OrderPropsValueTable::getMap();
373 }
374
382 protected function __construct(array $property = null, array $value = [], array $relation = null)
383 {
384 if (!$property && !$value)
385 {
386 throw new Main\SystemException('invalid arguments', 0, __FILE__, __LINE__);
387 }
388
389 if ($property)
390 {
391 if (is_array($property['SETTINGS']))
392 {
393 $property += $property['SETTINGS'];
394 unset ($property['SETTINGS']);
395 }
396 }
397 else
398 {
399 $property = [
400 'TYPE' => 'STRING',
401 'PROPS_GROUP_ID' => 0,
402 'NAME' => $value['NAME'],
403 'CODE' => $value['CODE'],
404 ];
405 }
406
407
408 $propertyClassName = static::getPropertyClassName();
409
410 $this->property = new $propertyClassName($property, $relation);
411
412 if (isset($value['VALUE']))
413 {
414 $value['VALUE'] = $this->property->normalizeValue($value['VALUE']);
415 }
416
417 parent::__construct($value);
418
419 if (!$value)
420 {
421 $value = [
422 'ORDER_PROPS_ID' => $this->property->getId(),
423 'NAME' => $this->property->getName(),
424 'CODE' => $this->property->getField('CODE'),
425 'XML_ID' => static::generateXmlId(),
426 'ENTITY_TYPE' => $this->property->getField('ENTITY_TYPE')
427 ];
428
429 if (!empty($this->property->getField('DEFAULT_VALUE')))
430 {
431 $value['VALUE'] = $this->property->getField('DEFAULT_VALUE');
432 }
433
434 $this->setFieldsNoDemand($value);
435 }
436 }
437
441 public static function generateXmlId(): string
442 {
443 return uniqid('bx_');
444 }
445
453 public static function create(EntityPropertyValueCollection $collection, array $property = [])
454 {
455 $propertyValue = static::createPropertyValueObject($property);
456 $propertyValue->setCollection($collection);
457 return $propertyValue;
458 }
459
463 public static function getAvailableFields()
464 {
465 return ['VALUE'];
466 }
467
471 protected static function getMeaningfulFields()
472 {
473 return [];
474 }
475
484 public function setField($name, $value)
485 {
486 $result = new Result();
487
488 $value = $this->property->normalizeValue($value);
489
490 $res = parent::setField($name, $value);
491 if (!$res->isSuccess())
492 {
493 $result->addErrors($res->getErrors());
494 }
495
496 return $result;
497 }
498
506 public function save(): Result
507 {
508 $this->checkCallingContext();
509
510 $result = new Result();
511
512 if (!$this->isChanged())
513 {
514 return $result;
515 }
516
517 if ($this->getId() > 0)
518 {
519 $res = $this->update();
520 }
521 else
522 {
523 $res = $this->add();
524 }
525
526 if (!$res->isSuccess())
527 {
528 $result->addErrors($res->getErrors());
529 }
530
532
533 return $result;
534 }
535
536 private function checkCallingContext(): void
537 {
538 $order = $this->getOrder();
539
540 if (!$order->isSaveRunning())
541 {
542 trigger_error("Incorrect call to the save process. Use method save() on \Bitrix\Sale\Order entity", E_USER_WARNING);
543 }
544 }
545
549 public function getOrder(): ?Order
550 {
552 $collection = $this->getCollection();
553 if (!$collection)
554 {
555 return null;
556 }
557
559 $order = $collection->getOrder();
560 if (!$order)
561 {
562 return null;
563 }
564
565 return $order;
566 }
567
572 protected function update()
573 {
574 $result = new Result();
575
576 $value = $this->property->getPreparedValueForSave($this);
577 $res = $this->updateInternal($this->getId(), ['VALUE' => $value]);
578
579 if ($res->isSuccess())
580 {
581 $result->setId($res->getId());
582 }
583 else
584 {
585 $result->addErrors($res->getErrors());
586 }
587
588 return $result;
589 }
590
596 protected function add()
597 {
598 $result = new Result();
599
600 $value = $this->property->getPreparedValueForSave($this);
603 $res = $this->addInternal(
604 [
605 'ORDER_ID' => $this->getOrder()->getId(),
606 'ORDER_PROPS_ID' => $this->property->getId(),
607 'NAME' => $this->property->getName(),
608 'VALUE' => $value,
609 'CODE' => $this->property->getField('CODE'),
610 'XML_ID' => $this->getField('XML_ID'),
611 'ENTITY_ID' => $this->getCollection()->getEntityParentId(),
612 'ENTITY_TYPE' => $this->getField('ENTITY_TYPE')
613 ]
614 );
615
616 if ($res->isSuccess())
617 {
618 $this->setFieldNoDemand('ID', $res->getId());
619 $result->setId($res->getId());
620 }
621 else
622 {
623 $result->addErrors($res->getErrors());
624 }
625
626 return $result;
627 }
628
632 protected function callEventOnPropertyValueEntitySaved(): void
633 {
634 $event = new Main\Event(
635 'sale',
636 static::getOnSavedEventName(),
637 [
638 'ENTITY' => $this,
639 'VALUES' => $this->fields->getOriginalValues(),
640 ]
641 );
642
643 $event->send();
644 }
645
652 public function setValueFromPost(array $post): Result
653 {
654 $result = new Result();
655
656 $key = ($this->getField('ORDER_PROPS_ID')) ?: "n".$this->getInternalIndex();
657
658 if (is_array($post['PROPERTIES']) && array_key_exists($key, $post['PROPERTIES']))
659 {
660 $this->setValue($post['PROPERTIES'][$key]);
661 }
662
663 return $result;
664 }
665
672 public function checkValue($key, $value)
673 {
674 $result = new Result();
675
676 $res = $this->property->checkValue($value);
677 if (!$res->isSuccess())
678 {
679 $errors = $res->getErrors();
680 foreach ($errors as $error)
681 {
682 $result->addError(new ResultError($error->getMessage(), "PROPERTIES[$key]"));
683 $result->addError(new ResultWarning($error->getMessage(), "PROPERTIES[$key]"));
684 }
685 }
686
687 return $result;
688 }
689
697 public function checkRequiredValue($key, $value)
698 {
699 $result = new Result();
700
701 $res = $this->property->checkRequiredValue($value);
702 if (!$res->isSuccess())
703 {
704 $errors = $res->getErrors();
705 foreach ($errors as $error)
706 {
707 $result->addError(new ResultError($error->getMessage(), "PROPERTIES[$key]"));
708 $result->addError(new ResultWarning($error->getMessage(), "PROPERTIES[$key]"));
709 }
710 }
711
712 return $result;
713 }
714
718 public function getProperty(): array
719 {
720 return $this->property->getFields();
721 }
722
727 {
728 return $this->property;
729 }
730
734 public function getValueId(): ?string
735 {
736 return $this->getField('ID');
737 }
738
742 public function getPropertyId()
743 {
744 return $this->property->getId();
745 }
746
750 public function getPersonTypeId()
751 {
752 return $this->property->getPersonTypeId();
753 }
754
758 public function getGroupId()
759 {
760 return $this->property->getGroupId();
761 }
762
766 public function getName()
767 {
768 return $this->property->getName();
769 }
770
774 public function getRelations()
775 {
776 return $this->property->getRelations();
777 }
778
782 public function getDescription()
783 {
784 return $this->property->getDescription();
785 }
786
790 public function getType()
791 {
792 return $this->property->getType();
793 }
794
798 public function isRequired()
799 {
800 return $this->property->isRequired();
801 }
802
806 public function isUtil()
807 {
808 return $this->property->isUtil();
809 }
810
814 public static function getRegistryType()
815 {
817 }
818
822 public static function getRegistryEntity(): string
823 {
825 }
826
832 protected function addInternal(array $data)
833 {
834 return OrderPropsValueTable::add($data);
835 }
836
843 protected function updateInternal($primary, array $data)
844 {
845 return OrderPropsValueTable::update($primary, $data);
846 }
847
855 public static function getList(array $parameters = [])
856 {
857 return OrderPropsValueTable::getList($parameters);
858 }
859
865 public function setValue($value)
866 {
867 $this->setField('VALUE', $value);
868 }
869
874 public function getViewHtml()
875 {
876 return $this->property->getViewHtml($this->getValue());
877 }
878
883 public function getEditHtml()
884 {
885 return $this->property->getEditHtml($this->getFieldValues());
886 }
887
891 public function getValue()
892 {
893 return $this->getField("VALUE");
894 }
895
900 public function verify()
901 {
902 $res = $this->checkValue($this->getPropertyId(), $this->getValue());
903 if (!$res->isSuccess())
904 {
905 $order = $this->getOrder();
906
907 $registry = Registry::getInstance(static::getRegistryType());
908
910 $entityMarker = $registry->getEntityMarkerClassName();
911 $entityMarker::addMarker($order, $this, $res);
912 }
913
914 return $res;
915 }
916
921 public static function loadForEntity(Entity $entity): array
922 {
923 [$properties, $propertyValues, $propRelation, $propertyValuesMap] = static::loadFromDb($entity);
924 return static::createPropertyValuesObjects($properties, $propertyValues, $propRelation, $propertyValuesMap);
925 }
926
927 public static function getTableEntity()
928 {
929 return \Bitrix\Sale\Internals\OrderPropsValueTable::getEntity();
930 }
931}
static add(array $data)
Definition: entity.php:150
static constructPropertyFilter(Entity $entity)
updateInternal($primary, array $data)
static extractPaySystemIdList(Entity $entity)
static create(EntityPropertyValueCollection $collection, array $property=[])
static extractTpLandingIdList(Entity $entity)
static extractDeliveryIdList(Entity $entity)
static loadForEntity(Entity $entity)
static constructPropertyRelatedEntitiesFilter(Entity $entity)
static createPropertyValueObject(array $property=null, array $value=[], array $relation=null)
__construct(array $property=null, array $value=[], array $relation=null)
static hasPresetForLanding(Entity $entity)
static createPropertyValuesObjects(array $properties, array $propertyValues, array $propRelation, array $propertyValuesMap)
static getList(array $parameters=[])
const ENTITY_PROPERTY_VALUE
Definition: registry.php:27
static getInstance($type)
Definition: registry.php:183
const REGISTRY_TYPE_ORDER
Definition: registry.php:16