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