Перейти к основному содержимому

Коллекции полей

Общее использование

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

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

Конфигурация fieldcollection

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

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

Конфигурация fieldcollection

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

Поле 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 возможны некоторые визуальные нюансы при использовании такого подхода.


Вы можете предложить улучшение документации или задать вопрос в комментариях.
Если вам нужна полноценная консультация — вы можете заказать её на нашем сайте.