Completed
Pull Request — master (#3)
by Emily
06:07
created

ReflectionCompositeFactory::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 4
cts 4
cp 1
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 2
crap 1
1
<?php
2
/**
3
 * This file is part of the Composite Utils package.
4
 *
5
 * (c) Emily Shepherd <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the
8
 * LICENSE.md file that was distributed with this source code.
9
 *
10
 * @package spaark/composite-utils
11
 * @author Emily Shepherd <[email protected]>
12
 * @license MIT
13
 */
14
15
namespace Spaark\CompositeUtils\Factory\Reflection;
16
17
use Spaark\CompositeUtils\Factory\BaseFactory;
18
use Spaark\CompositeUtils\Model\Reflection\ReflectionComposite;
19
use Spaark\CompositeUtils\Model\Reflection\ReflectionProperty;
20
use Spaark\CompositeUtils\Model\Reflection\ReflectionMethod;
21
use Spaark\CompositeUtils\Service\ReflectionCompositeProviderInterface;
22
use Spaark\CompositeUtils\Service\ReflectionCompositeProvider;
23
use \ReflectionClass as PHPNativeReflectionClass;
24
use \ReflectionProperty as PHPNativeReflectionProperty;
25
use \ReflectionMethod as PHPNativeReflectionMethod;
26
use \Reflector;
27
28
/**
29
 * Builds a ReflectionComposite for a given class
30
 */
31
class ReflectionCompositeFactory extends ReflectorFactory
32
{
33
    const REFLECTION_OBJECT = ReflectionComposite::class;
34
35
    /**
36
     * @var PHPNativeReflector
37
     */
38
    protected $reflector;
39
40
    /**
41
     * @var ReflectionComposite
42
     */
43
    protected $object;
44
45
    /**
46
     * @var ReflectionCompositeProviderInterface
47
     */
48
    protected $provider;
49
50
    /**
51
     * Creates a new ReflectionCompositeFactory from the given
52
     * classname
53
     *
54
     * @param string $classname The class to build a reflect upon
55
     * @return ReflectionCompositeFactory
56
     */
57 20
    public static function fromClassName(string $classname)
58
    {
59 20
        return new static
60
        (
61 20
            new PHPNativeReflectionClass($classname),
62 20
            ReflectionCompositeProvider::getDefault()
63
        );
64
    }
65
66
    /**
67
     * Constructs the Factory with the given reflector and Composite
68
     * provider
69
     *
70
     * @param PHPNativeReflectionClass $reflect
71
     * @param ReflectionCompositeProviderInterface $provider
72
     */
73 20
    public function __construct
74
    (
75
        PHPNativeReflectionClass $reflect,
76
        ReflectionCompositeProviderInterface $provider
77
    )
78
    {
79 20
        parent::__construct($reflect);
80 20
        $this->provider = $provider;
81 20
    }
82
83
    /**
84
     * Builds the ReflectionComposite from the provided parameters
85
     *
86
     * @return ReflectionComposite
87
     */
88 20
    public function build()
89
    {
90 20
        foreach ($this->reflector->getTraits() as $trait)
91
        {
92 3
            $this->addInheritance('traits', $trait);
93
        }
94
95 20
        if ($parent = $this->reflector->getParentClass())
96
        {
97 2
            $this->addInheritance('parent', $parent, 'setRawValue');
98
        }
99
100 20
        foreach ($this->reflector->getInterfaces() as $interface)
101
        {
102 1
            $this->addInheritance('interfaces', $interface);
103
        }
104
105 20
        $fileName = $this->reflector->getFileName();
106
107 20
        $file = (new ReflectionFileFactory($fileName))->build();
108 20
        $this->accessor->setRawValue('file', $file);
109
110 20
        $this->accessor->setRawValue
111
        (
112 20
            'classname',
113 20
            $this->reflector->name
114
        );
115 20
        $this->accessor->setRawValue
116
        (
117 20
            'namespace',
118 20
            $file->namespaces[$this->reflector->getNamespaceName()]
119
        );
120
121 20
        $this->addItems('properties', false, 'Property');
122 20
        $this->addItems('methods', true, 'Method');
123
124 20
        return $this->object;
125
    }
126
127
    /**
128
     * Loops through the list methods or properties adding them to the
129
     * Composite
130
     *
131
     * @param string $name
132
     * @param bool $checkFile
133
     * @param string $singular
0 ignored issues
show
Bug introduced by
There is no parameter named $singular. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
134
     */
135 20
    protected function addItems
136
    (
137
        string $name,
138
        bool $checkFile,
139
        string $signular
140
    )
141
    {
142 20
        foreach ($this->reflector->{'get' . $name}() as $item)
143
        {
144
            // We only reflect on methods in userspace
145 20
            if ($checkFile && !$item->getFileName())
146
            {
147 1
                continue;
148
            }
149
            // This belongs to a super class, use that definition
150
            // instead
151 20
            elseif ($item->class !== $this->reflector->getName())
152
            {
153 2
                $item = $this->provider->get($item->class)
154 2
                    ->$name[$item->getName()];
155
            }
156
            // Parse this method
157
            else
158
            {
159
                $factory =
160
                      '\Spaark\CompositeUtils\Factory\Reflection'
161 20
                    . '\Reflection' . $signular . 'Factory';
162 20
                $item = $this->{'build' . $signular}
163
                (
164 20
                    new $factory($item),
165
                    $item
166
                );
167 20
                $this->accessor->rawAddToValue
0 ignored issues
show
Deprecated Code introduced by
The method Spaark\CompositeUtils\Se...cessor::rawAddToValue() has been deprecated.

This method has been deprecated.

Loading history...
168
                (
169 20
                    'local' . ucfirst($name),
170
                    $item
171
                );
172
            }
173
174 20
            $this->accessor->getRawValue($name)[$item->name] = $item;
175
        }
176 20
    }
177
178
    /**
179
     * Adds a super class / interface / trait to this Composite
180
     *
181
     * @param string $group The type of superclass (parent, etc...)
182
     * @param PHPNativeReflectionClass $reflect
183
     * @param string $method
184
     */
185 4
    protected function addInheritance
186
    (
187
        string $group,
188
        PHPNativeReflectionClass $reflect,
189
        string $method = 'rawAddToValue'
190
    )
191
    {
192
        // We only reflect on classes within userspace
193 4
        if ($reflect->getFileName())
194
        {
195 4
            $item = $this->provider->get($reflect->getName());
0 ignored issues
show
Bug introduced by
Consider using $reflect->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
196 4
            $this->accessor->$method($group, $item);
197
        }
198 4
    }
199
200
    /**
201
     * Uses a ReflectionPropertyFactory to build a ReflectionProperty
202
     *
203
     * @param ReflectionPropertyFactory $factory
204
     * @return ReflectionProperty
205
     */
206 20
    protected function buildProperty
207
    (
208
        ReflectionPropertyFactory $factory,
209
        PHPNativeReflectionProperty $reflect
210
    )
211
    : ReflectionProperty
212
    {
213 20
        return $factory->build
214
        (
215 20
            $this->object,
216 20
            $this->reflector
217 20
                ->getDefaultProperties()[$reflect->getName()]
218
        );
219
    }
220
221
    /**
222
     * Uses a ReflectionMethodFactory to build a ReflectionMethod
223
     *
224
     * @param ReflectionMethodFactory $factory
225
     * @return ReflectionMethod
226
     */
227 20
    protected function buildMethod(ReflectionMethodFactory $factory)
228
        : ReflectionMethod
229
    {
230 20
        return $factory->build($this->object);
231
    }
232
}
233
234