1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
product.php
См. документацию.
1<?php
2
3namespace Bitrix\Catalog\RestView;
4
5use Bitrix\Catalog;
6use Bitrix\Catalog\ProductTable;
7use Bitrix\Iblock;
8use Bitrix\Iblock\PropertyTable;
9use Bitrix\Main\Config\Option;
10use Bitrix\Main\Engine\Response\Converter;
11use Bitrix\Main\Error;
12use Bitrix\Main\Localization\Loc;
13use Bitrix\Main\ORM\Fields\ScalarField;
14use Bitrix\Main\Result;
15use Bitrix\Main\Type\Date;
16use Bitrix\Main\Type\DateTime;
17use Bitrix\Rest\Integration\View\Attributes;
18use Bitrix\Rest\Integration\View\Base;
19use Bitrix\Rest\Integration\View\DataType;
20
21final class Product extends Base
22{
23 public const BOOLEAN_VALUE_YES = 'Y';
24 public const BOOLEAN_VALUE_NO = 'N';
25 private array $productFieldNames = [];
26
31 public function getFields(): array
32 {
33 $this->loadFieldNames();
34
35 return array_merge($this->getFieldsIBlockElement(), $this->getFieldsCatalogProduct());
36 }
37
43 protected function prepareFieldAttributs($info, $attributs): array
44 {
46 parent::prepareFieldAttributs($info, $attributs),
47 $info,
48 $attributs
49 );
50 }
51
55 private function getFieldsIBlockElement(): array
56 {
57 $fieldList = [
58 'ID' => [
59 'TYPE' => DataType::TYPE_INT,
60 'ATTRIBUTES' => [
61 Attributes::READONLY,
62 ],
63 ],
64 'CREATED_BY' => [
65 'TYPE' => DataType::TYPE_INT,
66 ],
67 'DATE_CREATE' => [
68 'TYPE' => DataType::TYPE_DATETIME,
69 ],
70 'MODIFIED_BY' => [
71 'TYPE' => DataType::TYPE_INT,
72 ],
73 'TIMESTAMP_X' => [
74 'TYPE' => DataType::TYPE_DATETIME,
75 'ATTRIBUTES' => [
76 Attributes::READONLY,
77 ],
78 ],
79 'ACTIVE' => [
80 'TYPE' => DataType::TYPE_CHAR,
81 ],
82 'DATE_ACTIVE_FROM' => [
83 'TYPE' => DataType::TYPE_DATETIME,
84 ],
85 'DATE_ACTIVE_TO' => [
86 'TYPE' => DataType::TYPE_DATETIME,
87 ],
88 'NAME' => [
89 'TYPE' => DataType::TYPE_STRING,
90 'ATTRIBUTES' => [
91 Attributes::REQUIRED_ADD,
92 ],
93 ],
94 'CODE' => [
95 'TYPE' => DataType::TYPE_STRING,
96 ],
97 'SORT' => [
98 'TYPE' => DataType::TYPE_INT,
99 ],
100 'PREVIEW_TEXT' => [
101 'TYPE' => DataType::TYPE_STRING,
102 ],
103 'PREVIEW_TEXT_TYPE' => [
104 'TYPE' => DataType::TYPE_STRING,
105 ],
106 'PREVIEW_PICTURE' => [
107 'TYPE' => DataType::TYPE_FILE,
108 ],
109 'DETAIL_TEXT' => [
110 'TYPE' => DataType::TYPE_STRING,
111 ],
112 'DETAIL_TEXT_TYPE' => [
113 'TYPE' => DataType::TYPE_STRING,
114 ],
115 'DETAIL_PICTURE' => [
116 'TYPE' => DataType::TYPE_FILE,
117 ],
118 'IBLOCK_ID' => [
119 'TYPE' => DataType::TYPE_INT,
120 'ATTRIBUTES' => [
121 Attributes::REQUIRED,
122 Attributes::IMMUTABLE,
123 ],
124 ],
125 'IBLOCK_SECTION_ID' => [
126 'TYPE' => DataType::TYPE_INT,
127 ],
128 'IBLOCK_SECTION' => [
129 'TYPE' => DataType::TYPE_LIST,
130 ],
131 'XML_ID' => [
132 'TYPE' => DataType::TYPE_STRING,
133 ],
134 ];
135
136 return $this->fillFieldNames($fieldList);
137 }
138
143 private function getFieldsIBlockPropertyValuesByFilter(array $filter): Result
144 {
145 $result = new Result();
146 $fieldsInfo = [];
147
148 $iblockId = (int)($filter['IBLOCK_ID'] ?? 0);
149
150 if ($iblockId <= 0)
151 {
152 $result->addError(new Error('parameter - iblockId is empty'));
153 }
154
155 if ($result->isSuccess())
156 {
157 $catalogInfo = \CCatalogSku::GetInfoByOfferIBlock($iblockId);
158 $skuPropertyId = $catalogInfo['SKU_PROPERTY_ID'] ?? null;
159 unset($catalogInfo);
160
161 $allowedTypes = array_fill_keys(self::getUserType(), true);
162
163 $cache = [
164 'ttl' => 86400,
165 ];
166
167 $iterator = PropertyTable::getList([
168 'select' => [
169 'ID',
170 'IBLOCK_ID',
171 'NAME',
172 'SORT',
173 'PROPERTY_TYPE',
174 'LIST_TYPE',
175 'MULTIPLE',
176 'LINK_IBLOCK_ID',
177 'IS_REQUIRED',
178 'USER_TYPE',
179 ],
180 'filter' => [
181 '=IBLOCK_ID' => $iblockId,
182 '=ACTIVE' => 'Y',
183 ],
184 'order' => [
185 'SORT' => 'ASC',
186 'ID' => 'ASC',
187 ],
188 'cache' => $cache,
189 ]);
190 while ($property = $iterator->fetch())
191 {
192 $property['ID'] = (int)$property['ID'];
193 $userType = (string)$property['USER_TYPE'];
194 if (
195 $userType !== ''
196 && !isset($allowedTypes[$property['PROPERTY_TYPE'] . ':' . $userType])
197 )
198 {
199 continue;
200 }
201
202 $info = [
203 'TYPE' => EntityFieldType::PRODUCT_PROPERTY,
204 'PROPERTY_TYPE' => $property['PROPERTY_TYPE'],
205 'USER_TYPE' => $property['USER_TYPE'],
206 'ATTRIBUTES' => [Attributes::DYNAMIC],
207 'NAME' => $property['NAME'],
208 ];
209
210 if ($property['MULTIPLE'] === 'Y')
211 {
212 $info['ATTRIBUTES'][] = Attributes::MULTIPLE;
213 }
214 if ($property['IS_REQUIRED'] === 'Y')
215 {
216 $info['ATTRIBUTES'][] = Attributes::REQUIRED;
217 }
218
219 if (
220 $property['PROPERTY_TYPE'] === PropertyTable::TYPE_LIST
221 && $userType === ''
222 && $property['MULTIPLE'] === 'N'
223 )
224 {
225 $enumFilter = [
226 '=PROPERTY_ID' => $property['ID'],
227 ];
228 if (Iblock\PropertyEnumerationTable::getCount($enumFilter, $cache) === 1)
229 {
230 $variant = Iblock\PropertyEnumerationTable::getRow([
231 'select' => [
232 'ID',
233 'PROPERTY_ID',
234 'VALUE',
235 ],
236 'filter' => $enumFilter,
237 'cache' => $cache,
238 ]);
239 $info['BOOLEAN_VALUE_YES'] = [
240 'ID' => $variant['ID'],
241 'VALUE' => $variant['VALUE'],
242 ];
243 }
244 }
245
246 if ($this->isPropertyBoolean($info))
247 {
248 $info['USER_TYPE'] = Catalog\Controller\Enum::PROPERTY_USER_TYPE_BOOL_ENUM;
249 }
250
251 $canonicalName = 'PROPERTY_' . $property['ID'];
252 if ($property['ID'] === $skuPropertyId)
253 {
254 $info['CANONICAL_NAME'] = $canonicalName;
255 $fieldsInfo['PARENT_ID'] = $info;
256 }
257 else
258 {
259 $fieldsInfo[$canonicalName] = $info;
260 }
261 unset($canonicalName);
262 }
263 unset($property, $iterator);
264
265 $fieldsInfo['PROPERTY_*'] = [
266 'TYPE' => EntityFieldType::PRODUCT_PROPERTY,
267 'ATTRIBUTES' => [
268 Attributes::READONLY,
269 Attributes::DYNAMIC,
270 ],
271 ];
272
273 $result->setData($fieldsInfo);
274 }
275
276 return $result;
277 }
278
282 private function getFieldsCatalogProductCommonFields(): array
283 {
284 $fieldList = [
285 'ID' => [
286 'TYPE' => DataType::TYPE_INT,
287 'ATTRIBUTES' => [
288 Attributes::READONLY,
289 ],
290 ],
291 'TIMESTAMP_X' => [
292 'TYPE' => DataType::TYPE_DATETIME,
293 ],
294 'PRICE_TYPE' => [
295 'TYPE' => DataType::TYPE_CHAR,
296 ],
297 'TYPE' => [
298 'TYPE' => DataType::TYPE_INT,
299 'ATTRIBUTES' => [
300 Attributes::READONLY,
301 ],
302 ],
303 'BUNDLE' => [
304 'TYPE' => DataType::TYPE_CHAR,
305 'ATTRIBUTES' => [
306 Attributes::READONLY,
307 ],
308 ],
309 ];
310
311 return $this->fillFieldNames($fieldList);
312 }
313
314 public function isAllowedProductTypeByIBlockId($productTypeId, $iblockId): Result
315 {
317 if (!$result->isSuccess())
318 {
319 return $result;
320 }
321
322 $iblockData = $result->getData();
323
324 $allowedTypes = self::getProductTypes($iblockData['CATALOG_TYPE']);
325
326 if (!isset($allowedTypes[$productTypeId]))
327 {
328 $result->addError(new Error('productType is not allowed for this catalog'));
329 }
330
331 return $result;
332 }
333
341 {
342 $result = new Result();
343
344 $iblockData = \CCatalogSku::GetInfoByIBlock($iblockId);
345 if (empty($iblockData))
346 {
347 $result->addError(new Error('iblock is not catalog'));
348 }
349 else
350 {
351 $result->setData($iblockData);
352 }
353
354 return $result;
355 }
356
361 private function getFieldsCatalogProductByFilter(array $filter): Result
362 {
363 $result = new Result();
364
365 $iblockId = (int)($filter['IBLOCK_ID'] ?? 0);
366 $productTypeId = (int)($filter['PRODUCT_TYPE'] ?? 0);
367
368 if ($iblockId <= 0)
369 {
370 $result->addError(new Error('parameter - iblockId is empty'));
371 }
372
373 if ($productTypeId <= 0)
374 {
375 $result->addError(new Error('parameter - productType is empty'));
376 }
377
378 if ($result->isSuccess())
379 {
380 $r = $this->isAllowedProductTypeByIBlockId($productTypeId, $iblockId);
381 if ($r->isSuccess())
382 {
383 $result->setData($this->getFieldsCatalogProductByType($productTypeId));
384 }
385 else
386 {
387 $result->addErrors($r->getErrors());
388 }
389 }
390
391 return $result;
392 }
393
397 private function getFieldsCatalogProduct(): array
398 {
399 $fieldList = [
400 'TYPE' => [
401 'TYPE' => DataType::TYPE_INT,
402 'ATTRIBUTES' => [
403 Attributes::READONLY,
404 ],
405 ],
406 'AVAILABLE' => [
407 'TYPE' => DataType::TYPE_CHAR,
408 'ATTRIBUTES' => [
409 Attributes::READONLY,
410 ],
411 ],
412 'BUNDLE' => [
413 'TYPE' => DataType::TYPE_CHAR,
414 'ATTRIBUTES' => [
415 Attributes::READONLY,
416 ],
417 ],
418 'QUANTITY' => [
419 'TYPE' => DataType::TYPE_FLOAT,
420 ],
421 'QUANTITY_RESERVED' => [
422 'TYPE' => DataType::TYPE_FLOAT,
423 ],
424 'QUANTITY_TRACE' => [
425 'TYPE' => DataType::TYPE_CHAR,
426 ],
427 'CAN_BUY_ZERO' => [
428 'TYPE' => DataType::TYPE_CHAR,
429 ],
430 'SUBSCRIBE' => [
431 'TYPE' => DataType::TYPE_CHAR,
432 ],
433 'VAT_ID' => [
434 'TYPE' => DataType::TYPE_INT,
435 ],
436 'VAT_INCLUDED' => [
437 'TYPE' => DataType::TYPE_CHAR,
438 ],
439 'PURCHASING_PRICE' => [
440 'TYPE' => DataType::TYPE_FLOAT,
441 ],
442 'PURCHASING_CURRENCY' => [
443 'TYPE' => DataType::TYPE_STRING,
444 ],
445 'BARCODE_MULTI' => [
446 'TYPE' => DataType::TYPE_CHAR,
447 ],
448 'WEIGHT' => [
449 'TYPE' => DataType::TYPE_FLOAT,
450 ],
451 'LENGTH' => [
452 'TYPE' => DataType::TYPE_FLOAT,
453 ],
454 'WIDTH' => [
455 'TYPE' => DataType::TYPE_FLOAT,
456 ],
457 'HEIGHT' => [
458 'TYPE' => DataType::TYPE_FLOAT,
459 ],
460 'MEASURE' => [
461 'TYPE' => DataType::TYPE_INT,
462 ],
463 'RECUR_SCHEME_LENGTH' => [
464 'TYPE' => DataType::TYPE_INT,
465 ],
466 'RECUR_SCHEME_TYPE' => [
467 'TYPE' => DataType::TYPE_CHAR,
468 ],
469 'TRIAL_PRICE_ID' => [
470 'TYPE' => DataType::TYPE_INT,
471 ],
472 'WITHOUT_ORDER' => [
473 'TYPE' => DataType::TYPE_CHAR,
474 ],
475 ];
476
477 if (Catalog\Config\State::isUsedInventoryManagement())
478 {
479 $lockFields = [
480 'QUANTITY',
481 'QUANTITY_RESERVED',
482 'PURCHASING_PRICE',
483 'PURCHASING_CURRENCY',
484 ];
485
486 foreach ($lockFields as $fieldName)
487 {
488 if (!isset($fieldList[$fieldName]['ATTRIBUTES']))
489 {
490 $fieldList[$fieldName]['ATTRIBUTES'] = [
491 Attributes::READONLY,
492 ];
493 }
494 else
495 {
496 $fieldList[$fieldName]['ATTRIBUTES'][] = Attributes::READONLY;
497 $fieldList[$fieldName]['ATTRIBUTES'] = array_unique($fieldList[$fieldName]['ATTRIBUTES']);
498 }
499 }
500 }
501
502 return $this->fillFieldNames($fieldList);
503 }
504
509 private function getFieldsCatalogProductByType(int $id): array
510 {
511 return match ($id)
512 {
513 ProductTable::TYPE_SERVICE => $this->getFieldsCatalogProductByTypeService(),
514 ProductTable::TYPE_PRODUCT => $this->getFieldsCatalogProductByTypeProduct(),
515 ProductTable::TYPE_SET => $this->getFieldsCatalogProductByTypeSet(),
516 ProductTable::TYPE_SKU, ProductTable::TYPE_EMPTY_SKU => $this->getFieldsCatalogProductByTypeSKU(),
517 ProductTable::TYPE_OFFER, ProductTable::TYPE_FREE_OFFER => $this->getFieldsCatalogProductByTypeOffer(),
518 default => [],
519 };
520 }
521
525 private function getFieldsCatalogProductByTypeService(): array
526 {
527 $fieldList = [
528 'AVAILABLE' => [
529 'TYPE' => DataType::TYPE_CHAR,
530 ],
531 'MEASURE' => [
532 'TYPE' => DataType::TYPE_INT,
533 ],
534 'VAT_ID' => [
535 'TYPE' => DataType::TYPE_INT,
536 ],
537 'VAT_INCLUDED' => [
538 'TYPE' => DataType::TYPE_CHAR,
539 ],
540 ];
541
542 return $this->fillFieldNames($fieldList);
543 }
544
548 private function getFieldsCatalogProductByTypeProduct(): array
549 {
550 $fieldList = [
551 'AVAILABLE' => [
552 'TYPE' => DataType::TYPE_CHAR,
553 'ATTRIBUTES' => [
554 Attributes::READONLY,
555 ],
556 ],
557 'PURCHASING_PRICE' => [
558 'TYPE' => DataType::TYPE_STRING,
559 ],
560 'PURCHASING_CURRENCY' => [
561 'TYPE' => DataType::TYPE_STRING,
562 ],
563 'VAT_ID' => [
564 'TYPE' => DataType::TYPE_INT,
565 ],
566 'VAT_INCLUDED' => [
567 'TYPE' => DataType::TYPE_CHAR,
568 ],
569 'QUANTITY' => [
570 'TYPE' => DataType::TYPE_FLOAT,
571 ],
572 'QUANTITY_RESERVED' => [
573 'TYPE' => DataType::TYPE_FLOAT,
574 ],
575 'MEASURE' => [
576 'TYPE' => DataType::TYPE_INT,
577 ],
578 'QUANTITY_TRACE' => [
579 'TYPE' => DataType::TYPE_CHAR,
580 ],
581 'CAN_BUY_ZERO' => [
582 'TYPE' => DataType::TYPE_CHAR,
583 ],
584 'NEGATIVE_AMOUNT_TRACE' => [
585 'TYPE' => DataType::TYPE_CHAR,
586 'ATTRIBUTES' => [
587 Attributes::READONLY,
588 ],
589 ],
590 'SUBSCRIBE' => [
591 'TYPE' => DataType::TYPE_CHAR,
592 ],
593 'WEIGHT' => [
594 'TYPE' => DataType::TYPE_FLOAT,
595 ],
596 'LENGTH' => [
597 'TYPE' => DataType::TYPE_FLOAT,
598 ],
599 'WIDTH' => [
600 'TYPE' => DataType::TYPE_FLOAT,
601 ],
602 'HEIGHT' => [
603 'TYPE' => DataType::TYPE_FLOAT,
604 ],
605 'BARCODE_MULTI' => [
606 'TYPE' => DataType::TYPE_CHAR,
607 ],
608 'RECUR_SCHEME_LENGTH' => [
609 'TYPE' => DataType::TYPE_INT,
610 ],
611 'RECUR_SCHEME_TYPE' => [
612 'TYPE' => DataType::TYPE_CHAR,
613 ],
614 'TRIAL_PRICE_ID' => [
615 'TYPE' => DataType::TYPE_INT,
616 ],
617 'WITHOUT_ORDER' => [
618 'TYPE' => DataType::TYPE_CHAR,
619 ],
620 ];
621
622 return $this->fillFieldNames($fieldList);
623 }
624
628 private function getFieldsCatalogProductByTypeSKU(): array
629 {
630 $fieldList = [
631 'AVAILABLE' => [
632 'TYPE' => DataType::TYPE_CHAR,
633 'ATTRIBUTES' => [
634 Attributes::READONLY,
635 ],
636 ],
637 ];
638
639 if (Option::get('catalog', 'show_catalog_tab_with_offers') === 'Y')
640 {
641 $fieldListCatalogTabWithOffers = [
642 'PURCHASING_PRICE' => [
643 'TYPE' => DataType::TYPE_STRING,
644 ],
645 'PURCHASING_CURRENCY' => [
646 'TYPE' => DataType::TYPE_STRING,
647 ],
648 'VAT_ID' => [
649 'TYPE' => DataType::TYPE_INT,
650 ],
651 'VAT_INCLUDED' => [
652 'TYPE' => DataType::TYPE_CHAR,
653 ],
654 'QUANTITY' => [
655 'TYPE' => DataType::TYPE_FLOAT,
656 ],
657 'MEASURE' => [
658 'TYPE' => DataType::TYPE_INT,
659 ],
660 'CAN_BUY_ZERO' => [
661 'TYPE' => DataType::TYPE_CHAR,
662 ],
663 'SUBSCRIBE' => [
664 'TYPE' => DataType::TYPE_CHAR,
665 ],
666 'WEIGHT' => [
667 'TYPE' => DataType::TYPE_FLOAT,
668 ],
669 'LENGTH' => [
670 'TYPE' => DataType::TYPE_FLOAT,
671 ],
672 'WIDTH' => [
673 'TYPE' => DataType::TYPE_FLOAT,
674 ],
675 'HEIGHT' => [
676 'TYPE' => DataType::TYPE_FLOAT,
677 ],
678 ];
679 $fieldList = array_merge($fieldList, $fieldListCatalogTabWithOffers);
680 }
681
682 return $this->fillFieldNames($fieldList);
683 }
684
688 private function getFieldsCatalogProductByTypeOffer(): array
689 {
690 return $this->getFieldsCatalogProductByTypeProduct();
691 }
692
696 private function getFieldsCatalogProductByTypeSet(): array
697 {
698 $fieldList = [
699 'AVAILABLE' => [
700 'TYPE' => DataType::TYPE_CHAR,
701 'ATTRIBUTES' => [
702 Attributes::READONLY,
703 ],
704 ],
705 'PURCHASING_PRICE' => [
706 'TYPE' => DataType::TYPE_STRING,
707 ],
708 'PURCHASING_CURRENCY' => [
709 'TYPE' => DataType::TYPE_STRING,
710 ],
711 'VAT_ID' => [
712 'TYPE' => DataType::TYPE_INT,
713 ],
714 'VAT_INCLUDED' => [
715 'TYPE' => DataType::TYPE_CHAR,
716 ],
717 'QUANTITY' => [
718 'TYPE' => DataType::TYPE_FLOAT,
719 'ATTRIBUTES' => [
720 Attributes::READONLY,
721 ],
722 ],
723 'MEASURE' => [
724 'TYPE' => DataType::TYPE_INT,
725 'ATTRIBUTES' => [
726 Attributes::READONLY,
727 ],
728 ],
729 'QUANTITY_TRACE' => [
730 'TYPE' => DataType::TYPE_CHAR,
731 'ATTRIBUTES' => [
732 Attributes::READONLY,
733 ],
734 ],
735 'CAN_BUY_ZERO' => [
736 'TYPE' => DataType::TYPE_CHAR,
737 'ATTRIBUTES' => [
738 Attributes::READONLY,
739 ],
740 ],
741 'NEGATIVE_AMOUNT_TRACE' => [
742 'TYPE' => DataType::TYPE_CHAR,
743 'ATTRIBUTES' => [
744 Attributes::READONLY,
745 ],
746 ],
747 'SUBSCRIBE' => [
748 'TYPE' => DataType::TYPE_CHAR,
749 ],
750 'WEIGHT' => [
751 'TYPE' => DataType::TYPE_FLOAT,
752 'ATTRIBUTES' => [
753 Attributes::READONLY,
754 ],
755 ],
756 'LENGTH' => [
757 'TYPE' => DataType::TYPE_FLOAT,
758 ],
759 'WIDTH' => [
760 'TYPE' => DataType::TYPE_FLOAT,
761 ],
762 'HEIGHT' => [
763 'TYPE' => DataType::TYPE_FLOAT,
764 ],
765 ];
766
767 return $this->fillFieldNames($fieldList);
768 }
769
775 {
776 $result = new Result();
777
778 $iblockId = (int)($filter['IBLOCK_ID'] ?? 0);
779 $productTypeId = (int)($filter['PRODUCT_TYPE'] ?? 0);
780 if ($iblockId <= 0)
781 {
782 $result->addError(new Error('parameter - iblockId is empty'));
783 }
784
785 if ($productTypeId <= 0)
786 {
787 $result->addError(new Error('parameter - productType is empty'));
788 }
789
790 if ($result->isSuccess())
791 {
792 $this->loadFieldNames();
793
794 $r = $this->isAllowedProductTypeByIBlockId($productTypeId, $iblockId);
795 if ($r->isSuccess())
796 {
797 $propertyValues = $this->getFieldsIBlockPropertyValuesByFilter(['IBLOCK_ID' => $iblockId]);
798 $properties = [];
799 if ($propertyValues->isSuccess())
800 {
801 $properties = $propertyValues->getData();
802 unset($properties['PROPERTY_*']);
803 }
804 unset($propertyValues);
805 $result->setData(
806 array_merge(
807 $this->getFieldsIBlockElement(),
808 $properties,
809 $this->getFieldsCatalogProductCommonFields(),
810 $this->getFieldsCatalogProductByType($productTypeId)
811 )
812 );
813 unset($properties);
814 }
815 else
816 {
817 $result->addErrors($r->getErrors());
818 }
819 }
820
821 return $result;
822 }
823
828 private static function getProductTypes($catalogType): array
829 {
830 //TODO: remove after create \Bitrix\Catalog\Model\CatalogIblock
831 return match ($catalogType)
832 {
833 \CCatalogSku::TYPE_CATALOG => [
837 ],
838 \CCatalogSku::TYPE_OFFERS => [
841 ],
842 \CCatalogSku::TYPE_FULL => [
848 ],
849 \CCatalogSku::TYPE_PRODUCT => [
852 ],
853 default => [],
854 };
855 }
856
860 private static function getUserType(): array
861 {
862 return [
863 PropertyTable::TYPE_STRING . ':' . PROPERTYTable::USER_TYPE_DATE,
869 PropertyTable::TYPE_STRING . ':map_yandex',
870 PropertyTable::TYPE_STRING . ':map_google',
871 PropertyTable::TYPE_STRING . ':employee',
873 PropertyTable::TYPE_STRING . ':UserID',
874
876
880
882
883 //TODO: support types
884 //'S:video',
885 //'S:TopicID',
886 //'S:FileMan',
887 //'S:DiskFile',
888 ];
889 }
890
891 public function internalizeFieldsList($arguments, $fieldsInfo = []): array
892 {
893 // param - IBLOCK_ID is reqired in filter
894 $iblockId = (int)($arguments['filter']['IBLOCK_ID'] ?? 0);
895
896 $propertyValues = $this->getFieldsIBlockPropertyValuesByFilter(['IBLOCK_ID' => $iblockId]);
897 $fieldsInfo = array_merge(
898 $this->getFields(),
899 ($propertyValues->isSuccess() ? $propertyValues->getData() : [])
900 );
901 unset($propertyValues);
902
903 return parent::internalizeFieldsList($arguments, $fieldsInfo);
904 }
905
906 public function internalizeFieldsAdd($fields, $fieldsInfo = []): array
907 {
908 // param - IBLOCK_ID is reqired in filter
909 $iblockId = (int)($fields['IBLOCK_ID'] ?? 0);
910 $productType = (int)($fields['TYPE'] ?? 0);
911
912 $propertyValues = $this->getFieldsIBlockPropertyValuesByFilter(['IBLOCK_ID' => $iblockId]);
913 $product = $this->getFieldsCatalogProductByFilter(['IBLOCK_ID' => $iblockId, 'PRODUCT_TYPE' => $productType]);
914
915 if ($product->isSuccess())
916 {
917 $fieldsInfo = array_merge(
918 $this->getFieldsIBlockElement(),
919 ($propertyValues->isSuccess() ? $propertyValues->getData() : []),
920 $this->getFieldsCatalogProductCommonFields(),
921 $product->getData()
922 );
923 }
924 else
925 {
926 $fieldsInfo = array_merge(
927 $this->getFields(),
928 ($propertyValues->isSuccess() ? $propertyValues->getData() : [])
929 );
930 }
931 unset($product, $propertyValues);
932
933 return parent::internalizeFieldsAdd($fields, $fieldsInfo);
934 }
935
936 public function internalizeFieldsUpdate($fields, $fieldsInfo = []): array
937 {
938 // param - IBLOCK_ID is reqired in filter
939 $iblockId = (int)($fields['IBLOCK_ID'] ?? 0);
940 $productType = (int)($fields['TYPE'] ?? 0);
941
942 $propertyValues = $this->getFieldsIBlockPropertyValuesByFilter(['IBLOCK_ID' => $iblockId]);
943 $product = $this->getFieldsCatalogProductByFilter(['IBLOCK_ID' => $iblockId, 'PRODUCT_TYPE' => $productType]);
944
945 if ($product->isSuccess())
946 {
947 $fieldsInfo = array_merge(
948 $this->getFieldsIBlockElement(),
949 ($propertyValues->isSuccess() ? $propertyValues->getData() : []),
950 $this->getFieldsCatalogProductCommonFields(),
951 $product->getData()
952 );
953 }
954 else
955 {
956 $fieldsInfo = array_merge(
957 $this->getFields(),
958 ($propertyValues->isSuccess() ? $propertyValues->getData() : [])
959 );
960 }
961 unset($product, $propertyValues);
962
963 return parent::internalizeFieldsUpdate($fields, $fieldsInfo);
964 }
965
966 protected function internalizeDateValue($value): Result
967 {
968 //API does not accept DataTime objects, so the ISO format is transformed into a format for a filter.
969
970 $r = new Result();
971
972 $date = $this->internalizeDate($value);
973
974 if ($date instanceof Date)
975 {
976 $value = $date->format('d.m.Y');
977 }
978 else
979 {
980 $r->addError(new Error('Wrong type data'));
981 }
982
983 if ($r->isSuccess())
984 {
985 $r->setData([$value]);
986 }
987
988 return $r;
989 }
990
991 protected function internalizeDateTimeValue($value): Result
992 {
993 //API does not accept DataTime objects, so the ISO format is transformed into a format for a filter.
994
995 $r = new Result();
996
997 $date = $this->internalizeDateTime($value);
998 if ($date instanceof DateTime)
999 {
1000 $value = $date->format('d.m.Y H:i:s');
1001 }
1002 else
1003 {
1004 $r->addError(new Error('Wrong type datetime'));
1005 }
1006
1007 if ($r->isSuccess())
1008 {
1009 $r->setData([$value]);
1010 }
1011
1012 return $r;
1013 }
1014
1016 {
1017 //API does not accept DataTime objects, so the ISO format is transformed into a format for a filter.
1018
1019 $r = new Result();
1020
1021 $date = $this->internalizeDate($value);
1022
1023 if ($date instanceof Date)
1024 {
1025 $value = $date->format('Y-m-d');
1026 }
1027 else
1028 {
1029 $r->addError(new Error('Wrong type data'));
1030 }
1031
1032 if ($r->isSuccess())
1033 {
1034 $r->setData([$value]);
1035 }
1036
1037 return $r;
1038 }
1039
1041 {
1042 //API does not accept DataTime objects, so the ISO format is transformed into a format for a filter.
1043
1044 $r = new Result();
1045
1046 $date = $this->internalizeDateTime($value);
1047 if ($date instanceof DateTime)
1048 {
1049 $value = $date->format('Y-m-d H:i:s');
1050 }
1051 else
1052 {
1053 $r->addError(new Error('Wrong type datetime'));
1054 }
1055
1056 if ($r->isSuccess())
1057 {
1058 $r->setData([$value]);
1059 }
1060
1061 return $r;
1062 }
1063
1064 protected function internalizeExtendedTypeValue($value, $info): Result
1065 {
1066 $r = new Result();
1067
1068 $type = $info['TYPE'] ?? '';
1069
1071 {
1072 $propertyType = $info['PROPERTY_TYPE'] ?? '';
1073 $userType = $info['USER_TYPE'] ?? '';
1074
1075 $attrs = $info['ATTRIBUTES'] ?? [];
1076 $isMultiple = in_array(Attributes::MULTIPLE, $attrs, true);
1077
1078 $r = $isMultiple ? $this->checkIndexedMultipleValue($value) : new Result();
1079
1080 if ($r->isSuccess())
1081 {
1082 $value = $isMultiple ? $value : [$value];
1083 if (!is_array($value))
1084 {
1085 $value = [$value];
1086 }
1087
1088 if ($propertyType === PropertyTable::TYPE_STRING && $userType === PropertyTable::USER_TYPE_DATE)
1089 {
1090 array_walk($value, function(&$item) use ($r)
1091 {
1092 $date = $this->internalizeDateProductPropertyValue($item['VALUE']);
1093 if ($date->isSuccess())
1094 {
1095 $item['VALUE'] = $date->getData()[0];
1096 }
1097 else
1098 {
1099 $r->addErrors($date->getErrors());
1100 }
1101 });
1102 }
1103 elseif ($propertyType === PropertyTable::TYPE_STRING && $userType === PropertyTable::USER_TYPE_DATETIME)
1104 {
1105 array_walk($value, function(&$item) use ($r)
1106 {
1107 $date = $this->internalizeDateTimeProductPropertyValue($item['VALUE']);
1108 if ($date->isSuccess())
1109 {
1110 $item['VALUE'] = $date->getData()[0];
1111 }
1112 else
1113 {
1114 $r->addErrors($date->getErrors());
1115 }
1116 });
1117 }
1118 elseif ($propertyType === PropertyTable::TYPE_FILE && empty($userType))
1119 {
1120 array_walk($value, function(&$item) use ($r)
1121 {
1122 $date = $this->internalizeFileValue($item['VALUE']);
1123 if (!empty($date))
1124 {
1125 $item['VALUE'] = $date;
1126 }
1127 else
1128 {
1129 $r->addError(new Error('Wrong file date'));
1130 }
1131 });
1132 }
1133 elseif ($this->isPropertyBoolean($info))
1134 {
1135 $booleanValue = $value[0]['VALUE'];
1136 if ($booleanValue === self::BOOLEAN_VALUE_YES)
1137 {
1138 $value[0]['VALUE'] = $info['BOOLEAN_VALUE_YES']['ID'];
1139 }
1140 elseif ($booleanValue === self::BOOLEAN_VALUE_NO)
1141 {
1142 $value[0]['VALUE'] = null;
1143 }
1144 }
1145 //elseif ($propertyType === 'S' && $userType === 'HTML'){}
1146
1147 $value = $isMultiple? $value: $value[0];
1148 }
1149 }
1150
1151 if ($r->isSuccess())
1152 {
1153 $r->setData([$value]);
1154 }
1155
1156 return $r;
1157 }
1158
1159 public function internalizeArguments($name, $arguments): array
1160 {
1161 if (
1162 $name === 'getfieldsbyfilter'
1163 || $name === 'download'
1164 )
1165 {
1166 return $arguments;
1167 }
1168
1169 // Returns throw
1170 return parent::internalizeArguments($name, $arguments);
1171 }
1172
1173 protected function externalizeEmptyValue($name, $value, $fields, $fieldsInfo)
1174 {
1175 $fieldInfo = $fieldsInfo[$name] ?? [];
1176 if ($this->isPropertyBoolean($fieldInfo))
1177 {
1178 return self::BOOLEAN_VALUE_NO;
1179 }
1180
1181 return parent::externalizeEmptyValue($name, $value, $fields, $fieldsInfo);
1182 }
1183
1184 public function externalizeFieldsGet($fields, $fieldsInfo = []): array
1185 {
1186 // param - IBLOCK_ID is reqired in filter
1187 $iblockId = (int)($fields['IBLOCK_ID'] ?? 0);
1188 $productType = (int)($fields['TYPE'] ?? 0);
1189
1190 $propertyValues = $this->getFieldsIBlockPropertyValuesByFilter(['IBLOCK_ID' => $iblockId]);
1191 $product = $this->getFieldsCatalogProductByFilter(['IBLOCK_ID' => $iblockId, 'PRODUCT_TYPE' => $productType]);
1192
1193 if ($product->isSuccess())
1194 {
1195 $fieldsInfo = array_merge(
1196 $this->getFieldsIBlockElement(),
1197 ($propertyValues->isSuccess() ? $propertyValues->getData() : []),
1198 $this->getFieldsCatalogProductCommonFields(),
1199 $product->getData()
1200 );
1201 }
1202 else
1203 {
1204 // if it was not possible to determine the view fields by product type,
1205 // we get the default fields, all fields of the catalog and fields of the Information Block
1206
1207 $fieldsInfo = array_merge(
1208 $this->getFields(),
1209 ($propertyValues->isSuccess() ? $propertyValues->getData() : [])
1210 );
1211 }
1212 unset($product, $propertyValues);
1213
1214 return parent::externalizeFieldsGet($fields, $fieldsInfo);
1215 }
1216
1217 public function externalizeListFields($list, $fieldsInfo = []): array
1218 {
1219 // param - IBLOCK_ID is reqired in filter
1220 $iblockId = (int)($list[0]['IBLOCK_ID'] ?? 0);
1221
1222 $propertyValues = $this->getFieldsIBlockPropertyValuesByFilter(['IBLOCK_ID' => $iblockId]);
1223 $fieldsInfo = array_merge(
1224 $this->getFields(),
1225 ($propertyValues->isSuccess() ? $propertyValues->getData() : [])
1226 );
1227 unset($propertyValues);
1228
1229 return parent::externalizeListFields($list, $fieldsInfo);
1230 }
1231
1233 {
1234 if (
1235 $name === 'getfieldsbyfilter'
1236 || $name === 'download'
1237 )
1238 {
1239 return $fields;
1240 }
1241
1242 // Returns throw
1243 return parent::externalizeResult($name, $fields);
1244 }
1245
1246 public function convertKeysToSnakeCaseArguments($name, $arguments)
1247 {
1248 if ($name === 'getfieldsbyfilter')
1249 {
1250 if (isset($arguments['filter']))
1251 {
1252 $filter = $arguments['filter'];
1253 if (!empty($filter))
1254 {
1255 $arguments['filter'] = $this->convertKeysToSnakeCaseFilter($filter);
1256 }
1257 }
1258 }
1259 elseif ($name === 'download')
1260 {
1261 if (isset($arguments['fields']))
1262 {
1263 $fields = $arguments['fields'];
1264 if (!empty($fields))
1265 {
1266 $converter = new Converter(
1267 Converter::VALUES
1268 | Converter::TO_SNAKE
1269 | Converter::TO_SNAKE_DIGIT
1270 | Converter::TO_UPPER
1271 );
1272 $converterForKey = new Converter(
1273 Converter::KEYS
1274 | Converter::TO_SNAKE
1275 | Converter::TO_SNAKE_DIGIT
1276 | Converter::TO_UPPER
1277 );
1278
1279 $result = [];
1280 foreach ($converter->process($fields) as $key => $value)
1281 {
1282 $result[$converterForKey->process($key)] = $value;
1283 }
1284 $arguments['fields'] = $result;
1285 }
1286 }
1287 }
1288 else
1289 {
1290 parent::convertKeysToSnakeCaseArguments($name, $arguments);
1291 }
1292
1293 return $arguments;
1294 }
1295
1296 public function checkFieldsList($arguments): Result
1297 {
1298 $r = new Result();
1299
1300 $select = $arguments['select'] ?? [];
1301 if (!is_array($select))
1302 {
1303 $select = [];
1304 }
1305
1306 $error = [];
1307 if (!in_array('ID', $select))
1308 {
1309 $error[] = 'id';
1310 }
1311 if (!in_array('IBLOCK_ID', $select))
1312 {
1313 $error[] = 'iblockId';
1314 }
1315
1316 if (!empty($error))
1317 {
1318 $r->addError(new Error('Required select fields: ' . implode(', ', $error)));
1319 }
1320
1321 if (!isset($arguments['filter']['IBLOCK_ID']))
1322 {
1323 $r->addError(new Error('Required filter fields: iblockId'));
1324 }
1325
1326 return $r;
1327 }
1328
1329 public function checkArguments($name, $arguments): Result
1330 {
1331 if ($name === 'download')
1332 {
1333 $fields = $arguments['fields'];
1334 return $this->checkFieldsDownload($fields);
1335 }
1336 else
1337 {
1338 return parent::checkArguments($name, $arguments);
1339 }
1340 }
1341
1343 {
1344 $r = new Result();
1345
1346 $emptyFields = [];
1347
1348 if (!isset($fields['FIELD_NAME']))
1349 {
1350 $emptyFields[] = 'fieldName';
1351 }
1352
1353 if (!isset($fields['FILE_ID']))
1354 {
1355 $emptyFields[] = 'fileId';
1356 }
1357
1358 if (!isset($fields['PRODUCT_ID']))
1359 {
1360 $emptyFields[] = 'productId';
1361 }
1362
1363 if (!empty($emptyFields))
1364 {
1365 $r->addError(new Error('Required fields: '.implode(', ', $emptyFields)));
1366 }
1367
1368 return $r;
1369 }
1370
1371 protected function getActionUriToDownload(): string
1372 {
1373 return '/rest/catalog.product.download';
1374 }
1375
1376 protected function externalizeFileValue($name, $value, $fields): array
1377 {
1378 $productId = null;
1379 if (isset($fields['PRODUCT_ID']))
1380 {
1381 $productId = $fields['PRODUCT_ID'];
1382 }
1383 elseif (isset($fields['ID']))
1384 {
1385 $productId = $fields['ID'];
1386 }
1387 $productId = (int)$productId;
1388
1389 $data = [
1390 'fields' => [
1391 'fieldName' => Converter::toJson()
1392 ->process($name)
1393 ,
1394 'fileId' => $value,
1395 'productId' => $productId,
1396 ],
1397 ];
1398
1399 $uri = new \Bitrix\Main\Web\Uri($this->getActionUriToDownload());
1400
1401 return [
1402 'ID' => $value,
1403 'URL' => new \Bitrix\Main\Engine\Response\DataType\ContentUri(
1404 $uri->addParams($data)
1405 ->__toString()
1406 ),
1407 ];
1408 }
1409
1410 protected function externalizeExtendedTypeValue($name, $value, $fields, $fieldsInfo): Result
1411 {
1412 $r = new Result();
1413
1414 $info = $fieldsInfo[$name] ?? [];
1415 $type = $info['TYPE'] ?? '';
1416
1418 {
1419 $attrs = $info['ATTRIBUTES'] ?? [];
1420 $isMultiple = in_array(Attributes::MULTIPLE, $attrs, true);
1421
1422 $propertyType = $info['PROPERTY_TYPE'] ?? '';
1423 $userType = $info['USER_TYPE'] ?? '';
1424
1425 $value = $isMultiple? $value: [$value];
1426
1427 if ($propertyType === PropertyTable::TYPE_STRING && $userType === PropertyTable::USER_TYPE_DATE)
1428 {
1429 array_walk($value, function(&$item)use($r)
1430 {
1431 $date = $this->externalizeDateValue($item['VALUE']);
1432 if ($date->isSuccess())
1433 {
1434 $item['VALUE'] = $date->getData()[0];
1435 }
1436 else
1437 {
1438 $r->addErrors($date->getErrors());
1439 }
1440 });
1441 }
1442 elseif ($propertyType === PropertyTable::TYPE_STRING && $userType === PropertyTable::USER_TYPE_DATETIME)
1443 {
1444 array_walk($value, function(&$item) use($r)
1445 {
1446 $date = $this->externalizeDateTimeValue($item['VALUE']);
1447 if ($date->isSuccess())
1448 {
1449 $item['VALUE'] = $date->getData()[0];
1450 }
1451 else
1452 {
1453 $r->addErrors($date->getErrors());
1454 }
1455 });
1456 }
1457 elseif ($propertyType === PropertyTable::TYPE_FILE && empty($userType))
1458 {
1459 array_walk($value, function(&$item) use ($fields, $name)
1460 {
1461 $item['VALUE'] = $this->externalizeFileValue($name, $item['VALUE'], ['PRODUCT_ID' => $fields['ID']]);
1462 });
1463 }
1464 elseif ($this->isPropertyBoolean($info))
1465 {
1466 if ($value)
1467 {
1468 $value = self::BOOLEAN_VALUE_YES;
1469 }
1470 else
1471 {
1472 $value = self::BOOLEAN_VALUE_NO;
1473 }
1474 }
1475
1476 $value = $isMultiple? $value: $value[0];
1477 }
1478
1479 if ($r->isSuccess())
1480 {
1481 $r->setData([$value]);
1482 }
1483
1484 return $r;
1485 }
1486
1492 private function loadFieldNames(): void
1493 {
1494 if (!empty($this->productFieldNames))
1495 {
1496 return;
1497 }
1498
1499 $this->loadEntityFieldNames(Iblock\ElementTable::getMap());
1500 $this->loadEntityFieldNames(Catalog\ProductTable::getMap());
1501 $this->loadAdditionalFieldNames();
1502 }
1503
1510 private function loadEntityFieldNames(array $fieldList): void
1511 {
1513 foreach ($fieldList as $field)
1514 {
1515 if ($field instanceof ScalarField)
1516 {
1517 $name = $field->getName();
1518 $title = $field->getTitle();
1519
1520 $this->productFieldNames[$name] = $title ?: $name;
1521 }
1522 }
1523 }
1524
1525 private function loadAdditionalFieldNames(): void
1526 {
1527 $this->productFieldNames['IBLOCK_SECTION'] = Loc::getMessage('RESTVIEW_PRODUCT_FIELD_NAME_IBLOCK_SECTION');
1528 }
1529
1536 private function fillFieldNames(array $fieldList): array
1537 {
1538 foreach (array_keys($fieldList) as $id)
1539 {
1540 $fieldList[$id]['NAME'] = $this->productFieldNames[$id] ?? $id;
1541 }
1542
1543 return $fieldList;
1544 }
1545
1546 private function isPropertyBoolean(array $property): bool
1547 {
1548 if (($property['PROPERTY_TYPE'] ?? '') !== PropertyTable::TYPE_LIST)
1549 {
1550 return false;
1551 }
1552 $attributes = $property['ATTRIBUTES'] ?? [];
1553 if (!is_array($attributes))
1554 {
1555 $attributes = [];
1556 }
1557 if (in_array(Attributes::MULTIPLE, $attributes, true))
1558 {
1559 return false;
1560 }
1561 $userType = (string)($property['USER_TYPE'] ?? '');
1562 if ($userType !== '' && $userType !== Catalog\Controller\Enum::PROPERTY_USER_TYPE_BOOL_ENUM)
1563 {
1564 return false;
1565 }
1566 return (!empty($property['BOOLEAN_VALUE_YES']) && is_array($property['BOOLEAN_VALUE_YES']));
1567 }
1568
1569 protected function checkIndexedMultipleValue($values): Result
1570 {
1571 $r = new Result();
1572
1573 return
1574 $this->isIndexedArray($values)
1575 ? $r
1576 : $r->addError(new Error('For type Multiple field - value must be an Indexed array'))
1577 ;
1578 }
1579
1580 protected function isIndexedArray($ary): bool
1581 {
1582 if (!is_array($ary))
1583 {
1584 return false;
1585 }
1586
1587 $keys = array_keys($ary);
1588 foreach ($keys as $k)
1589 {
1590 if (!is_int($k))
1591 {
1592 return false;
1593 }
1594 }
1595 return true;
1596 }
1597}
$type
Определения options.php:106
const PROPERTY_USER_TYPE_BOOL_ENUM
Определения enum.php:18
static getMap()
Определения product.php:112
const TYPE_EMPTY_SKU
Определения product.php:75
const TYPE_SET
Определения product.php:71
const TYPE_SKU
Определения product.php:72
const TYPE_FREE_OFFER
Определения product.php:74
const TYPE_SERVICE
Определения product.php:76
const TYPE_OFFER
Определения product.php:73
const TYPE_PRODUCT
Определения product.php:70
static prepareProductField(array $field, array $description, array $attributes)
Определения entityfieldtype.php:12
internalizeDateProductPropertyValue($value)
Определения product.php:1015
checkIndexedMultipleValue($values)
Определения product.php:1569
externalizeExtendedTypeValue($name, $value, $fields, $fieldsInfo)
Определения product.php:1410
getCatalogDescription(int $iblockId)
Определения product.php:340
isAllowedProductTypeByIBlockId($productTypeId, $iblockId)
Определения product.php:314
internalizeFieldsList($arguments, $fieldsInfo=[])
Определения product.php:891
const BOOLEAN_VALUE_NO
Определения product.php:24
getActionUriToDownload()
Определения product.php:1371
internalizeArguments($name, $arguments)
Определения product.php:1159
internalizeFieldsAdd($fields, $fieldsInfo=[])
Определения product.php:906
checkFieldsDownload($fields)
Определения product.php:1342
isIndexedArray($ary)
Определения product.php:1580
internalizeDateTimeProductPropertyValue($value)
Определения product.php:1040
internalizeDateTimeValue($value)
Определения product.php:991
convertKeysToSnakeCaseArguments($name, $arguments)
Определения product.php:1246
externalizeFieldsGet($fields, $fieldsInfo=[])
Определения product.php:1184
checkArguments($name, $arguments)
Определения product.php:1329
internalizeFieldsUpdate($fields, $fieldsInfo=[])
Определения product.php:936
getFieldsByFilter(array $filter)
Определения product.php:774
const BOOLEAN_VALUE_YES
Определения product.php:23
externalizeFileValue($name, $value, $fields)
Определения product.php:1376
externalizeListFields($list, $fieldsInfo=[])
Определения product.php:1217
externalizeResult($name, $fields)
Определения product.php:1232
prepareFieldAttributs($info, $attributs)
Определения product.php:43
internalizeDateValue($value)
Определения product.php:966
checkFieldsList($arguments)
Определения product.php:1296
externalizeEmptyValue($name, $value, $fields, $fieldsInfo)
Определения product.php:1173
internalizeExtendedTypeValue($value, $info)
Определения product.php:1064
static getMap()
Определения elementtable.php:93
const USER_TYPE_HTML
Определения propertytable.php:79
const USER_TYPE_ELEMENT_AUTOCOMPLETE
Определения propertytable.php:82
const TYPE_ELEMENT
Определения propertytable.php:68
const TYPE_FILE
Определения propertytable.php:67
const USER_TYPE_SKU
Определения propertytable.php:83
const TYPE_STRING
Определения propertytable.php:65
const USER_TYPE_XML_ID
Определения propertytable.php:77
const USER_TYPE_ELEMENT_LIST
Определения propertytable.php:80
const USER_TYPE_SEQUENCE
Определения propertytable.php:81
const TYPE_LIST
Определения propertytable.php:70
const USER_TYPE_DATETIME
Определения propertytable.php:76
const TYPE_SECTION
Определения propertytable.php:69
const USER_TYPE_DIRECTORY
Определения propertytable.php:93
const TYPE_NUMBER
Определения propertytable.php:66
const USER_TYPE_SECTION_AUTOCOMPLETE
Определения propertytable.php:84
const USER_TYPE_DATE
Определения propertytable.php:75
Определения error.php:15
Определения date.php:9
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$iblockId
Определения iblock_catalog_edit.php:30
$select
Определения iblock_catalog_list.php:194
$filter
Определения iblock_catalog_list.php:54
if(file_exists($_SERVER['DOCUMENT_ROOT'] . "/urlrewrite.php")) $uri
Определения urlrewrite.php:61
if($NS['step']==6) if( $NS[ 'step']==7) if(COption::GetOptionInt('main', 'disk_space', 0) > 0) $info
Определения backup.php:924
$name
Определения menu_edit.php:35
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
$title
Определения pdf.php:123
$error
Определения subscription_card_product.php:20
$k
Определения template_pdf.php:567
$iterator
Определения yandex_run.php:610
$fields
Определения yandex_run.php:501