Accessor   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 5
Bugs 2 Features 0
Metric Value
wmc 21
c 5
b 2
f 0
lcom 1
cbo 2
dl 0
loc 151
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A identifyEntity() 0 11 2
B getPropertyValue() 0 15 6
A setPropertyValue() 0 19 4
A assertEntity() 0 6 3
A getReflection() 0 10 2
A getProperty() 0 7 1
A addPropertyValue() 0 11 3
1
<?php
2
3
/*
4
* This file is part of the moss-storage package
5
*
6
* (c) Michal Wachowski <[email protected]>
7
*
8
* For the full copyright and license information, please view the LICENSE
9
* file that was distributed with this source code.
10
*/
11
12
namespace Moss\Storage\Query\Accessor;
13
14
use Moss\Storage\Model\ModelInterface;
15
16
/**
17
 * Property accessor
18
 * Grants access to entity properties
19
 *
20
 * @package Moss\Storage
21
 */
22
final class Accessor implements AccessorInterface
23
{
24
    private $buffer = [];
25
26
    /**
27
     * Assigns passed identifier to primary key
28
     * Possible only when entity has one primary key
29
     *
30
     * @param ModelInterface $model
31
     * @param mixed          $entity
32
     * @param int|string     $identifier
33
     *
34
     * @return void
35
     */
36
    public function identifyEntity(ModelInterface $model, &$entity, $identifier)
37
    {
38
        $primaryKeys = $model->primaryFields();
39
        if (count($primaryKeys) !== 1) {
40
            return;
41
        }
42
43
        $field = reset($primaryKeys)->name();
44
45
        $this->setPropertyValue($entity, $field, $identifier);
46
    }
47
48
    /**
49
     * Returns property value
50
     *
51
     * @param array|object $entity
52
     * @param string       $field
53
     * @param mixed        $default
54
     *
55
     * @return mixed
56
     * @throws AccessorException
57
     */
58
    public function getPropertyValue($entity, $field, $default = null)
59
    {
60
        $this->assertEntity($entity);
61
62
        if (is_array($entity) || $entity instanceof \ArrayAccess) {
63
            return isset($entity[$field]) ? $entity[$field] : $default;
64
        }
65
66
        $ref = $this->getReflection($entity);
67
        if (!$ref->hasProperty($field)) {
68
            return isset($entity->{$field}) ? $entity->{$field} : $default;
69
        }
70
71
        return $this->getProperty($ref, $field)->getValue($entity);
72
    }
73
74
    /**
75
     * Sets property value
76
     *
77
     * @param array|object $entity
78
     * @param string       $field
79
     * @param mixed        $value
80
     *
81
     * @throws AccessorException
82
     */
83
    public function setPropertyValue(&$entity, $field, $value)
84
    {
85
        $this->assertEntity($entity);
86
87
        if (is_array($entity) || $entity instanceof \ArrayAccess) {
88
            $entity[$field] = $value;
89
90
            return;
91
        }
92
93
        $ref = $this->getReflection($entity);
94
        if (!$ref->hasProperty($field)) {
95
            $entity->{$field} = $value;
96
97
            return;
98
        }
99
100
        $this->getProperty($ref, $field)->setValue($entity, $value);
101
    }
102
103
    /**
104
     * Asserts if entity is array or object
105
     *
106
     * @param mixed $entity
107
     *
108
     * @throws AccessorException
109
     */
110
    private function assertEntity($entity)
111
    {
112
        if (!is_array($entity) && !is_object($entity)) {
113
            throw new AccessorException('Unable to access entity properties, missing instance');
114
        }
115
    }
116
117
    /**
118
     * Returns object reflection instance
119
     *
120
     * @param object $object
121
     *
122
     * @return \ReflectionClass
123
     */
124
    private function getReflection($object)
125
    {
126
        $key = get_class($object);
127
128
        if (!array_key_exists($key, $this->buffer)) {
129
            $this->buffer[$key] = new \ReflectionClass($object);
130
        }
131
132
        return $this->buffer[$key];
133
    }
134
135
    /**
136
     * Returns object property instance
137
     *
138
     * @param \ReflectionClass $ref
139
     * @param string            $property
140
     *
141
     * @return \ReflectionProperty
142
     */
143
    private function getProperty(\ReflectionClass $ref, $property)
144
    {
145
        $prop = $ref->getProperty($property);
146
        $prop->setAccessible(true);
147
148
        return $prop;
149
    }
150
151
    /**
152
     * Adds value to array property
153
     * If property is not an array - will be converted into one preserving existing value as first element
154
     *
155
     * @param mixed  $entity
156
     * @param string $field
157
     * @param mixed  $value
158
     *
159
     * @throws AccessorException
160
     */
161
    public function addPropertyValue(&$entity, $field, $value)
162
    {
163
        $container = $this->getPropertyValue($entity, $field, $entity);
164
165
        if (!is_array($container)) {
166
            $container = empty($container) ? [] : [$container];
167
        }
168
        $container[] = $value;
169
170
        $this->setPropertyValue($entity, $field, $container);
171
    }
172
}
173