Failed Conditions
Push — experimental/3.1 ( c6bbe9...5ca513 )
by Yangsin
235:43 queued 228:52
created

DependencyBuilder::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
dl 0
loc 55
c 0
b 0
f 0
cc 11
eloc 33
nc 17
nop 0
ccs 31
cts 33
cp 0.9394
crap 11.0269
rs 6.6153

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 DependencyBuilder
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 AutoWiring[]
26
     */
27
    private $wirings;
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\DependencyBuilder
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 7 spaces after parameter type; 1 found
Loading history...
57
     * @param string $providerClass
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
58
     * @param AutoWiring[] $wirings
59
     * @param Reader $reader
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
60
     * @param bool $debug
0 ignored issues
show
introduced by
Expected 9 spaces after parameter type; 1 found
Loading history...
61
     */
62 1124
    public function __construct($providerDir, $providerClass, array $wirings, Reader $reader, $debug)
63
    {
64 1124
        $this->providerDir = $providerDir;
65 1124
        $this->providerClass = $providerClass;
66 1124
        $this->wirings = $wirings;
67 1124
        $this->reader = $reader;
68 1124
        $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 1124
    public function getProviderPath()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
78
    {
79 1124
        return $this->providerDir.'/'.$this->providerClass.'.php';
80
    }
81
82 1122
    public function build(Container $container)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
83
    {
84 1122
        if ($this->debug || false === file_exists($this->getProviderPath())) {
85 26
            $this->generateServiceProvider();
86
        }
87
88 1122
        $path = $this->getProviderPath();
89 1122
        $class = $this->providerClass;
90
91 1122
        require_once $path;
92
93 1122
        $container->register(new $class());
94
    }
95
96 27
    public function findClasses(array $dirs)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
97
    {
98 27
        $files = Finder::create()
99 27
            ->in($dirs)
100 27
            ->name('*.php')
101 27
            ->files();
102
103 27
        $classes = [];
104 27
        $includedFiles = [];
105 27
        foreach ($files as $file) {
106 27
            $path = $file->getRealPath();
107 27
            require_once $path;
108 27
            $includedFiles[] = $path;
109
        }
110
111 27
        $declared = get_declared_classes();
112
113 27 View Code Duplication
        foreach ($declared as $className) {
114 27
            $rc = new \ReflectionClass($className);
115 27
            $sourceFile = $rc->getFileName();
116 27
            if (in_array($sourceFile, $includedFiles)) {
117 27
                $classes[] = $className;
118
            }
119
        }
120
121 27
        return $classes;
122
    }
123
124 26
    private function generateServiceProvider()
125
    {
126 26
        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->wirings, function($result, AutoWiring $wiring) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
133 26
            return array_merge($result, $wiring->getScanDirs());
134 26
        }, []), 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 26
            return file_exists($dir);
136 26
        });
137
138 26
        $classes = $this->findClasses($scanDirs);
139
140 26
        $twig = new \Twig_Environment(new \Twig_Loader_Array());
141 26
        $twig->addFunction(new \Twig_SimpleFunction('is_app', [$this, 'isApplication']));
142
143 26
        $snippets = '';
144
145 26
        foreach ($this->wirings as $wiring) {
146 26
            $components = [];
147
148 26
            foreach ($classes as $className) {
149 26
                $rc = new \ReflectionClass($className);
150 26
                $anno = $wiring->findAnnotation($this->reader, $rc);
151 26
                if ($anno) {
152 26
                    $component = $components[] = $wiring->createComponentDefinition($anno, $rc);
153
154 26
                    $refProps = $rc->getProperties();
155 26
                    foreach ($refProps as $refProp) {
156 22
                        $anno = $this->reader->getPropertyAnnotation($refProp, Inject::class);
157 22
                        if (is_null($anno)) {
158 17
                            continue;
159
                        }
160 26
                        $component->addDenendency(new Dependency($anno->value, $refProp->getName()));
161
                    }
162
                }
163
            }
164
165 26
            if (!empty($components)) {
166 26
                if ($snippets) $snippets .= PHP_EOL;
167 26
                $snippets .= $wiring->generate($twig, $components);
168 26
                $snippets .= $wiring->generateExtend($twig, $components);
169
            }
170
        }
171
172 26
        $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 26
            'provider_class' => $this->providerClass,
174 26
            'snippets' => preg_replace('/^/m', '        ', $snippets)
175
        ]);
176
177 26
        file_put_contents($this->getProviderPath(), $content);
178
    }
179
}
180