Completed
Pull Request — master (#3)
by Emily
02:16
created

ReflectionCompositeFactory::fromClassName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
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\Service\ReflectionCompositeProviderInterface;
20
use Spaark\CompositeUtils\Service\ReflectionCompositeProvider;
21
use \ReflectionClass as PHPNativeReflectionClass;
22
use \ReflectionProperty as PHPNativeReflectionProperty;
23
use \ReflectionMethod as PHPNativeReflectionMethod;
24
use \Reflector;
25
26
/**
27
 * Builds a ReflectionComposite for a given class
28
 */
29
class ReflectionCompositeFactory extends ReflectorFactory
30
{
31
    const REFLECTION_OBJECT = ReflectionComposite::class;
32
33
    /**
34
     * @var PHPNativeReflector
35
     */
36
    protected $reflector;
37
38
    /**
39
     * @var ReflectionComposite
40
     */
41
    protected $object;
42
43
    /**
44
     * @var ReflectionCompositeProviderInterface
45
     */
46
    protected $provider;
47
48
    /**
49
     * Creates a new ReflectionCompositeFactory from the given
50
     * classname
51
     *
52
     * @param string $classname The class to build a reflect upon
53
     * @return ReflectionCompositeFactory
54
     */
55 19
    public static function fromClassName(string $classname)
56
    {
57 19
        return new static
58
        (
59 19
            new PHPNativeReflectionClass($classname),
60 19
            ReflectionCompositeProvider::getDefault()
61
        );
62
    }
63
64 19
    public function __construct
65
    (
66
        PHPNativeReflectionClass $reflect,
67
        ReflectionCompositeProviderInterface $provider
68
    )
69
    {
70 19
        parent::__construct($reflect);
71 19
        $this->provider = $provider;
72 19
    }
73
74
    /**
75
     * Builds the ReflectionComposite from the provided parameters
76
     *
77
     * @return ReflectionComposite
78
     */
79 19
    public function build()
80
    {
81
        $file = 
82 19
            (new ReflectionFileFactory($this->reflector->getFileName()))
83 19
                ->build();
84 19
        $this->accessor->setRawValue('file', $file);
85 19
        $this->accessor->setRawValue
86
        (
87 19
            'classname',
88 19
            $this->reflector->name
89
        );
90 19
        $this->accessor->setRawValue
91
        (
92 19
            'namespace',
93 19
            $file->namespaces[$this->reflector->getNamespaceName()]
94
        );
95
96 19
        foreach ($this->reflector->getProperties() as $property)
97
        {
98 19
            if ($this->checkIfLocal($property))
99
            {
100 19
                $this->buildProperty($property);
101
            }
102
        }
103
104 19
        foreach ($this->reflector->getMethods() as $method)
105
        {
106 19
            if ($this->checkIfLocal($method))
107
            {
108 19
                $this->buildMethod($method);
109
            }
110
        }
111
112 19
        return $this->object;
113
    }
114
115
    /**
116
     * Uses a ReflectionPropertyFactory to build a ReflectionProperty,
117
     * and adds that to this ReflectionComposite
118
     *
119
     * @param PHPNativeReflectionProperty
120
     */
121 19
    protected function buildProperty
122
    (
123
        PHPNativeReflectionProperty $reflect
124
    )
125
    {
126 19
        $properties = $this->accessor->getRawValue('properties');
127
128 19
        $properties[$reflect->getName()] = 
129 19
            (new ReflectionPropertyFactory($reflect))
130 19
                ->build
131
                (
132 19
                    $this->object,
133 19
                    $this->reflector
134 19
                        ->getDefaultProperties()[$reflect->getName()]
135
                );
136 19
    }
137
138
    /**
139
     * Uses a ReflectionMethodFactory to build a ReflectionMethod, and
140
     * adds that to this ReflectionComposite
141
     *
142
     * @param PHPNativeReflectionMethod
143
     */
144 19
    protected function buildMethod(PHPNativeReflectionMethod $reflect)
145
    {
146 19
        $methods = $this->accessor->getRawValue('methods');
147 19
        $methods[$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...
148 19
            (new ReflectionMethodFactory($reflect))
149 19
                ->build($this->object);
150 19
    }
151
152
    /**
153
     * Checks if a property is defined in the class
154
     *
155
     * @param Reflector $reflector
156
     * @return boolean
157
     */
158 19
    protected function checkIfLocal(Reflector $reflector)
159
    {
160 19
        return $reflector->class === $this->reflector->getName();
0 ignored issues
show
Bug introduced by
Accessing class on the interface Reflector suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
161
    }
162
}
163
164