1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
IBlockService.php
См. документацию.
1<?php
2
3namespace Bitrix\Lists\Api\Service\IBlockService;
4
5use Bitrix\Iblock\SectionTable;
6use Bitrix\Lists\Api\Data\IBlockService\IBlockElementsToGet;
7use Bitrix\Lists\Api\Data\IBlockService\IBlockElementToAdd;
8use Bitrix\Lists\Api\Data\IBlockService\IBlockElementToUpdate;
9use Bitrix\Lists\Api\Data\IBlockService\IBlockToGet;
10use Bitrix\Lists\Api\Data\IBlockService\IBlockToGetById;
11use Bitrix\Lists\Api\Request\IBlockService\AddIBlockElementRequest;
12use Bitrix\Lists\Api\Request\IBlockService\GetIBlockDefaultFieldsRequest;
13use Bitrix\Lists\Api\Request\IBlockService\UpdateIBlockElementRequest;
14use Bitrix\Lists\Api\Response\IBlockService\AddIBlockElementResponse;
15use Bitrix\Lists\Api\Response\IBlockService\GetIBlockByIdResponse;
16use Bitrix\Lists\Api\Response\IBlockService\GetIBlockDefaultFieldsResponse;
17use Bitrix\Lists\Api\Response\IBlockService\GetIBlockElementFieldsResponse;
18use Bitrix\Lists\Api\Response\IBlockService\GetIBlockElementListResponse;
19use Bitrix\Lists\Api\Response\IBlockService\GetIBlockListResponse;
20use Bitrix\Lists\Api\Response\IBlockService\UpdateIBlockElementResponse;
21use Bitrix\Lists\Api\Response\Response;
22use Bitrix\Lists\Service\Param;
23use Bitrix\Lists\Workflow\Starter;
24use Bitrix\Main\ArgumentException;
25use Bitrix\Main\Error;
26use Bitrix\Main\Loader;
27use Bitrix\Main\Localization\Loc;
28
29final class IBlockService
30{
33
34 private string $iBlockTypeId;
35 private int $socNetGroupId;
36 private bool $isBpFeatureEnabled;
37
38 private static array $cache = [];
39
40 public function __construct(
41 Param $parameters,
43 )
44 {
45 $parameters->checkRequiredInputParams(['IBLOCK_TYPE_ID', 'SOCNET_GROUP_ID']);
46 if ($parameters->hasErrors())
47 {
48 $firstError = $parameters->getErrors()[0];
49
50 throw new ArgumentException($firstError->getMessage());
51 }
52
53 $this->accessService = $accessService;
54 $this->dataService = new IBlockDataService();
55
56 $this->iBlockTypeId = $parameters->getParams()['IBLOCK_TYPE_ID'];
57 $this->socNetGroupId = $parameters->getParams()['SOCNET_GROUP_ID'];
58
59 $this->isBpFeatureEnabled = (
60 Loader::includeModule('bizproc')
61 && \CLists::isBpFeatureEnabled($this->iBlockTypeId) === true
62 );
63 }
64
65 public function getIBlockById(IBlockToGetById $iBlockToGetById): GetIBlockByIdResponse
66 {
68
69 if ($iBlockToGetById->needCheckPermissions())
70 {
71 $response->fillFromResponse($this->accessService->canUserReadIBlock($iBlockToGetById->getIBlockId()));
72 }
73
74 if ($response->isSuccess() && Loader::includeModule('iblock'))
75 {
76 $response->setIBlock(\CIBlock::GetArrayByID($iBlockToGetById->getIBlockId()) ?: []);
77 }
78
79 return $response;
80 }
81
82 public function getIBlockList(IBlockToGet $iBlockToGet): GetIBlockListResponse
83 {
85
86 if ($iBlockToGet->needCheckPermissions())
87 {
88 $response->fillFromResponse($this->accessService->canUserReadIBlockList());
89 }
90
91 if ($response->isSuccess() && Loader::includeModule('iblock'))
92 {
93 $filter =
94 $iBlockToGet->getFilter()
95 ->setIBLockTypeId($this->iBlockTypeId)
96 ->setSocNetGroupId($this->socNetGroupId)
97 ;
98 if (!$filter->hasField('CHECK_PERMISSIONS'))
99 {
100 $filter->setCheckPermission(!$this->accessService->isAdminPermission($response->getPermission()));
101 }
102
103 $iBlocks = [];
104 $iterator = \CIBlock::GetList($iBlockToGet->getOrder(), $filter->getOrmFilter());
105 while ($item = $iterator->Fetch())
106 {
107 $iBlocks[] = $item;
108 }
109
110 $response->setIBlocks($iBlocks);
111 }
112
113 return $response;
114 }
115
117 {
119 $filter = $iBlockElementsToGet->getFilter();
120
121 $elementId = $filter->getFieldValue('ID');
122 $iBlockId = $filter->getFieldValue('IBLOCK_ID');
123 if ($elementId === null || is_array($elementId) || $iBlockId === null)
124 {
125 // todo: loc
126 return $response->addError(new Error('required parameters'));
127 }
128
129 if ($iBlockElementsToGet->isCheckPermissionsEnabled())
130 {
131 $sectionId = $filter->getFieldValue('SECTION_ID') ?? 0;
132 $response->fillFromResponse(
133 $this->accessService->canUserReadElement((int)$elementId, (int)$sectionId, (int)$iBlockId)
134 );
135 }
136
137 if ($response->isSuccess())
138 {
139 $iBlockElementsToGet->disableCheckPermissions();
140 if (!$iBlockElementsToGet->getFilter()->hasField('CHECK_PERMISSIONS'))
141 {
142 $iBlockElementsToGet->getFilter()->setCheckPermission(false);
143 }
144
145 if ((int)$elementId === 0)
146 {
147 return $response->setElements([['ID' => 0]]);
148 }
149
150 return $this->getIBlockElementList($iBlockElementsToGet);
151 }
152
153 return $response;
154 }
155
157 {
159
160 $filter = $iBlockElementsToGet->getFilter();
161 $iBlockId = $filter->hasField('IBLOCK_ID') ? (int)$filter->getFieldValue('IBLOCK_ID') : null;
162 if ($iBlockElementsToGet->isCheckPermissionsEnabled())
163 {
164 $response->fillFromResponse($this->accessService->canUserReadElementList($iBlockId));
165 }
166
167 $elements = [];
168 if ($response->isSuccess() && Loader::includeModule('iblock'))
169 {
170 $filter->setIBlockType($this->iBlockTypeId);
171 if (!$filter->hasField('CHECK_PERMISSIONS'))
172 {
173 $filter->setCheckPermission(!$this->accessService->isAdminPermission($response->getPermission()));
174 }
175
176 $iterator = \CIBlockElement::GetList(
177 $iBlockElementsToGet->getOrder(),
178 $filter->getOrmFilter(),
179 false,
180 $iBlockElementsToGet->getNavigation(),
181 $iBlockElementsToGet->getSelect()
182 );
183
184 while ($element = $iterator->Fetch())
185 {
186 $elementId = (int)$element['ID'];
187
188 $propertiesValues = [];
189 if ($iBlockId && $iBlockElementsToGet->isNeedLoadProps())
190 {
191 $propertiesValues = $this->loadIBlockElementPropertiesValues($iBlockId, $elementId);
192 }
193
194 $workflowStateInfo = [];
195 if ($this->isBpFeatureEnabled && $iBlockElementsToGet->isNeedLoadWorkflowState())
196 {
197 $workflowStateInfo = $this->loadWorkflowStateInfo($elementId);
198 }
199
200 $elements[] = array_merge($element, $propertiesValues, $workflowStateInfo);
201 }
202 }
203
204 $response->setElements($elements);
205
206 return $response;
207 }
208
209 private function loadIBlockElementPropertiesValues(int $iBlockId, int $elementId): array
210 {
211 if (!Loader::includeModule('iblock'))
212 {
213 return [];
214 }
215
216 $result = [];
217 $order = ['sort' => 'asc', 'id' => 'asc', 'enum_sort' => 'asc', 'value_id' => 'asc'];
218 $filter = ['ACTIVE' => 'Y', 'EMPTY' => 'N'];
219 $iterator = \CIBlockElement::GetProperty($iBlockId, $elementId, $order, $filter);
220 while ($property = $iterator->Fetch())
221 {
222 $id = 'PROPERTY_' . $property['ID'];
223 if (!array_key_exists($id, $result))
224 {
225 $result[$id] = [];
226 }
227
228 $result[$id][$property['PROPERTY_VALUE_ID']] = $property['VALUE'];
229 }
230
231 return $result;
232 }
233
234 private function loadWorkflowStateInfo(int $elementId): array
235 {
236 $documentState =
237 $elementId > 0
238 ? $this->getActualElementState(\BizprocDocument::getDocumentComplexId($this->iBlockTypeId, $elementId))
239 : null
240 ;
241
242 return [
243 'WORKFLOW_STATE' => $documentState ? $documentState['STATE_TITLE'] : '',
244 'STARTED_BY' => $documentState ? $documentState['STARTED_BY'] : '',
245 'WORKFLOW_STATE_ID' => $documentState ? $documentState['ID'] : '',
246 ];
247 }
248
249 private function getActualElementState(array $documentId): ?array
250 {
251 if (Loader::includeModule('bizproc'))
252 {
253 $state = \CBPDocument::getActiveStates($documentId, 1);
254 if ($state)
255 {
256 return array_shift($state);
257 }
258
259 $ids = \CBPStateService::getIdsByDocument($documentId, 1);
260 if ($ids)
261 {
262 return \CBPStateService::getWorkflowState(array_shift($ids));
263 }
264 }
265
266 return null;
267 }
268
269 // todo: VO
270 public function getIBlockFields(int $iBlockId, bool $isEnableCheckPermissions, bool $loadEnumValues): GetIBlockElementFieldsResponse
271 {
273
274 if ($isEnableCheckPermissions)
275 {
276 $response->fillFromResponse($this->accessService->canUserReadIBlock($iBlockId));
277 if (!$response->isSuccess())
278 {
279 return $response;
280 }
281 }
282
283 $list = new \CList($iBlockId);
284
285 $all = [];
286 $fields = [];
287 $props = [];
288 foreach ($list->GetFields() as $fieldId => $property)
289 {
290 if ($loadEnumValues)
291 {
292 $property['ENUM_VALUES'] = [];
293
294 if ($property['TYPE'] === 'L')
295 {
296 $property = $this->loadEnumValuesByTypeL($property);
297 }
298 }
299
300 $all[$fieldId] = $property;
301 if ($list->is_field($fieldId))
302 {
303 $fields[$fieldId] = $property;
304 }
305 else
306 {
307 $props[$fieldId] = $property;
308 }
309 }
310
311 return $response->setFields($fields)->setProps($props)->setAll($all);
312 }
313
314 private function loadEnumValuesByTypeL(array $property): array
315 {
316 $queryObject = \CIBlockProperty::getPropertyEnum($property['ID']);
317 while($enum = $queryObject->fetch())
318 {
319 if ($enum['DEF'] === 'Y')
320 {
321 if (is_array($property['DEFAULT_VALUE']))
322 {
323 $property['DEFAULT_VALUE'][] = $enum['ID'];
324 }
325 elseif (empty($property['DEFAULT_VALUE']))
326 {
327 $property['DEFAULT_VALUE'] = $enum['ID'];
328 }
329 else
330 {
331 $property['DEFAULT_VALUE'] = (array)$property['DEFAULT_VALUE'];
332 $property['DEFAULT_VALUE'][] = $enum['ID'];
333 }
334 }
335 $property['ENUM_VALUES'][] = $enum;
336 }
337
338 return $property;
339 }
340
342 {
344 $iBlockId = $request->iBlockId;
345 if ($iBlockId <= 0)
346 {
347 return $response->addError(new Error(Loc::getMessage('LISTS_LIB_API_IBLOCK_SERVICE_ERROR_WRONG_IBLOCK')));
348 }
349
350 if ($request->needCheckPermissions)
351 {
352 $response->fillFromResponse($this->accessService->canUserReadIBlock($iBlockId));
353 }
354
355 if ($response->isSuccess())
356 {
357 $iBlockToGet = (new IBlockToGetById($iBlockId))->disableCheckPermissions();
358 $iBlock = $this->getIBlockById($iBlockToGet)->getIBlock();
359
360 if ($iBlock && Loader::includeModule('iblock'))
361 {
362 if (!isset(self::$cache[$iBlockId]))
363 {
364 self::$cache[$iBlockId] = [];
365 }
366
367 if (!isset(self::$cache[$iBlockId]['hasSections']))
368 {
369 $section = (
370 SectionTable::query()
371 ->setSelect(['ID'])
372 ->where('IBLOCK_ID', $iBlockId)
373 ->setLimit(1)
374 ->exec()
375 ->fetchObject()
376 );
377
378 self::$cache[$iBlockId]['hasSections'] = (bool)$section;
379 }
380
381 if (
382 self::$cache[$iBlockId]['hasSections']
383 && $request->loadEnumValues
384 && !isset(self::$cache[$iBlockId]['sections'])
385 )
386 {
387 $sections = [];
388 $iterator = \CIBlockSection::GetTreeList(['IBLOCK_ID' => $iBlockId]);
389 while ($section = $iterator->GetNext())
390 {
391 $sectionId = (int)$section['ID'];
392 $sections[$sectionId] = $section;
393 }
394
395 self::$cache[$iBlockId]['sections'] = $sections;
396 }
397
398 $fields = [
399 'IBLOCK_SECTION_ID' => [
400 'FIELD_ID' => 'IBLOCK_SECTION_ID',
401 'NAME' => $iBlock['SECTION_NAME'] ?? '',
402 'IS_REQUIRED' => 'N',
403 'MULTIPLE' => 'N',
404 'DEFAULT_VALUE' => 0,
405 'TYPE' => 'G',
406 'SETTINGS' => [
407 'SHOW_ADD_FORM' => 'Y',
408 'SHOW_EDIT_FORM' => 'Y',
409 'ADD_READ_ONLY_FIELD' => 'N',
410 'EDIT_READ_ONLY_FIELD' => 'N',
411 ],
412 'LINK_IBLOCK_ID' => $iBlockId,
413 'HAS_SECTIONS' => self::$cache[$iBlockId]['hasSections'] ? 'Y' : 'N',
414 'ENUM_VALUES' => (
415 $request->loadEnumValues && isset(self::$cache[$iBlockId]['sections'])
416 ? self::$cache[$iBlockId]['sections']
417 : []
418 ),
419 ],
420 ];
421
422 $response->setDefaultFields($fields);
423 }
424 }
425
426 return $response;
427 }
428
430 {
432
433 $elementToAdd = $this->dataService->getIBlockElementToAddObject($request, $response);
434 if (!$elementToAdd)
435 {
436 return $response;
437 }
438
439 $iBlockId = $elementToAdd->getIBlockId();
440
441 if ($request->needCheckPermissions && $response->isSuccess())
442 {
443 $response->fillFromResponse(
444 $this->accessService->canUserAddElement($elementToAdd->getSectionId(), $iBlockId)
445 );
446 }
447
448 if ($response->isSuccess() && Loader::includeModule('iblock'))
449 {
450 $element = $this->prepareElementValuesToUpsert($elementToAdd, $response);
451 $wfStarter =
452 $response->isSuccess() && $request->needStartWorkflows
453 ? $this->getWfStarter($response, $elementToAdd, $request->wfParameterValues)
454 : null
455 ;
456
457 if ($response->isSuccess())
458 {
459 $iBlockElement = new \CIBlockElement();
460 $id = $iBlockElement->Add($element, false, true, true);
461 $elementId = (int)(is_scalar($id) ? $id : 0);
462
463 $response->setId($elementId);
464 if ($elementId <= 0)
465 {
466 $response->addErrors($this->separateUpsertErrors($iBlockElement->LAST_ERROR));
467 }
468
469 if ($wfStarter && $elementId > 0)
470 {
471 $wfStarter->setTimeToStart($request->timeToStart)->setElementId($elementId);
472 $startWorkflowResult = $wfStarter->run(true);
473 $response->addErrors($startWorkflowResult->getErrors());
474 }
475 }
476 }
477
478 return $response;
479 }
480
481 private function getWfStarter(
484 array $parameters,
485 ): ?Starter
486 {
487 $iBlockId = $elementToUpsert->getIBlockId();
488 $elementId = $elementToUpsert->getElementId();
489 $modifiedBy = $elementToUpsert->getModifiedBy();
490
491 $iBlockInfo = $this->getIBlockById((new IBlockToGetById($iBlockId))->disableCheckPermissions())->getIBlock();
492
493 $wfStarter = new Starter($iBlockInfo, $this->accessService->getUserId());
494 $wfStarter->setElementId($elementId);
495
496 if (!$wfStarter->isEnabled())
497 {
498 return null;
499 }
500
501 $isRunnableWfResult = $wfStarter->isRunnable($modifiedBy);
502 $response->addErrors($isRunnableWfResult->getErrors());
503
504 if ($isRunnableWfResult->isSuccess())
505 {
506 $setParametersResult = $wfStarter->setParameters($parameters);
507 $response->addErrors($setParametersResult->getErrors());
508 }
509
510 return $wfStarter;
511 }
512
514 {
516
517 $elementToUpdate = $this->dataService->getIBlockElementToUpdateObject($request, $response);
518 if (!$elementToUpdate)
519 {
520 return $response;
521 }
522
523 if ($request->needCheckPermissions && $response->isSuccess())
524 {
525 $response->fillFromResponse(
526 $this->accessService->canUserEditElement(
527 $elementToUpdate->getElementId(),
528 $elementToUpdate->getSectionId(),
529 $elementToUpdate->getIBlockId()
530 )
531 );
532 }
533
534 if ($response->isSuccess())
535 {
536 $element = $this->prepareElementValuesToUpsert($elementToUpdate, $response);
537 $wfStarter =
538 $response->isSuccess() && $request->needStartWorkflows
539 ? $this->getWfStarter($response, $elementToUpdate, $request->wfParameterValues)
540 : null
541 ;
542
543 if ($response->isSuccess())
544 {
545 if ($element)
546 {
547 $iBlockElement = new \CIBlockElement();
548 $result = $iBlockElement->Update($elementToUpdate->getElementId(), $element, false, true, true);
549
550 if ($result)
551 {
552 $response->setIsSuccessUpdate(true);
553 }
554 else
555 {
557 ->addErrors($this->separateUpsertErrors($iBlockElement->LAST_ERROR))
558 ->setIsSuccessUpdate(false)
559 ;
560 }
561 }
562
563 if ($wfStarter && (empty($element) || $response->getIsSuccessUpdate()))
564 {
565 $wfStarter->setTimeToStart($request->timeToStart);
566
567 if ($wfStarter->hasTemplatesOnStartup())
568 {
569 $wfStarter->setChangedFields(
570 empty($element) ? [] : $elementToUpdate->getChangedFieldsAfterUpdate()
571 );
572 }
573
574 $startWorkflowResult = $wfStarter->run();
575 $response->addErrors($startWorkflowResult->getErrors());
576 }
577 }
578 }
579
580 return $response;
581 }
582
583 private function prepareElementValuesToUpsert(
586 ): array
587 {
588 $iBlockFields = $this->getIBlockFields($elementToUpsert->getIBlockId(), false, true);
589 $response->addErrors($iBlockFields->getErrors());
590
591 $element = [];
592 if ($response->isSuccess())
593 {
594 $result = $elementToUpsert->getElementValues($iBlockFields->getFields(), $iBlockFields->getProps());
595 $element = $result->getElementData() ?? [];
596 $response->addErrors($result->getErrors());
597
598 if (!$result->getHasChangedFields() && !$result->getHasChangedProps())
599 {
600 return [];
601 }
602 }
603
604 return $element;
605 }
606
607 private function separateUpsertErrors(string $errorMessages): array
608 {
609 $errors = [];
610
611 $messages = explode('<br>', $errorMessages);
612 foreach ($messages as $message)
613 {
614 $message = trim($message);
615 if ($message)
616 {
617 $errors[] = new Error($message);
618 }
619 }
620
621 return $errors;
622 }
623}
if(!Loader::includeModule('catalog')) if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_PRICE_EDIT)) if(!check_bitrix_sessid()) $request
Определения catalog_reindex.php:36
getIBlockDefaultFields(GetIBlockDefaultFieldsRequest $request)
Определения IBlockService.php:341
getIBlockElementList(IBlockElementsToGet $iBlockElementsToGet)
Определения IBlockService.php:156
getIBlockById(IBlockToGetById $iBlockToGetById)
Определения IBlockService.php:65
getIBlockList(IBlockToGet $iBlockToGet)
Определения IBlockService.php:82
getElementDetailInfo(IBlockElementsToGet $iBlockElementsToGet)
Определения IBlockService.php:116
updateIBlockElement(UpdateIBlockElementRequest $request)
Определения IBlockService.php:513
__construct(Param $parameters, AccessService $accessService,)
Определения IBlockService.php:40
addIBlockElement(AddIBlockElementRequest $request)
Определения IBlockService.php:429
getIBlockFields(int $iBlockId, bool $isEnableCheckPermissions, bool $loadEnumValues)
Определения IBlockService.php:270
checkRequiredInputParams(array $requiredInputParams)
Определения param.php:39
getParams()
Определения param.php:70
Определения error.php:15
static getDocumentComplexId($iblockType, $documentId)
Определения bizprocdocument.php:54
</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
$errors
Определения iblock_catalog_edit.php:74
$filter
Определения iblock_catalog_list.php:54
$iBlockId
Определения iblock_subelement_generator.php:45
$order
Определения payment.php:8
$message
Определения payment.php:8
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$messages
Определения template.php:8
$props
Определения template.php:269
$response
Определения result.php:21
$iterator
Определения yandex_run.php:610
$fields
Определения yandex_run.php:501