vendor/ibexa/core/src/lib/Persistence/Legacy/Content/Mapper/ResolveVirtualFieldSubscriber.php line 54

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\Persistence\Legacy\Content\Mapper;
  8. use Ibexa\Contracts\Core\Event\Mapper\ResolveMissingFieldEvent;
  9. use Ibexa\Contracts\Core\FieldType\DefaultDataFieldStorage;
  10. use Ibexa\Contracts\Core\Persistence\Content\Field;
  11. use Ibexa\Contracts\Core\Persistence\Content\FieldValue;
  12. use Ibexa\Contracts\Core\Persistence\Content\Type\FieldDefinition;
  13. use Ibexa\Contracts\Core\Persistence\Content\VersionInfo;
  14. use Ibexa\Core\FieldType\NullStorage;
  15. use Ibexa\Core\Persistence\Legacy\Content\FieldValue\Converter\Exception\NotFound;
  16. use Ibexa\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry;
  17. use Ibexa\Core\Persistence\Legacy\Content\Gateway as ContentGateway;
  18. use Ibexa\Core\Persistence\Legacy\Content\StorageFieldValue;
  19. use Ibexa\Core\Persistence\Legacy\Content\StorageRegistry;
  20. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  21. final class ResolveVirtualFieldSubscriber implements EventSubscriberInterface
  22. {
  23.     private ConverterRegistry $converterRegistry;
  24.     private StorageRegistry $storageRegistry;
  25.     private ContentGateway $contentGateway;
  26.     public function __construct(
  27.         ConverterRegistry $converterRegistry,
  28.         StorageRegistry $storageRegistry,
  29.         ContentGateway $contentGateway
  30.     ) {
  31.         $this->converterRegistry $converterRegistry;
  32.         $this->storageRegistry $storageRegistry;
  33.         $this->contentGateway $contentGateway;
  34.     }
  35.     public static function getSubscribedEvents(): array
  36.     {
  37.         return [
  38.             ResolveMissingFieldEvent::class => [
  39.                 ['persistExternalStorageField', -100],
  40.                 ['resolveVirtualExternalStorageField', -80],
  41.                 ['resolveVirtualField'0],
  42.             ],
  43.         ];
  44.     }
  45.     public function resolveVirtualField(ResolveMissingFieldEvent $event): void
  46.     {
  47.         if ($event->getField()) {
  48.             return;
  49.         }
  50.         $content $event->getContent();
  51.         try {
  52.             $emptyField $this->createEmptyField(
  53.                 $content->versionInfo,
  54.                 $event->getFieldDefinition(),
  55.                 $event->getLanguageCode()
  56.             );
  57.             $event->setField($emptyField);
  58.         } catch (NotFound $exception) {
  59.             return;
  60.         }
  61.     }
  62.     /**
  63.      * @throws \Ibexa\Core\Persistence\Legacy\Content\FieldValue\Converter\Exception\NotFound
  64.      */
  65.     public function persistExternalStorageField(ResolveMissingFieldEvent $event): void
  66.     {
  67.         $field $event->getField();
  68.         if ($field === null) {
  69.             // Nothing to persist
  70.             return;
  71.         }
  72.         if ($field->id !== null) {
  73.             // Not a virtual field
  74.             return;
  75.         }
  76.         $fieldDefinition $event->getFieldDefinition();
  77.         $storage $this->storageRegistry->getStorage($fieldDefinition->fieldType);
  78.         if ($storage instanceof NullStorage) {
  79.             // Not an external storage
  80.             return;
  81.         }
  82.         $content $event->getContent();
  83.         $field->id $this->contentGateway->insertNewField(
  84.             $content,
  85.             $field,
  86.             $this->getDefaultStorageValue()
  87.         );
  88.         if ($field->value->data !== null) {
  89.             $result $storage->storeFieldData(
  90.                 $content->versionInfo,
  91.                 $field,
  92.                 []
  93.             );
  94.             if ($result === true) {
  95.                 $storageValue = new StorageFieldValue();
  96.                 $converter $this->converterRegistry->getConverter($fieldDefinition->fieldType);
  97.                 $converter->toStorageValue(
  98.                     $field->value,
  99.                     $storageValue
  100.                 );
  101.                 $this->contentGateway->updateField(
  102.                     $field,
  103.                     $storageValue
  104.                 );
  105.             }
  106.         }
  107.         $storage->getFieldData(
  108.             $content->versionInfo,
  109.             $field,
  110.             []
  111.         );
  112.         $event->setField($field);
  113.     }
  114.     public function resolveVirtualExternalStorageField(ResolveMissingFieldEvent $event): void
  115.     {
  116.         $field $event->getField();
  117.         if ($field === null) {
  118.             // Nothing to resolve
  119.             return;
  120.         }
  121.         if ($field->id !== null) {
  122.             // Not a virtual field
  123.             return;
  124.         }
  125.         $fieldDefinition $event->getFieldDefinition();
  126.         $storage $this->storageRegistry->getStorage($fieldDefinition->fieldType);
  127.         if ($storage instanceof NullStorage) {
  128.             // Not an external storage
  129.             return;
  130.         }
  131.         if (!$storage instanceof DefaultDataFieldStorage) {
  132.             return;
  133.         }
  134.         $content $event->getContent();
  135.         $storage->getDefaultFieldData(
  136.             $content->versionInfo,
  137.             $field
  138.         );
  139.         $event->setField($field);
  140.         // Do not persist the external storage field
  141.         $event->stopPropagation();
  142.     }
  143.     /**
  144.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
  145.      */
  146.     private function createEmptyField(
  147.         VersionInfo $versionInfo,
  148.         FieldDefinition $fieldDefinition,
  149.         string $languageCode
  150.     ): Field {
  151.         $field = new Field();
  152.         $field->fieldDefinitionId $fieldDefinition->id;
  153.         $field->type $fieldDefinition->fieldType;
  154.         $field->value $this->getDefaultValue($fieldDefinition);
  155.         $field->languageCode $languageCode;
  156.         $field->versionNo $versionInfo->versionNo;
  157.         return $field;
  158.     }
  159.     /**
  160.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
  161.      */
  162.     private function getDefaultValue(FieldDefinition $fieldDefinition): FieldValue
  163.     {
  164.         $value = clone $fieldDefinition->defaultValue;
  165.         $storageValue $this->getDefaultStorageValue();
  166.         $converter $this->converterRegistry->getConverter($fieldDefinition->fieldType);
  167.         $converter->toStorageValue($value$storageValue);
  168.         $converter->toFieldValue($storageValue$value);
  169.         return $value;
  170.     }
  171.     private function getDefaultStorageValue(): StorageFieldValue
  172.     {
  173.         $storageValue = new StorageFieldValue();
  174.         $storageValue->dataFloat 0;
  175.         $storageValue->dataInt 0;
  176.         $storageValue->dataText '';
  177.         $storageValue->sortKeyInt 0;
  178.         $storageValue->sortKeyString '';
  179.         return $storageValue;
  180.     }
  181. }