Failed Conditions
Pull Request — experimental/3.1 (#2532)
by Kentaro
34:08 queued 17:05
created

EntityProxyService::generate()   F

Complexity

Conditions 15
Paths 1476

Size

Total Lines 96
Code Lines 57

Duplication

Lines 7
Ratio 7.29 %

Code Coverage

Tests 50
CRAP Score 15.4166

Importance

Changes 0
Metric Value
cc 15
eloc 57
nc 1476
nop 3
dl 7
loc 96
ccs 50
cts 57
cp 0.8772
crap 15.4166
rs 2
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
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2017 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
namespace Eccube\Service;
25
26
27
use Doctrine\Common\Annotations\AnnotationReader;
28
use Doctrine\ORM\EntityManager;
29
use Eccube\Annotation\EntityExtension;
30
use Eccube\Annotation\Inject;
31
use Eccube\Annotation\Service;
32
use Symfony\Component\Console\Output\ConsoleOutput;
33
use Symfony\Component\Console\Output\OutputInterface;
34
use Symfony\Component\Finder\Finder;
35
use Zend\Code\Generator\ClassGenerator;
36
use Zend\Code\Generator\FileGenerator;
37
use Zend\Code\Reflection\ClassReflection;
38
39
/**
40
 * @Service
41
 */
42
class EntityProxyService
43
{
44
    /**
45
     * @Inject("orm.em")
46
     * @var EntityManager
47
     */
48
    protected $entityManager;
49
50
    /**
51
     * EntityのProxyを生成します。
52
     *
53
     * @param array $scanDirs スキャン対象ディレクトリ
0 ignored issues
show
introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
54
     * @param string $outputDir 出力先
0 ignored issues
show
introduced by
Expected 10 spaces after parameter type; 1 found
Loading history...
55
     * @param OutputInterface $output ログ出力
0 ignored issues
show
introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
56
     * @return array 生成したファイルのリスト
57
     */
58 11
    public function generate($scanDirs, $outputDir, OutputInterface $output = null)
59
    {
60 11
        if (is_null($output)) {
61 11
            $output = new ConsoleOutput();
62
        }
63
64
        // Acmeからファイルを抽出
65 11
        $files = Finder::create()
66 11
            ->in(array_filter($scanDirs, 'file_exists'))
67 11
            ->name('*.php')
68 11
            ->files();
69
70
        // traitの一覧を取得
71 11
        $traits = [];
72 11
        $includedFiles = [];
73 11
        foreach ($files as $file) {
74 11
            require_once $file->getRealPath();
75 11
            $includedFiles[] = $file->getRealPath();
76
        }
77
78 11
        $declared = get_declared_traits();
79
80 11 View Code Duplication
        foreach ($declared as $className) {
81 11
            $rc = new \ReflectionClass($className);
82 11
            $sourceFile = $rc->getFileName();
83 11
            if (in_array($sourceFile, $includedFiles)) {
84 11
                $traits[] = $className;
85
            }
86
        }
87
88
        // traitから@EntityExtensionを抽出
89 11
        $reader = new AnnotationReader();
90 11
        $proxies = [];
91 11
        foreach ($traits as $trait) {
92 11
            $anno = $reader->getClassAnnotation(new \ReflectionClass($trait), EntityExtension::class);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $anno is correct as $reader->getClassAnnotat...EntityExtension::class) (which targets Doctrine\Common\Annotati...r::getClassAnnotation()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
93 11
            if ($anno) {
94 11
                $proxies[$anno->value][] = $trait;
95
            }
96
        }
97
98 11
        $generatedFiles = [];
99
100
        // プロキシファイルの生成
101 11
        foreach ($proxies as $targetEntity => $traits) {
102 11
            $rc = new ClassReflection($targetEntity);
103 11
            $generator = ClassGenerator::fromReflection($rc);
104 11
            $uses = FileGenerator::fromReflectedFileName($rc->getFileName())->getUses();
105
106 11
            foreach ($uses as $use) {
107 11
                $generator->addUse($use[0], $use[1]);
108
            }
109
110 11
            foreach ($traits as $trait) {
111 11
                $rt = new ClassReflection($trait);
112 11
                foreach ($rt->getProperties() as $prop) {
113
                    // すでにProxyがある場合, $generatorにuse XxxTrait;が存在せず,
114
                    // traitに定義されているフィールド,メソッドがクラス側に追加されてしまう
115 11
                    if ($generator->hasProperty($prop->getName())) {
116
                        // $generator->removeProperty()はzend-code 2.6.3 では未実装なのでリフレクションで削除.
117
                        $generatorRefObj = new \ReflectionObject($generator);
118
                        $generatorRefProp = $generatorRefObj->getProperty('properties');
119
                        $generatorRefProp->setAccessible(true);
120
                        $properies = $generatorRefProp->getValue($generator);
121
                        unset($properies[$prop->getName()]);
122 11
                        $generatorRefProp->setValue($generator, $properies);
123
                    }
124
                }
125 11
                foreach ($rt->getMethods() as $method) {
126
                    if ($generator->hasMethod($method->getName())) {
0 ignored issues
show
Bug introduced by
Consider using $method->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
127
                        $generator->removeMethod($method->getName());
0 ignored issues
show
Bug introduced by
Consider using $method->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
128
                    }
129
                }
130 11
                $generator->addTrait('\\'.$trait);
131
            }
132
133
            // extendしたクラスが相対パスになるので
134 11
            $extendClass = $generator->getExtendedClass();
135 11
            $generator->setExtendedClass('\\'.$extendClass);
136
137
            // interfaceが相対パスになるので
138 11
            $interfaces = $generator->getImplementedInterfaces();
139 11
            foreach ($interfaces as &$interface) {
140 10
                $interface = '\\'.$interface;
141
            }
142 11
            $generator->setImplementedInterfaces($interfaces);
143
144 11
            $file = basename($rc->getFileName());
145
146 11
            $code = $generator->generate();
147 11
            $generatedFiles[] = $outputFile = $outputDir.'/'.$file;
148 11
            file_put_contents($outputFile, '<?php '.PHP_EOL.$code);
149 11
            $output->writeln('gen -> '.$outputFile);
150
        }
151
152 11
        return $generatedFiles;
153
    }
154
}
155