Passed
Pull Request — main (#112)
by Tom
03:05
created

src/Services.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApiSkeletons\Doctrine\GraphQL;
6
7
use Doctrine\ORM\EntityManager;
8
use League\Event\EventDispatcher;
9
use Psr\Container\ContainerInterface;
10
11
/**
12
 * This trait is used to remove complexity from the Driver class.
13
 * It doesn't change what the Driver does.  It just separates the container work
14
 * from the GraphQL Driver.
15
 */
16
trait Services
17
{
18
    /**
19
     * By default all Driver instances share the same TypeManager.
20
     * The reason for this is because PageInfo is a required type name and
21
     * would collide if two drivers are used in the same schema.
22
     * To override this and use a non-shared local TypeManager, set this flag
23
     * before you instantiate the driver.
24
     */
25
    public static bool $clearTypeManager = false;
26
27
    /**
28
     * This is the shared TypeManger for all Drivers
29
     */
30
    private static Type\TypeManager|null $typeManagerShared = null;
31
32
    /**
33
     * A local persisting flag for the value of $clearTypeManager when
34
     * the Driver is created.
35
     */
36
    private bool $clearTypeManagerLocal = false;
37
38
    /**
39
     * @param string                 $entityManagerAlias required
40
     * @param Config                 $config             required
41
     * @param Metadata\Metadata|null $metadata           optional so cached metadata can be loaded
42
     */
43
    public function __construct(
44
        EntityManager $entityManager,
45
        Config|null $config = null,
46
        array|null $metadataConfig = null,
47
    ) {
48
        $this->clearTypeManagerLocal = self::$clearTypeManager;
49
50
        if (! self::$typeManagerShared) {
51
            self::$typeManagerShared = new Type\TypeManager();
52
        }
53
54
        $this
55
            // Plain classes
56
            ->set(EntityManager::class, $entityManager)
57
            ->set(
58
                Config::class,
59
                static function () use ($config) {
60
                    if (! $config) {
61
                        $config = new Config();
62
                    }
63
64
                    return $config;
65
                },
66
            )
67
            ->set(
68
                EventDispatcher::class,
69
                static fn () => new EventDispatcher()
70
            )
71
            ->set(
72
                Type\TypeManager::class,
73
                fn () => $this->clearTypeManagerLocal ?
74
                        new Type\TypeManager()
75
                        : self::$typeManagerShared,
76
            )
77
            ->set(
78
                Metadata\Metadata::class,
79
                static function (ContainerInterface $container) use ($metadataConfig) {
80
                    return (new Metadata\MetadataFactory($container, $metadataConfig))->getMetadata();
81
                },
82
            )
83
            ->set(
84
                Resolve\FieldResolver::class,
85
                static function (ContainerInterface $container) {
86
                    return new Resolve\FieldResolver(
87
                        $container->get(Config::class),
88
                        $container->get(Metadata\Metadata::class),
89
                    );
90
                },
91
            )
92
            ->set(
93
                Resolve\ResolveCollectionFactory::class,
94
                static function (ContainerInterface $container) {
95
                    return new Resolve\ResolveCollectionFactory(
96
                        $container->get(EntityManager::class),
97
                        $container->get(Config::class),
98
                        $container->get(Resolve\FieldResolver::class),
99
                        $container->get(Type\TypeManager::class),
100
                    );
101
                },
102
            )
103
            ->set(
104
                Resolve\ResolveEntityFactory::class,
105
                static function (ContainerInterface $container) {
106
                    return new Resolve\ResolveEntityFactory(
107
                        $container->get(Config::class),
108
                        $container->get(EntityManager::class),
109
                        $container->get(EventDispatcher::class),
110
                    );
111
                },
112
            )
113
            ->set(
114
                Criteria\CriteriaFactory::class,
115
                static function (ContainerInterface $container) {
116
                    return new Criteria\CriteriaFactory(
117
                        $container->get(Config::class),
118
                        $container->get(EntityManager::class),
119
                        $container->get(Type\TypeManager::class),
120
                        $container->get(EventDispatcher::class),
121
                    );
122
                },
123
            )
124
            ->set(
125
                Hydrator\HydratorFactory::class,
126
                static function (ContainerInterface $container) {
127
                    return new Hydrator\HydratorFactory(
128
                        $container->get(EntityManager::class),
129
                        $container->get(Metadata\Metadata::class),
130
                    );
131
                },
132
            )
133
            ->set(
134
                Input\InputFactory::class,
135
                static function (ContainerInterface $container) {
136
                    return new Input\InputFactory(
137
                        $container->get(Config::class),
138
                        $container->get(EntityManager::class),
139
                        $container->get(Type\TypeManager::class),
140
                        $container->get(Metadata\Metadata::class),
141
                    );
142
                },
143
            );
144
145
        if (! $this->get(Config::class)->getGlobalEnable()) {
0 ignored issues
show
It seems like get() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

145
        if (! $this->/** @scrutinizer ignore-call */ get(Config::class)->getGlobalEnable()) {
Loading history...
146
            return;
147
        }
148
149
        $this->set(Type\TypeManager::class, new Type\TypeManager());
150
    }
151
152
    abstract public function set(string $id, mixed $value): mixed;
153
}
154