Коллекции полей
Общее использование
Коллекции полей (fieldcollections) объектов — это предопределённые наборы данных и элементов интерфейса, которые можно добавлять в объекты в произвольном количестве.
Коллекция полей объекта очень похожа на сам объект. У неё есть класс или в данном случае определение поля, которое предварительно нужно создать. После этого разные определения коллекций полей можно добавлять в объекты как наборы полей.

С некоторыми оговорками можно сказать, что коллекция полей — это объект внутри объекта.
При добавлении поля типа fieldcollection в определение класса объекта, разработчик указывает допустимые типы определений полей, которые можно будет использовать внутри этой коллекции.

Пользователь затем выбирает, какие и в каком количестве из доступных определений коллекций добавить в объект.

Хранение данных
Данные определений полей сохраняются в отдельной таблице для каждого определения коллекции и каждого класса объекта.
Конвенция именования таких таблиц: object_collection_COLLECTION-NAME_OBJECT-ID.
Такая таблица содержит все данные полей коллекции, идентификатор конкретного объекта, имя поля и индекс элемента
коллекции внутри поля fieldcollection.
Чтобы полностью понять структуру данных объектов и коллекций полей, полезно добавить несколько примеров данных и просмотреть таблицы, которые создаёт Pimcore.
Работа через PHP API
Данные коллекций полей можно задавать программно. Следующий фрагмент кода иллюстрирует, как этого можно достичь. Предположим, есть класс объекта collectiontest и определение fieldcollection с именем *MyCollection. В классе объекта есть поле collectionitems типа fieldcollection.
$object = new DataObject\Collectiontest();
$object->setParentId(1);
$object->setUserOwner(1);
$object->setUserModification(1);
$object->setCreationDate(time());
$object->setKey(uniqid() . rand(10, 99));
$items = new DataObject\Fieldcollection();
for ($i = 0; $i < 5; $i++) {
$item = new DataObject\Fieldcollection\Data\MyCollection();
$item->setMyinput("This is a test " . $i);
$items->add($item);
}
$object->setCollectionitems($items);
$object->save();
Если внутри коллекций полей используются локализованные поля, необходимо в явном виде установить объект в элемент коллекции перед вызовом методов, связанных с локализацией:
$item = new DataObject\Fieldcollection\Data\MyCollection();
$item->setObject($object);
Наследование
По умолчанию коллекции полей не поддерживают наследование, потому что данные коллекций в текущей реализации не сохраняются в таблицу запросов (query table), и, следовательно, по ним нельзя выполнять запросы для унаследованных значений.
Тем не менее можно реализовать поведение, приближенное к наследованию, для удобства поддержки данных, с помощью переопределения класса, который содержит поле коллекции, и добавив в него собственный getter:
// пользовательский геттер для поля fieldcollection с именем 'fieldCollection'
public function getFieldCollection(): mixed
{
$data = parent::getFieldCollection();
$inheritedData = DataObject\Service::useInheritedValues(true, function() use ($data) {
if (\Pimcore\Model\DataObject::doGetInheritedValues($this) && $this->getClass()->getFieldDefinition("fieldCollection")->isEmpty($data)) {
try {
return $this->getValueFromParent("fieldCollection");
} catch (\Pimcore\Model\DataObject\Exception\InheritanceParentNotFoundException $e) {
// данные от родителя недоступны, продолжаем ...
return null;
}
}
return null;
});
return $inheritedData ?? $data;
}
Обратите внимание: наследоваться может только весь контейнер коллекции целиком. Как только вы изменяете порядок элементов коллекции или любое значение поля в дочернем объекте, вся коллекция полей будет назначена этому дочернему объекту (то есть дочерний объект получит собственную копию коллекции).
Также в бэкенде Pimcore возможны некоторые визуальные нюансы при использовании такого подхода.
Вы можете предложить улучшение документации или задать вопрос в комментариях.
Если вам нужна полноценная консультация — вы можете заказать её на нашем сайте.