ServiceManager   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 138
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 14

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 14
dl 0
loc 138
c 0
b 0
f 0
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A generateCode() 0 16 3
A prepareConstructStatement() 0 16 1
B prepareArguments() 0 25 4
A prepareMethodStatement() 0 18 2
A prepareReturnStatement() 0 6 1
B prepareNode() 0 25 1
1
<?php
2
3
namespace Saxulum\RouteController\Manager;
4
5
use PhpParser\Node\Arg;
6
use PhpParser\Node\Expr\ArrayDimFetch;
7
use PhpParser\Node\Expr\Assign;
8
use PhpParser\Node\Expr\Closure;
9
use PhpParser\Node\Expr\ClosureUse;
10
use PhpParser\Node\Expr\MethodCall;
11
use PhpParser\Node\Expr\New_;
12
use PhpParser\Node\Expr\Variable;
13
use PhpParser\Node\Name;
14
use PhpParser\Node\Scalar\String_;
15
use PhpParser\Node\Stmt\Return_;
16
use Saxulum\RouteController\Annotation\DI;
17
use Saxulum\AnnotationManager\Helper\ClassInfo;
18
use Saxulum\AnnotationManager\Helper\MethodInfo;
19
20
class ServiceManager
21
{
22
    /**
23
     * @param  ClassInfo $classInfo
24
     * @return Assign[]
25
     */
26
    public function generateCode(ClassInfo $classInfo)
27
    {
28
        $statements = array();
29
        $statements[] = $this->prepareConstructStatement($classInfo);
30
31
        foreach ($classInfo->getMethodInfos() as $methodInfo) {
32
            $statement = $this->prepareMethodStatement($methodInfo);
33
            if (!is_null($statement)) {
34
                $statements[] = $statement;
35
            }
36
        }
37
38
        $statements[] = $this->prepareReturnStatement();
39
40
        return array($this->prepareNode($classInfo, $statements));
41
    }
42
43
    /**
44
     * @param  ClassInfo $classInfo
45
     * @return Assign
46
     */
47
    protected function prepareConstructStatement(ClassInfo $classInfo)
48
    {
49
        $di = $classInfo->getFirstAnnotationInstanceof(
50
            'Saxulum\\RouteController\\Annotation\\DI'
51
        );
52
53
        /** @var DI $di */
54
55
        return new Assign(
56
            new Variable('controller'),
57
            new New_(
58
                new Name($classInfo->getName()),
59
                $this->prepareArguments($di)
60
            )
61
        );
62
    }
63
64
    /**
65
     * @param  DI    $di
66
     * @return Arg[]
67
     */
68
    protected function prepareArguments(DI $di = null)
69
    {
70
        if (is_null($di)) {
71
            return array();
72
        }
73
74
        $arguments = array();
75
76
        if ($di->injectContainer) {
77
            $arguments[] = new Arg(
78
                new Variable('app')
79
            );
80
        } else {
81
            foreach ($di->serviceIds as $serviceId) {
82
                $arguments[] = new Arg(
83
                    new ArrayDimFetch(
84
                        new Variable('app'),
85
                        new String_($serviceId)
86
                    )
87
                );
88
            }
89
        }
90
91
        return $arguments;
92
    }
93
94
    /**
95
     * @param  MethodInfo      $methodInfo
96
     * @return null|MethodCall
97
     */
98
    protected function prepareMethodStatement(MethodInfo $methodInfo)
99
    {
100
        $di = $methodInfo->getFirstAnnotationInstanceof(
101
            'Saxulum\\RouteController\\Annotation\\DI'
102
        );
103
104
        /** @var DI $di */
105
106
        if (is_null($di)) {
107
            return null;
108
        }
109
110
        return new MethodCall(
111
            new Variable('controller'),
112
            $methodInfo->getName(),
113
            $this->prepareArguments($di)
114
        );
115
    }
116
117
    /**
118
     * @return Return_
119
     */
120
    protected function prepareReturnStatement()
121
    {
122
        return new Return_(
123
            new Variable('controller')
124
        );
125
    }
126
127
    /**
128
     * @param  ClassInfo $classInfo
129
     * @param  array     $statements
130
     * @return Assign
131
     */
132
    protected function prepareNode(ClassInfo $classInfo, array $statements)
133
    {
134
        return new Assign(
135
            new ArrayDimFetch(
136
                new Variable('app'),
137
                new String_($classInfo->getServiceId())
138
            ),
139
            new MethodCall(
140
                new Variable('app'),
141
                'share',
142
                array(
143
                    new Arg(
144
                        new Closure(
145
                            array(
146
                                'uses' => array(
147
                                    new ClosureUse('app')
148
                                ),
149
                                'stmts' => $statements
150
                            )
151
                        )
152
                    )
153
                )
154
            )
155
        );
156
    }
157
}
158