Passed
Push — main ( 2621a4...7e0081 )
by Gabriel
02:32
created

TrackOriginalTrait::fillOriginal()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 2
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 4
rs 10
ccs 0
cts 1
cp 0
crap 6
1
<?php
2
3
namespace ByTIC\DataObjects\Behaviors\TrackOriginal;
4
5
use InvalidArgumentException;
6
use Nip\Utility\Arr;
7
8
/**
9
 * Trait TrackOriginalTrait
10
 * @package ByTIC\DataObjects\Behaviors\TrackOriginal
11
 */
12
trait TrackOriginalTrait
13
{
14
    use \ByTIC\DataObjects\Legacy\Behaviors\OldDBDataTrait;
15
16
    /**
17
     * The Object original state.
18
     *
19
     * @var array
20
     */
21
    protected $original = [];
22
23
    /**
24
     * @param $data
25
     */
26
    public function fillOriginal($data)
27
    {
28
        foreach ($data as $key => $value) {
29
            $this->original[$key] = $value;
30
        }
31
    }
32
33
    public function getOriginal(): array
34
    {
35
        return $this->original;
36
    }
37
38
    /**
39
     * Returns the value of an original field by name
40
     *
41
     * @param string $field the name of the field for which original value is retrieved.
42
     * @param null $default
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $default is correct as it would always require null to be passed?
Loading history...
43
     * @return mixed
44
     */
45
    public function getOriginalField(string $field, $default = null)
46
    {
47
        if (!strlen($field)) {
48
            throw new InvalidArgumentException('Cannot get an empty field');
49
        }
50
51
        if (array_key_exists($field, $this->original)) {
52
            return $this->original[$field];
53
        }
54
55
        return $this->get($field, $default);
0 ignored issues
show
Bug introduced by
It seems like get() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

55
        return $this->/** @scrutinizer ignore-call */ get($field, $default);
Loading history...
56
    }
57
58 15
    /**
59
     * Get the model's raw original attribute values.
60 15
     *
61 15
     * @param string|null $key
62
     * @param mixed $default
63
     * @return mixed|array
64
     */
65
    public function getRawOriginal($key = null, $default = null)
66
    {
67
        return Arr::get($this->original, $key, $default);
68
    }
69
70
    /**
71
     * Sync the original attributes with the current.
72
     *
73
     * @return $this
74
     */
75
    public function syncOriginal()
76
    {
77
        $this->original = $this->getAttributes();
0 ignored issues
show
Bug introduced by
It seems like getAttributes() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

77
        /** @scrutinizer ignore-call */ 
78
        $this->original = $this->getAttributes();
Loading history...
78
        return $this;
79
    }
80
81
    /**
82
     * Determine if the model or any of the given attribute(s) have been modified.
83
     *
84
     * @param array|string|null $attributes
85
     * @return bool
86
     */
87
    public function isDirty($attributes = null)
88
    {
89
        return $this->hasChanges(
90
            $this->getDirty(),
91
            is_array($attributes) ? $attributes : func_get_args()
92
        );
93
    }
94
95
    /**
96
     * Determine if the model and all the given attribute(s) have remained the same.
97
     *
98
     * @param array|string|null $attributes
99
     * @return bool
100
     */
101
    public function isClean($attributes = null)
102
    {
103
        return !$this->isDirty(...func_get_args());
104
    }
105
106
    /**
107
     * Determine if the model or any of the given attribute(s) have been modified.
108
     *
109
     * @param array|string|null $attributes
110
     * @return bool
111
     */
112
    public function wasChanged($attributes = null)
113
    {
114
        return $this->hasChanges(
115
            $this->getChanges(),
0 ignored issues
show
Bug introduced by
It seems like getChanges() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

115
            $this->/** @scrutinizer ignore-call */ 
116
                   getChanges(),
Loading history...
116
            is_array($attributes) ? $attributes : func_get_args()
117
        );
118
    }
119
120
    /**
121
     * Get the attributes that have been changed since last sync.
122
     *
123
     * @param null $fields
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $fields is correct as it would always require null to be passed?
Loading history...
124
     * @return array
125
     */
126
    public function getDirty($fields = null): array
127
    {
128
        $dirty = [];
129
        $fields = is_array($fields) && count($fields) > 0 ? $fields : array_keys($this->getAttributes());
0 ignored issues
show
introduced by
The condition is_array($fields) is always false.
Loading history...
130
        foreach ($fields as $field) {
131
            $value = $this->getPropertyRaw($field);
0 ignored issues
show
Bug introduced by
It seems like getPropertyRaw() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

131
            /** @scrutinizer ignore-call */ 
132
            $value = $this->getPropertyRaw($field);
Loading history...
132
            if (!$this->originalIsEquivalent($field, $value)) {
133
                $dirty[$field] = $value;
134
            }
135
        }
136
137
        return $dirty;
138
    }
139
140
    /**
141
     * Determine if any of the given attributes were changed.
142
     *
143
     * @param array $changes
144
     * @param array|string|null $attributes
145
     * @return bool
146
     */
147
    protected function hasChanges($changes, $attributes = null)
148
    {
149
        // If no specific attributes were provided, we will just see if the dirty array
150
        // already contains any attributes. If it does we will just return that this
151
        // count is greater than zero. Else, we need to check specific attributes.
152
        if (empty($attributes)) {
153
            return count($changes) > 0;
154
        }
155
156
        // Here we will spin through every attribute and see if this is in the array of
157
        // dirty attributes. If it is, we will return true and if we make it through
158
        // all of the attributes for the entire array we will return false at end.
159
        foreach (Arr::wrap($attributes) as $attribute) {
160
            if (array_key_exists($attribute, $changes)) {
161
                return true;
162
            }
163
        }
164
165
        return false;
166
    }
167
168
    /**
169
     * @param string $key
170
     * @param null $value
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $value is correct as it would always require null to be passed?
Loading history...
171
     * @return bool
172
     */
173
    protected function originalIsEquivalent(string $key, $value = null): bool
174
    {
175
        if (!array_key_exists($key, $this->original)) {
176
            return false;
177
        }
178
        $attribute = $value ?? $this->getPropertyRaw($key);
179
        $original = Arr::get($this->original, $key);
180
181
        if ($attribute === $original) {
182
            return true;
183
        }
184
185
        return is_numeric($attribute) && is_numeric($original)
186
            && strcmp((string)$attribute, (string)$original) === 0;
187
    }
188
}
189