vendor/ibexa/taxonomy/src/lib/Event/Subscriber/ValidateTaxonomyEntryAssignmentSubscriber.php line 47

Open in your IDE?
  1. <?php
  2. /**
  3. * @copyright Copyright (C) Ibexa AS. All rights reserved.
  4. * @license For full copyright and license information view LICENSE file distributed with this source code.
  5. */
  6. declare(strict_types=1);
  7. namespace Ibexa\Taxonomy\Event\Subscriber;
  8. use Ibexa\Contracts\Core\Repository\ContentService;
  9. use Ibexa\Contracts\Core\Repository\Events\Content\BeforeUpdateContentEvent;
  10. use Ibexa\Contracts\Core\Repository\PermissionResolver;
  11. use Ibexa\Core\Base\Exceptions\UnauthorizedException;
  12. use Ibexa\Core\FieldType\FieldType;
  13. use Ibexa\Core\Repository\Values\ContentType\FieldDefinition;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. /**
  16. * @internal
  17. */
  18. final class ValidateTaxonomyEntryAssignmentSubscriber implements EventSubscriberInterface
  19. {
  20. private ContentService $contentService;
  21. private FieldType $taxonomyEntryAssignmentFieldType;
  22. private PermissionResolver $permissionResolver;
  23. public function __construct(
  24. ContentService $contentService,
  25. FieldType $taxonomyEntryAssignmentFieldType,
  26. PermissionResolver $permissionResolver
  27. ) {
  28. $this->contentService = $contentService;
  29. $this->taxonomyEntryAssignmentFieldType = $taxonomyEntryAssignmentFieldType;
  30. $this->permissionResolver = $permissionResolver;
  31. }
  32. public static function getSubscribedEvents(): array
  33. {
  34. return [
  35. BeforeUpdateContentEvent::class => 'onBeforeUpdateContent',
  36. ];
  37. }
  38. public function onBeforeUpdateContent(BeforeUpdateContentEvent $event): void
  39. {
  40. $versionInfo = $event->getVersionInfo();
  41. $contentUpdateStruct = $event->getContentUpdateStruct();
  42. $taxonomyEntryAssignmentFieldTypeIdentifier = $this->taxonomyEntryAssignmentFieldType->getFieldTypeIdentifier();
  43. $content = $this->contentService->loadContentByVersionInfo($versionInfo);
  44. $contentType = $content->getContentType();
  45. if (!$contentType->hasFieldDefinitionOfType($taxonomyEntryAssignmentFieldTypeIdentifier)) {
  46. return;
  47. }
  48. $taxonomyEntryAssignmentFieldDefinitions = $contentType->getFieldDefinitionsOfType(
  49. $taxonomyEntryAssignmentFieldTypeIdentifier
  50. );
  51. $taxonomyEntryAssignmentFieldDefIdentifiers = $taxonomyEntryAssignmentFieldDefinitions->map(
  52. static fn (FieldDefinition $field): string => $field->identifier,
  53. );
  54. foreach ($contentUpdateStruct->fields as $field) {
  55. $contentField = $content->getField($field->fieldDefIdentifier, $field->languageCode);
  56. if (
  57. null === $contentField
  58. || !in_array($field->fieldDefIdentifier, $taxonomyEntryAssignmentFieldDefIdentifiers, true)
  59. || $this->taxonomyEntryAssignmentFieldType->isEmptyValue($field->value)
  60. ) {
  61. continue;
  62. }
  63. /** @var \Ibexa\Taxonomy\FieldType\TaxonomyEntryAssignment\Value $originalFieldValue */
  64. $originalFieldValue = $contentField->value;
  65. /** @var \Ibexa\Taxonomy\FieldType\TaxonomyEntryAssignment\Value $updatedFieldValue */
  66. $updatedFieldValue = $field->value;
  67. $originalEntryIdentifiers = array_column($originalFieldValue->getTaxonomyEntries(), 'identifier');
  68. $updatedEntryIdentifiers = array_column($updatedFieldValue->getTaxonomyEntries(), 'identifier');
  69. $isFieldUpdated = $originalFieldValue->getTaxonomy() !== $updatedFieldValue->getTaxonomy()
  70. || $originalEntryIdentifiers != $updatedEntryIdentifiers;
  71. if ($isFieldUpdated && !$this->permissionResolver->hasAccess('taxonomy', 'assign')) {
  72. throw new UnauthorizedException('taxonomy', 'read', ['contentId' => $content->id]);
  73. }
  74. }
  75. }
  76. }