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
Push — master ( ddaabd...e014e6 )
by Jérémiah
08:04
created

AutoMappingPass::process()   B

Complexity

Conditions 5
Paths 12

Size

Total Lines 39
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 39
ccs 29
cts 29
cp 1
rs 8.439
c 0
b 0
f 0
cc 5
eloc 24
nc 12
nop 1
crap 5
1
<?php
2
3
/*
4
 * This file is part of the OverblogGraphQLBundle package.
5
 *
6
 * (c) Overblog <http://github.com/overblog/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Overblog\GraphQLBundle\DependencyInjection\Compiler;
13
14
use GraphQL\Type\Definition\Type;
15
use Overblog\GraphQLBundle\Definition\Resolver\AliasedInterface;
16
use Overblog\GraphQLBundle\Definition\Resolver\MutationInterface;
17
use Overblog\GraphQLBundle\Definition\Resolver\ResolverInterface;
18
use Overblog\GraphQLBundle\OverblogGraphQLBundle;
19
use Symfony\Component\Config\Resource\DirectoryResource;
20
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
21
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
22
use Symfony\Component\DependencyInjection\ContainerBuilder;
23
use Symfony\Component\DependencyInjection\Definition;
24
use Symfony\Component\DependencyInjection\Reference;
25
use Symfony\Component\Finder\Finder;
26
27
class AutoMappingPass implements CompilerPassInterface
28
{
29
    private static $serviceSubclassTagMapping = [
30
        MutationInterface::class => 'overblog_graphql.mutation',
31
        ResolverInterface::class => 'overblog_graphql.resolver',
32
        Type::class => 'overblog_graphql.type',
33
    ];
34
35 14
    public function process(ContainerBuilder $container)
36
    {
37 14
        $enabled = $container->getParameter('overblog_graphql.auto_mapping.enabled');
38
        // enabled auto mapping for all bundles and custom dirs ?
39 14
        if ($enabled) {
40 1
            $directories = $container->getParameter('overblog_graphql.auto_mapping.directories');
41 1
            $bundles = $container->getParameter('kernel.bundles');
42 1
            $directories = array_merge(
43 1
                array_map(
44 1
                    function ($class) {
45 1
                        $bundleDir = $this->bundleDir($class);
46
47 1
                        return $bundleDir.'/GraphQL';
48 1
                    },
49
                    $bundles
50 1
                ),
51
                $directories
52 1
            );
53
            // add app dir
54 1
            if ($container->hasParameter('kernel.root_dir')) {
55 1
                $directories[] = $container->getParameter('kernel.root_dir').'/GraphQL';
56 1
            }
57 1
        } else {
58
            // enabled auto mapping only for this bundle
59 13
            $directories = [$this->bundleDir(OverblogGraphQLBundle::class).'/GraphQL'];
60
        }
61 14
        $directoryList = [];
62
63 14
        foreach ($directories as $directory) {
64 14
            list($reflectionClasses, $directories) = $this->reflectionClassesFromDirectory($directory);
65 14
            $directoryList = array_merge($directoryList, $directories);
66 14
            $this->addServicesDefinitions($container, $reflectionClasses);
67 14
        }
68
69 14
        foreach ($directoryList as $directory => $v) {
70 14
            $directory = realpath($directory);
71 14
            $container->addResource(new DirectoryResource($directory, '/\.php$/'));
72 14
        }
73 14
    }
74
75
    /**
76
     * @param ContainerBuilder   $container
77
     * @param \ReflectionClass[] $reflectionClasses
78
     */
79 14
    private function addServicesDefinitions(ContainerBuilder $container, array $reflectionClasses)
80
    {
81 14
        foreach ($reflectionClasses as $reflectionClass) {
82 14
            $this->addServiceDefinition($container, $reflectionClass);
83 14
        }
84 14
    }
85
86 14
    private function addServiceDefinition(ContainerBuilder $container, \ReflectionClass $reflectionClass)
87
    {
88 14
        $className = $reflectionClass->getName();
0 ignored issues
show
Bug introduced by
Consider using $reflectionClass->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
89 14
        $definition = $container->setDefinition($className, new Definition($className));
90 14
        $definition->setPublic(false);
91 14
        $definition->setAutowired(true);
92 14
        if (is_subclass_of($definition->getClass(), ContainerAwareInterface::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Symfony\Component\Depen...erAwareInterface::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
93 1
            $definition->addMethodCall('setContainer', [new Reference('service_container')]);
94 1
        }
95 14
        $this->addDefinitionTags($definition, $reflectionClass);
96 14
    }
97
98 14
    private function addDefinitionTags(Definition $definition, \ReflectionClass $reflectionClass)
99
    {
100 14
        $className = $definition->getClass();
101
102 14
        foreach (self::$serviceSubclassTagMapping as $subclass => $tagName) {
103 14
            if (!$reflectionClass->isSubclassOf($subclass)) {
104 14
                continue;
105
            }
106
107 14
            if (Type::class !== $subclass) {
108 14
                $publicReflectionMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
109 14
                $isAliased = $reflectionClass->implementsInterface(AliasedInterface::class);
110 14
                foreach ($publicReflectionMethods as $publicReflectionMethod) {
111 14
                    if ('__construct' === $publicReflectionMethod->name || $isAliased && 'getAliases' === $publicReflectionMethod->name) {
112 14
                        continue;
113
                    }
114 14
                    $definition->addTag($tagName, ['method' => $publicReflectionMethod->name]);
115 14
                }
116 14
                if ($isAliased) {
117 14
                    $this->addDefinitionTagsFromAliasesMethod($definition, $className, $tagName, true);
118 14
                }
119 14
            } else {
120 1
                $definition->addTag($tagName);
121 1
                $this->addDefinitionTagsFromAliasesMethod($definition, $className, $tagName, false);
122
            }
123 14
        }
124 14
    }
125
126 14
    private function addDefinitionTagsFromAliasesMethod(Definition $definition, $className, $tagName, $withMethod)
127
    {
128
        // from getAliases
129 14
        if (!is_callable([$className, 'getAliases'])) {
130 1
            return;
131
        }
132 14
        $aliases = call_user_func([$className, 'getAliases']);
133
134 14
        foreach ($aliases as $key => $alias) {
135 14
            $definition->addTag($tagName, $withMethod ? ['alias' => $alias, 'method' => $key] : ['alias' => $alias]);
136 14
        }
137 14
    }
138
139 14
    private function subclass($class)
140
    {
141 14
        $interfaces = array_keys(self::$serviceSubclassTagMapping);
142
143 14
        foreach ($interfaces as $interface) {
144 14
            if (is_a($class, $interface, true)) {
145 14
                return $interface;
146
            }
147 14
        }
148
149 14
        return false;
150
    }
151
152
    /**
153
     * Gets the classes reflection of class in the given directory.
154
     *
155
     * @param string $directory
156
     *
157
     * @return array
158
     */
159 14
    private function reflectionClassesFromDirectory($directory)
160
    {
161 14
        $classes = [];
162 14
        $directoryList = [];
163 14
        $includedFiles = [];
164 14
        $reflectionClasses = [];
165
166 14
        $finder = new Finder();
167
        try {
168 14
            $finder->in($directory)->files()->name('*.php');
169 14
        } catch (\InvalidArgumentException $e) {
170 1
            return [$reflectionClasses, $directoryList];
171
        }
172
173 14
        foreach ($finder as $file) {
174 14
            $directoryList[$file->getPath()] = true;
175 14
            $sourceFile = $file->getRealpath();
176 14
            if (!preg_match('(^phar:)i', $sourceFile)) {
177 14
                $sourceFile = realpath($sourceFile);
178 14
            }
179
180 14
            require_once $sourceFile;
181 14
            $includedFiles[$sourceFile] = true;
182 14
        }
183
184 14
        $declared = get_declared_classes();
185 14
        foreach ($declared as $className) {
186 14
            $subclass = $this->subclass($className);
187 14
            if (false === $subclass) {
188 14
                continue;
189
            }
190 14
            $reflectionClass = new \ReflectionClass($className);
191 14
            $reflectionClasses[$className] = $reflectionClass;
192 14
            $sourceFile = $reflectionClass->getFileName();
193
194 14
            if ($reflectionClass->isAbstract()) {
195 14
                continue;
196
            }
197
198 14
            if (isset($includedFiles[$sourceFile])) {
199 14
                $classes[$className] = true;
200 14
            }
201 14
        }
202
203 14
        return [array_intersect_key($reflectionClasses, $classes), $directoryList];
204
    }
205
206 14
    private function bundleDir($bundleClass)
207
    {
208 14
        $bundle = new \ReflectionClass($bundleClass);
209 14
        $bundleDir = dirname($bundle->getFileName());
210
211 14
        return $bundleDir;
212
    }
213
}
214