AutoRegisterCompilerPass::process()   A
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 51
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 31
dl 0
loc 51
rs 9.1128
c 0
b 0
f 0
cc 5
nc 5
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Neimheadh\SonataAnnotationBundle\DependencyInjection\Compiler;
6
7
use Doctrine\Common\Annotations\AnnotationReader;
8
use Exception;
9
use IteratorAggregate;
10
use Neimheadh\SonataAnnotationBundle\Annotation\Admin;
11
use ReflectionClass;
12
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
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
use Symfony\Component\Finder\SplFileInfo;
18
19
use function class_exists;
20
21
/**
22
 * Auto-registering Sonata annotated admin services compiler.
23
 *
24
 * @author Marko Kunic <[email protected]>
25
 * @author Mathieu Wambre <[email protected]>
26
 */
27
final class AutoRegisterCompilerPass implements CompilerPassInterface
28
{
29
30
    private const DEFAULT_SERVICE_PREFIX = 'app.admin.';
31
32
    /**
33
     * {@inheritDoc}
34
     *
35
     * @throws Exception
36
     */
37
    public function process(ContainerBuilder $container): void
38
    {
39
        /** @var AnnotationReader $annotationReader */
40
        $annotationReader = $container->get('annotation_reader');
41
42
        $files = $this->findFiles(
43
            $container->getParameter('sonata_annotation.directory')
44
        );
45
46
        foreach ($files as $file) {
47
            if (!($className = $this->getFullyQualifiedClassName($file))) {
48
                continue;
49
            }
50
51
            if (!class_exists($className)) {
52
                continue;
53
            }
54
55
            if (!($annotation = $annotationReader->getClassAnnotation(
56
                new ReflectionClass($className),
57
                Admin::class
58
            ))) {
59
                continue;
60
            }
61
62
            $definition = new Definition(
63
                $annotation->admin,
64
                [
65
                    new Reference('sonata.annotation.reader.action_button'),
66
                    new Reference('sonata.annotation.reader.datagrid'),
67
                    new Reference('sonata.annotation.reader.datagrid_values'),
68
                    new Reference('sonata.annotation.reader.dashboard_action'),
69
                    new Reference('sonata.annotation.reader.export'),
70
                    new Reference('sonata.annotation.reader.form'),
71
                    new Reference('sonata.annotation.reader.list'),
72
                    new Reference('sonata.annotation.reader.route'),
73
                    new Reference('sonata.annotation.reader.show'),
74
                ]
75
            );
76
77
            $definition->addTag(
78
                'sonata.admin',
79
                array_merge(
80
                    $annotation->getTagOptions(),
81
                    ['model_class' => $className],
82
                )
83
            );
84
85
            $container->setDefinition(
86
                $annotation->serviceId ?? $this->getServiceId($file),
87
                $definition
88
            );
89
        }
90
    }
91
92
    /**
93
     * List PHP files in given directory.
94
     *
95
     * @param string $directory Directory path.
96
     *
97
     * @return IteratorAggregate
98
     */
99
    private function findFiles(string $directory): IteratorAggregate
100
    {
101
        return Finder::create()
102
            ->in($directory)
103
            ->files()
104
            ->name('*.php');
105
    }
106
107
    /**
108
     * Get the given file associated full class name.
109
     *
110
     * @param SplFileInfo $file PHP class file.
111
     *
112
     * @return string|null
113
     */
114
    private function getFullyQualifiedClassName(SplFileInfo $file): ?string
115
    {
116
        if (!($namespace = $this->getNamespace($file->getPathname()))) {
117
            return null;
118
        }
119
120
        return $namespace . '\\' . $this->getClassName($file->getFilename());
121
    }
122
123
    /**
124
     * Get the given file associated namespace.
125
     *
126
     * @param string $filePath PHP class file path.
127
     *
128
     * @return string|null
129
     */
130
    private function getNamespace(string $filePath): ?string
131
    {
132
        $namespaceLine = preg_grep('/^namespace /', file($filePath));
133
134
        if (empty($namespaceLine)) {
135
            return null;
136
        }
137
138
        preg_match('/namespace (.*);$/', trim(reset($namespaceLine)), $match);
139
140
        return array_pop($match);
141
    }
142
143
    /**
144
     * Get the given file associated class name.
145
     *
146
     * @param string $fileName PHP class name.
147
     *
148
     * @return string
149
     */
150
    private function getClassName(string $fileName): string
151
    {
152
        return str_replace('.php', '', $fileName);
153
    }
154
155
    /**
156
     * Get default admin service id.
157
     *
158
     * @param SplFileInfo $file PHP class file.
159
     *
160
     * @return string
161
     */
162
    private function getServiceId(SplFileInfo $file): string
163
    {
164
        return self::DEFAULT_SERVICE_PREFIX . $this->getClassName(
165
                $file->getFilename()
166
            );
167
    }
168
169
}
170