Details
-
Bug
-
Resolution: Fixed
-
Medium
-
4.5.1
-
None
-
Yes
Description
The documentation for \Ibexa\Contracts\Core\Repository\Validator\ContentValidator::validate() states :
* @return array Grouped validation errors by field definition and language code, in format: * $returnValue[string|int $fieldDefinitionId][string $languageCode] = $fieldErrors;
However, \Ibexa\Taxonomy\Repository\Content\Validator\AbstractTaxonomyIdentifierValidator::doValidate() doesn't do that, and this causes Ibexa\Taxonomy\Repository\Content\Validator\ContentCreateStructValidator and Ibexa\Taxonomy\Repository\Content\Validator\ContentUpdateStructValidator to return validation errors with wrong structure.
Steps to reproduce :
src/Controller/TestController.php
<?PHP declare(strict_types=1); namespace App\Controller; use Ibexa\Contracts\Core\Repository\Repository; use Ibexa\Contracts\Taxonomy\Service\TaxonomyServiceInterface; use Ibexa\Core\Base\Exceptions\ContentFieldValidationException; use Ibexa\Core\FieldType\TextLine\Value as TextLineValue; use Ibexa\Taxonomy\FieldType\TaxonomyEntry\Value as TaxonomyEntryValue; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; final class TestController extends AbstractController { public function __construct( private readonly Repository $repository, private readonly TaxonomyServiceInterface $taxonomyService, ) {} #[Route('/taxtest')] public function test(): Response { $this->repository->sudo( function (Repository $repository) { $identifier = "Test"; $contentService = $repository->getContentService(); $contentType = $repository->getContentTypeService()->loadContentTypeByIdentifier('tag'); $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); $contentCreateStruct->setField('name', new TextLineValue($identifier)); $contentCreateStruct->setField('identifier', new TextLineValue(strtolower($identifier))); $contentCreateStruct->setField('parent', new TaxonomyEntryValue( $this->taxonomyService->loadRootEntry('tags'), )); $locationCreateStruct = $repository->getLocationService()->newLocationCreateStruct(59); $contentService->publishVersion($contentService->createContent($contentCreateStruct, [$locationCreateStruct])->versionInfo); $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); $contentCreateStruct->setField('name', new TextLineValue('')); $contentCreateStruct->setField('identifier', new TextLineValue(strtolower($identifier))); $contentCreateStruct->setField('parent', new TaxonomyEntryValue( $this->taxonomyService->loadRootEntry('tags'), )); try { $locationCreateStruct = $repository->getLocationService()->newLocationCreateStruct(59); $contentService->publishVersion($contentService->createContent($contentCreateStruct, [$locationCreateStruct])->versionInfo); } catch (ContentFieldValidationException $e) { dump($e->getFieldErrors()); } } ); return new Response("<html><body>Done</body></html>"); } }
The code above will first create two tags with same identifier. The second time, the tag will be created with two validations errors and you can see the structure is not consistent.
It will look like this:
array:2 [▼ 190 => array:1 [▼ "eng-GB" => Ibexa\Core\FieldType\ValidationError {#5685 ▼ #singular: "Value for required field definition '%identifier%' with language '%languageCode%' is empty" #plural: null #values: array:2 [▶] #target: "empty" } ] 0 => Ibexa\Core\FieldType\ValidationError {#5680 ▼ #singular: "Taxonomy Entry with identifier "{{ identifier }}" already exists in "{{ taxonomy }}" taxonomy tree. Please use unique identifier." #plural: null #values: array:2 [▶] #target: null } ]