Completed
Push — master ( c09ce2...1f44ff )
by Emily
02:06
created

ReflectionPropertyFactory::fromName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 0
cts 0
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
crap 2
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 <emily@emilyshepherd>
12
 * @license MIT
13
 */
14
15
namespace Spaark\CompositeUtils\Factory\Reflection;
16
17
use Spaark\CompositeUtils\Model\Reflection\ReflectionComposite;
18
use Spaark\CompositeUtils\Model\Reflection\ReflectionProperty;
19
use Spaark\CompositeUtils\Model\Reflection\ReflectionParameter;
20
use Spaark\CompositeUtils\Model\Reflection\Type\BooleanType;
21
use Spaark\CompositeUtils\Model\Reflection\Type\CollectionType;
22
use Spaark\CompositeUtils\Model\Reflection\Type\IntegerType;
23
use Spaark\CompositeUtils\Model\Reflection\Type\MixedType;
24
use Spaark\CompositeUtils\Model\Reflection\Type\ObjectType;
25
use Spaark\CompositeUtils\Model\Reflection\Type\StringType;
26
use Spaark\CompositeUtils\Service\RawPropertyAccessor;
27
use \ReflectionProperty as PHPNativeReflectionProperty;
28
29
class ReflectionPropertyFactory extends ReflectorFactory
30
{
31
    const REFLECTION_OBJECT = ReflectionProperty::class;
32
33
    protected $acceptedParams =
34
    [
35
        'readable' => 'setBool',
36
        'writable' => 'setBool',
37
        'var' => 'setType',
38
        'construct' => 'setConstruct'
39
    ];
40
41
    public static function fromName($class, $property)
42
    {
43
        return new static(new PHPNativeReflectionProperty
44
        (
45
            $class, $property
46
        ));
47
    }
48
49 14
    public function build(ReflectionComposite $parent, $default)
50
    {
51 14
        $this->accessor->setRawValue('owner', $parent);
52 14
        $this->accessor->setRawValue('defaultValue', $default);
53 14
        $this->accessor->setRawValue
54
        (
55 14
            'name',
56 14
            $this->reflector->getName()
57
        );
58
59 14
        $this->parseDocComment();
60
61 14
        return $this->object;
62
    }
63
64 14
    protected function setType($name, $value)
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
65
    {
66 14 View Code Duplication
        if ($value{0} !== '?')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
67
        {
68 14
            $nullable = false;
69
        }
70
        else
71
        {
72 13
            $nullable = true;
73 13
            $value = substr($value, 1);
74
        }
75
76 14 View Code Duplication
        if (substr($value, -2) !== '[]')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
77
        {
78 14
            $collection = false;
79
        }
80
        else
81
        {
82
            $collection = true;
83
            $value = substr($value, 0, -2);
84
        }
85
86
        switch ($value)
87
        {
88 14
            case 'string':
89 14
                $class = new StringType();
90 14
                break;
91 14
            case 'int':
92 14
            case 'integer':
93 1
                $class = new IntegerType();
94 1
                break;
95 14
            case 'bool':
96 14
            case 'boolean':
97 14
                $class = new BooleanType();
98 14
                break;
99 14
            case 'mixed':
100 14
            case '':
101
                $class = new MixedType();
102
                break;
103 14
            case 'null':
104
                $class = new NullType();
105
                break;
106
            default:
107
                $useStatements =
108 14
                    $this->object->owner->namespace->useStatements;
0 ignored issues
show
Documentation introduced by
The property owner does not exist on object<Spaark\CompositeU...l\Reflection\Reflector>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
109
110 14
                if ($useStatements->contains($value))
111
                {
112 13
                    $value = $useStatements[$value]->classname;
113
                }
114
115 14
                $class = new ObjectType($value);
116
        }
117
118 14
        if ($nullable)
119
        {
120 13
            (new RawPropertyAccessor($class))
121 13
                ->setRawValue('nullable', true);
122
        }
123
124 14
        if ($collection)
125
        {
126
            $class = new CollectionType($class);
127
        }
128
129 14
        $this->accessor->setRawValue('type', $class);
130 14
    }
131
132 13
    public function setConstruct($name, $value)
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
133
    {
134 13
        $value = explode(' ', $value);
135
        $compositeAccessor =
136 13
            new RawPropertyAccessor($this->object->owner);
0 ignored issues
show
Documentation introduced by
The property owner does not exist on object<Spaark\CompositeU...l\Reflection\Reflector>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
137
138 13
        switch ($value[0])
139
        {
140 13
            case 'required':
141 13
                $this->accessor->setRawValue
142
                (
143 13
                    'passedToConstructor',
144 13
                    true
145
                );
146 13
                $this->accessor->setRawValue
147
                (
148 13
                    'requiredInConstructor',
149 13
                    true
150
                );
151 13
                $compositeAccessor->rawAddToValue
152
                (
153 13
                    'requiredProperties',
154 13
                    $this->object
155
                );
156 13
                break;
157 13
            case 'new':
158 13
                $this->accessor->setRawValue
159
                (
160 13
                    'builtInConstructor',
161 13
                    true
162
                );
163 13
                $compositeAccessor->rawAddToValue
164
                (
165 13
                    'builtProperties',
166 13
                    $this->object
167
                );
168 13
                break;
169 13
            case 'optional':
170 13
                $this->accessor->setRawValue
171
                (
172 13
                    'passedToConstructor',
173 13
                    true
174
                );
175 13
                $compositeAccessor->rawAddToValue
176
                (
177 13
                    'optionalProperties',
178 13
                    $this->object
179
                );
180
181 13
                if (isset($value[1]) && $value[1] === 'new')
182
                {
183 13
                    $this->accessor->setRawValue
184
                    (
185 13
                        'builtInConstructor',
186 13
                        true
187
                    );
188
                }
189
        }
190 13
    }
191
}
192
193