app/Plugin/Api42/GraphQL/Types.php line 70

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Plugin\Api42\GraphQL;
  13. use Doctrine\ORM\EntityManager;
  14. use Doctrine\ORM\Mapping\ClassMetadata;
  15. use GraphQL\Type\Definition\ObjectType;
  16. use GraphQL\Type\Definition\Type;
  17. use Plugin\Api42\GraphQL\Type\Definition\DateTimeType;
  18. /**
  19.  * DoctrineのEntityからGraphQLのObjectTypeを変換するクラス.
  20.  */
  21. class Types
  22. {
  23.     /** @var EntityManager */
  24.     private $entityManager;
  25.     private $types = [];
  26.     private $allowLists = [];
  27.     /**
  28.      * Types constructor.
  29.      */
  30.     public function __construct(EntityManager $entityManager)
  31.     {
  32.         $this->entityManager $entityManager;
  33.     }
  34.     public function addAllowList(AllowList $allowList)
  35.     {
  36.         $this->allowLists[] = $allowList;
  37.     }
  38.     /**
  39.      * Entityに対応するObjectTypeを返す.
  40.      *
  41.      * @param $className string Entityクラス名
  42.      *
  43.      * @return ObjectType
  44.      */
  45.     public function get($className)
  46.     {
  47.         if (!isset($this->types[$className])) {
  48.             $this->types[$className] = $this->createObjectType($className);
  49.         }
  50.         return $this->types[$className];
  51.     }
  52.     private function createObjectType($className)
  53.     {
  54.         return new ObjectType([
  55.             'name' => (new \ReflectionClass($className))->getShortName(),
  56.             'fields' => function () use ($className) {
  57.                 $classMetadata $this->entityManager->getClassMetadata($className);
  58.                 $fields array_reduce($classMetadata->fieldMappings, function ($acc$mapping) use ($classMetadata) {
  59.                     $type $this->convertFieldMappingToType($mapping);
  60.                     $fieldName $mapping['fieldName'];
  61.                     $allowed array_filter($this->allowLists, function (AllowList $al) use ($classMetadata$fieldName) {
  62.                         return $al->isAllowed($classMetadata->name$fieldName);
  63.                     });
  64.                     if ($allowed && $type) {
  65.                         $acc[$fieldName] = $type;
  66.                     }
  67.                     return $acc;
  68.                 }, []);
  69.                 $fields array_reduce($classMetadata->associationMappings, function ($acc$mapping) use ($classMetadata) {
  70.                     $fieldName $mapping['fieldName'];
  71.                     $allowed array_filter($this->allowLists, function (AllowList $al) use ($classMetadata$fieldName) {
  72.                         return $al->isAllowed($classMetadata->name$fieldName);
  73.                     });
  74.                     if ($allowed) {
  75.                         $acc[$fieldName] = [
  76.                             'type' => $this->convertAssociationMappingToType($mapping),
  77.                         ];
  78.                     }
  79.                     return $acc;
  80.                 }, $fields);
  81.                 return $fields;
  82.             },
  83.         ]);
  84.     }
  85.     private function convertFieldMappingToType($fieldMapping)
  86.     {
  87.         $type = isset($fieldMapping['id']) ? Type::id() : [
  88.             'string' => Type::string(),
  89.             'text' => Type::string(),
  90.             'integer' => Type::int(),
  91.             'decimal' => Type::float(),
  92.             'datetimetz' => DateTimeType::dateTime(),
  93.             'smallint' => Type::int(),
  94.             'boolean' => Type::boolean(),
  95.         ][$fieldMapping['type']];
  96.         if ($type) {
  97.             return $fieldMapping['nullable'] ? $type Type::nonNull($type);
  98.         }
  99.         return null;
  100.     }
  101.     private function convertAssociationMappingToType($mapping)
  102.     {
  103.         return $this->isToManyAssociation($mapping) ? Type::listOf($this->get($mapping['targetEntity'])) : $this->get($mapping['targetEntity']);
  104.     }
  105.     private function isToManyAssociation($mapping)
  106.     {
  107.         return $mapping['type'] & ClassMetadata::TO_MANY;
  108.     }
  109. }