vendor/gedmo/doctrine-extensions/src/Translatable/Mapping/Driver/Attribute.php line 60

  1. <?php
  2. /*
  3.  * This file is part of the Doctrine Behavioral Extensions package.
  4.  * (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
  5.  * For the full copyright and license information, please view the LICENSE
  6.  * file that was distributed with this source code.
  7.  */
  8. namespace Gedmo\Translatable\Mapping\Driver;
  9. use Gedmo\Exception\InvalidMappingException;
  10. use Gedmo\Mapping\Annotation\Language;
  11. use Gedmo\Mapping\Annotation\Locale;
  12. use Gedmo\Mapping\Annotation\Translatable;
  13. use Gedmo\Mapping\Annotation\TranslationEntity;
  14. use Gedmo\Mapping\Driver\AbstractAnnotationDriver;
  15. /**
  16.  * Mapping driver for the translatable extension which reads extended metadata from annotations on a translatable class.
  17.  *
  18.  * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  19.  *
  20.  * @internal
  21.  */
  22. class Attribute extends AbstractAnnotationDriver
  23. {
  24.     /**
  25.      * Mapping object to configure the translation model for a translatable class.
  26.      */
  27.     public const ENTITY_CLASS TranslationEntity::class;
  28.     /**
  29.      * Mapping object to identify a field as translatable in a translatable class.
  30.      */
  31.     public const TRANSLATABLE Translatable::class;
  32.     /**
  33.      * Mapping object to identify the field which stores the locale or language for the translation.
  34.      *
  35.      * This object is an alias of {@see self::LANGUAGE}
  36.      */
  37.     public const LOCALE Locale::class;
  38.     /**
  39.      * Mapping object to identify the field which stores the locale or language for the translation.
  40.      *
  41.      * This object is an alias of {@see self::LOCALE}
  42.      */
  43.     public const LANGUAGE Language::class;
  44.     public function readExtendedMetadata($meta, array &$config)
  45.     {
  46.         $class $this->getMetaReflectionClass($meta);
  47.         // class annotations
  48.         if ($annot $this->reader->getClassAnnotation($classself::ENTITY_CLASS)) {
  49.             \assert($annot instanceof TranslationEntity);
  50.             if (!$cl $this->getRelatedClassName($meta$annot->class)) {
  51.                 throw new InvalidMappingException("Translation class: {$annot->class} does not exist.");
  52.             }
  53.             $config['translationClass'] = $cl;
  54.         }
  55.         // property annotations
  56.         foreach ($class->getProperties() as $property) {
  57.             if ($meta->isMappedSuperclass && !$property->isPrivate()
  58.                 || $meta->isInheritedField($property->name)
  59.                 || isset($meta->associationMappings[$property->name]['inherited'])
  60.             ) {
  61.                 continue;
  62.             }
  63.             // translatable property
  64.             if ($translatable $this->reader->getPropertyAnnotation($propertyself::TRANSLATABLE)) {
  65.                 \assert($translatable instanceof Translatable);
  66.                 $field $property->getName();
  67.                 if (!$meta->hasField($field)) {
  68.                     throw new InvalidMappingException("Unable to find translatable [{$field}] as mapped property in entity - {$meta->getName()}");
  69.                 }
  70.                 // fields cannot be overrided and throws mapping exception
  71.                 $config['fields'][] = $field;
  72.                 if (isset($translatable->fallback)) {
  73.                     $config['fallback'][$field] = $translatable->fallback;
  74.                 }
  75.             }
  76.             // locale property
  77.             if ($this->reader->getPropertyAnnotation($propertyself::LOCALE)) {
  78.                 $field $property->getName();
  79.                 if ($meta->hasField($field)) {
  80.                     throw new InvalidMappingException("Locale field [{$field}] should not be mapped as column property in entity - {$meta->getName()}, since it makes no sense");
  81.                 }
  82.                 $config['locale'] = $field;
  83.             } elseif ($this->reader->getPropertyAnnotation($propertyself::LANGUAGE)) {
  84.                 $field $property->getName();
  85.                 if ($meta->hasField($field)) {
  86.                     throw new InvalidMappingException("Language field [{$field}] should not be mapped as column property in entity - {$meta->getName()}, since it makes no sense");
  87.                 }
  88.                 $config['locale'] = $field;
  89.             }
  90.         }
  91.         // Embedded entity
  92.         if (property_exists($meta'embeddedClasses') && $meta->embeddedClasses) {
  93.             foreach ($meta->embeddedClasses as $propertyName => $embeddedClassInfo) {
  94.                 if ($meta->isInheritedEmbeddedClass($propertyName)) {
  95.                     continue;
  96.                 }
  97.                 $embeddedClass = new \ReflectionClass($embeddedClassInfo['class']);
  98.                 foreach ($embeddedClass->getProperties() as $embeddedProperty) {
  99.                     if ($translatable $this->reader->getPropertyAnnotation($embeddedPropertyself::TRANSLATABLE)) {
  100.                         \assert($translatable instanceof Translatable);
  101.                         $field $propertyName.'.'.$embeddedProperty->getName();
  102.                         $config['fields'][] = $field;
  103.                         if (isset($translatable->fallback)) {
  104.                             $config['fallback'][$field] = $translatable->fallback;
  105.                         }
  106.                     }
  107.                 }
  108.             }
  109.         }
  110.         if (!$meta->isMappedSuperclass && $config) {
  111.             if (is_array($meta->getIdentifier()) && count($meta->getIdentifier()) > 1) {
  112.                 throw new InvalidMappingException("Translatable does not support composite identifiers in class - {$meta->getName()}");
  113.             }
  114.         }
  115.         return $config;
  116.     }
  117. }