1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
element.php
См. документацию.
1<?
2namespace Bitrix\Lists\Entity;
3
4use Bitrix\Lists\Service\Param;
5use Bitrix\Main\Error;
6use Bitrix\Main\Errorable;
7use Bitrix\Main\ErrorCollection;
8use Bitrix\Main\Loader;
9use Bitrix\Main\ErrorableImplementation;
10use Bitrix\Rest\RestException;
11
13{
15
16 const ERROR_ADD_ELEMENT = "ERROR_ADD_ELEMENT";
17 const ERROR_UPDATE_ELEMENT = "ERROR_UPDATE_ELEMENT";
18 const ERROR_DELETE_ELEMENT = "ERROR_DELETE_ELEMENT";
19 const ERROR_ELEMENT_ALREADY_EXISTS = "ERROR_ELEMENT_ALREADY_EXISTS";
20 const ERROR_ELEMENT_NOT_FOUND = "ERROR_ELEMENT_NOT_FOUND";
21 const ERROR_ELEMENT_FIELD_VALUE = "ERROR_ELEMENT_FIELD_VALUE";
22 const ERROR_ELEMENT_PARAM_VALUE = "ERROR_ELEMENT_PARAM_VALUE";
23
24 private $param;
25 private $params = [];
26
27 private $iblockId;
28 private $elementId;
29 private array $elementFields = [];
30 private array $elementProperty = [];
31 private $listObject;
32
34
35 public function __construct(Param $param)
36 {
37 $this->param = $param;
38 $this->params = $param->getParams();
39
40 $this->iblockId = Utils::getIblockId($this->params);
41 $this->elementId = Utils::getElementId($this->params);
42
43 $this->listObject = new \CList($this->iblockId);
44
45 $this->errorCollection = new ErrorCollection;
46 }
47
53 public function isExist()
54 {
55 $this->param->checkRequiredInputParams(["IBLOCK_CODE", "IBLOCK_ID", "ELEMENT_CODE", "ELEMENT_ID"]);
56 if ($this->param->hasErrors())
57 {
58 $this->errorCollection->add($this->param->getErrors());
59
60 return false;
61 }
62
63 $this->validateParams();
64 if ($this->hasErrors())
65 {
66 return false;
67 }
68
69 $filter = [
70 "ID" => $this->params["ELEMENT_ID"] ?? "",
71 "IBLOCK_ID" => $this->iblockId,
72 "=CODE" => $this->params["ELEMENT_CODE"] ?? "",
73 "CHECK_PERMISSIONS" => "N",
74 ];
75 $queryObject = \CIBlockElement::getList([], $filter, false, false, ["ID"]);
76 return (bool) $queryObject->fetch();
77 }
78
84 public function add()
85 {
86 $this->param->checkRequiredInputParams(
87 [
88 "IBLOCK_TYPE_ID",
89 "IBLOCK_CODE",
90 "IBLOCK_ID",
91 "ELEMENT_CODE",
92 [
93 "FIELDS" => ["NAME"],
94 ],
95 ]
96 );
97
98 if ($this->param->hasErrors())
99 {
100 $this->errorCollection->add($this->param->getErrors());
101
102 return false;
103 }
104
105 $this->setUrlTemplate();
106
107 $this->validateParams();
108 $this->validateFields();
109
110 $isEnabledBp = $this->isEnabledBizproc($this->params["IBLOCK_TYPE_ID"]);
111 $hasBpTemplatesWithAutoStart = false;
112 if ($isEnabledBp)
113 {
114 $hasBpTemplatesWithAutoStart = $this->hasBpTemplatesWithAutoStart(\CBPDocumentEventType::Create);
115 }
116
117 if ($this->hasErrors())
118 {
119 return false;
120 }
121
122 $elementFields = $this->getElementFields($this->elementId, $this->params["FIELDS"]);
123
124 $elementObject = new \CIBlockElement;
125 $this->elementId = $elementObject->add($elementFields, false, true, true);
126 if ($this->elementId)
127 {
128 if ($isEnabledBp && $hasBpTemplatesWithAutoStart)
129 {
130 $this->startBp($this->elementId, \CBPDocumentEventType::Create);
131 }
132
133 return $this->elementId;
134 }
135 else
136 {
137 if ($elementObject->LAST_ERROR)
138 {
139 $this->errorCollection->setError(
140 new Error($elementObject->LAST_ERROR, self::ERROR_ADD_ELEMENT)
141 );
142 }
143 else
144 {
145 $this->errorCollection->setError(
146 new Error("Unknown error", self::ERROR_ADD_ELEMENT)
147 );
148 }
149
150 return false;
151 }
152 }
153
161 public function get(array $navData = [])
162 {
163 $this->param->checkRequiredInputParams(["IBLOCK_TYPE_ID", "IBLOCK_CODE", "IBLOCK_ID"]);
164 if ($this->param->hasErrors())
165 {
166 $this->errorCollection->add($this->param->getErrors());
167 return [];
168 }
169
170 return $this->getElements($navData);
171 }
172
178 public function update()
179 {
180 $this->param->checkRequiredInputParams(
181 [
182 "IBLOCK_TYPE_ID",
183 "IBLOCK_CODE",
184 "IBLOCK_ID",
185 "ELEMENT_CODE",
186 "ELEMENT_ID",
187 ]
188 );
189 if ($this->param->hasErrors())
190 {
191 $this->errorCollection->add($this->param->getErrors());
192
193 return false;
194 }
195
196 $this->validateParams();
197 $this->validateFields();
198
199 $isEnabledBp = $this->isEnabledBizproc($this->params["IBLOCK_TYPE_ID"]);
200 $hasBpTemplatesWithAutoStart = false;
201 if ($isEnabledBp)
202 {
203 $hasBpTemplatesWithAutoStart = $this->hasBpTemplatesWithAutoStart(\CBPDocumentEventType::Edit);
204 }
205
206 if ($this->hasErrors())
207 {
208 return false;
209 }
210
211 [$elementSelect, $elementFields, $elementProperty] = $this->getElementData();
212 $this->elementFields = $elementFields;
213 $this->elementProperty = $elementProperty;
214
215 $fields = $this->getElementFields($this->elementId, $this->params["FIELDS"]);
216
217 $elementObject = new \CIBlockElement;
218 $updateResult = $elementObject->update($this->elementId, $fields, false, true, true);
219 if ($updateResult)
220 {
221 if ($isEnabledBp && $hasBpTemplatesWithAutoStart)
222 {
223 $changedElementFields = \CLists::checkChangedFields(
224 $this->iblockId,
225 $this->elementId,
226 $elementSelect,
227 $elementFields,
228 $elementProperty
229 );
230
231 $this->startBp($this->elementId, \CBPDocumentEventType::Edit, $changedElementFields);
232
233 if ($this->hasErrors())
234 {
235 return false;
236 }
237 }
238
239 return true;
240 }
241 else
242 {
243 if ($elementObject->LAST_ERROR)
244 {
245 $this->errorCollection->setError(
246 new Error($elementObject->LAST_ERROR, self::ERROR_UPDATE_ELEMENT)
247 );
248 }
249 else
250 {
251 $this->errorCollection->setError(
252 new Error("Unknown error", self::ERROR_UPDATE_ELEMENT)
253 );
254 }
255
256 return false;
257 }
258 }
259
265 public function delete()
266 {
267 $this->param->checkRequiredInputParams(["IBLOCK_TYPE_ID", "IBLOCK_CODE", "IBLOCK_ID",
268 "ELEMENT_CODE", "ELEMENT_ID"]);
269 if ($this->param->hasErrors())
270 {
271 $this->errorCollection->add($this->param->getErrors());
272 return false;
273 }
274
275 $elementObject = new \CIBlockElement;
276
277 global $APPLICATION;
278 $APPLICATION->resetException();
279
280 if ($elementObject->delete($this->elementId))
281 {
282 return true;
283 }
284 else
285 {
286 if ($exception = $APPLICATION->getException())
287 $this->errorCollection->setError(new Error($exception->getString(), self::ERROR_UPDATE_ELEMENT));
288 else
289 $this->errorCollection->setError(new Error("Unknown error", self::ERROR_UPDATE_ELEMENT));
290
291 return false;
292 }
293 }
294
300 public function getFileUrl()
301 {
302 $this->param->checkRequiredInputParams(["IBLOCK_CODE", "IBLOCK_ID", "ELEMENT_CODE", "ELEMENT_ID", "FIELD_ID"]);
303 if ($this->param->hasErrors())
304 {
305 $this->errorCollection->add($this->param->getErrors());
306 return [];
307 }
308
309 $urls = [];
310
311 $sefFolder = $this->getSefFolder();
312
313 $queryProperty = \CIBlockElement::getProperty($this->iblockId, $this->elementId,
314 "SORT", "ASC", array("ACTIVE"=>"Y", "EMPTY"=>"N", "ID" => $this->params["FIELD_ID"])
315 );
316 while ($property = $queryProperty->fetch())
317 {
318 if ($property["PROPERTY_TYPE"] == "F")
319 {
320 $file = new \CListFile($this->iblockId, 0, $this->elementId,
321 "PROPERTY_".$this->params["FIELD_ID"], $property["VALUE"]);
322 $file->SetSocnetGroup($this->params["SOCNET_GROUP_ID"]);
323 $urls[] = $file->GetImgSrc(["url_template" => $sefFolder.
324 "#list_id#/file/#section_id#/#element_id#/#field_id#/#file_id#/"]);
325 }
326 elseif ($property["USER_TYPE"] == "DiskFile")
327 {
328 if (is_array($property["VALUE"]))
329 {
330 foreach ($property["VALUE"] as $attacheId)
331 {
332 $driver = \Bitrix\Disk\Driver::getInstance();
333 $urls[] = $driver->getUrlManager()->getUrlUfController(
334 "download", array("attachedId" => $attacheId));
335 }
336 }
337 }
338 }
339 return $urls;
340 }
341
347 public function getAvailableFields()
348 {
349 $availableFields = array("ID", "ACTIVE", "NAME", "TAGS", "XML_ID", "EXTERNAL_ID", "PREVIEW_TEXT",
350 "PREVIEW_TEXT_TYPE", "PREVIEW_PICTURE", "DETAIL_TEXT", "DETAIL_TEXT_TYPE", "DETAIL_PICTURE",
351 "CHECK_PERMISSIONS", "PERMISSIONS_BY", "CATALOG_TYPE", "MIN_PERMISSION", "SEARCHABLE_CONTENT",
352 "SORT", "TIMESTAMP_X", "DATE_MODIFY_FROM", "DATE_MODIFY_TO", "MODIFIED_USER_ID", "MODIFIED_BY",
353 "DATE_CREATE", "CREATED_USER_ID", "CREATED_BY", "DATE_ACTIVE_FROM", "DATE_ACTIVE_TO", "ACTIVE_DATE",
354 "ACTIVE_FROM", "ACTIVE_TO", "SECTION_ID");
355
356 $listCustomFields = [];
357
358 $fields = $this->listObject->getFields();
359
360 foreach ($fields as $field)
361 {
362 if (!empty($field["CODE"]))
363 {
364 $availableFields[] = "PROPERTY_".$field["CODE"];
365 }
366
367 if ($this->isFieldDateType($field["TYPE"]))
368 {
369 $callback = $field["PROPERTY_USER_TYPE"]["ConvertToDB"] ?? null;
370 $listCustomFields[$field["FIELD_ID"]] = function ($value) use ($callback) {
371 $regexDetectsIso8601 = '/^([\+-]?\d{4}(?!\d{2}\b))'
372 . '((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?'
373 . '|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d'
374 . '|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])'
375 . '((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d'
376 . '([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/';
377 if (is_string($value) && preg_match($regexDetectsIso8601, $value) === 1)
378 {
379 return \CRestUtil::unConvertDateTime($value);
380 }
381 elseif (is_callable($callback))
382 {
383 return call_user_func_array($callback, [[], ["VALUE" => $value]]);
384 }
385 else
386 {
387 return $value;
388 }
389 };
390 }
391 }
392
393 $availableFields = array_merge($availableFields, array_keys($fields));
394
395 return array($availableFields, $listCustomFields);
396 }
397
398 private function isEnabledBizproc(string $iblockTypeId): bool
399 {
400 return (Loader::includeModule("bizproc") && \CLists::isBpFeatureEnabled($iblockTypeId));
401 }
402
403 private function setUrlTemplate()
404 {
405 if (!empty($this->params["LIST_ELEMENT_URL"]))
406 {
407 $this->listObject->actualizeDocumentAdminPage(str_replace(
408 ["#list_id#", "#group_id#"],
409 [$this->iblockId, $this->params["SOCNET_GROUP_ID"]],
410 $this->params["LIST_ELEMENT_URL"])
411 );
412 }
413 }
414
415 private function validateFields()
416 {
417 $fields = $this->listObject->getFields();
418 foreach ($fields as $fieldId => $fieldData)
419 {
420 $fieldValue = $this->params["FIELDS"][$fieldId] ?? null;
421
422 if (
423 empty($this->params["FIELDS"][$fieldId])
424 && $fieldData["IS_REQUIRED"] === "Y"
425 && !is_numeric($this->params["FIELDS"][$fieldId] ?? null)
426 )
427 {
428 $this->errorCollection->setError(
429 new Error(
430 "The field \"".$fieldData["NAME"]."\" is required",
431 self::ERROR_ELEMENT_FIELD_VALUE
432 )
433 );
434 }
435
436 if (!$this->listObject->is_field($fieldId))
437 {
438 if (!is_array($fieldValue))
439 {
440 $fieldValue = [$fieldValue];
441 }
442
443 switch ($fieldData["TYPE"])
444 {
445 case "N":
446 foreach($fieldValue as $key => $value)
447 {
448 $value = str_replace(" ", "", str_replace(",", ".", $value));
449 if ($value && !is_numeric($value))
450 {
451 $this->errorCollection->setError(new Error(
452 "Value of the \"".$fieldData["NAME"]."\" field is not correct",
453 self::ERROR_ELEMENT_FIELD_VALUE)
454 );
455 }
456 }
457 break;
458 }
459 }
460 }
461 }
462
463 private function validateParams()
464 {
465 if (isset($this->params["ELEMENT_CODE"]) && !is_scalar($this->params["ELEMENT_CODE"]))
466 {
467 $this->errorCollection->setError(new Error(
468 'Value of the "ELEMENT_CODE" is not correct',
469 self::ERROR_ELEMENT_PARAM_VALUE
470 )
471 );
472 }
473 }
474
475 private function getElementFields($elementId, array $values)
476 {
477 $elementFields = [
478 "IBLOCK_ID" => $this->iblockId,
479 "CODE" => $this->params["ELEMENT_CODE"] ?? '',
480 "ID" => $elementId,
481 "PROPERTY_VALUES" => [],
482 ];
483
484 $fields = $this->listObject->getFields();
485 foreach ($fields as $fieldId => $fieldData)
486 {
487 $fieldValue = $values[$fieldId] ?? null;
488
489 if ($this->listObject->is_field($fieldId))
490 {
491 if ($fieldId == "PREVIEW_PICTURE" || $fieldId == "DETAIL_PICTURE")
492 {
493 $this->setPictureValue($elementFields, $fieldId, $fieldValue, $values);
494 }
495 elseif ($fieldId == "PREVIEW_TEXT" || $fieldId == "DETAIL_TEXT")
496 {
497 $this->setTextValue($elementFields, $fieldId, $fieldValue, $fieldData);
498 }
499 else
500 {
501 $this->setBaseValue($elementFields, $fieldId, $fieldValue);
502 }
503 }
504 else
505 {
506 if (!is_array($fieldValue))
507 {
508 $fieldValue = [$fieldValue];
509 }
510
511 switch ($fieldData["TYPE"])
512 {
513 case "F":
514 $this->setFileValue($elementFields, $fieldId, $fieldValue, $fieldData, $values);
515 break;
516 case "N":
517 $this->setIntegerValue($elementFields, $fieldValue, $fieldData);
518 break;
519 case "S:DiskFile":
520 $this->setFileDiskValue($elementFields, $fieldValue, $fieldData);
521 break;
522 case "S:Date":
523 $this->setDateValue($elementFields, $fieldValue, $fieldData);
524 break;
525 case "S:DateTime":
526 $this->setDateTimeValue($elementFields, $fieldValue, $fieldData);
527 break;
528 case "S:HTML":
529 $this->setHtmlValue($elementFields, $fieldValue, $fieldData);
530 break;
531 default:
532 $this->setPropertyValue($elementFields, $fieldValue, $fieldData);
533 }
534 }
535 }
536
537 global $USER;
538 if (empty($values["MODIFIED_BY"]) && isset($USER) && is_object($USER))
539 {
540 $userId = $USER->getID();
541 $elementFields["MODIFIED_BY"] = $userId;
542 }
543 unset($elementFields["TIMESTAMP_X"]);
544
545 $elementFields["IBLOCK_SECTION_ID"] = (
546 is_numeric($values['IBLOCK_SECTION_ID'] ?? null)
547 ? (int) $values['IBLOCK_SECTION_ID'] : 0
548 );
549
550 return $elementFields;
551 }
552
553 private function setPictureValue(&$elementFields, $fieldId, $fieldValue, array $values)
554 {
555 if (intval($fieldValue))
556 {
557 $elementFields[$fieldId] = \CFile::makeFileArray($fieldValue);
558 }
559 else
560 {
561 $elementFields[$fieldId] = \CRestUtil::saveFile($fieldValue);
562 }
563
564 if (!empty($values[$fieldId."_DEL"]))
565 {
566 $elementFields[$fieldId]["del"] = "Y";
567 }
568 }
569
570 private function setTextValue(&$elementFields, $fieldId, $fieldValue, $fieldData)
571 {
572 if (is_array($fieldValue))
573 {
574 $fieldValue = current($fieldValue);
575 }
576
577 if (!empty($fieldData["SETTINGS"]["USE_EDITOR"]) && $fieldData["SETTINGS"]["USE_EDITOR"] == "Y")
578 {
579 $elementFields[$fieldId."_TYPE"] = "html";
580 }
581 else
582 {
583 $elementFields[$fieldId."_TYPE"] = "text";
584 }
585
586 $elementFields[$fieldId] = $fieldValue;
587 }
588
589 private function setBaseValue(&$elementFields, $fieldId, $fieldValue)
590 {
591 if (is_array($fieldValue))
592 {
593 $fieldValue = current($fieldValue);
594 }
595
596 $elementFields[$fieldId] = $fieldValue;
597 }
598
599 private function setFileValue(&$elementFields, $fieldId, array $fieldValue, array $fieldData, array $values)
600 {
601 if (!empty($values[$fieldId."_DEL"]))
602 $delete = $values[$fieldId."_DEL"];
603 else
604 $delete = [];
605
606 if (!Loader::includeModule("rest"))
607 {
608 return;
609 }
610
611 $property = isset($fieldData['ID'])
612 ? ($this->elementProperty[$fieldData['ID']] ?? null)
613 : ($this->elementFields[$fieldId] ?? null)
614 ;
615
616 $prevIds = array_values($property['VALUES_LIST'] ?? []);
617
618 foreach ($fieldValue as $key => $value)
619 {
620 if (is_array($value))
621 {
622 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$key]["VALUE"] = \CRestUtil::saveFile($value);
623 }
624 else
625 {
626 if (is_numeric($value))
627 {
628 if (!in_array($value, $prevIds))
629 {
630 // security bugfix #188430
631 throw new RestException('Writing file values by ID is not supported', static::ERROR_ELEMENT_FIELD_VALUE);
632 }
633 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$key]["VALUE"] = \CFile::makeFileArray($value);
634 }
635 else
636 {
637 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$key]["VALUE"] = \CRestUtil::saveFile($fieldValue);
638
639 break;
640 }
641 }
642 }
643
644 foreach ($delete as $elementPropertyId => $mark)
645 {
646 if (isset($elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$elementPropertyId]["VALUE"]))
647 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$elementPropertyId]["VALUE"]["del"] = "Y";
648 else
649 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$elementPropertyId]["del"] = "Y";
650
651 }
652 }
653
654 private function setIntegerValue(&$elementFields, array $fieldValue, $fieldData)
655 {
656 foreach ($fieldValue as $key => $value)
657 {
658 $value = str_replace(" ", "", str_replace(",", ".", $value));
659 $value = is_numeric($value) ? doubleval($value) : '';
660 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$key]["VALUE"] = $value;
661 }
662 }
663
664 private function setFileDiskValue(&$elementFields, array $fieldValue, $fieldData)
665 {
666 foreach ($fieldValue as $key => $value)
667 {
668 if (is_array($value))
669 {
670 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$key]["VALUE"] = $value;
671 }
672 else
673 {
674 if (!is_array($elementFields["PROPERTY_VALUES"][$fieldData["ID"]]["VALUE"]))
675 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]]["VALUE"] = [];
676 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]]["VALUE"][] = $value;
677 }
678 }
679 }
680
681 private function setDateValue(&$elementFields, array $fieldValue, $fieldData)
682 {
683 if (!Loader::includeModule("rest"))
684 {
685 return;
686 }
687
688 foreach ($fieldValue as $key => $value)
689 {
690 if (is_array($value))
691 {
692 foreach($value as $k => $v)
693 {
694 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$k]["VALUE"] = \CRestUtil::unConvertDate($v);
695 }
696 }
697 else
698 {
699 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$key]["VALUE"] = \CRestUtil::unConvertDate($value);
700 }
701 }
702 }
703
704 private function setDateTimeValue(&$elementFields, array $fieldValue, $fieldData)
705 {
706 if (!Loader::includeModule("rest"))
707 {
708 return;
709 }
710
711 foreach ($fieldValue as $key => $value)
712 {
713 if (is_array($value))
714 {
715 foreach($value as $k => $v)
716 {
717 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$k]["VALUE"] =
718 \CRestUtil::unConvertDateTime($v);
719 }
720 }
721 else
722 {
723 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$key]["VALUE"] =
724 \CRestUtil::unConvertDateTime($value);
725 }
726 }
727 }
728
729 private function setHtmlValue(&$elementFields, array $fieldValue, $fieldData)
730 {
731 foreach($fieldValue as $key => $value)
732 {
733 if (!is_array($value))
734 {
735 $value = [$key => $value];
736 }
737
738 foreach($value as $k => $v)
739 {
740 if (CheckSerializedData($v) && @unserialize($v, ['allowed_classes' => false]))
741 {
742 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$k]["VALUE"] = unserialize($v, ['allowed_classes' => false]);
743 }
744 else
745 {
746 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$k]["VALUE"]["TYPE"] = "html";
747 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$k]["VALUE"]["TEXT"] = $v;
748 }
749 }
750 }
751 }
752
753 private function setPropertyValue(&$elementFields, array $fieldValue, $fieldData)
754 {
755 foreach($fieldValue as $key => $value)
756 {
757 if(is_array($value))
758 {
759 foreach($value as $k => $v)
760 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$k]["VALUE"] = $v;
761 }
762 else
763 {
764 $elementFields["PROPERTY_VALUES"][$fieldData["ID"]][$key]["VALUE"] = $value;
765 }
766 }
767 }
768
769 private function hasBpTemplatesWithAutoStart(int $execType): bool
770 {
771 $documentType = \BizProcDocument::generateDocumentComplexType(
772 $this->params["IBLOCK_TYPE_ID"],
773 $this->iblockId
774 );
775
776 $bpTemplatesWithAutoStart = \CBPWorkflowTemplateLoader::searchTemplatesByDocumentType(
777 $documentType,
778 $execType
779 );
780
781 foreach ($bpTemplatesWithAutoStart as $template)
782 {
783 if (!\CBPWorkflowTemplateLoader::isConstantsTuned($template["ID"]))
784 {
785 $this->errorCollection->setError(
786 new Error("Workflow constants need to be configured", self::ERROR_ADD_ELEMENT)
787 );
788 }
789 }
790
791 return !empty($bpTemplatesWithAutoStart);
792 }
793
794 private function startBp(int $elementId, int $execType, $changedElementFields = []): void
795 {
796 $documentType = \BizprocDocument::generateDocumentComplexType(
797 $this->params["IBLOCK_TYPE_ID"],
798 $this->iblockId
799 );
800 $documentId = \BizProcDocument::getDocumentComplexId(
801 $this->params["IBLOCK_TYPE_ID"],
802 $elementId
803 );
804 $documentStates = \CBPWorkflowTemplateLoader::getDocumentTypeStates(
805 $documentType,
806 $execType
807 );
808
809 if (is_array($documentStates) && !empty($documentStates))
810 {
811 global $USER;
812
813 $userId = $USER->getID();
814
815 $currentUserGroups = $USER->getUserGroupArray();
816 if ($this->params["CREATED_BY"] == $userId)
817 {
818 $currentUserGroups[] = "author";
819 }
820
821 if ($execType === \CBPDocumentEventType::Create)
822 {
823 $canWrite = \CBPDocument::canUserOperateDocumentType(
825 $userId,
826 $documentType,
827 [
828 "AllUserGroups" => $currentUserGroups,
829 "DocumentStates" => $documentStates,
830 ]
831 );
832 }
833 else
834 {
835 $canWrite = \CBPDocument::canUserOperateDocument(
837 $userId,
838 $documentId,
839 [
840 "AllUserGroups" => $currentUserGroups,
841 "DocumentStates" => $documentStates,
842 ]
843 );
844 }
845
846 if (!$canWrite)
847 {
848 $this->errorCollection->setError(
849 new Error("You do not have enough permissions to edit this record in its current bizproc state")
850 );
851
852 return;
853 }
854
855 $errors = [];
856
857 foreach ($documentStates as $documentState)
858 {
859 $parameters = \CBPDocument::startWorkflowParametersValidate(
860 $documentState["TEMPLATE_ID"],
861 $documentState["TEMPLATE_PARAMETERS"],
862 $documentType,
863 $errors
864 );
865
866 \CBPDocument::startWorkflow(
867 $documentState["TEMPLATE_ID"],
868 \BizProcDocument::getDocumentComplexId($this->params["IBLOCK_TYPE_ID"], $elementId),
869 array_merge(
870 $parameters,
871 [
872 \CBPDocument::PARAM_TAGRET_USER => "user_" . intval($userId),
873 \CBPDocument::PARAM_MODIFIED_DOCUMENT_FIELDS => $changedElementFields,
874 ]
875 ),
876 $errors
877 );
878 }
879
880 foreach($errors as $message)
881 {
882 $this->errorCollection->setError(new Error($message));
883 }
884 }
885 }
886
887 private function getElementData()
888 {
889 $elementSelect = ["ID", "IBLOCK_ID", "NAME", "IBLOCK_SECTION_ID", "CREATED_BY", "BP_PUBLISHED", "CODE"];
890 $elementFields = [];
891 $elementProperty = [];
892
893 $fields = $this->listObject->getFields();
894 $propertyFields = [];
895 foreach ($fields as $fieldId => $field)
896 {
897 if ($this->listObject->is_field($fieldId))
898 $elementSelect[] = $fieldId;
899 else
900 $propertyFields[] = $fieldId;
901
902 if ($fieldId == "CREATED_BY")
903 $elementSelect[] = "CREATED_USER_NAME";
904 if ($fieldId == "MODIFIED_BY")
905 $elementSelect[] = "USER_NAME";
906 }
907
908 $filter = [
909 "IBLOCK_TYPE" => $this->params["IBLOCK_TYPE_ID"],
910 "IBLOCK_ID" => $this->iblockId,
911 "ID" => $this->elementId,
912 "CHECK_PERMISSIONS" => "N",
913 ];
914 $queryObject = \CIBlockElement::getList([], $filter, false, false, $elementSelect);
915 if ($result = $queryObject->fetch())
916 {
917 $elementFields = $result;
918
919 if (!empty($propertyFields))
920 {
921 $queryProperty = \CIBlockElement::getProperty(
922 $this->iblockId,
923 $result["ID"], "SORT", "ASC",
924 array("ACTIVE"=>"Y", "EMPTY"=>"N")
925 );
926 while ($property = $queryProperty->fetch())
927 {
928 $propertyId = $property["ID"];
929 if (!array_key_exists($propertyId, $elementProperty))
930 {
931 $elementProperty[$propertyId] = $property;
932 unset($elementProperty[$propertyId]["DESCRIPTION"]);
933 unset($elementProperty[$propertyId]["VALUE_ENUM_ID"]);
934 unset($elementProperty[$propertyId]["VALUE_ENUM"]);
935 unset($elementProperty[$propertyId]["VALUE_XML_ID"]);
936 $elementProperty[$propertyId]["FULL_VALUES"] = [];
937 $elementProperty[$propertyId]["VALUES_LIST"] = [];
938 }
939 $elementProperty[$propertyId]["FULL_VALUES"][$property["PROPERTY_VALUE_ID"]] = [
940 "VALUE" => $property["VALUE"],
941 "DESCRIPTION" => $property["DESCRIPTION"],
942 ];
943 $elementProperty[$propertyId]["VALUES_LIST"][$property["PROPERTY_VALUE_ID"]] = $property["VALUE"];
944 }
945 }
946 }
947
948 return [$elementSelect, $elementFields, $elementProperty];
949 }
950
951 private function getElements($navData)
952 {
953 $elements = [];
954
955 $fields = $this->listObject->getFields();
956
957 $elementSelect = ["ID", "IBLOCK_ID", "NAME", "IBLOCK_SECTION_ID", "CREATED_BY", "BP_PUBLISHED", "CODE"];
958 $propertyFields = [];
959 $ignoreSortFields = ["S:Money", "PREVIEW_TEXT", "DETAIL_TEXT", "S:ECrm", "S:map_yandex", "PREVIEW_PICTURE",
960 "DETAIL_PICTURE", "S:DiskFile", "IBLOCK_SECTION_ID", "BIZPROC", "COMMENTS"];
961
962 $availableFieldsIdForSort = ["ID"];
963 foreach ($fields as $fieldId => $field)
964 {
965 if ($this->listObject->is_field($fieldId))
966 $elementSelect[] = $fieldId;
967 else
968 $propertyFields[$field['ID']] = $fieldId;
969
970 if ($fieldId == "CREATED_BY")
971 $elementSelect[] = "CREATED_USER_NAME";
972 if ($fieldId == "MODIFIED_BY")
973 $elementSelect[] = "USER_NAME";
974
975 if (!($field["MULTIPLE"] == "Y" || in_array($field["TYPE"], $ignoreSortFields)))
976 {
977 $availableFieldsIdForSort[] = $fieldId;
978 }
979 }
980
981 $elementSelect = array_unique($elementSelect);
982 if (is_array($this->params['SELECT'] ?? null))
983 {
984 $elementSelect = array_intersect($elementSelect, $this->params['SELECT']);
985 $propertyFields = array_intersect($propertyFields, $this->params['SELECT']);
986 if (empty($elementSelect))
987 {
988 $elementSelect = ['ID'];
989 }
990 }
991
992 $order = $this->getOrder($availableFieldsIdForSort);
993
994 $filter = [
995 "=IBLOCK_TYPE" => $this->params["IBLOCK_TYPE_ID"],
996 "IBLOCK_ID" => $this->iblockId,
997 "ID" => $this->params["ELEMENT_ID"] ?? "",
998 "=CODE" => $this->params["ELEMENT_CODE"] ?? "",
999 "SHOW_NEW" => (!empty($this->params["CAN_FULL_EDIT"]) && $this->params["CAN_FULL_EDIT"] == "Y" ? "Y" : "N"),
1000 "CHECK_PERMISSIONS" => "Y",
1001 ];
1002 $filter = $this->getInputFilter($filter);
1003 $queryObject = \CIBlockElement::getList($order, $filter, false, $navData, $elementSelect);
1004 while ($result = $queryObject->fetch())
1005 {
1006 $elements[$result["ID"]] = $result;
1007
1008 if (!empty($propertyFields))
1009 {
1010 $queryProperty = \CIBlockElement::getProperty(
1011 $this->iblockId,
1012 $result["ID"], "SORT", "ASC",
1013 [
1014 "ACTIVE" => "Y",
1015 "EMPTY" => "N",
1016 'ID' => array_keys($propertyFields),
1017 ]
1018 );
1019 while ($property = $queryProperty->fetch())
1020 {
1021 $propertyId = $property["ID"];
1022 $elements[$result["ID"]]["PROPERTY_".$propertyId][
1023 $property["PROPERTY_VALUE_ID"]] = $property["VALUE"];
1024 }
1025 }
1026 }
1027
1028 return array($elements, $queryObject);
1029 }
1030
1031 private function getOrder($availableFieldsIdForSort)
1032 {
1033 $order = [];
1034
1035 if (is_array($this->params["ELEMENT_ORDER"] ?? null))
1036 {
1037 $orderList = ["nulls,asc", "asc,nulls", "nulls,desc", "desc,nulls", "asc", "desc"];
1038 foreach ($this->params["ELEMENT_ORDER"] as $fieldId => $orderParam)
1039 {
1040 $orderParam = mb_strtolower($orderParam);
1041 if (!in_array($orderParam, $orderList) || !in_array($fieldId, $availableFieldsIdForSort))
1042 {
1043 continue;
1044 }
1045 $order[$fieldId] = $orderParam;
1046 }
1047 }
1048
1049 if (empty($order))
1050 {
1051 $order = ["ID" => "asc"];
1052 }
1053
1054 return $order;
1055 }
1056
1057 private function getInputFilter(array $filter)
1058 {
1059 if (is_array($this->params["FILTER"] ?? null))
1060 {
1061 foreach ($this->resultSanitizeFilter as $key => $value)
1062 {
1063 $key = str_replace(["ACTIVE_FROM", "ACTIVE_TO"], ["DATE_ACTIVE_FROM", "DATE_ACTIVE_TO"], $key);
1064 $filter[$key] = $value === '' ? false : $value;
1065 }
1066 }
1067
1068 return $filter;
1069 }
1070
1071 private function isFieldDateType($type)
1072 {
1073 return (in_array($type, ["DATE_CREATE", "TIMESTAMP_X", "DATE_MODIFY_FROM", "DATE_MODIFY_TO", "ACTIVE_DATE",
1074 "S:Date", "S:DateTime", "DATE_ACTIVE_FROM", "DATE_ACTIVE_TO", "ACTIVE_FROM", "ACTIVE_TO"]));
1075 }
1076
1077 private function getSefFolder()
1078 {
1079 $defaultSefFolder = [
1080 "lists" => "/company/lists/",
1081 "lists_socnet" => "/workgroups/group/#group_id#/lists/",
1082 "bitrix_processes" => "/bizproc/processes/",
1083 ];
1084
1085 if (!empty($this->params["SEF_FOLDER"]))
1086 {
1087 $sefFolder = $this->params["SEF_FOLDER"];
1088 }
1089 elseif (!empty($defaultSefFolder[$this->params["IBLOCK_TYPE_ID"]]))
1090 {
1091 $sefFolder = $defaultSefFolder[$this->params["IBLOCK_TYPE_ID"]];
1092 }
1093 else
1094 {
1095 $sefFolder = $defaultSefFolder["lists"];
1096 }
1097
1098 return $sefFolder;
1099 }
1100}
$type
Определения options.php:106
global $APPLICATION
Определения include.php:80
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
const ERROR_ADD_ELEMENT
Определения element.php:16
const ERROR_ELEMENT_NOT_FOUND
Определения element.php:20
const ERROR_ELEMENT_PARAM_VALUE
Определения element.php:22
const ERROR_DELETE_ELEMENT
Определения element.php:18
const ERROR_ELEMENT_ALREADY_EXISTS
Определения element.php:19
getAvailableFields()
Определения element.php:347
const ERROR_UPDATE_ELEMENT
Определения element.php:17
const ERROR_ELEMENT_FIELD_VALUE
Определения element.php:21
$resultSanitizeFilter
Определения element.php:33
__construct(Param $param)
Определения element.php:35
static getIblockId(array $params)
Определения utils.php:13
static getElementId(array $params)
Определения utils.php:41
Определения error.php:15
const WriteDocument
Определения constants.php:215
const Edit
Определения constants.php:154
const Create
Определения constants.php:153
$template
Определения file_edit.php:49
</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
$iblockTypeId
Определения group_lists.php:25
$iblockId
Определения iblock_catalog_edit.php:30
$errors
Определения iblock_catalog_edit.php:74
$filter
Определения iblock_catalog_list.php:54
global $USER
Определения csv_new_run.php:40
CheckSerializedData($str, $max_depth=200)
Определения tools.php:4949
$value
Определения Param.php:39
trait ErrorableImplementation
Определения errorableimplementation.php:8
hasErrors()
Определения errorableimplementation.php:17
if(!function_exists(__NAMESPACE__.'\\___972068685'))
Определения license.php:1
trait Error
Определения error.php:11
$order
Определения payment.php:8
$message
Определения payment.php:8
return false
Определения prolog_main_admin.php:185
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
$canWrite
Определения options.php:10
$k
Определения template_pdf.php:567
$propertyFields
Определения yandex_run.php:558
$fields
Определения yandex_run.php:501