Failed Conditions
Pull Request — experimental/3.1 (#2521)
by Kiyotaka
83:08 queued 76:21
created

Di::generateServiceProvider()   C

Complexity

Conditions 11
Paths 17

Size

Total Lines 55
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 11.0269

Importance

Changes 0
Metric Value
cc 11
eloc 33
nc 17
nop 0
dl 0
loc 55
ccs 31
cts 33
cp 0.9394
crap 11.0269
rs 6.6153
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
namespace Eccube\Di;
4
5
use Doctrine\Common\Annotations\Reader;
6
use Eccube\Annotation\Inject;
7
use Eccube\Application;
8
use Pimple\Container;
9
use Symfony\Component\Finder\Finder;
10
11
class Di
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
12
{
13
14
    /**
15
     * @var string
16
     */
17
    private $providerDir;
18
19
    /**
20
     * @var string
21
     */
22
    private $providerClass;
23
24
    /**
25
     * @var Scanner[]
26
     */
27
    private $scanners;
28
29
    /**
30
     * @var Reader
31
     */
32
    private $reader;
33
34
    /**
35
     * @var bool
36
     */
37
    private $debug;
38
39
    private static $template = '<?php
40
41
/**
42
 * {{ provider_class }}
43
 *
44
 * This class has been auto-generated by Eccube\Di\ProviderGenerator
45
 */
46
class {{ provider_class }} implements \Pimple\ServiceProviderInterface
47
{
48
    public function register(\Pimple\Container $app)
49
    {
50
{{ snippets|raw }}
51
    }
52
}';
53
54
    /**
55
     * Di constructor.
56
     * @param string $providerDir
0 ignored issues
show
introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
57
     * @param string $providerClass
0 ignored issues
show
introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
58
     * @param Scanner[] $scanners
59
     * @param Reader $reader
0 ignored issues
show
introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
60
     * @param bool $debug
0 ignored issues
show
introduced by
Expected 6 spaces after parameter type; 1 found
Loading history...
61
     */
62 1142
    public function __construct($providerDir, $providerClass, array $scanners, Reader $reader, $debug)
63
    {
64 1142
        $this->providerDir = $providerDir;
65 1142
        $this->providerClass = $providerClass;
66 1142
        $this->scanners = $scanners;
67 1142
        $this->reader = $reader;
68 1142
        $this->debug = $debug;
69
    }
70
71
72 18
    public function isApplication($class)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
73
    {
74 18
        return $class === Application::class;
75
    }
76
77 1142
    public function getProviderPath()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
78
    {
79 1142
        return $this->providerDir.'/'.$this->providerClass.'.php';
80
    }
81
82 1140
    public function build(Container $container)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
83
    {
84 1140
        if ($this->debug || false === file_exists($this->getProviderPath())) {
85 22
            $this->generateServiceProvider();
86
        }
87
88 1140
        $path = $this->getProviderPath();
89 1140
        $class = $this->providerClass;
90
91 1140
        require_once $path;
92
93 1140
        $container->register(new $class());
94
    }
95
96 23
    public function findClasses(array $dirs)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
97
    {
98 23
        $files = Finder::create()
99 23
            ->in($dirs)
100 23
            ->name('*.php')
101 23
            ->files();
102
103 23
        $classes = [];
104 23
        $includedFiles = [];
105 23
        foreach ($files as $file) {
106 23
            $path = $file->getRealPath();
107 23
            require_once $path;
108 23
            $includedFiles[] = $path;
109
        }
110
111 23
        $declared = get_declared_classes();
112
113 23 View Code Duplication
        foreach ($declared as $className) {
114 23
            $rc = new \ReflectionClass($className);
115 23
            $sourceFile = $rc->getFileName();
116 23
            if (in_array($sourceFile, $includedFiles)) {
117 23
                $classes[] = $className;
118
            }
119
        }
120
121 23
        return $classes;
122
    }
123
124 22
    private function generateServiceProvider()
125
    {
126 22
        if (!is_dir($this->providerDir) && !@mkdir($this->providerDir, 0777, true) && !is_dir($this->providerDir)) {
127
            throw new \RuntimeException(
128
                sprintf('ProviderGenerator was not able to create directory "%s"', $this->providerDir)
129
            );
130
        }
131
132
        $scanDirs = array_filter(array_reduce($this->scanners, function($result, Scanner $scanner) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
133 22
            return array_merge($result, $scanner->getScanDirs());
134 22
        }, []), function($dir) {
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 12 spaces, but found 8.
Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
135 22
            return file_exists($dir);
136 22
        });
137
138 22
        $classes = $this->findClasses($scanDirs);
139
140 22
        $twig = new \Twig_Environment(new \Twig_Loader_Array());
141 22
        $twig->addFunction(new \Twig_SimpleFunction('is_app', [$this, 'isApplication']));
142
143 22
        $snippets = '';
144
145 22
        foreach ($this->scanners as $wiring) {
146 22
            $components = [];
147
148 22
            foreach ($classes as $className) {
149 22
                $rc = new \ReflectionClass($className);
150 22
                $anno = $wiring->findAnnotation($this->reader, $rc);
151 22
                if ($anno) {
152 22
                    $component = $components[] = $wiring->createComponentDefinition($anno, $rc);
153
154 22
                    $refProps = $rc->getProperties();
155 22
                    foreach ($refProps as $refProp) {
156 18
                        $anno = $this->reader->getPropertyAnnotation($refProp, Inject::class);
157 18
                        if (is_null($anno)) {
158 15
                            continue;
159
                        }
160 22
                        $component->addDenendency(new Dependency($anno->value, $refProp->getName()));
161
                    }
162
                }
163
            }
164
165 22
            if (!empty($components)) {
166 22
                if ($snippets) $snippets .= PHP_EOL;
167 22
                $snippets .= $wiring->generate($twig, $components);
168 22
                $snippets .= $wiring->generateExtend($twig, $components);
169
            }
170
        }
171
172 22
        $content = $twig->createTemplate(self::$template)->render([
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
173 22
            'provider_class' => $this->providerClass,
174 22
            'snippets' => preg_replace('/^/m', '        ', $snippets)
175
        ]);
176
177 22
        file_put_contents($this->getProviderPath(), $content);
178
    }
179
}
180