Completed
Push — master ( a12959...164d8d )
by Mario
03:20
created

ObjectProperty::getObjectProperties()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 17
ccs 10
cts 10
cp 1
rs 9.4285
cc 2
eloc 9
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Marek\Toggable\Hydrator;
4
5
use ReflectionClass;
6
use ReflectionProperty;
7
use ArrayObject;
8
use BadMethodCallException;
9
use InvalidArgumentException;
10
11
/**
12
 * Class ObjectProperty
13
 * @package Marek\Toggable\Hydrator
14
 */
15
class ObjectProperty implements HydratorInterface, StrategyEnabledInterface
16
{
17
    /**
18
    * The list with strategies that this hydrator has.
19
    *
20
    * @var \ArrayObject
21
    */
22
    protected $strategies;
23
24
    /**
25
     * ObjectProperty constructor.
26
     */
27 72
    public function __construct()
28
    {
29 72
        $this->strategies = new ArrayObject();
30 72
    }
31
32
    /**
33
     * {@inheritdoc}
34
     */
35 14
    public function extract($object)
36
    {
37 14
        if (!is_object($object)) {
38 1
            throw new BadMethodCallException(
39 1
                sprintf('%s expects the provided $object to be a PHP object)', __METHOD__)
40 1
            );
41
        }
42
43 13
        $properties = $this->getObjectProperties($object);
44
45 13
        $data = array();
46 13
        foreach ($properties as $name => $value) {
47
48 13
            if (!empty($object->$name) || $object->$name === false) {
49 13
                $data[$name] = $this->extractValue($name, $object->$name);
50 13
            }
51
52 13
        }
53
54 13
        return $data;
55
    }
56
57
    /**
58
     * @inheritDoc
59
     */
60 14
    public function hydrate(array $data, $object)
61
    {
62 14
        if (!is_object($object)) {
63 1
            throw new BadMethodCallException(
64 1
                sprintf('%s expects the provided $object to be a PHP object)', __METHOD__)
65 1
            );
66
        }
67
68 13
        $props = $this->getObjectProperties($object);
69
70 13
        foreach ($data as $name => $value) {
71
72 13
            if (!isset($props[$name])) {
73 1
                continue;
74
            }
75
76 13
            $object->$name = $this->hydrateValue($name, $value);
77 13
        }
78
79 13
        return $object;
80
    }
81
82
    /**
83
     * @inheritDoc
84
     */
85 1
    public function canHydrate($object)
86
    {
87 1
        return true;
88
    }
89
90
    /**
91
     * @inheritDoc
92
     */
93 67
    public function addStrategy($name, StrategyInterface $strategy)
94
    {
95 67
        $this->strategies[$name] = $strategy;
96
97 67
        return $this;
98
    }
99
100
    /**
101
     * @inheritDoc
102
     */
103 21
    public function getStrategy($name)
104
    {
105 21
        return $this->strategies[$name];
106
    }
107
108
    /**
109
     * @inheritDoc
110
     */
111 29
    public function hasStrategy($name)
112
    {
113 29
        return array_key_exists($name, $this->strategies);
114
    }
115
116
    /**
117
     * @inheritDoc
118
     */
119 1
    public function removeStrategy($name)
120
    {
121 1
        unset($this->strategies[$name]);
122
123 1
        return $this;
124
    }
125
126
    /**
127
     * Converts a value for extraction. If no strategy exists the plain value is returned.
128
     *
129
     * @param string $name
130
     * @param mixed $value
131
     *
132
     * @return mixed
133
     */
134 13 View Code Duplication
    public function extractValue($name, $value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
135
    {
136 13
        if ($this->hasStrategy($name)) {
137 10
            $strategy = $this->getStrategy($name);
138 10
            $value = $strategy->extract($value);
139 10
        }
140
141 13
        return $value;
142
    }
143
144
    /**
145
     * Converts a value for hydration. If no strategy exists the plain value is returned.
146
     *
147
     * @param string $name
148
     * @param mixed $value
149
     *
150
     * @return mixed
151
     */
152 13 View Code Duplication
    public function hydrateValue($name, $value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
153
    {
154 13
        if ($this->hasStrategy($name)) {
155 10
            $strategy = $this->getStrategy($name);
156 10
            $value = $strategy->hydrate($value);
157 10
        }
158
159 13
        return $value;
160
    }
161
162
    /**
163
     * Return list of object properties
164
     *
165
     * @param object $object
166
     *
167
     * @return array
168
     */
169 26
    protected function getObjectProperties($object)
170
    {
171 26
        $reflection = new ReflectionClass($object);
172
173 26
        $properties = $reflection->getProperties(
174
            ReflectionProperty::IS_PRIVATE
175 26
            + ReflectionProperty::IS_PROTECTED
176 26
        );
177
178 26
        $props = array();
179
        /** @var ReflectionProperty $property */
180 26
        foreach ($properties as $property) {
181 26
            $props[$property->getName()] = true;
182 26
        }
183
184 26
        return $props;
185
    }
186
}
187