My first approach was to use TaxonomyEntry and TaxonomyEntryCreateStruct for this. Unfortunately, I ended up with duplicate tags. It seems that the mandatory Content object is sufficient. Surprisingly a published Content object is all that’s needed for a product category tag.
Let’s say you have a similar list like this
name | description |
Some category | Some category description |
Another category | Another long category description |
If you read in your list and loop over the rows, you might have an array like this:
$rows = [
['name' => 'Some category', 'description' => 'Some category description'],
['name' => 'Another category', 'description' => 'Another long category description'],
];
So looping over $rows, this is what you do with the individual records:
use Ibexa\Contracts\Core\Repository\Repository;
use Ibexa\Core\FieldType\TextLine\Value as TextLineValue;
use Ibexa\Taxonomy\FieldType\TaxonomyEntry\Value as TaxonomyEntryValue;
use Ibexa\Taxonomy\Service\TaxonomyService;
$newIdentifier = 'product_category_tag_' . md5($record['name]); // unique per name to prevent dups
$parent = $this->taxonomyService->loadRootEntry('product_categories');
if ($parent->getContent()) {
$tagContent = $this->repository->getContentService()->loadContent($parent->content->id);
$parentLocationId = $tagContent->contentInfo->mainLocationId;
}
$tagType = $this->repository->getContentTypeService()->loadContentTypeByIdentifier('product_category_tag');
$contentCreateStruct = $this->repository->getContentService()->newContentCreateStruct($tagType, 'eng-GB');
$contentCreateStruct->setField('name', $record['name], 'eng-GB');
$contentCreateStruct->setField('identifier', new TextLineValue($newIdentifier), 'eng-GB');
$contentCreateStruct->setField('description', $record['description'], 'eng-GB');
$contentCreateStruct->setField('parent', new TaxonomyEntryValue($parent));
$locationCreateStruct = $this->repository->getLocationService()->newLocationCreateStruct($parentLocationId);
// fails if identifier isnt unique exists
try {
$contentDraft = $this->repository->getContentService()->createContent($contentCreateStruct, [$locationCreateStruct], []); // the [] prevents validation
$this->repository->getContentService()->publishVersion($contentDraft->versionInfo);
} catch (ValidationError $e) {
// we expect this to fail in case it already exists
}