1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
entitypropertyvalue.php
См. документацию.
1<?php
2
3namespace Bitrix\Sale;
4
5use Bitrix\Main\DB\SqlExpression;
6use Bitrix\Main\Entity\ReferenceField;
7use Bitrix\Sale\Internals\CollectableEntity;
8use Bitrix\Sale\Internals\Entity;
9use Bitrix\Sale\Internals\OrderPropsRelationTable;
10use Bitrix\Main;
11use Bitrix\Sale\Internals\OrderPropsValueTable;
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
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 if (!empty($properties))
152 {
153 $dbRes = OrderPropsRelationTable::getList(
154 [
155 'select' => [
156 'PROPERTY_ID',
157 'ENTITY_ID',
158 'ENTITY_TYPE'
159 ],
160 'filter' => [
161 'PROPERTY_ID' => array_keys($properties)
162 ]
163 ]
164 );
165
166 while ($row = $dbRes->fetch())
167 {
168 $propRelation[$row['PROPERTY_ID']][] = $row;
169 }
170 }
171
172 return [$properties, $propertyValues, $propRelation, $propertyValuesMap];
173 }
174
178 public function needDeleteOnRefresh() : bool
179 {
180 $property = $this->getPropertyObject();
181
182 return $property ? !empty($property->getRelations()) : false;
183 }
184
185 protected static function constructPropertyFilter(Entity $entity) : array
186 {
187 $filter = [
188 '=ENTITY_TYPE' => static::getEntityType()
189 ];
190
191 if ($entity->getPersonTypeId() > 0)
192 {
193 $filter['=PERSON_TYPE_ID'] = $entity->getPersonTypeId();
194 }
195
196 $subFilter = [
197 'LOGIC' => 'OR',
198 static::constructPropertyRelatedEntitiesFilter($entity)
199 ];
200
201 if ($entity->getId() > 0)
202 {
203 $dbRes = static::getList([
204 'select' => ['ORDER_PROPS_ID'],
205 'filter' => [
206 '=ENTITY_ID' => $entity->getId(),
207 '=ENTITY_TYPE' => static::getEntityType()
208 ]
209 ]);
210
211 while ($row = $dbRes->fetch())
212 {
213 $subFilter['@ID'][] = $row['ORDER_PROPS_ID'];
214 }
215 }
216
217 $filter[] = $subFilter;
218
219 return $filter;
220 }
221
222 protected static function hasPresetForLanding(Entity $entity) : bool
223 {
224 $tpLandingList = static::extractTpLandingIdList($entity);
225
226 if ($tpLandingList)
227 {
228 $dbRes = Internals\OrderPropsRelationTable::getList([
229 'filter' => [
230 '@ENTITY_ID' => $tpLandingList,
231 '=ENTITY_TYPE' => OrderPropsRelationTable::ENTITY_TYPE_LANDING,
232 ],
233 'cache' => ['ttl' => 86400],
234 'limit' => 1
235 ]);
236
237 return (bool)$dbRes->fetch();
238 }
239
240 return false;
241 }
242
243 protected static function hasPresetFotTradingPlatform(Entity $entity): bool
244 {
245 $tpList = static::extractTradingPlatformIdList($entity);
246
247 if ($tpList)
248 {
249 $dbRes = Internals\OrderPropsRelationTable::getList([
250 'filter' => [
251 '@ENTITY_ID' => $tpList,
252 '=ENTITY_TYPE' => OrderPropsRelationTable::ENTITY_TYPE_TRADING_PLATFORM
253 ],
254 'cache' => ['ttl' => 86400],
255 'limit' => 1
256 ]);
257
258 return (bool)$dbRes->fetch();
259 }
260
261 return false;
262 }
263
268 protected static function constructPropertyRelatedEntitiesFilter(Entity $entity): array
269 {
270 $result = [];
271
272 $psFilter = ['=RELATION_PS.ENTITY_ID' => null];
273
274 if ($paySystemList = static::extractPaySystemIdList($entity))
275 {
276 $psFilter['LOGIC'] = 'OR';
277 $psFilter['@RELATION_PS.ENTITY_ID'] = $paySystemList;
278 }
279
280 $result[] = $psFilter;
281 $dlvFilter = ['=RELATION_DLV.ENTITY_ID' => null];
282
283 if ($deliveryList = static::extractDeliveryIdList($entity))
284 {
285 $dlvFilter['LOGIC'] = 'OR';
286 $dlvFilter['@RELATION_DLV.ENTITY_ID'] = $deliveryList;
287 }
288
289 $result[] = $dlvFilter;
290
291 if (self::hasPresetForLanding($entity))
292 {
293 $result[] = [
294 'LOGIC' => 'OR',
295 '!RELATION_PS.ENTITY_ID' => null,
296 '!RELATION_DLV.ENTITY_ID' => null,
297 ];
298
299 $result = [
300 'LOGIC' => 'OR',
301 '@RELATION_TP_LANDING.ENTITY_ID' => static::extractTpLandingIdList($entity),
302 $result,
303 ];
304 }
305 else
306 {
307 $result = [
308 '=RELATION_TP_LANDING.ENTITY_ID' => null,
309 $result,
310 ];
311 }
312
313 if (self::hasPresetFotTradingPlatform($entity))
314 {
315 $result[] = [
316 'LOGIC' => 'OR',
317 '!RELATION_PS.ENTITY_ID' => null,
318 '!RELATION_DLV.ENTITY_ID' => null,
319 '!RELATION_TP_LANDING.ENTITY_ID' => null,
320 ];
321
322 $result = [
323 'LOGIC' => 'OR',
324 '@RELATION_TP.ENTITY_ID' => static::extractTradingPlatformIdList($entity),
325 $result,
326 ];
327 }
328 else
329 {
330 $result = [
331 '=RELATION_TP.ENTITY_ID' => null,
332 $result,
333 ];
334 }
335
336 return $result;
337 }
338
339 protected static function getRelationRuntimeFields(): array
340 {
341 return [
342 new ReferenceField(
343 'RELATION_PS',
344 '\Bitrix\Sale\Internals\OrderPropsRelation',
345 [
346 '=this.ID' => 'ref.PROPERTY_ID',
347 'ref.ENTITY_TYPE' => new SqlExpression('?', OrderPropsRelationTable::ENTITY_TYPE_PAY_SYSTEM)
348 ],
349 'left_join'
350 ),
351 new ReferenceField(
352 'RELATION_DLV',
353 '\Bitrix\Sale\Internals\OrderPropsRelation',
354 [
355 '=this.ID' => 'ref.PROPERTY_ID',
356 'ref.ENTITY_TYPE' => new SqlExpression('?', OrderPropsRelationTable::ENTITY_TYPE_DELIVERY)
357 ],
358 'left_join'
359 ),
360 new Main\Entity\ReferenceField(
361 'RELATION_TP_LANDING',
362 '\Bitrix\Sale\Internals\OrderPropsRelation',
363 [
364 '=this.ID' => 'ref.PROPERTY_ID',
365 'ref.ENTITY_TYPE' => new Main\DB\SqlExpression('?', OrderPropsRelationTable::ENTITY_TYPE_LANDING)
366 ],
367 'left_join'
368 ),
369 new Main\Entity\ReferenceField(
370 'RELATION_TP',
371 '\Bitrix\Sale\Internals\OrderPropsRelation',
372 [
373 '=this.ID' => 'ref.PROPERTY_ID',
374 'ref.ENTITY_TYPE' => new Main\DB\SqlExpression('?', OrderPropsRelationTable::ENTITY_TYPE_TRADING_PLATFORM)
375 ],
376 'left_join'
377 ),
378 ];
379 }
380
390 protected static function createPropertyValuesObjects(
391 array $properties,
392 array $propertyValues,
393 array $propRelation,
394 array $propertyValuesMap): array
395 {
396 $result = [];
397
398 foreach ($properties as $property)
399 {
400 $id = $property['ID'];
401
402 if (isset($propertyValuesMap[$id]))
403 {
404 $fields = $propertyValues[$propertyValuesMap[$id]];
405 unset($propertyValues[$propertyValuesMap[$id]]);
406 unset($propertyValuesMap[$id]);
407 }
408 else
409 {
410 if ($property['ACTIVE'] === 'N')
411 {
412 continue;
413 }
414
415 $fields = [];
416 }
417
418 $result[$id] = static::createPropertyValueObject($property, $fields, $propRelation[$id]);
419 }
420
421 foreach ($propertyValues as $propertyValue)
422 {
423 $result[$propertyValue['ORDER_PROPS_ID']] = static::createPropertyValueObject(null, $propertyValue);
424 }
425
426 return $result;
427 }
428
432 protected static function getFieldsMap()
433 {
434 return OrderPropsValueTable::getMap();
435 }
436
444 protected function __construct(array $property = null, array $value = [], array $relation = null)
445 {
446 if (!$property && !$value)
447 {
448 throw new Main\SystemException('invalid arguments', 0, __FILE__, __LINE__);
449 }
450
451 if ($property)
452 {
453 if (isset($property['SETTINGS']) && is_array($property['SETTINGS']))
454 {
455 $property += $property['SETTINGS'];
456 unset ($property['SETTINGS']);
457 }
458 }
459 else
460 {
461 $property = [
462 'TYPE' => 'STRING',
463 'PROPS_GROUP_ID' => 0,
464 'NAME' => $value['NAME'],
465 'CODE' => $value['CODE'],
466 // defaults
467 'PERSON_TYPE_ID' => null,
468 'DESCRIPTION' => null,
469 'REQUIRED' => null,
470 'DEFAULT_VALUE' => null,
471 'SORT' => null,
472 'USER_PROPS' => null,
473 'IS_LOCATION' => 'N',
474 'IS_EMAIL' => 'N',
475 'IS_PROFILE_NAME' => 'N',
476 'IS_PAYER' => 'N',
477 'IS_LOCATION4TAX' => 'N',
478 'IS_FILTERED' => 'N',
479 'IS_ZIP' => 'N',
480 'IS_PHONE' => 'N',
481 'IS_ADDRESS' => 'N',
482 'IS_ADDRESS_FROM' => 'N',
483 'IS_ADDRESS_TO' => 'N',
484 'ACTIVE' => null,
485 'UTIL' => null,
486 'INPUT_FIELD_LOCATION' => null,
487 'MULTIPLE' => null,
488 ];
489 }
490
491 $property['ENTITY_TYPE'] = static::getEntityType();
492
493 $propertyClassName = static::getPropertyClassName();
494
495 $this->property = new $propertyClassName($property, $relation);
496
497 if (isset($value['VALUE']))
498 {
499 $value['VALUE'] = $this->property->normalizeValue($value['VALUE']);
500 }
501
502 parent::__construct($value);
503
504 if (!$value)
505 {
506 $value = [
507 'ORDER_PROPS_ID' => $this->property->getId(),
508 'NAME' => $this->property->getName(),
509 'CODE' => $this->property->getField('CODE'),
510 'XML_ID' => static::generateXmlId(),
511 'ENTITY_TYPE' => $this->property->getField('ENTITY_TYPE')
512 ];
513
514 if (!empty($this->property->getField('DEFAULT_VALUE')))
515 {
516 $value['VALUE'] = $this->property->getField('DEFAULT_VALUE');
517 }
518
519 $this->setFieldsNoDemand($value);
520 }
521 }
522
526 public static function generateXmlId(): string
527 {
528 return uniqid('bx_');
529 }
530
539 {
540 $propertyValue = static::createPropertyValueObject($property);
541 $propertyValue->setCollection($collection);
542 return $propertyValue;
543 }
544
548 public static function getAvailableFields()
549 {
550 return ['VALUE'];
551 }
552
556 protected static function getMeaningfulFields()
557 {
558 return [];
559 }
560
570 public function normalizeValue($name, $value)
571 {
572 if ($name === 'VALUE')
573 {
574 $value = $this->property->normalizeValue($value);
575 }
576
577 return parent::normalizeValue($name, $value);
578 }
579
587 public function save(): Result
588 {
589 $this->checkCallingContext();
590
591 $result = new Result();
592
593 if (!$this->isChanged())
594 {
595 return $result;
596 }
597
598 if ($this->getId() > 0)
599 {
600 $res = $this->update();
601 }
602 else
603 {
604 $res = $this->add();
605 }
606
607 if (!$res->isSuccess())
608 {
609 $result->addErrors($res->getErrors());
610 }
611
613
614 return $result;
615 }
616
617 private function checkCallingContext(): void
618 {
619 $order = $this->getOrder();
620
621 if (!$order->isSaveRunning())
622 {
623 trigger_error("Incorrect call to the save process. Use method save() on \Bitrix\Sale\Order entity", E_USER_WARNING);
624 }
625 }
626
630 public function getOrder(): ?Order
631 {
633 $collection = $this->getCollection();
634 if (!$collection)
635 {
636 return null;
637 }
638
640 $order = $collection->getOrder();
641 if (!$order)
642 {
643 return null;
644 }
645
646 return $order;
647 }
648
653 protected function update()
654 {
655 $result = new Result();
656
657 $value = $this->property->getPreparedValueForSave($this);
658 $res = $this->updateInternal($this->getId(), ['VALUE' => $value]);
659
660 if ($res->isSuccess())
661 {
662 $result->setId($res->getId());
663 }
664 else
665 {
666 $result->addErrors($res->getErrors());
667 }
668
669 return $result;
670 }
671
677 protected function add()
678 {
679 $result = new Result();
680
681 $value = $this->property->getPreparedValueForSave($this);
683
684 $res = $this->addInternal(
685 [
686 'ORDER_ID' => $this->getOrder()->getId(),
687 'ORDER_PROPS_ID' => $this->property->getId(),
688 'NAME' => $this->property->getName(),
689 'VALUE' => $value,
690 'CODE' => $this->property->getField('CODE'),
691 'XML_ID' => $this->getField('XML_ID'),
692 'ENTITY_ID' => $this->getCollection()->getEntityParentId(),
693 'ENTITY_TYPE' => $this->getField('ENTITY_TYPE')
694 ]
695 );
696
697 if ($res->isSuccess())
698 {
699 $this->setFieldNoDemand('ID', $res->getId());
700 $result->setId($res->getId());
701 }
702 else
703 {
704 $result->addErrors($res->getErrors());
705 }
706
707 return $result;
708 }
709
713 protected function callEventOnPropertyValueEntitySaved(): void
714 {
715 $event = new Main\Event(
716 'sale',
717 static::getOnSavedEventName(),
718 [
719 'ENTITY' => $this,
720 'VALUES' => $this->fields->getOriginalValues(),
721 ]
722 );
723
724 $event->send();
725 }
726
734 {
735 $result = new Result();
736
737 $key = ($this->getField('ORDER_PROPS_ID')) ?: "n".$this->getInternalIndex();
738
739 if (is_array($post['PROPERTIES']) && array_key_exists($key, $post['PROPERTIES']))
740 {
741 $this->setValue($post['PROPERTIES'][$key]);
742 }
743
744 return $result;
745 }
746
753 public function checkValue($key, $value)
754 {
755 $result = new Result();
756
757 $res = $this->property->checkValue($value);
758 if (!$res->isSuccess())
759 {
760 $errors = $res->getErrors();
761 foreach ($errors as $error)
762 {
763 $result->addError(new ResultError($error->getMessage(), "PROPERTIES[$key]"));
764 $result->addError(new ResultWarning($error->getMessage(), "PROPERTIES[$key]"));
765 }
766 }
767
768 return $result;
769 }
770
778 public function checkRequiredValue($key, $value)
779 {
780 $result = new Result();
781
782 $res = $this->property->checkRequiredValue($value);
783 if (!$res->isSuccess())
784 {
785 $errors = $res->getErrors();
786 foreach ($errors as $error)
787 {
788 $result->addError(new ResultError($error->getMessage(), "PROPERTIES[$key]"));
789 $result->addError(new ResultWarning($error->getMessage(), "PROPERTIES[$key]"));
790 }
791 }
792
793 return $result;
794 }
795
799 public function getProperty(): array
800 {
801 return $this->property->getFields();
802 }
803
808 {
809 return $this->property;
810 }
811
815 public function getValueId(): ?string
816 {
817 return $this->getField('ID');
818 }
819
823 public function getPropertyId()
824 {
825 return $this->property->getId();
826 }
827
831 public function getPersonTypeId()
832 {
833 return $this->property->getPersonTypeId();
834 }
835
839 public function getGroupId()
840 {
841 return $this->property->getGroupId();
842 }
843
847 public function getName()
848 {
849 return $this->property->getName();
850 }
851
855 public function getRelations()
856 {
857 return $this->property->getRelations();
858 }
859
863 public function getDescription()
864 {
865 return $this->property->getDescription();
866 }
867
871 public function getType()
872 {
873 return $this->property->getType();
874 }
875
879 public function isRequired()
880 {
881 return $this->property->isRequired();
882 }
883
887 public function isUtil()
888 {
889 return $this->property->isUtil();
890 }
891
895 public static function getRegistryType()
896 {
898 }
899
903 public static function getRegistryEntity(): string
904 {
906 }
907
913 protected function addInternal(array $data)
914 {
915 return OrderPropsValueTable::add($data);
916 }
917
924 protected function updateInternal($primary, array $data)
925 {
926 return OrderPropsValueTable::update($primary, $data);
927 }
928
936 public static function getList(array $parameters = [])
937 {
938 return OrderPropsValueTable::getList($parameters);
939 }
940
946 public function setValue($value)
947 {
948 return $this->setField('VALUE', $value);
949 }
950
955 public function getViewHtml()
956 {
957 return $this->property->getViewHtml($this->getValue());
958 }
959
964 public function getEditHtml()
965 {
966 return $this->property->getEditHtml($this->getFieldValues());
967 }
968
972 public function getValue()
973 {
974 return $this->getField("VALUE");
975 }
976
981 public function verify()
982 {
983 $res = $this->checkValue($this->getPropertyId(), $this->getValue());
984 if (!$res->isSuccess())
985 {
986 $order = $this->getOrder();
987
988 $registry = Registry::getInstance(static::getRegistryType());
989
991 $entityMarker = $registry->getEntityMarkerClassName();
992 $entityMarker::addMarker($order, $this, $res);
993 }
994
995 return $res;
996 }
997
1002 public static function loadForEntity(Entity $entity): array
1003 {
1004 [$properties, $propertyValues, $propRelation, $propertyValuesMap] = static::loadFromDb($entity);
1005 return static::createPropertyValuesObjects($properties, $propertyValues, $propRelation, $propertyValuesMap);
1006 }
1007
1008 public static function getTableEntity()
1009 {
1010 return \Bitrix\Sale\Internals\OrderPropsValueTable::getEntity();
1011 }
1012}
static add(array $data)
Определения entity.php:150
Определения event.php:5
static constructPropertyFilter(Entity $entity)
Определения entitypropertyvalue.php:185
updateInternal($primary, array $data)
Определения entitypropertyvalue.php:924
checkRequiredValue($key, $value)
Определения entitypropertyvalue.php:778
setValueFromPost(array $post)
Определения entitypropertyvalue.php:733
static extractPaySystemIdList(Entity $entity)
Определения entitypropertyvalue.php:52
static create(EntityPropertyValueCollection $collection, array $property=[])
Определения entitypropertyvalue.php:538
static extractTpLandingIdList(Entity $entity)
Определения entitypropertyvalue.php:62
static extractDeliveryIdList(Entity $entity)
Определения entitypropertyvalue.php:57
static loadForEntity(Entity $entity)
Определения entitypropertyvalue.php:1002
static hasPresetFotTradingPlatform(Entity $entity)
Определения entitypropertyvalue.php:243
static constructPropertyRelatedEntitiesFilter(Entity $entity)
Определения entitypropertyvalue.php:268
static createPropertyValueObject(array $property=null, array $value=[], array $relation=null)
addInternal(array $data)
Определения entitypropertyvalue.php:913
__construct(array $property=null, array $value=[], array $relation=null)
Определения entitypropertyvalue.php:444
checkValue($key, $value)
Определения entitypropertyvalue.php:753
static hasPresetForLanding(Entity $entity)
Определения entitypropertyvalue.php:222
normalizeValue($name, $value)
Определения entitypropertyvalue.php:570
static createPropertyValuesObjects(array $properties, array $propertyValues, array $propRelation, array $propertyValuesMap)
Определения entitypropertyvalue.php:390
static getList(array $parameters=[])
Определения entitypropertyvalue.php:936
static getRelationRuntimeFields()
Определения entitypropertyvalue.php:339
static extractTradingPlatformIdList(Entity $entity)
Определения entitypropertyvalue.php:67
const ENTITY_PROPERTY_VALUE
Определения registry.php:27
static getInstance($type)
Определения registry.php:183
const REGISTRY_TYPE_ORDER
Определения registry.php:16
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr ><?endif?><? $propertyIndex=0;foreach( $arGlobalProperties as $propertyCode=> $propertyValue
Определения file_new.php:729
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
$result
Определения get_property_values.php:14
$entity
$errors
Определения iblock_catalog_edit.php:74
$getListParams
Определения iblock_catalog_list.php:210
$filter
Определения iblock_catalog_list.php:54
$name
Определения menu_edit.php:35
Определения arrayresult.php:2
Определения ufield.php:9
$order
Определения payment.php:8
$event
Определения prolog_after.php:141
if(empty($signedUserToken)) $key
Определения quickway.php:257
$post
Определения template.php:8
$error
Определения subscription_card_product.php:20
$dbRes
Определения yandex_detail.php:168