Bitrix-D7 22.6
 
Загрузка...
Поиск...
Не найдено
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
67 protected static function extractTradingPlatformIdList(Entity $entity): array
68 {
69 return [];
70 }
71
79 protected static function loadFromDb(Entity $entity): array
80 {
81 $propertyValues = [];
82 $propertyValuesMap = [];
83
84 if ($entity->getId() > 0)
85 {
86 $dbRes = static::getList(
87 [
88 'select' => ['ID', 'NAME', 'VALUE', 'CODE', 'ORDER_PROPS_ID'],
89 'filter' => [
90 'ENTITY_ID' => $entity->getId(),
91 'ENTITY_TYPE' => static::getEntityType()
92 ]
93 ]
94 );
95 while ($row = $dbRes->fetch())
96 {
97 $propertyValues[$row['ID']] = $row;
98 $propertyValuesMap[$row['ORDER_PROPS_ID']] = $row['ID'];
99 }
100 }
101
103 $propertyClassName = static::getPropertyClassName();
104
105 $getListParams = [
106 'select' => [
107 'ID',
108 'PERSON_TYPE_ID',
109 'NAME',
110 'TYPE',
111 'REQUIRED',
112 'DEFAULT_VALUE',
113 'SORT',
114 'USER_PROPS',
115 'IS_LOCATION',
116 'PROPS_GROUP_ID',
117 'DESCRIPTION',
118 'IS_EMAIL',
119 'IS_PROFILE_NAME',
120 'IS_PAYER',
121 'IS_LOCATION4TAX',
122 'IS_FILTERED',
123 'CODE',
124 'IS_ZIP',
125 'IS_PHONE',
126 'IS_ADDRESS',
127 'IS_ADDRESS_FROM',
128 'IS_ADDRESS_TO',
129 'ACTIVE',
130 'UTIL',
131 'INPUT_FIELD_LOCATION',
132 'MULTIPLE',
133 'SETTINGS',
134 'ENTITY_TYPE'
135 ],
136 'filter' => static::constructPropertyFilter($entity),
137 'runtime' => static::getRelationRuntimeFields(),
138 'order' => ['SORT' => 'ASC'],
139 ];
140
141 $dbRes = $propertyClassName::getList($getListParams);
142 $properties = [];
143 $propRelation = [];
144
145 while ($row = $dbRes->fetch())
146 {
147 $properties[$row['ID']] = $row;
148 $propRelation[$row['ID']] = [];
149 }
150
151 $dbRes = OrderPropsRelationTable::getList(
152 [
153 'select' => [
154 'PROPERTY_ID',
155 'ENTITY_ID',
156 'ENTITY_TYPE'
157 ],
158 'filter' => [
159 'PROPERTY_ID' => array_keys($properties)
160 ]
161 ]
162 );
163
164 while ($row = $dbRes->fetch())
165 {
166 $propRelation[$row['PROPERTY_ID']][] = $row;
167 }
168
169 return [$properties, $propertyValues, $propRelation, $propertyValuesMap];
170 }
171
175 public function needDeleteOnRefresh() : bool
176 {
177 $property = $this->getPropertyObject();
178
179 return $property ? !empty($property->getRelations()) : false;
180 }
181
182 protected static function constructPropertyFilter(Entity $entity) : array
183 {
184 $filter = [
185 '=ENTITY_TYPE' => static::getEntityType()
186 ];
187
188 if ($entity->getPersonTypeId() > 0)
189 {
190 $filter['=PERSON_TYPE_ID'] = $entity->getPersonTypeId();
191 }
192
193 $subFilter = [
194 'LOGIC' => 'OR',
195 static::constructPropertyRelatedEntitiesFilter($entity)
196 ];
197
198 if ($entity->getId() > 0)
199 {
200 $dbRes = static::getList([
201 'select' => ['ORDER_PROPS_ID'],
202 'filter' => [
203 '=ENTITY_ID' => $entity->getId(),
204 '=ENTITY_TYPE' => static::getEntityType()
205 ]
206 ]);
207
208 while ($row = $dbRes->fetch())
209 {
210 $subFilter['@ID'][] = $row['ORDER_PROPS_ID'];
211 }
212 }
213
214 $filter[] = $subFilter;
215
216 return $filter;
217 }
218
219 protected static function hasPresetForLanding(Entity $entity) : bool
220 {
221 $tpLandingList = static::extractTpLandingIdList($entity);
222
223 if ($tpLandingList)
224 {
225 $dbRes = Internals\OrderPropsRelationTable::getList([
226 'filter' => [
227 '@ENTITY_ID' => $tpLandingList,
228 '=ENTITY_TYPE' => OrderPropsRelationTable::ENTITY_TYPE_LANDING,
229 ],
230 'limit' => 1
231 ]);
232
233 return (bool)$dbRes->fetch();
234 }
235
236 return false;
237 }
238
239 protected static function hasPresetFotTradingPlatform(Entity $entity): bool
240 {
241 $tpList = static::extractTradingPlatformIdList($entity);
242
243 if ($tpList)
244 {
245 $dbRes = Internals\OrderPropsRelationTable::getList([
246 'filter' => [
247 '@ENTITY_ID' => $tpList,
248 '=ENTITY_TYPE' => OrderPropsRelationTable::ENTITY_TYPE_TRADING_PLATFORM
249 ],
250 'limit' => 1
251 ]);
252
253 return (bool)$dbRes->fetch();
254 }
255
256 return false;
257 }
258
263 protected static function constructPropertyRelatedEntitiesFilter(Entity $entity): array
264 {
265 $result = [];
266
267 $psFilter = ['=RELATION_PS.ENTITY_ID' => null];
268
269 if ($paySystemList = static::extractPaySystemIdList($entity))
270 {
271 $psFilter['LOGIC'] = 'OR';
272 $psFilter['@RELATION_PS.ENTITY_ID'] = $paySystemList;
273 }
274
275 $result[] = $psFilter;
276 $dlvFilter = ['=RELATION_DLV.ENTITY_ID' => null];
277
278 if ($deliveryList = static::extractDeliveryIdList($entity))
279 {
280 $dlvFilter['LOGIC'] = 'OR';
281 $dlvFilter['@RELATION_DLV.ENTITY_ID'] = $deliveryList;
282 }
283
284 $result[] = $dlvFilter;
285
286 if (self::hasPresetForLanding($entity))
287 {
288 $result[] = [
289 'LOGIC' => 'OR',
290 '!RELATION_PS.ENTITY_ID' => null,
291 '!RELATION_DLV.ENTITY_ID' => null,
292 ];
293
294 $result = [
295 'LOGIC' => 'OR',
296 '@RELATION_TP_LANDING.ENTITY_ID' => static::extractTpLandingIdList($entity),
297 $result,
298 ];
299 }
300 else
301 {
302 $result = [
303 '=RELATION_TP_LANDING.ENTITY_ID' => null,
304 $result,
305 ];
306 }
307
308 if (self::hasPresetFotTradingPlatform($entity))
309 {
310 $result[] = [
311 'LOGIC' => 'OR',
312 '!RELATION_PS.ENTITY_ID' => null,
313 '!RELATION_DLV.ENTITY_ID' => null,
314 '!RELATION_TP_LANDING.ENTITY_ID' => null,
315 ];
316
317 $result = [
318 'LOGIC' => 'OR',
319 '@RELATION_TP.ENTITY_ID' => static::extractTradingPlatformIdList($entity),
320 $result,
321 ];
322 }
323 else
324 {
325 $result = [
326 '=RELATION_TP.ENTITY_ID' => null,
327 $result,
328 ];
329 }
330
331 return $result;
332 }
333
334 protected static function getRelationRuntimeFields(): array
335 {
336 return [
337 new ReferenceField(
338 'RELATION_PS',
339 '\Bitrix\Sale\Internals\OrderPropsRelation',
340 [
341 '=this.ID' => 'ref.PROPERTY_ID',
342 'ref.ENTITY_TYPE' => new SqlExpression('?', OrderPropsRelationTable::ENTITY_TYPE_PAY_SYSTEM)
343 ],
344 'left_join'
345 ),
346 new ReferenceField(
347 'RELATION_DLV',
348 '\Bitrix\Sale\Internals\OrderPropsRelation',
349 [
350 '=this.ID' => 'ref.PROPERTY_ID',
351 'ref.ENTITY_TYPE' => new SqlExpression('?', OrderPropsRelationTable::ENTITY_TYPE_DELIVERY)
352 ],
353 'left_join'
354 ),
355 new Main\Entity\ReferenceField(
356 'RELATION_TP_LANDING',
357 '\Bitrix\Sale\Internals\OrderPropsRelation',
358 [
359 '=this.ID' => 'ref.PROPERTY_ID',
360 'ref.ENTITY_TYPE' => new Main\DB\SqlExpression('?', OrderPropsRelationTable::ENTITY_TYPE_LANDING)
361 ],
362 'left_join'
363 ),
364 new Main\Entity\ReferenceField(
365 'RELATION_TP',
366 '\Bitrix\Sale\Internals\OrderPropsRelation',
367 [
368 '=this.ID' => 'ref.PROPERTY_ID',
369 'ref.ENTITY_TYPE' => new Main\DB\SqlExpression('?', OrderPropsRelationTable::ENTITY_TYPE_TRADING_PLATFORM)
370 ],
371 'left_join'
372 ),
373 ];
374 }
375
385 protected static function createPropertyValuesObjects(
386 array $properties,
387 array $propertyValues,
388 array $propRelation,
389 array $propertyValuesMap): array
390 {
391 $result = [];
392
393 foreach ($properties as $property)
394 {
395 $id = $property['ID'];
396
397 if (isset($propertyValuesMap[$id]))
398 {
399 $fields = $propertyValues[$propertyValuesMap[$id]];
400 unset($propertyValues[$propertyValuesMap[$id]]);
401 unset($propertyValuesMap[$id]);
402 }
403 else
404 {
405 if ($property['ACTIVE'] === 'N')
406 {
407 continue;
408 }
409
410 $fields = [];
411 }
412
413 $result[$id] = static::createPropertyValueObject($property, $fields, $propRelation[$id]);
414 }
415
416 foreach ($propertyValues as $propertyValue)
417 {
418 $result[$propertyValue['ORDER_PROPS_ID']] = static::createPropertyValueObject(null, $propertyValue);
419 }
420
421 return $result;
422 }
423
427 protected static function getFieldsMap()
428 {
429 return OrderPropsValueTable::getMap();
430 }
431
439 protected function __construct(array $property = null, array $value = [], array $relation = null)
440 {
441 if (!$property && !$value)
442 {
443 throw new Main\SystemException('invalid arguments', 0, __FILE__, __LINE__);
444 }
445
446 if ($property)
447 {
448 if (is_array($property['SETTINGS']))
449 {
450 $property += $property['SETTINGS'];
451 unset ($property['SETTINGS']);
452 }
453 }
454 else
455 {
456 $property = [
457 'TYPE' => 'STRING',
458 'PROPS_GROUP_ID' => 0,
459 'NAME' => $value['NAME'],
460 'CODE' => $value['CODE'],
461 // defaults
462 'PERSON_TYPE_ID' => null,
463 'DESCRIPTION' => null,
464 'REQUIRED' => null,
465 'DEFAULT_VALUE' => null,
466 'SORT' => null,
467 'USER_PROPS' => null,
468 'IS_LOCATION' => 'N',
469 'IS_EMAIL' => 'N',
470 'IS_PROFILE_NAME' => 'N',
471 'IS_PAYER' => 'N',
472 'IS_LOCATION4TAX' => 'N',
473 'IS_FILTERED' => 'N',
474 'IS_ZIP' => 'N',
475 'IS_PHONE' => 'N',
476 'IS_ADDRESS' => 'N',
477 'IS_ADDRESS_FROM' => 'N',
478 'IS_ADDRESS_TO' => 'N',
479 'ACTIVE' => null,
480 'UTIL' => null,
481 'INPUT_FIELD_LOCATION' => null,
482 'MULTIPLE' => null,
483 ];
484 }
485
486 $property['ENTITY_TYPE'] = static::getEntityType();
487
488 $propertyClassName = static::getPropertyClassName();
489
490 $this->property = new $propertyClassName($property, $relation);
491
492 if (isset($value['VALUE']))
493 {
494 $value['VALUE'] = $this->property->normalizeValue($value['VALUE']);
495 }
496
497 parent::__construct($value);
498
499 if (!$value)
500 {
501 $value = [
502 'ORDER_PROPS_ID' => $this->property->getId(),
503 'NAME' => $this->property->getName(),
504 'CODE' => $this->property->getField('CODE'),
505 'XML_ID' => static::generateXmlId(),
506 'ENTITY_TYPE' => $this->property->getField('ENTITY_TYPE')
507 ];
508
509 if (!empty($this->property->getField('DEFAULT_VALUE')))
510 {
511 $value['VALUE'] = $this->property->getField('DEFAULT_VALUE');
512 }
513
514 $this->setFieldsNoDemand($value);
515 }
516 }
517
521 public static function generateXmlId(): string
522 {
523 return uniqid('bx_');
524 }
525
533 public static function create(EntityPropertyValueCollection $collection, array $property = [])
534 {
535 $propertyValue = static::createPropertyValueObject($property);
536 $propertyValue->setCollection($collection);
537 return $propertyValue;
538 }
539
543 public static function getAvailableFields()
544 {
545 return ['VALUE'];
546 }
547
551 protected static function getMeaningfulFields()
552 {
553 return [];
554 }
555
565 public function normalizeValue($name, $value)
566 {
567 if ($name === 'VALUE')
568 {
569 $value = $this->property->normalizeValue($value);
570 }
571
572 return parent::normalizeValue($name, $value);
573 }
574
582 public function save(): Result
583 {
584 $this->checkCallingContext();
585
586 $result = new Result();
587
588 if (!$this->isChanged())
589 {
590 return $result;
591 }
592
593 if ($this->getId() > 0)
594 {
595 $res = $this->update();
596 }
597 else
598 {
599 $res = $this->add();
600 }
601
602 if (!$res->isSuccess())
603 {
604 $result->addErrors($res->getErrors());
605 }
606
608
609 return $result;
610 }
611
612 private function checkCallingContext(): void
613 {
614 $order = $this->getOrder();
615
616 if (!$order->isSaveRunning())
617 {
618 trigger_error("Incorrect call to the save process. Use method save() on \Bitrix\Sale\Order entity", E_USER_WARNING);
619 }
620 }
621
625 public function getOrder(): ?Order
626 {
628 $collection = $this->getCollection();
629 if (!$collection)
630 {
631 return null;
632 }
633
635 $order = $collection->getOrder();
636 if (!$order)
637 {
638 return null;
639 }
640
641 return $order;
642 }
643
648 protected function update()
649 {
650 $result = new Result();
651
652 $value = $this->property->getPreparedValueForSave($this);
653 $res = $this->updateInternal($this->getId(), ['VALUE' => $value]);
654
655 if ($res->isSuccess())
656 {
657 $result->setId($res->getId());
658 }
659 else
660 {
661 $result->addErrors($res->getErrors());
662 }
663
664 return $result;
665 }
666
672 protected function add()
673 {
674 $result = new Result();
675
676 $value = $this->property->getPreparedValueForSave($this);
679 $res = $this->addInternal(
680 [
681 'ORDER_ID' => $this->getOrder()->getId(),
682 'ORDER_PROPS_ID' => $this->property->getId(),
683 'NAME' => $this->property->getName(),
684 'VALUE' => $value,
685 'CODE' => $this->property->getField('CODE'),
686 'XML_ID' => $this->getField('XML_ID'),
687 'ENTITY_ID' => $this->getCollection()->getEntityParentId(),
688 'ENTITY_TYPE' => $this->getField('ENTITY_TYPE')
689 ]
690 );
691
692 if ($res->isSuccess())
693 {
694 $this->setFieldNoDemand('ID', $res->getId());
695 $result->setId($res->getId());
696 }
697 else
698 {
699 $result->addErrors($res->getErrors());
700 }
701
702 return $result;
703 }
704
708 protected function callEventOnPropertyValueEntitySaved(): void
709 {
710 $event = new Main\Event(
711 'sale',
712 static::getOnSavedEventName(),
713 [
714 'ENTITY' => $this,
715 'VALUES' => $this->fields->getOriginalValues(),
716 ]
717 );
718
719 $event->send();
720 }
721
728 public function setValueFromPost(array $post): Result
729 {
730 $result = new Result();
731
732 $key = ($this->getField('ORDER_PROPS_ID')) ?: "n".$this->getInternalIndex();
733
734 if (is_array($post['PROPERTIES']) && array_key_exists($key, $post['PROPERTIES']))
735 {
736 $this->setValue($post['PROPERTIES'][$key]);
737 }
738
739 return $result;
740 }
741
748 public function checkValue($key, $value)
749 {
750 $result = new Result();
751
752 $res = $this->property->checkValue($value);
753 if (!$res->isSuccess())
754 {
755 $errors = $res->getErrors();
756 foreach ($errors as $error)
757 {
758 $result->addError(new ResultError($error->getMessage(), "PROPERTIES[$key]"));
759 $result->addError(new ResultWarning($error->getMessage(), "PROPERTIES[$key]"));
760 }
761 }
762
763 return $result;
764 }
765
773 public function checkRequiredValue($key, $value)
774 {
775 $result = new Result();
776
777 $res = $this->property->checkRequiredValue($value);
778 if (!$res->isSuccess())
779 {
780 $errors = $res->getErrors();
781 foreach ($errors as $error)
782 {
783 $result->addError(new ResultError($error->getMessage(), "PROPERTIES[$key]"));
784 $result->addError(new ResultWarning($error->getMessage(), "PROPERTIES[$key]"));
785 }
786 }
787
788 return $result;
789 }
790
794 public function getProperty(): array
795 {
796 return $this->property->getFields();
797 }
798
803 {
804 return $this->property;
805 }
806
810 public function getValueId(): ?string
811 {
812 return $this->getField('ID');
813 }
814
818 public function getPropertyId()
819 {
820 return $this->property->getId();
821 }
822
826 public function getPersonTypeId()
827 {
828 return $this->property->getPersonTypeId();
829 }
830
834 public function getGroupId()
835 {
836 return $this->property->getGroupId();
837 }
838
842 public function getName()
843 {
844 return $this->property->getName();
845 }
846
850 public function getRelations()
851 {
852 return $this->property->getRelations();
853 }
854
858 public function getDescription()
859 {
860 return $this->property->getDescription();
861 }
862
866 public function getType()
867 {
868 return $this->property->getType();
869 }
870
874 public function isRequired()
875 {
876 return $this->property->isRequired();
877 }
878
882 public function isUtil()
883 {
884 return $this->property->isUtil();
885 }
886
890 public static function getRegistryType()
891 {
893 }
894
898 public static function getRegistryEntity(): string
899 {
901 }
902
908 protected function addInternal(array $data)
909 {
910 return OrderPropsValueTable::add($data);
911 }
912
919 protected function updateInternal($primary, array $data)
920 {
921 return OrderPropsValueTable::update($primary, $data);
922 }
923
931 public static function getList(array $parameters = [])
932 {
933 return OrderPropsValueTable::getList($parameters);
934 }
935
941 public function setValue($value)
942 {
943 return $this->setField('VALUE', $value);
944 }
945
950 public function getViewHtml()
951 {
952 return $this->property->getViewHtml($this->getValue());
953 }
954
959 public function getEditHtml()
960 {
961 return $this->property->getEditHtml($this->getFieldValues());
962 }
963
967 public function getValue()
968 {
969 return $this->getField("VALUE");
970 }
971
976 public function verify()
977 {
978 $res = $this->checkValue($this->getPropertyId(), $this->getValue());
979 if (!$res->isSuccess())
980 {
981 $order = $this->getOrder();
982
983 $registry = Registry::getInstance(static::getRegistryType());
984
986 $entityMarker = $registry->getEntityMarkerClassName();
987 $entityMarker::addMarker($order, $this, $res);
988 }
989
990 return $res;
991 }
992
997 public static function loadForEntity(Entity $entity): array
998 {
999 [$properties, $propertyValues, $propRelation, $propertyValuesMap] = static::loadFromDb($entity);
1000 return static::createPropertyValuesObjects($properties, $propertyValues, $propRelation, $propertyValuesMap);
1001 }
1002
1003 public static function getTableEntity()
1004 {
1005 return \Bitrix\Sale\Internals\OrderPropsValueTable::getEntity();
1006 }
1007}
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 hasPresetFotTradingPlatform(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=[])
static extractTradingPlatformIdList(Entity $entity)
const ENTITY_PROPERTY_VALUE
Definition: registry.php:27
static getInstance($type)
Definition: registry.php:183
const REGISTRY_TYPE_ORDER
Definition: registry.php:16