Completed
Push — master ( 7f9410...fc77a4 )
by Jacob
10s
created

Properties::set()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 19
rs 8.8571
cc 6
eloc 13
nc 4
nop 2
1
<?php
2
3
namespace As3\Modlr\Models;
4
5
use As3\Modlr\Store\Store;
6
use As3\Modlr\Metadata\EntityMetadata;
7
8
/**
9
 * Represents the properties of a Model.
10
 *
11
 * @author Jacob Bare <[email protected]>
12
 */
13
abstract class Properties
14
{
15
    /**
16
     * The original property values.
17
     *
18
     * @var array
19
     */
20
    protected $original = [];
21
22
    /**
23
     * The current/modified property values.
24
     *
25
     * @var array
26
     */
27
    protected $current = [];
28
29
    /**
30
     * Any properties that have been flagged for removal.
31
     *
32
     * @var array
33
     */
34
    protected $remove = [];
35
36
    /**
37
     * Constructor.
38
     *
39
     * @param   array   $original   Any original properties to apply.
40
     */
41
    public function __construct(array $original = [])
42
    {
43
        $this->original = $original;
44
    }
45
46
    /**
47
     * Gets the current value of an property.
48
     *
49
     * @param   string  $key    The property key.
50
     * @return  mixed
51
     */
52
    public function get($key)
53
    {
54
        if ($this->willRemove($key)) {
55
            return null;
56
        }
57
        if (true === $this->willChange($key)) {
58
            return $this->getCurrent($key);
59
        }
60
        return $this->getOriginal($key);
61
    }
62
63
    /**
64
     * Sets a new value to an property.
65
     *
66
     * @param   string  $key    The property key.
67
     * @param   mixed   $value  The value to set.
68
     * @return  mixed
69
     */
70
    public function set($key, $value)
71
    {
72
        if (null === $value) {
73
            return $this->remove($key);
74
        }
75
        $this->clearRemoval($key);
76
77
        $original = $this->getOriginal($key);
78
        if ($value === $original) {
79
            $this->clearChange($key);
80
        } else {
81
            if (($value instanceof \DateTime && $original instanceof \DateTime) && ($value->getTimestamp() === $original->getTimestamp())) {
82
                $this->clearChange($key);
83
            } else {
84
                $this->current[$key] = $value;
85
            }
86
        }
87
        return $this;
88
    }
89
90
    /**
91
     * Sets a new value to an property.
92
     *
93
     * @param   string  $key    The property key.
94
     * @return  self
95
     */
96
    public function remove($key)
97
    {
98
        if (false === $this->willRemove($key)) {
99
            $this->clearChange($key);
100
            if (true === $this->hasOriginal($key)) {
101
                $this->remove[] = $key;
102
            }
103
        }
104
        return $this;
105
    }
106
107
    /**
108
     * Rolls back the properties to their original state.
109
     *
110
     * @return  self
111
     */
112
    public function rollback()
113
    {
114
        $this->current = [];
115
        $this->remove = [];
116
        return $this;
117
    }
118
119
    /**
120
     * Replaces the current properties with new ones.
121
     * Will revert/rollback any current changes.
122
     *
123
     * @param   array   $original
124
     * @return  self
125
     */
126
    public function replace(array $original)
127
    {
128
        $this->rollback();
129
        $this->original = $original;
130
        return $this;
131
    }
132
133
134
    /**
135
     * Deteremines if the properties have different values from their original state.
136
     *
137
     * @return  bool
138
     */
139
    public function areDirty()
140
    {
141
        return !empty($this->current) || !empty($this->remove);
142
    }
143
144
    /**
145
     * Calculates any property changes.
146
     *
147
     * @return  array
148
     */
149 View Code Duplication
    public function calculateChangeSet()
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...
150
    {
151
        $set = [];
152
        foreach ($this->current as $key => $current) {
153
            $original = isset($this->original[$key]) ? $this->original[$key] : null;
154
            $set[$key]['old'] = $original;
155
            $set[$key]['new'] = $current;
156
        }
157
        foreach ($this->remove as $key) {
158
            $set[$key]['old'] = $this->original[$key];
159
            $set[$key]['new'] = null;
160
        }
161
        ksort($set);
162
        return $set;
163
    }
164
165
    /**
166
     * Clears an property from the removal queue.
167
     *
168
     * @param   string  $key    The field key.
169
     * @return  self
170
     */
171
    protected function clearRemoval($key)
172
    {
173
        if (false === $this->willRemove($key)) {
174
            return $this;
175
        }
176
        $key = array_search($key, $this->remove);
177
        unset($this->remove[$key]);
178
        $this->remove = array_values($this->remove);
179
        return $this;
180
    }
181
182
    /**
183
     * Clears an property as having been changed.
184
     *
185
     * @param   string  $key    The field key.
186
     * @return  self
187
     */
188
    protected function clearChange($key)
189
    {
190
        if (true === $this->willChange($key)) {
191
            unset($this->current[$key]);
192
        }
193
        return $this;
194
    }
195
196
    /**
197
     * Determines if an property is in the removal queue.
198
     *
199
     * @param   string  $key    The field key.
200
     * @return  bool
201
     */
202
    protected function willRemove($key)
203
    {
204
        return in_array($key, $this->remove);
205
    }
206
207
    /**
208
     * Determines if an property has a new value.
209
     *
210
     * @param   string  $key    The field key.
211
     * @return  bool
212
     */
213
    protected function willChange($key)
214
    {
215
        return null !== $this->getCurrent($key);
216
    }
217
218
    /**
219
     * Determines if an property has an original value.
220
     *
221
     * @param   string  $key    The field key.
222
     * @return  bool
223
     */
224
    protected function hasOriginal($key)
225
    {
226
        return null !== $this->getOriginal($key);
227
    }
228
229
    /**
230
     * Gets the property's original value.
231
     *
232
     * @param   string  $key    The field key.
233
     * @return  mixed
234
     */
235
    protected function getOriginal($key)
236
    {
237
        if (isset($this->original[$key])) {
238
            return $this->original[$key];
239
        }
240
        return null;
241
    }
242
243
    /**
244
     * Gets all original properties.
245
     *
246
     * @return  array
247
     */
248
    protected function getOriginalAll()
249
    {
250
        return $this->original;
251
    }
252
253
    /**
254
     * Gets all current properties.
255
     *
256
     * @return  array
257
     */
258
    protected function getCurrentAll()
259
    {
260
        return $this->current;
261
    }
262
263
    /**
264
     * Gets the property's current value.
265
     *
266
     * @param   string  $key    The field key.
267
     * @return  mixed
268
     */
269
    protected function getCurrent($key)
270
    {
271
        if (isset($this->current[$key])) {
272
            return $this->current[$key];
273
        }
274
        return null;
275
    }
276
}
277