Completed
Push — master ( 91ba70...1b5b6b )
by Alexander
11s
created

AbstractProxy::getParameters()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2
Metric Value
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.6666
cc 2
eloc 5
nc 2
nop 1
crap 2
1
<?php
2
/*
3
 * Go! AOP framework
4
 *
5
 * @copyright Copyright 2012, Lisachenko Alexander <[email protected]>
6
 *
7
 * This source file is subject to the license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
11
namespace Go\Proxy;
12
13
use ReflectionFunctionAbstract;
14
use ReflectionParameter;
15
16
/**
17
 * Abstract class for building different proxies
18
 */
19
abstract class AbstractProxy
20
{
21
22
    /**
23
     * Indent for source code
24
     *
25
     * @var int
26
     */
27
    protected $indent = 4;
28
29
    /**
30
     * List of advices that are used for generation of child
31
     *
32
     * @var array
33
     */
34
    protected $advices = [];
35
36
    /**
37
     * PHP expression string for accessing LSB information
38
     *
39
     * @var string
40
     */
41
    protected static $staticLsbExpression = 'static::class';
42
43
    /**
44
     * Constructs an abstract proxy class
45
     *
46
     * @param array $advices List of advices
47
     */
48 6
    public function __construct(array $advices = [])
49
    {
50 6
        $this->advices = $this->flattenAdvices($advices);
51 6
    }
52
53
    /**
54
     * Returns text representation of class
55
     *
56
     * @return string
57
     */
58
    abstract public function __toString();
59
60
    /**
61
     * Indent block of code
62
     *
63
     * @param string $text Non-indented text
64
     *
65
     * @return string Indented text
66
     */
67 6
    protected function indent($text)
68
    {
69 6
        $pad   = str_pad('', $this->indent, ' ');
70 6
        $lines = array_map(function($line) use ($pad) {
71 6
            return $pad . $line;
72 6
        }, explode("\n", $text));
73
74 6
        return join("\n", $lines);
75
    }
76
77
    /**
78
     * Returns list of string representation of parameters
79
     *
80
     * @param array|ReflectionParameter[] $parameters List of parameters
81
     *
82
     * @return array
83
     */
84 6
    protected function getParameters(array $parameters)
85
    {
86 6
        $parameterDefinitions = [];
87 6
        foreach ($parameters as $parameter) {
88 3
            $parameterDefinitions[] = $this->getParameterCode($parameter);
89
        }
90
91 6
        return $parameterDefinitions;
92
    }
93
94
    /**
95
     * Return string representation of parameter
96
     *
97
     * @param ReflectionParameter $parameter Reflection parameter
98
     *
99
     * @return string
100
     */
101 3
    protected function getParameterCode(ReflectionParameter $parameter)
102
    {
103 3
        $type = '';
104 3
        if (PHP_VERSION_ID >= 50700) {
105 3
            $reflectionType = $parameter->getType();
106 3
            if ($reflectionType) {
107 1
                $nsPrefix = $reflectionType->isBuiltin() ? '' : '\\';
108 3
                $type     = $nsPrefix . (string) $reflectionType;
109
            }
110
        } else {
111
            if ($parameter->isArray()) {
112
                $type = 'array';
113
            } elseif ($parameter->isCallable()) {
114
                $type = 'callable';
115
            } elseif ($parameter->getClass()) {
116
                $type = '\\' . $parameter->getClass()->name;
117
            }
118
        }
119 3
        $defaultValue = null;
120 3
        $isDefaultValueAvailable = $parameter->isDefaultValueAvailable();
121 3
        if ($isDefaultValueAvailable) {
122 2
            $defaultValue = var_export($parameter->getDefaultValue(), true);
123 3
        } elseif ($parameter->isOptional()) {
124
            $defaultValue = 'null';
125
        }
126
        $code = (
127 3
            ($type ? "$type " : '') . // Typehint
128 3
            ($parameter->isPassedByReference() ? '&' : '') . // By reference sign
129 3
            ($parameter->isVariadic() ? '...' : '') . // Variadic symbol
130 3
            '$' . // Variable symbol
131 3
            ($parameter->name) . // Name of the argument
132 3
            ($defaultValue !== null ? (" = " . $defaultValue) : '') // Default value if present
133
        );
134
135 3
        return $code;
136
    }
137
138
    /**
139
     * Replace concrete advices with list of ids
140
     *
141
     * @param $advices
142
     *
143
     * @return array flatten list of advices
144
     */
145 6
    private function flattenAdvices($advices)
146
    {
147 6
        $flattenAdvices = [];
148 6
        foreach ($advices as $type => $typedAdvices) {
149 6
            foreach ($typedAdvices as $name => $concreteAdvices) {
150 6
                if (is_array($concreteAdvices)) {
151 6
                    $flattenAdvices[$type][$name] = array_keys($concreteAdvices);
152
                }
153
            }
154
        }
155
156 6
        return $flattenAdvices;
157
    }
158
159
    /**
160
     * Prepares a line with args from the method definition
161
     *
162
     * @param ReflectionFunctionAbstract $functionLike
163
     *
164
     * @return string
165
     */
166 6
    protected function prepareArgsLine(ReflectionFunctionAbstract $functionLike)
167
    {
168 6
        $argumentsPart = [];
169 6
        $arguments     = [];
170 6
        $hasOptionals  = false;
171
172 6
        foreach ($functionLike->getParameters() as $parameter) {
173 3
            $byReference  = ($parameter->isPassedByReference() && !$parameter->isVariadic()) ? '&' : '';
174 3
            $hasOptionals = $hasOptionals || $parameter->isOptional();
175
176 3
            $arguments[] = $byReference . '$' . $parameter->name;
177
        }
178
179 6
        $isVariadic = $functionLike->isVariadic();
180 6
        if ($isVariadic) {
181 1
            $argumentsPart[] = array_pop($arguments);
182
        }
183 6
        if (!empty($arguments)) {
184
            // Unshifting to keep correct order
185 3
            $argumentLine = '[' . join(', ', $arguments) . ']';
186 3
            if ($hasOptionals) {
187 2
                $argumentLine = "\\array_slice($argumentLine, 0, \\func_num_args())";
188
            }
189 3
            array_unshift($argumentsPart, $argumentLine);
190
        }
191
192 6
        return join(', ', $argumentsPart);
193
    }
194
}
195