vendor/ibexa/core/src/lib/Repository/EventSubscriber/NameSchemaSubscriber.php line 48

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\Core\Repository\EventSubscriber;
  8. use Ibexa\Contracts\Core\Event\NameSchema\AbstractSchemaEvent;
  9. use Ibexa\Contracts\Core\Event\NameSchema\ResolveContentNameSchemaEvent;
  10. use Ibexa\Contracts\Core\Event\NameSchema\ResolveNameSchemaEvent;
  11. use Ibexa\Contracts\Core\Event\NameSchema\ResolveUrlAliasSchemaEvent;
  12. use Ibexa\Contracts\Core\Repository\Values\Content\Content;
  13. use Ibexa\Contracts\Core\Repository\Values\Content\Language;
  14. use Ibexa\Contracts\Core\Repository\Values\ContentType\ContentType;
  15. use Ibexa\Core\FieldType\FieldTypeRegistry;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. /**
  18. * @internal
  19. */
  20. final class NameSchemaSubscriber implements EventSubscriberInterface
  21. {
  22. private FieldTypeRegistry $fieldTypeRegistry;
  23. public function __construct(FieldTypeRegistry $fieldTypeRegistry)
  24. {
  25. $this->fieldTypeRegistry = $fieldTypeRegistry;
  26. }
  27. public static function getSubscribedEvents(): array
  28. {
  29. return [
  30. ResolveNameSchemaEvent::class => [
  31. ['onResolveNameSchema', -100],
  32. ],
  33. ResolveContentNameSchemaEvent::class => [
  34. ['onResolveContentNameSchema', -100],
  35. ],
  36. ResolveUrlAliasSchemaEvent::class => [
  37. ['onResolveUrlAliasSchema', -100],
  38. ],
  39. ];
  40. }
  41. public function onResolveNameSchema(ResolveNameSchemaEvent $event): void
  42. {
  43. if (!$this->isValid($event)) {
  44. return;
  45. }
  46. $tokenValues = $this->processEvent(
  47. $event->getLanguageCodes(),
  48. $event->getSchemaIdentifiers()['field'],
  49. $event->getContentType(),
  50. null,
  51. $event->getTokenValues(),
  52. $event->getFieldMap()
  53. );
  54. $event->setTokenValues($tokenValues);
  55. }
  56. public function onResolveContentNameSchema(ResolveContentNameSchemaEvent $event): void
  57. {
  58. if (!$this->isValid($event)) {
  59. return;
  60. }
  61. $tokenValues = $this->processEvent(
  62. $event->getLanguageCodes(),
  63. $event->getSchemaIdentifiers()['field'],
  64. $event->getContentType(),
  65. $event->getContent(),
  66. $event->getTokenValues(),
  67. $event->getFieldMap()
  68. );
  69. $event->setTokenValues($tokenValues);
  70. }
  71. public function onResolveUrlAliasSchema(ResolveUrlAliasSchemaEvent $event): void
  72. {
  73. if (!$this->isValid($event)) {
  74. return;
  75. }
  76. $languageList = array_map(
  77. static fn (Language $language): string => $language->getLanguageCode(),
  78. (array)$event->getContent()->getVersionInfo()->getLanguages()
  79. );
  80. $content = $event->getContent();
  81. $contentType = $content->getContentType();
  82. $tokenValues = $this->processEvent(
  83. $languageList,
  84. $event->getSchemaIdentifiers()['field'],
  85. $contentType,
  86. $content,
  87. $event->getTokenValues()
  88. );
  89. $event->setTokenValues($tokenValues);
  90. }
  91. public function isValid(AbstractSchemaEvent $event): bool
  92. {
  93. return array_key_exists('field', $event->getSchemaIdentifiers());
  94. }
  95. /**
  96. * @param array<string> $languages
  97. * @param array<int, string> $identifiers
  98. * @param array<string, array<string, string>> $tokenValues
  99. * @param array<int|string, array<string, \Ibexa\Contracts\Core\FieldType\Value>> $fieldMap
  100. *
  101. * @return array<string, array<string, string>>
  102. */
  103. private function processEvent(
  104. array $languages,
  105. array $identifiers,
  106. ContentType $contentType,
  107. ?Content $content,
  108. array $tokenValues,
  109. array $fieldMap = []
  110. ): array {
  111. foreach ($languages as $languageCode) {
  112. $values = $content !== null || !empty($fieldMap)
  113. ? $this->getValues(
  114. $identifiers,
  115. $contentType,
  116. $content,
  117. $fieldMap,
  118. $languageCode
  119. )
  120. : [];
  121. $tokenValues[$languageCode] = array_merge($tokenValues[$languageCode] ?? [], $values);
  122. }
  123. return $tokenValues;
  124. }
  125. /**
  126. * @param array<int, string> $identifiers
  127. * @param array<int|string, array<string, \Ibexa\Contracts\Core\FieldType\Value>> $fieldMap
  128. *
  129. * @return array<string, string>
  130. */
  131. private function getValues(
  132. array $identifiers,
  133. ContentType $contentType,
  134. ?Content $content,
  135. array $fieldMap,
  136. string $languageCode
  137. ): array {
  138. $tokenValues = [];
  139. foreach ($identifiers as $identifier) {
  140. $fieldDefinition = $contentType->getFieldDefinition($identifier);
  141. if (null === $fieldDefinition) {
  142. continue;
  143. }
  144. $persistenceFieldType = $this->fieldTypeRegistry->getFieldType($fieldDefinition->fieldTypeIdentifier);
  145. if (!empty($fieldMap)) {
  146. $fieldValue = $fieldMap[$identifier][$languageCode] ?? null;
  147. } else {
  148. $fieldValue = $content !== null ? $content->getFieldValue($identifier, $languageCode) : null;
  149. }
  150. $tokenValues[$identifier] = $fieldValue !== null ? $persistenceFieldType->getName(
  151. $fieldValue,
  152. $fieldDefinition,
  153. $languageCode
  154. ) : '';
  155. }
  156. return $tokenValues;
  157. }
  158. }