29 private $propertyValueFactory;
34 $this->propertyValueFactory = $propertyValueFactory;
41 throw new \OutOfRangeException($id);
50 return reset($entities) ?:
null;
53 public function getEntitiesBy($params, array $propertySettings = []): array
58 foreach ($propertySettings as $setting)
60 if ((
int)$setting[
'ID'] > 0)
62 $sortedSettings[(int)$setting[
'ID']] = $setting;
66 foreach ($this->
getList((array)$params) as $elementId => $properties)
68 if (!is_array($properties))
73 foreach ($properties as $propertyId => $item)
76 if ($sortedSettings[$propertyId])
78 $settings = $sortedSettings[$propertyId];
79 $settings[
'IBLOCK_ELEMENT_ID'] = $elementId;
97 foreach ($entities as $property)
99 if ($parentEntity && $parentEntity !== $property->getParent())
101 $result->addError(
new Error(
'Saving should only be done with properties of a common parent.'));
104 if ($parentEntity ===
null)
106 $parentEntity = $property->getParent();
109 $valueCollection = $property->getPropertyValueCollection();
111 $props[$property->getId()] = $valueCollection->toArray();
113 if ($property->getPropertyType() === PropertyTable::TYPE_FILE)
115 foreach ($props[$property->getId()] as $id => $prop)
119 $props[$property->getId()][$id] = \CIBlock::makeFilePropArray(
121 $prop[
'VALUE'] ===
'',
122 $prop[
'DESCRIPTION'],
123 [
'allow_file_id' =>
true]
128 foreach ($valueCollection->getRemovedItems() as $removed)
130 if ($removed->isNew())
135 $fieldsToDelete = \CIBlock::makeFilePropArray($removed->getFields(),
true);
136 $props[$property->getId()][$removed->getId()] = $fieldsToDelete;
143 $result->addError(
new Error(
'Parent entity not found while saving properties.'));
146 if (!($parentEntity instanceof BaseIblockElementEntity))
148 $result->addError(
new Error(sprintf(
149 'Parent entity of property must be an instance of {%s}.',
150 BaseIblockElementEntity::class
154 if (!empty($props) && $result->isSuccess())
156 $element = new \CIBlockElement();
157 $res = $element->update($parentEntity->getId(), [
158 'PROPERTY_VALUES' => $props,
162 $result->addError(
new Error($element->LAST_ERROR));
176 if ($entity->
isNew())
184 'ID' => $entity->
getId(),
188 $entityFields = $result[$entity->
getId()] ?? [];
193 protected function getList(array $params): array
197 $filter = $params[
'filter'] ?? [];
199 $propertyValuesIterator = \CIBlockElement::getPropertyValues($filter[
'IBLOCK_ID'], $filter,
true);
200 while ($propertyValues = $propertyValuesIterator->fetch())
202 $descriptions = $propertyValues[
'DESCRIPTION'] ?? [];
203 $propertyValueIds = $propertyValues[
'PROPERTY_VALUE_ID'] ?? [];
204 $elementId = $propertyValues[
'IBLOCK_ELEMENT_ID'];
205 unset($propertyValues[
'IBLOCK_ELEMENT_ID'], $propertyValues[
'PROPERTY_VALUE_ID'], $propertyValues[
'DESCRIPTION']);
209 foreach ($propertyValues as $id => $value)
211 $entityFields[$id] = [];
212 $description = $descriptions[$id] ??
null;
214 if ($value !==
false || $description !==
null)
216 if (is_array($value))
218 foreach ($value as $key => $item)
221 'VALUE' => $item ??
'',
222 'DESCRIPTION' => empty($description[$key]) ? null : $description[$key],
225 if (isset($propertyValueIds[$id][$key]))
227 $fields[
'ID'] = $propertyValueIds[$id][$key];
230 $entityFields[$id][$key] = $fields;
236 'VALUE' => $value ??
'',
237 'DESCRIPTION' => empty($descriptions[$id]) ? null : $descriptions[$id],
240 if (isset($propertyValueIds[$id]))
242 $fields[
'ID'] = $propertyValueIds[$id];
245 $entityFields[$id][] = $fields;
250 $result[$elementId] = $entityFields;
258 return $this->factory->createCollection();
263 $propertySettings = [];
267 $linkedPropertyIds = $this->getLinkedPropertyIds($parent->
getIblockId(), $parent);
268 if (!empty($linkedPropertyIds))
271 '@ID' => $linkedPropertyIds,
285 foreach ($propertySettings as $settings)
287 $fields = $entityFields[$settings[
'ID']] ?? [];
288 $settings[
'IBLOCK_ELEMENT_ID'] = $parent->
getId();
291 $collection->add($property);
299 $linkedPropertyIds = [$this->loadPropertyIdsWithoutAnyLink($iblockId)];
303 $linkedPropertyIds[] = array_keys(\CIBlockSectionPropertyLink::getArray($iblockId));
309 $linkedPropertyIds[] = array_keys(\CIBlockSectionPropertyLink::getArray($iblockId, $section->getValue()));
312 if (!empty($linkedPropertyIds))
314 $linkedPropertyIds = array_merge(...$linkedPropertyIds);
315 Collection::normalizeArrayValuesByInt($linkedPropertyIds,
false);
316 $linkedPropertyIds = array_unique($linkedPropertyIds);
319 return $linkedPropertyIds;
322 private function loadPropertyIdsWithoutAnyLink(
int $iblockId): array
324 $propertyIds = PropertyTable::getList([
327 '=IBLOCK_ID' => $iblockId,
328 '==SECTION_LINK.SECTION_ID' =>
null,
333 '\Bitrix\Iblock\SectionPropertyTable',
335 '=this.ID' =>
'ref.PROPERTY_ID',
336 '=this.IBLOCK_ID' =>
'ref.IBLOCK_ID',
338 [
'join_type' =>
'LEFT']
345 return array_column($propertyIds,
'ID');
350 $settings = PropertyTable::getList([
361 return $this->loadEnumSettings($settings);
366 foreach ($fields as &$field)
368 if (!empty($settings[
'USER_TYPE']))
370 $userType = \CIBlockProperty::GetUserType($settings[
'USER_TYPE']);
372 if (isset($userType[
'ConvertFromDB']))
374 $field = call_user_func($userType[
'ConvertFromDB'], $settings, $field);
384 if (isset($settings[
'USER_TYPE_SETTINGS_LIST']))
386 $settings[
'USER_TYPE_SETTINGS'] = $settings[
'USER_TYPE_SETTINGS_LIST'];
387 unset($settings[
'USER_TYPE_SETTINGS_LIST']);
395 $entity = $this->factory->createEntity();
401 $entity->setSettings($settings);
404 $propertyValueCollection = $this->propertyValueFactory->createCollection();
405 $propertyValueCollection->initValues($fields);
407 $entity->setPropertyValueCollection($propertyValueCollection);
412 private function loadEnumSettings(array $settings): array
416 foreach ($settings as $setting)
418 if ($setting[
'PROPERTY_TYPE'] === PropertyTable::TYPE_LIST)
420 $enumIds[] = $setting[
'ID'];
424 $enumSettings = PropertyEnumerationTable::getList([
425 'select' => [
'ID',
'PROPERTY_ID'],
427 'PROPERTY_ID' => $enumIds,
433 $enumSettings = array_column($enumSettings,
'ID',
'PROPERTY_ID');
435 if (!empty($enumSettings))
437 foreach ($settings as &$setting)
439 if (isset($enumSettings[$setting[
'ID']]))
441 $setting[
'DEFAULT_VALUE'] = $enumSettings[$setting[
'ID']];