29 private array $propertyWithoutLink = [];
34 $this->propertyValueFactory = $propertyValueFactory;
41 throw new \OutOfRangeException($id);
50 return reset($entities) ?:
null;
58 foreach ($propertySettings as $setting)
60 if ((
int)$setting[
'ID'] > 0)
62 $sortedSettings[(int)$setting[
'ID']] = $setting;
68 if (!is_array($properties))
73 foreach ($properties as $propertyId => $item)
76 if (isset($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();
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))
149 'Parent entity of property must be an instance of {%s}.',
150 BaseIblockElementEntity::class
156 $elementId = $parentEntity->getId();
157 $element = new \CIBlockElement();
158 $res = $element->update(
161 'PROPERTY_VALUES' =>
$props,
170 $ipropValues = new \Bitrix\Iblock\InheritedProperty\ElementValues(
171 \CIBlockElement::GetIBlockByID($elementId),
174 $ipropValues->clearValues();
189 $disabledPropertyIds =
$params[
'filter'][
'!PROPERTY_ID'] ?? [];
190 unset(
$params[
'filter'][
'!PROPERTY_ID']);
225 $propertyFilter = [];
227 if (isset(
$filter[
'PROPERTY_ID']))
229 $propertyFilter[
'ID'] =
$filter[
'PROPERTY_ID'];
232 if (isset(
$filter[
'PROPERTY_CODE']))
234 $propertyFilter[
'ID'] = $this->getPropertyIdByCode(
$filter[
'IBLOCK_ID'],
$filter[
'PROPERTY_CODE']);
235 if (!$propertyFilter[
'ID'])
239 unset(
$filter[
'PROPERTY_CODE']);
242 $propertyValuesIterator = \CIBlockElement::getPropertyValues(
$filter[
'IBLOCK_ID'],
$filter,
true, $propertyFilter);
243 while ($propertyValues = $propertyValuesIterator->fetch())
245 $descriptions = $propertyValues[
'DESCRIPTION'] ?? [];
246 $propertyValueIds = $propertyValues[
'PROPERTY_VALUE_ID'] ?? [];
247 $elementId = $propertyValues[
'IBLOCK_ELEMENT_ID'];
248 unset($propertyValues[
'IBLOCK_ELEMENT_ID'], $propertyValues[
'PROPERTY_VALUE_ID'], $propertyValues[
'DESCRIPTION']);
252 foreach ($propertyValues as $id => $value)
254 $entityFields[$id] = [];
259 if (is_array($value))
261 foreach ($value as
$key => $item)
264 'VALUE' => $item ??
'',
268 if (isset($propertyValueIds[$id][
$key]))
279 'VALUE' => $value ??
'',
280 'DESCRIPTION' => empty($descriptions[$id]) ? null : $descriptions[$id],
283 if (isset($propertyValueIds[$id]))
285 $fields[
'ID'] = $propertyValueIds[$id];
288 $entityFields[$id][] =
$fields;
293 $result[$elementId] = $entityFields;
299 private function getPropertyIdByCode(
int $iblockId,
string $code): ?int
312 return isset($propertyData[
'ID']) ? (int)$propertyData[
'ID'] : null;
317 return $this->factory->createCollection();
322 $propertySettings = [];
326 $linkedPropertyIds = $this->getLinkedPropertyIds($parent->
getIblockId(), $parent);
327 if (!empty($linkedPropertyIds))
329 $linkedPropertyIds = array_diff($linkedPropertyIds, $disabledPropertyIds);
330 if (!empty($linkedPropertyIds))
333 '@ID' => $linkedPropertyIds,
343 '!ID' => $disabledPropertyIds,
358 $linkedPropertyIds = [$this->loadPropertyIdsWithoutAnyLink(
$iblockId)];
362 $linkedPropertyIds[] = array_keys(\CIBlockSectionPropertyLink::getArray(
$iblockId));
368 $linkedPropertyIds[] = array_keys(\CIBlockSectionPropertyLink::getArray(
$iblockId, $section->getValue()));
371 if (!empty($linkedPropertyIds))
373 $linkedPropertyIds = array_merge(...$linkedPropertyIds);
374 Collection::normalizeArrayValuesByInt($linkedPropertyIds,
false);
375 $linkedPropertyIds = array_unique($linkedPropertyIds);
378 return $linkedPropertyIds;
381 private function loadPropertyIdsWithoutAnyLink(
int $iblockId):
array
383 if (!isset($this->propertyWithoutLink[
$iblockId]))
385 $this->propertyWithoutLink[
$iblockId] = [];
390 '==SECTION_LINK.SECTION_ID' =>
null,
395 '\Bitrix\Iblock\SectionPropertyTable',
397 '=this.ID' =>
'ref.PROPERTY_ID',
398 '=this.IBLOCK_ID' =>
'ref.IBLOCK_ID',
400 [
'join_type' =>
'LEFT']
406 $this->propertyWithoutLink[
$iblockId][] = (int)$row[
'ID'];
411 return $this->propertyWithoutLink[
$iblockId];
427 return $this->loadEnumSettings(
$settings);
436 $userType = \CIBlockProperty::GetUserType(
$settings[
'USER_TYPE']);
438 if (isset($userType[
'ConvertFromDB']))
440 $field = call_user_func($userType[
'ConvertFromDB'],
$settings, $field);
450 if (isset(
$settings[
'USER_TYPE_SETTINGS_LIST']))
453 unset(
$settings[
'USER_TYPE_SETTINGS_LIST']);
461 $entity = $this->factory->createEntity();
470 $propertyValueCollection = $this->propertyValueFactory->createCollection();
471 $propertyValueCollection->initValues(
$fields);
473 $entity->setPropertyValueCollection($propertyValueCollection);
490 $enumIds[] = $setting[
'ID'];
498 $enumSettings = PropertyEnumerationTable::getList([
504 '@PROPERTY_ID' => $enumIds,
510 $enumSettings = array_column($enumSettings,
'ID',
'PROPERTY_ID');
512 if (!empty($enumSettings))
516 if (isset($enumSettings[$setting[
'ID']]))
518 $setting[
'DEFAULT_VALUE'] = $enumSettings[$setting[
'ID']];
static getRow(array $parameters)