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 — 0.11 ( bc751e...035a35 )
by Jérémiah
17s
created

AutoMappingPass::process()   A

Complexity

Conditions 5
Paths 12

Size

Total Lines 37
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 5

Importance

Changes 0
Metric Value
eloc 23
dl 0
loc 37
ccs 23
cts 23
cp 1
rs 9.2408
c 0
b 0
f 0
cc 5
nc 12
nop 1
crap 5
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
            if ($container->hasParameter('kernel.root_dir')) {
46 1
                $directories[] = $container->getParameter('kernel.root_dir').'/GraphQL';
47
            }
48
        } else {
49
            // enabled auto mapping only for this bundle
50 30
            $directories = [$this->bundleDir(OverblogGraphQLBundle::class).'/GraphQL'];
51
        }
52 31
        $directoryList = [];
53
54 31
        foreach ($directories as $directory) {
55 31
            list($reflectionClasses, $directories) = $this->reflectionClassesFromDirectory($directory);
56 31
            $directoryList = \array_merge($directoryList, $directories);
57 31
            $this->addServicesDefinitions($container, $reflectionClasses);
58
        }
59
60 31
        foreach ($directoryList as $directory => $v) {
61 31
            $directory = \realpath($directory);
62 31
            $container->addResource(new DirectoryResource($directory, '/\.php$/'));
63
        }
64 31
    }
65
66
    /**
67
     * @param ContainerBuilder   $container
68
     * @param \ReflectionClass[] $reflectionClasses
69
     */
70 31
    private function addServicesDefinitions(ContainerBuilder $container, array $reflectionClasses)
71
    {
72 31
        foreach ($reflectionClasses as $reflectionClass) {
73 31
            $this->addServiceDefinition($container, $reflectionClass);
74
        }
75 31
    }
76
77 31
    private function addServiceDefinition(ContainerBuilder $container, \ReflectionClass $reflectionClass)
78
    {
79 31
        $className = $reflectionClass->getName();
80 31
        $definition = $container->setDefinition($className, new Definition($className));
81 31
        $definition->setPublic(false);
82 31
        $definition->setAutowired(true);
83 31
        if (\is_subclass_of($definition->getClass(), ContainerAwareInterface::class)) {
84 1
            $definition->addMethodCall('setContainer', [new Reference('service_container')]);
85
        }
86 31
        $this->addDefinitionTags($definition, $reflectionClass);
87 31
    }
88
89 31
    private function addDefinitionTags(Definition $definition, \ReflectionClass $reflectionClass)
90
    {
91 31
        foreach (self::SERVICE_SUBCLASS_TAG_MAPPING as $subclass => $tagName) {
92 31
            if (!$reflectionClass->isSubclassOf($subclass)) {
93 31
                continue;
94
            }
95
96 31
            if (Type::class !== $subclass) {
97 31
                $publicReflectionMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
98 31
                $isAliased = $reflectionClass->implementsInterface(AliasedInterface::class);
99 31
                foreach ($publicReflectionMethods as $publicReflectionMethod) {
100 31
                    if ('__construct' === $publicReflectionMethod->name || $isAliased && 'getAliases' === $publicReflectionMethod->name) {
101 31
                        continue;
102
                    }
103 31
                    $definition->addTag($tagName, ['method' => $publicReflectionMethod->name]);
104
                }
105
            } else {
106 31
                $definition->addTag($tagName);
107
            }
108
        }
109 31
    }
110
111 31
    private function subclass($class)
112
    {
113 31
        $interfaces = \array_keys(self::SERVICE_SUBCLASS_TAG_MAPPING);
114
115 31
        foreach ($interfaces as $interface) {
116 31
            if (\is_a($class, $interface, true)) {
117 31
                return $interface;
118
            }
119
        }
120
121 31
        return false;
122
    }
123
124
    /**
125
     * Gets the classes reflection of class in the given directory.
126
     *
127
     * @param string $directory
128
     *
129
     * @return array
130
     */
131 31
    private function reflectionClassesFromDirectory($directory)
132
    {
133 31
        $classes = [];
134 31
        $directoryList = [];
135 31
        $includedFiles = [];
136 31
        $reflectionClasses = [];
137
138 31
        $finder = new Finder();
139
        try {
140 31
            $finder->in($directory)->files()->name('*.php');
141 1
        } catch (\InvalidArgumentException $e) {
142 1
            return [$reflectionClasses, $directoryList];
143
        }
144
145 31
        foreach ($finder as $file) {
146 31
            $directoryList[$file->getPath()] = true;
147 31
            $sourceFile = $file->getRealpath();
148 31
            if (!\preg_match('(^phar:)i', $sourceFile)) {
149 31
                $sourceFile = \realpath($sourceFile);
150
            }
151
152 31
            require_once $sourceFile;
153 31
            $includedFiles[$sourceFile] = true;
154
        }
155
156 31
        $declared = \get_declared_classes();
157 31
        foreach ($declared as $className) {
158 31
            $subclass = $this->subclass($className);
159 31
            if (false === $subclass) {
160 31
                continue;
161
            }
162 31
            $reflectionClass = new \ReflectionClass($className);
163 31
            $reflectionClasses[$className] = $reflectionClass;
164 31
            $sourceFile = $reflectionClass->getFileName();
165
166 31
            if ($reflectionClass->isAbstract()) {
167 31
                continue;
168
            }
169
170 31
            if (isset($includedFiles[$sourceFile])) {
171 31
                $classes[$className] = true;
172
            }
173
        }
174
175 31
        return [\array_intersect_key($reflectionClasses, $classes), $directoryList];
176
    }
177
178 31
    private function bundleDir($bundleClass)
179
    {
180 31
        $bundle = new \ReflectionClass($bundleClass);
181 31
        $bundleDir = \dirname($bundle->getFileName());
182
183 31
        return $bundleDir;
184
    }
185
}
186