Bitrix-D7  20.5.0
propertyvaluecollectionbase.php
См. документацию.
1 <?php
2 
3 namespace Bitrix\Sale;
4 
5 use Bitrix\Main;
10 
11 Loc::loadMessages(__FILE__);
12 
13 /**
14  * Class PropertyValueCollectionBase
15  * @package Bitrix\Sale
16  */
18 {
19  /** @var OrderBase */
20  protected $order;
21 
22  protected $propertyGroups = null;
23 
24  /**
25  * @param OrderBase $order
26  * @return PropertyValueCollectionBase
27  * @throws Main\ArgumentException
28  * @throws Main\NotImplementedException
29  * @throws Main\ObjectPropertyException
30  * @throws Main\SystemException
31  */
32  public static function load(OrderBase $order)
33  {
34  /** @var PropertyValueCollectionBase $propertyCollection */
35  $propertyCollection = static::createPropertyValueCollectionObject();
36  $propertyCollection->setOrder($order);
37 
38  $registry = Registry::getInstance(static::getRegistryType());
39  /** @var PropertyValueBase $propertyValueClassName */
40  $propertyValueClassName = $registry->getPropertyValueClassName();
41 
42  $props = $propertyValueClassName::loadForOrder($order);
43 
44  /** @var PropertyValueBase $prop */
45  foreach ($props as $prop)
46  {
47  $prop->setCollection($propertyCollection);
48  $propertyCollection->addItem($prop);
49  }
50 
51  return $propertyCollection;
52  }
53 
54  /**
55  * @return OrderBase
56  */
57  protected function getEntityParent()
58  {
59  return $this->getOrder();
60  }
61 
62  /**
63  * @param array $prop
64  * @return mixed
65  * @throws Main\ArgumentException
66  * @throws Main\NotImplementedException
67  */
68  public function createItem(array $prop)
69  {
70  $registry = Registry::getInstance(static::getRegistryType());
71 
72  /** @var PropertyValueBase $propertyValueClass */
73  $propertyValueClass = $registry->getPropertyValueClassName();
74  $property = $propertyValueClass::create($this, $prop);
75  $this->addItem($property);
76 
77  return $property;
78  }
79 
80  /**
81  * @param Internals\CollectableEntity $property
82  * @return Internals\CollectableEntity|Result
83  * @throws Main\ArgumentTypeException
84  */
85  public function addItem(Internals\CollectableEntity $property)
86  {
87  /** @var PropertyValueBase $property */
88  $property = parent::addItem($property);
89 
90  $order = $this->getOrder();
91  return $order->onPropertyValueCollectionModify(EventActions::ADD, $property);
92  }
93 
94  /**
95  * @internal
96  *
97  * @param $index
98  * @return Result|mixed
99  * @throws ArgumentOutOfRangeException
100  */
101  public function deleteItem($index)
102  {
103  $oldItem = parent::deleteItem($index);
104 
105  /** @var OrderBase $order */
106  $order = $this->getOrder();
107  return $order->onPropertyValueCollectionModify(EventActions::DELETE, $oldItem);
108  }
109 
110  /**
111  * @param Internals\CollectableEntity $item
112  * @param null $name
113  * @param null $oldValue
114  * @param null $value
115  * @return Result
116  * @throws Main\NotSupportedException
117  */
118  public function onItemModify(Internals\CollectableEntity $item, $name = null, $oldValue = null, $value = null)
119  {
120  if (!$item instanceof PropertyValueBase)
121  throw new Main\NotSupportedException();
122 
123  /** @var OrderBase $order */
124  $order = $this->getOrder();
125  return $order->onPropertyValueCollectionModify(EventActions::UPDATE, $item, $name, $oldValue, $value);
126  }
127 
128  /**
129  * @param $name
130  * @param $oldValue
131  * @param $value
132  * @return Result
133  */
134  public function onOrderModify($name, $oldValue, $value)
135  {
136  return new Result();
137  }
138 
139  /**
140  * @return OrderBase
141  */
142  public function getOrder()
143  {
144  return $this->order;
145  }
146 
147  /**
148  * @param OrderBase $order
149  */
150  public function setOrder(OrderBase $order)
151  {
152  $this->order = $order;
153  }
154 
155  /**
156  * @return static
157  */
158  private static function createPropertyValueCollectionObject()
159  {
160  $registry = Registry::getInstance(static::getRegistryType());
161  $propertyValueCollectionClassName = $registry->getPropertyValueCollectionClassName();
162 
163  return new $propertyValueCollectionClassName();
164  }
165 
166  /**
167  * @param $name
168  * @return PropertyValueBase
169  * @throws ArgumentOutOfRangeException
170  */
171  public function getAttribute($name)
172  {
173  /** @var PropertyValueBase $item */
174  foreach ($this->collection as $item)
175  {
176  $property = $item->getPropertyObject();
177  if ($property->getField($name) === 'Y')
178  {
179  return $item;
180  }
181  }
182 
183  return null;
184  }
185 
186  /**
187  * @return PropertyValueBase
188  * @throws ArgumentOutOfRangeException
189  */
190  public function getUserEmail()
191  {
192  return $this->getAttribute('IS_EMAIL');
193  }
194 
195  /**
196  * @return PropertyValueBase
197  * @throws ArgumentOutOfRangeException
198  */
199  public function getPayerName()
200  {
201  return $this->getAttribute('IS_PAYER');
202  }
203 
204  /**
205  * @return PropertyValueBase
206  * @throws ArgumentOutOfRangeException
207  */
208  public function getDeliveryLocation()
209  {
210  return $this->getAttribute('IS_LOCATION');
211  }
212 
213  /**
214  * @return PropertyValueBase
215  * @throws ArgumentOutOfRangeException
216  */
217  public function getTaxLocation()
218  {
219  return $this->getAttribute('IS_LOCATION4TAX');
220  }
221 
222  /**
223  * @return PropertyValueBase
224  * @throws ArgumentOutOfRangeException
225  */
226  public function getProfileName()
227  {
228  return $this->getAttribute('IS_PROFILE_NAME');
229  }
230 
231  /**
232  * @return PropertyValueBase
233  * @throws ArgumentOutOfRangeException
234  */
235  public function getDeliveryLocationZip()
236  {
237  return $this->getAttribute('IS_ZIP');
238  }
239 
240  /**
241  * @return PropertyValueBase
242  * @throws ArgumentOutOfRangeException
243  */
244  public function getPhone()
245  {
246  return $this->getAttribute('IS_PHONE');
247  }
248 
249  /**
250  * @return PropertyValueBase
251  * @throws ArgumentOutOfRangeException
252  */
253  public function getAddress()
254  {
255  return $this->getAttribute('IS_ADDRESS');
256  }
257 
258  /**
259  * @param $post
260  * @param $files
261  * @return Result
262  * @throws ArgumentOutOfRangeException
263  * @throws Main\NotImplementedException
264  */
265  public function setValuesFromPost($post, $files)
266  {
267  $post = Input\File::getPostWithFiles($post, $files);
268 
269  $result = new Result();
270 
271  /** @var PropertyValueBase $property */
272  foreach ($this->collection as $property)
273  {
274  $r = $property->setValueFromPost($post);
275  if (!$r->isSuccess())
276  {
277  $result->addErrors($r->getErrors());
278  }
279  }
280 
281  return $result;
282  }
283 
284  /**
285  * @param $fields
286  * @param $files
287  * @param bool $skipUtils
288  * @return Result
289  * @throws Main\SystemException
290  */
291  public function checkErrors($fields, $files, $skipUtils = false)
292  {
293  $result = new Result();
294 
295  $fields = Input\File::getPostWithFiles($fields, $files);
296 
297  /** @var PropertyValueBase $propertyValue */
298  foreach ($this->collection as $propertyValue)
299  {
300  if ($skipUtils && $propertyValue->isUtil())
301  {
302  continue;
303  }
304 
305  if ($propertyValue->getField('ORDER_PROPS_ID') > 0)
306  {
307  $key = $propertyValue->getField('ORDER_PROPS_ID');
308  }
309  else
310  {
311  $key = "n".$propertyValue->getInternalIndex();
312  }
313 
314  $value = isset($fields['PROPERTIES'][$key]) ? $fields['PROPERTIES'][$key] : null;
315 
316  if (!isset($fields['PROPERTIES'][$key]))
317  {
318  $value = $propertyValue->getValue();
319  }
320 
321  $r = $propertyValue->checkValue($key, $value);
322  if (!$r->isSuccess())
323  {
324  $result->addErrors($r->getErrors());
325  }
326  }
327 
328  return $result;
329  }
330 
331  /**
332  * @param array $rules
333  * @param array $fields
334  *
335  * @return Result
336  */
337  public function checkRequired(array $rules, array $fields)
338  {
339  $result = new Result();
340 
341  /** @var PropertyValueBase $propertyValue */
342  foreach ($this->collection as $propertyValue)
343  {
344  if ($propertyValue->getField('ORDER_PROPS_ID') > 0)
345  {
346  $key = $propertyValue->getField('ORDER_PROPS_ID');
347  }
348  else
349  {
350  $key = "n".$propertyValue->getInternalIndex();
351  }
352 
353  if (!in_array($key, $rules))
354  {
355  continue;
356  }
357 
358  $value = isset($fields['PROPERTIES'][$key]) ? $fields['PROPERTIES'][$key] : null;
359  if (!isset($fields['PROPERTIES'][$key]))
360  {
361  $value = $propertyValue->getValue();
362  }
363 
364  $r = $propertyValue->checkRequiredValue($key, $value);
365  if (!$r->isSuccess())
366  {
367  $result->addErrors($r->getErrors());
368  }
369  }
370 
371  return $result;
372  }
373 
374  /**
375  * @return array|null
376  * @throws Main\ArgumentException
377  * @throws Main\ObjectPropertyException
378  * @throws Main\SystemException
379  */
380  public function getGroups()
381  {
382  $result = [];
383 
384  /** @var PropertyValueBase $propertyValue */
385  foreach ($this->collection as $propertyValue)
386  {
387  $property = $propertyValue->getPropertyObject();
388  $group = $property->getGroupInfo();
389  if (!isset($result[$group['ID']]))
390  {
391  $result[$group['ID']] = $group;
392  }
393  }
394 
395  return $result;
396  }
397 
398  /**
399  * @param $groupId
400  * @return array
401  * @throws Main\ArgumentException
402  * @throws Main\ObjectPropertyException
403  * @throws Main\SystemException
404  */
405  public function getPropertiesByGroupId($groupId)
406  {
407  $result = [];
408 
409  $groups = $this->getGroups();
410 
411  /** @var PropertyValueBase $propertyValue */
412  foreach ($this->collection as $propertyValue)
413  {
414  $property = $propertyValue->getPropertyObject();
415  if (!$property)
416  {
417  continue;
418  }
419 
420  $propertyGroupId = (int)$property->getGroupId();
421  if (!isset($groups[$propertyGroupId]))
422  {
423  $propertyGroupId = 0;
424  }
425 
426  if ($propertyGroupId === (int)$groupId)
427  {
428  $result[] = $propertyValue;
429  }
430  }
431 
432  return $result;
433  }
434 
435  /**
436  * @return array
437  * @throws Main\ArgumentException
438  * @throws Main\ObjectPropertyException
439  * @throws Main\SystemException
440  */
441  public function getArray()
442  {
443  $groups = $this->getGroups();
444 
445  $properties = array();
446 
447  /** @var PropertyValueBase $propertyValue */
448  foreach ($this->collection as $propertyValue)
449  {
450  $p = $propertyValue->getProperty();
451 
452  if (!isset($p["ID"]))
453  {
454  if ($propertyValue->getField("ORDER_PROPS_ID") > 0)
455  {
456  $p["ID"] = $propertyValue->getField('ORDER_PROPS_ID');
457  }
458  else
459  {
460  $p["ID"] = "n".$propertyValue->getInternalIndex();
461  }
462  }
463 
464  $value = $propertyValue->getValue();
465 
466  $value = $propertyValue->getValueId() ? $value : ($value ? $value : $p['DEFAULT_VALUE']);
467 
468  $value = array_values(Input\Manager::asMultiple($p, $value));
469 
470  $p['VALUE'] = $value;
471 
472  $properties[] = $p;
473  }
474 
475  return array('groups' => $groups, 'properties' => $properties);
476  }
477 
478  /**
479  * @param $orderPropertyId
480  * @return PropertyValueBase|null
481  */
482  public function getItemByOrderPropertyId($orderPropertyId)
483  {
484  /** @var PropertyValueBase $propertyValue */
485  foreach ($this->collection as $propertyValue)
486  {
487  if ($propertyValue->getField('ORDER_PROPS_ID') == $orderPropertyId)
488  {
489  return $propertyValue;
490  }
491  }
492 
493  return null;
494  }
495 
496  /**
497  * @param string $propertyCode
498  * @return PropertyValueBase[]
499  */
500  public function getItemsByOrderPropertyCode(string $propertyCode)
501  {
502  return $this->getItemsByFilter(
503  function ($propertyValue) use ($propertyCode)
504  {
505  return (
506  $propertyValue->getField('CODE') == $propertyCode
507  );
508  }
509  );
510  }
511 
512  /**
513  * @param string $propertyCode
514  * @return PropertyValueBase|null
515  */
516  public function getItemByOrderPropertyCode(string $propertyCode)
517  {
518  $items = $this->getItemsByOrderPropertyCode($propertyCode);
519 
520  return empty($items) ? null : current($items);
521  }
522 
523  /**
524  * @param callable $filter
525  * @return PropertyValueBase[]
526  */
527  public function getItemsByFilter(callable $filter)
528  {
529  $results = [];
530 
531  /** @var PropertyValueBase $propertyValue */
532  foreach ($this->collection as $propertyValue)
533  {
534  if (!$filter($propertyValue))
535  {
536  continue;
537  }
538 
539  $results[] = $propertyValue;
540  }
541 
542  return $results;
543  }
544 
545  /**
546  * @return Result
547  * @throws Main\ObjectNotFoundException
548  */
549  public function verify()
550  {
551  $result = new Result();
552 
553  /** @var PropertyValueBase $propertyValue */
554  foreach ($this->collection as $propertyValue)
555  {
556  $r = $propertyValue->verify();
557  if (!$r->isSuccess())
558  {
559  $result->addErrors($r->getErrors());
560  }
561  }
562 
563  return $result;
564  }
565 
566  /**
567  * @return Result
568  * @throws Main\ArgumentException
569  * @throws Main\ObjectNotFoundException
570  * @throws \Exception
571  */
572  public function save()
573  {
574  $result = new Result();
575 
576  if (!$this->isChanged())
577  {
578  return $result;
579  }
580 
581  $itemsFromDb = $this->getOriginalItemsValues();
582  foreach ($itemsFromDb as $k => $v)
583  {
584  if ($this->getItemById($k))
585  {
586  continue;
587  }
588 
590 
591  $r = self::delete($v);
592  if (!$r->isSuccess())
593  {
594  $result->addErrors($r->getErrors());
595  }
596 
598  }
599 
600  /** @var PropertyValue $property */
601  foreach ($this->collection as $property)
602  {
603  $r = $property->save();
604  if (!$r->isSuccess())
605  {
606  $result->addErrors($r->getErrors());
607  }
608  }
609 
610  return $result;
611  }
612 
613  /**
614  * @param $values
615  * @throws Main\NotImplementedException
616  */
617  protected function callEventOnSalePropertyValueDeleted($values)
618  {
619  $values['ENTITY_REGISTRY_TYPE'] = static::getRegistryType();
620 
621  /** @var Main\Event $event */
622  $event = new Main\Event(
623  'sale',
624  'OnSalePropertyValueDeleted',
625  array('VALUES' => $values)
626  );
627 
628  $event->send();
629  }
630 
631  /**
632  * @param $values
633  * @throws Main\NotImplementedException
634  */
635  protected function callEventOnBeforeSalePropertyValueDeleted($values)
636  {
637  $values['ENTITY_REGISTRY_TYPE'] = static::getRegistryType();
638 
639  /** @var Main\Event $event */
640  $event = new Main\Event(
641  'sale',
642  'OnBeforeSalePropertyValueDeleted',
643  array('VALUES' => $values)
644  );
645 
646  $event->send();
647  }
648 
649  /**
650  * @return array
651  * @throws Main\NotImplementedException
652  * @throws Main\ObjectNotFoundException
653  */
654  private function getOriginalItemsValues()
655  {
656  /** @var Order $order */
657  if (!$order = $this->getOrder())
658  {
659  throw new Main\ObjectNotFoundException('Entity "Order" not found');
660  }
661 
662  $itemsFromDb = array();
663  if ($order->getId() > 0)
664  {
665  $itemsFromDbList = static::getList(
666  array(
667  "filter" => array("ORDER_ID" => $this->getOrder()->getId()),
668  "select" => array("ID", "NAME", "CODE", "VALUE", "ORDER_PROPS_ID")
669  )
670  );
671  while ($itemsFromDbItem = $itemsFromDbList->fetch())
672  $itemsFromDb[$itemsFromDbItem["ID"]] = $itemsFromDbItem;
673  }
674 
675  return $itemsFromDb;
676  }
677 
678  /**
679  * @param $primary
680  * @throws Main\NotImplementedException
681  * @return Entity\DeleteResult
682  */
683  protected static function deleteInternal($primary)
684  {
685  throw new Main\NotImplementedException();
686  }
687 
688  /**
689  * @param array $parameters
690  * @throws Main\NotImplementedException
691  * @return Main\DB\Result
692  */
693  public static function getList(array $parameters = array())
694  {
695  throw new Main\NotImplementedException();
696  }
697 
698  /**
699  * @internal
700  *
701  * @param $idOrder
702  * @return Result
703  * @throws Main\ArgumentException
704  * @throws Main\NotImplementedException
705  */
706  public static function deleteNoDemand($idOrder)
707  {
708  $result = new Result();
709 
710  $propertiesDataList = static::getList(
711  array(
712  "filter" => array('=ORDER_ID' => $idOrder),
713  "select" => array('ID', 'ORDER_PROPS_ID')
714  )
715  );
716 
717  while ($propertyValue = $propertiesDataList->fetch())
718  {
719  $r = self::delete($propertyValue);
720  if (!$r->isSuccess())
721  {
722  $result->addErrors($r->getErrors());
723  }
724  }
725 
726  return $result;
727  }
728 
729  /**
730  * @param $value
731  * @return Result
732  * @throws Main\ArgumentException
733  * @throws Main\NotImplementedException
734  */
735  private static function delete(array $value)
736  {
737  $result = new Result();
738 
739  $r = static::deleteInternal($value['ID']);
740 
741  if ($r->isSuccess())
742  {
743  $registry = Registry::getInstance(static::getRegistryType());
744 
745  $propertyClass = $registry->getPropertyClassName();
746  /** @var PropertyBase $property */
747  $property = $propertyClass::getObjectById($value['ORDER_PROPS_ID']);
748  if ($property)
749  {
750  $property->onValueDelete($value['VALUE']);
751  }
752  }
753  else
754  {
755  $result->addErrors($r->getErrors());
756  }
757 
758  return $result;
759  }
760 
761  /**
762  * @internal
763  *
764  * @throws ArgumentOutOfRangeException
765  * @throws Main\ArgumentException
766  * @throws Main\ArgumentTypeException
767  * @throws Main\NotImplementedException
768  * @throws Main\ObjectNotFoundException
769  * @throws Main\ObjectPropertyException
770  * @throws Main\SystemException
771  */
772  public function refreshRelated()
773  {
774  $registry = Registry::getInstance(static::getRegistryType());
775 
776  /** @var PropertyValueBase $propertyValueClassName */
777  $propertyValueClassName = $registry->getPropertyValueClassName();
778 
779  $props = $propertyValueClassName::loadForOrder($this->getOrder());
780 
781  /** @var PropertyValueBase $propertyValue */
782  foreach ($this->collection as $propertyValue)
783  {
784  $property = $propertyValue->getPropertyObject();
785  if (!$property->getRelations())
786  {
787  continue;
788  }
789 
790  if ($propertyValue->getId() <= 0
791  && !isset($props[$propertyValue->getPropertyId()])
792  )
793  {
794  $propertyValue->delete();
795  }
796  }
797 
798  /** @var PropertyValueBase $propertyValue */
799  foreach ($props as $propertyValue)
800  {
801  $property = $propertyValue->getPropertyObject();
802  if (!$property->getRelations())
803  {
804  continue;
805  }
806 
807  if (!$this->getItemByOrderPropertyId($propertyValue->getPropertyId()))
808  {
809  $propertyValue->setCollection($this);
810  $this->addItem($propertyValue);
811  }
812  }
813  }
814 
815  /**
816  * @deprecated
817  * @use \Bitrix\Sale\PropertyValueCollectionBase::getPropertiesByGroupId
818  *
819  * @param $groupId
820  * @return array
821  * @throws Main\ArgumentException
822  * @throws Main\ObjectPropertyException
823  * @throws Main\SystemException
824  */
825  public function getGroupProperties($groupId)
826  {
827  return $this->getPropertiesByGroupId($groupId);
828  }
829 }
Exception is thrown when the value of an argument is outside the allowable range of values.
static loadMessages($file)
Loads language messages for specified file in a lazy way.
Definition: loc.php:67
Exception is thrown when operation is not implemented but should be.
Exception is thrown when operation is not supported.
Exception is thrown when an object is not present.
current()
Return the current element.
addItem(Internals\CollectableEntity $property)
checkErrors($fields, $files, $skipUtils=false)
onItemModify(Internals\CollectableEntity $item, $name=null, $oldValue=null, $value=null)