vendor/sonata-project/doctrine-orm-admin-bundle/src/FieldDescription/FieldDescriptionFactory.php line 34

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * This file is part of the Sonata Project package.
  5.  *
  6.  * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  7.  *
  8.  * For the full copyright and license information, please view the LICENSE
  9.  * file that was distributed with this source code.
  10.  */
  11. namespace Sonata\DoctrineORMAdminBundle\FieldDescription;
  12. use Doctrine\ORM\EntityManagerInterface;
  13. use Doctrine\ORM\Mapping\ClassMetadata;
  14. use Sonata\AdminBundle\FieldDescription\FieldDescriptionFactoryInterface;
  15. use Sonata\AdminBundle\FieldDescription\FieldDescriptionInterface;
  16. use Symfony\Bridge\Doctrine\ManagerRegistry;
  17. final class FieldDescriptionFactory implements FieldDescriptionFactoryInterface
  18. {
  19.     /**
  20.      * @var ManagerRegistry
  21.      */
  22.     private $registry;
  23.     public function __construct(ManagerRegistry $registry)
  24.     {
  25.         $this->registry $registry;
  26.     }
  27.     public function create(string $classstring $name, array $options = []): FieldDescriptionInterface
  28.     {
  29.         [$metadata$propertyName$parentAssociationMappings] = $this->getParentMetadataForProperty($class$name);
  30.         return new FieldDescription(
  31.             $name,
  32.             $options,
  33.             $metadata->fieldMappings[$propertyName] ?? [],
  34.             $metadata->associationMappings[$propertyName] ?? [],
  35.             $parentAssociationMappings,
  36.             $propertyName
  37.         );
  38.     }
  39.     /**
  40.      * @phpstan-param class-string $baseClass
  41.      *
  42.      * @phpstan-return array{ClassMetadata<object>, string, mixed[]}
  43.      */
  44.     private function getParentMetadataForProperty(string $baseClassstring $propertyFullName): array
  45.     {
  46.         $nameElements explode('.'$propertyFullName);
  47.         $lastPropertyName array_pop($nameElements);
  48.         $class $baseClass;
  49.         $parentAssociationMappings = [];
  50.         foreach ($nameElements as $nameElement) {
  51.             $metadata $this->getMetadata($class);
  52.             if (!isset($metadata->associationMappings[$nameElement])) {
  53.                 break;
  54.             }
  55.             $parentAssociationMappings[] = $metadata->associationMappings[$nameElement];
  56.             $class $metadata->getAssociationTargetClass($nameElement);
  57.         }
  58.         $properties = \array_slice($nameElements, \count($parentAssociationMappings));
  59.         $properties[] = $lastPropertyName;
  60.         return [
  61.             $this->getMetadata($class),
  62.             implode('.'$properties),
  63.             $parentAssociationMappings,
  64.         ];
  65.     }
  66.     /**
  67.      * @phpstan-template TObject of object
  68.      * @phpstan-param class-string<TObject> $class
  69.      * @phpstan-return ClassMetadata<TObject>
  70.      */
  71.     private function getMetadata(string $class): ClassMetadata
  72.     {
  73.         return $this->getEntityManager($class)->getClassMetadata($class);
  74.     }
  75.     /**
  76.      * @param class-string $class
  77.      *
  78.      * @throw \UnexpectedValueException
  79.      */
  80.     private function getEntityManager(string $class): EntityManagerInterface
  81.     {
  82.         $em $this->registry->getManagerForClass($class);
  83.         if (!$em instanceof EntityManagerInterface) {
  84.             throw new \UnexpectedValueException(sprintf('No entity manager defined for class "%s".'$class));
  85.         }
  86.         return $em;
  87.     }
  88. }