Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Completed
Pull Request — 0.11 (#621)
by Jérémiah
20:51 queued 18:00
created

AutoMappingPass::addServicesDefinitions()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 2
1
<?php
2
3
namespace Overblog\GraphQLBundle\DependencyInjection\Compiler;
4
5
use GraphQL\Type\Definition\Type;
6
use Overblog\GraphQLBundle\Definition\Resolver\AliasedInterface;
7
use Overblog\GraphQLBundle\Definition\Resolver\MutationInterface;
8
use Overblog\GraphQLBundle\Definition\Resolver\ResolverInterface;
9
use Overblog\GraphQLBundle\OverblogGraphQLBundle;
10
use Symfony\Component\Config\Resource\DirectoryResource;
11
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
12
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
13
use Symfony\Component\DependencyInjection\ContainerBuilder;
14
use Symfony\Component\DependencyInjection\Definition;
15
use Symfony\Component\DependencyInjection\Reference;
16
use Symfony\Component\Finder\Finder;
17
18
class AutoMappingPass implements CompilerPassInterface
19
{
20
    const SERVICE_SUBCLASS_TAG_MAPPING = [
21
        MutationInterface::class => 'overblog_graphql.mutation',
22
        ResolverInterface::class => 'overblog_graphql.resolver',
23
        Type::class => TypeTaggedServiceMappingPass::TAG_NAME,
24
    ];
25
26 31
    public function process(ContainerBuilder $container)
27
    {
28 31
        $enabled = $container->getParameter('overblog_graphql.auto_mapping.enabled');
29
        // enabled auto mapping for all bundles and custom dirs ?
30 31
        if ($enabled) {
31 1
            $directories = $container->getParameter('overblog_graphql.auto_mapping.directories');
32 1
            $bundles = $container->getParameter('kernel.bundles');
33 1
            $directories = \array_merge(
34 1
                \array_map(
35
                    function ($class) {
36 1
                        $bundleDir = $this->bundleDir($class);
37
38 1
                        return $bundleDir.'/GraphQL';
39 1
                    },
40 1
                    $bundles
41
                ),
42 1
                $directories
43
            );
44
            // add app dir
45 1
            $directories[] = $container->hasParameter('kernel.root_dir') ?
46
                $container->getParameter('kernel.root_dir').'/GraphQL' :
47 1
                $container->getParameter('kernel.project_dir').'/GraphQL'
48
            ;
49
        } else {
50
            // enabled auto mapping only for this bundle
51 30
            $directories = [$this->bundleDir(OverblogGraphQLBundle::class).'/GraphQL'];
52
        }
53 31
        $directoryList = [];
54
55 31
        foreach ($directories as $directory) {
56 31
            list($reflectionClasses, $directories) = $this->reflectionClassesFromDirectory($directory);
57 31
            $directoryList = \array_merge($directoryList, $directories);
58 31
            $this->addServicesDefinitions($container, $reflectionClasses);
59
        }
60
61 31
        foreach ($directoryList as $directory => $v) {
62 31
            $directory = \realpath($directory);
63 31
            $container->addResource(new DirectoryResource($directory, '/\.php$/'));
64
        }
65 31
    }
66
67
    /**
68
     * @param ContainerBuilder   $container
69
     * @param \ReflectionClass[] $reflectionClasses
70
     */
71 31
    private function addServicesDefinitions(ContainerBuilder $container, array $reflectionClasses)
72
    {
73 31
        foreach ($reflectionClasses as $reflectionClass) {
74 31
            $this->addServiceDefinition($container, $reflectionClass);
75
        }
76 31
    }
77
78 31
    private function addServiceDefinition(ContainerBuilder $container, \ReflectionClass $reflectionClass)
79
    {
80 31
        $className = $reflectionClass->getName();
81 31
        $definition = $container->setDefinition($className, new Definition($className));
82 31
        $definition->setPublic(false);
83 31
        $definition->setAutowired(true);
84 31
        if (\is_subclass_of($definition->getClass(), ContainerAwareInterface::class)) {
85 1
            $definition->addMethodCall('setContainer', [new Reference('service_container')]);
86
        }
87 31
        $this->addDefinitionTags($definition, $reflectionClass);
88 31
    }
89
90 31
    private function addDefinitionTags(Definition $definition, \ReflectionClass $reflectionClass)
91
    {
92 31
        foreach (self::SERVICE_SUBCLASS_TAG_MAPPING as $subclass => $tagName) {
93 31
            if (!$reflectionClass->isSubclassOf($subclass)) {
94 31
                continue;
95
            }
96
97 31
            if (Type::class !== $subclass) {
98 31
                $publicReflectionMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
99 31
                $isAliased = $reflectionClass->implementsInterface(AliasedInterface::class);
100 31
                foreach ($publicReflectionMethods as $publicReflectionMethod) {
101 31
                    if ('__construct' === $publicReflectionMethod->name || $isAliased && 'getAliases' === $publicReflectionMethod->name) {
102 31
                        continue;
103
                    }
104 31
                    $definition->addTag($tagName, ['method' => $publicReflectionMethod->name]);
105
                }
106
            } else {
107 1
                $definition->addTag($tagName);
108
            }
109
        }
110 31
    }
111
112 31
    private function subclass($class)
113
    {
114 31
        $interfaces = \array_keys(self::SERVICE_SUBCLASS_TAG_MAPPING);
115
116 31
        foreach ($interfaces as $interface) {
117 31
            if (\is_a($class, $interface, true)) {
118 31
                return $interface;
119
            }
120
        }
121
122 31
        return false;
123
    }
124
125
    /**
126
     * Gets the classes reflection of class in the given directory.
127
     *
128
     * @param string $directory
129
     *
130
     * @return array
131
     */
132 31
    private function reflectionClassesFromDirectory($directory)
133
    {
134 31
        $classes = [];
135 31
        $directoryList = [];
136 31
        $includedFiles = [];
137 31
        $reflectionClasses = [];
138
139 31
        $finder = new Finder();
140
        try {
141 31
            $finder->in($directory)->files()->name('*.php');
142 1
        } catch (\InvalidArgumentException $e) {
143 1
            return [$reflectionClasses, $directoryList];
144
        }
145
146 31
        foreach ($finder as $file) {
147 31
            $directoryList[$file->getPath()] = true;
148 31
            $sourceFile = $file->getRealpath();
149 31
            if (!\preg_match('(^phar:)i', $sourceFile)) {
150 31
                $sourceFile = \realpath($sourceFile);
151
            }
152
153 31
            require_once $sourceFile;
154 31
            $includedFiles[$sourceFile] = true;
155
        }
156
157 31
        $declared = \get_declared_classes();
158 31
        foreach ($declared as $className) {
159 31
            $subclass = $this->subclass($className);
160 31
            if (false === $subclass) {
161 31
                continue;
162
            }
163 31
            $reflectionClass = new \ReflectionClass($className);
164 31
            $reflectionClasses[$className] = $reflectionClass;
165 31
            $sourceFile = $reflectionClass->getFileName();
166
167 31
            if ($reflectionClass->isAbstract()) {
168 31
                continue;
169
            }
170
171 31
            if (isset($includedFiles[$sourceFile])) {
172 31
                $classes[$className] = true;
173
            }
174
        }
175
176 31
        return [\array_intersect_key($reflectionClasses, $classes), $directoryList];
177
    }
178
179 31
    private function bundleDir($bundleClass)
180
    {
181 31
        $bundle = new \ReflectionClass($bundleClass);
182 31
        $bundleDir = \dirname($bundle->getFileName());
183
184 31
        return $bundleDir;
185
    }
186
}
187