1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the overtrue/laravel-revaluation. |
5
|
|
|
* |
6
|
|
|
* (c) overtrue <[email protected]> |
7
|
|
|
* |
8
|
|
|
* This source file is subject to the MIT license that is bundled |
9
|
|
|
* with this source code in the file LICENSE. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Overtrue\LaravelRevaluation\Traits; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* Trait HasRevaluableAttributes. |
16
|
|
|
*/ |
17
|
|
|
trait HasRevaluableAttributes |
18
|
|
|
{ |
19
|
|
|
/** |
20
|
|
|
* Revaluated attributes append to array. |
21
|
|
|
* |
22
|
|
|
* @var bool |
23
|
|
|
*/ |
24
|
|
|
//protected $appendRevaluatedAttributesToArray = true; |
|
|
|
|
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* @var bool |
28
|
|
|
*/ |
29
|
|
|
//protected $replaceRawAttributesToArray = false; |
|
|
|
|
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Prefix of revaluated attribute getter. |
33
|
|
|
* |
34
|
|
|
* <pre> |
35
|
|
|
* $model->revaluated_price; |
36
|
|
|
* </pre> |
37
|
|
|
* |
38
|
|
|
* @var string |
39
|
|
|
*/ |
40
|
|
|
//protected $revaluatedAttributePrefix = 'revaluated'; |
|
|
|
|
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Return valuator instance of attribute. |
44
|
|
|
* |
45
|
|
|
* @param string $attribute |
46
|
|
|
* |
47
|
|
|
* @return \Overtrue\LaravelRevaluation\Revaluable |
48
|
|
|
*/ |
49
|
|
|
public function getRevaluatedAttribute($attribute) |
50
|
|
|
{ |
51
|
|
|
$attribute = snake_case($attribute); |
52
|
|
|
|
53
|
|
|
if ($valuator = $this->getAttributeValuator($attribute)) { |
54
|
|
|
return new $valuator(parent::getAttribute($attribute), $attribute, $this); |
|
|
|
|
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
return false; |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Return revaluable attributes. |
62
|
|
|
* |
63
|
|
|
* @example |
64
|
|
|
* |
65
|
|
|
* <pre> |
66
|
|
|
* // 1. Using default valuator: |
67
|
|
|
* protected $revaluable = [ |
68
|
|
|
* 'foo', 'bar', 'baz' |
69
|
|
|
* ]; |
70
|
|
|
* |
71
|
|
|
* // 2. Use the specified valuator: |
72
|
|
|
* protected $revaluable = [ |
73
|
|
|
* 'foo' => '\Foo\Support\Valuator\Foo', |
74
|
|
|
* 'bar' => '\Foo\Support\Valuator\Bar', |
75
|
|
|
* 'baz', |
76
|
|
|
* ]; |
77
|
|
|
* </pre> |
78
|
|
|
* |
79
|
|
|
* @return array |
80
|
|
|
*/ |
81
|
|
|
public function getRevaluableAttributes() |
82
|
|
|
{ |
83
|
|
|
if (!property_exists($this, 'revaluable') || !is_array($this->revaluable)) { |
|
|
|
|
84
|
|
|
return []; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
$revaluable = []; |
88
|
|
|
|
89
|
|
|
foreach ($this->revaluable as $key => $valuator) { |
90
|
|
|
if (is_int($key)) { |
91
|
|
|
$revaluable[$valuator] = config('revaluation.default_valuator'); |
92
|
|
|
} else { |
93
|
|
|
$revaluable[$key] = $valuator; |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
return $revaluable; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Return the additional attribute revaluate mutators. |
102
|
|
|
* |
103
|
|
|
* @return array |
104
|
|
|
*/ |
105
|
|
|
public function getRevaluateMutators() |
106
|
|
|
{ |
107
|
|
|
return property_exists($this, 'revaluateMutators') ? (array) $this->revaluateMutators : []; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* @return string |
112
|
|
|
*/ |
113
|
|
|
public function getRevaluableAttributePrefix() |
114
|
|
|
{ |
115
|
|
|
return rtrim($this->revaluatedAttributePrefix ?? 'revaluated', '_'); |
|
|
|
|
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @example |
120
|
|
|
* <pre> |
121
|
|
|
* $object->revaluated_price; |
122
|
|
|
* $object->raw_price; |
123
|
|
|
* </pre> |
124
|
|
|
* |
125
|
|
|
* @param string $attribute |
126
|
|
|
* |
127
|
|
|
* @return mixed |
128
|
|
|
* |
129
|
|
|
* @throws \Exception |
130
|
|
|
*/ |
131
|
|
|
public function getAttribute($attribute) |
132
|
|
|
{ |
133
|
|
|
if ($this->hasGetMutator($attribute)) { |
|
|
|
|
134
|
|
|
return parent::getAttribute($attribute); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
if (starts_with($attribute, 'raw_')) { |
138
|
|
|
return $this->getRevaluatedAttribute(substr($attribute, strlen('raw_')))->getRaw(); |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
$prefix = $this->getRevaluableAttributePrefix(); |
142
|
|
|
|
143
|
|
|
if (starts_with($attribute, $prefix)) { |
144
|
|
|
return $this->getRevaluatedAttribute(substr($attribute, strlen($prefix) + 1)); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
if ($valuator = $this->getRevaluatedAttribute($attribute)) { |
148
|
|
|
return $valuator->toDefaultFormat(); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* <pre> |
153
|
|
|
* $revaluateMutators = [ |
154
|
|
|
* 'display_price' => ['price', 'asCurrency'], |
155
|
|
|
* ]; |
156
|
|
|
* </pre>. |
157
|
|
|
* |
158
|
|
|
* @var array |
159
|
|
|
*/ |
160
|
|
|
$revaluateMutators = $this->getRevaluateMutators(); |
161
|
|
|
|
162
|
|
|
if (isset($revaluateMutators[$attribute])) { |
163
|
|
|
list($sourceAttribute, $method) = $revaluateMutators[$attribute]; |
164
|
|
|
$revaluated = $this->getRevaluatedAttribute($sourceAttribute); |
165
|
|
|
|
166
|
|
|
if (!is_callable([$revaluated, $method])) { |
167
|
|
|
throw new \Exception("$method not an callable method."); |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
return call_user_func([$revaluated, $method]); |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
return parent::getAttribute($attribute); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* Set attribute. |
178
|
|
|
* |
179
|
|
|
* @param string $attribute |
180
|
|
|
* @param mixed $value |
181
|
|
|
* |
182
|
|
|
* @return $this |
183
|
|
|
*/ |
184
|
|
|
public function setAttribute($attribute, $value) |
185
|
|
|
{ |
186
|
|
|
if ($valuator = $this->getAttributeValuator($attribute)) { |
187
|
|
|
$value = forward_static_call([$valuator, 'toStorableValue'], $value); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
return parent::setAttribute($attribute, $value); |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* Run the increment or decrement method on the model. |
195
|
|
|
* |
196
|
|
|
* @param string $column |
197
|
|
|
* @param int $amount |
198
|
|
|
* @param array $extra |
199
|
|
|
* @param string $method |
200
|
|
|
* @return int |
201
|
|
|
*/ |
202
|
|
|
protected function incrementOrDecrement($column, $amount, $extra, $method) |
203
|
|
|
{ |
204
|
|
|
$query = $this->newQuery(); |
|
|
|
|
205
|
|
|
|
206
|
|
|
if (! $this->exists) { |
|
|
|
|
207
|
|
|
return $query->{$method}($column, $amount, $extra); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
$this->incrementOrDecrementAttributeValue($column, $amount, $extra, $method); |
|
|
|
|
211
|
|
|
|
212
|
|
|
// ***[ fix increment/decrement bug]*** |
213
|
|
|
if ($valuator = $this->getAttributeValuator($column)) { |
214
|
|
|
$amount = forward_static_call([$valuator, 'toStorableValue'], $amount); |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
return $query->where( |
218
|
|
|
$this->getKeyName(), $this->getKey() |
|
|
|
|
219
|
|
|
)->{$method}($column, $amount, $extra); |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* Override HasAttributes::attributesToArray. |
224
|
|
|
* |
225
|
|
|
* @return array |
226
|
|
|
*/ |
227
|
|
|
public function attributesToArray() |
228
|
|
|
{ |
229
|
|
|
$attributes = parent::attributesToArray(); |
230
|
|
|
|
231
|
|
|
if ($this->shouldAppendRevaluatedAttributesToArray()) { |
232
|
|
|
foreach (array_keys($this->getRevaluableAttributes()) as $attribute) { |
233
|
|
|
if ($valuator = $this->getRevaluatedAttribute($attribute)) { |
234
|
|
|
$attribute = $this->shouldReplaceRawAttributesToArray() ? $attribute : $this->getRevaluablePrefixedAttributeName($attribute); |
235
|
|
|
$attributes[$attribute] = $valuator->toDefaultFormat(); |
236
|
|
|
} |
237
|
|
|
} |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
return $attributes; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* @param string $attribute |
245
|
|
|
* |
246
|
|
|
* @return string |
247
|
|
|
*/ |
248
|
|
|
public function getRevaluablePrefixedAttributeName($attribute) |
249
|
|
|
{ |
250
|
|
|
return $this->getRevaluableAttributePrefix().'_'.$attribute; |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
/** |
254
|
|
|
* Fetch attribute. |
255
|
|
|
* |
256
|
|
|
* @example |
257
|
|
|
* <pre> |
258
|
|
|
* $object->getRevaluatedPriceAttribute(); |
259
|
|
|
* $object->getRevaluatedXXXAttribute(); |
260
|
|
|
* </pre> |
261
|
|
|
* |
262
|
|
|
* @param string $method |
263
|
|
|
* |
264
|
|
|
* @return mixed |
265
|
|
|
*/ |
266
|
|
|
public function __call($method, $args) |
267
|
|
|
{ |
268
|
|
|
$prefix = studly_case($this->getRevaluableAttributePrefix()); |
269
|
|
|
if (preg_match("/get{$prefix}(?<attribute>\\w+)Attribute/i", $method, $matches)) { |
270
|
|
|
return $this->getRevaluatedAttribute($matches['attribute']); |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
return parent::__call($method, $args); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
/** |
277
|
|
|
* @return bool |
278
|
|
|
*/ |
279
|
|
|
protected function shouldAppendRevaluatedAttributesToArray() |
280
|
|
|
{ |
281
|
|
|
return property_exists($this, 'appendRevaluatedAttributesToArray') ? $this->appendRevaluatedAttributesToArray : true; |
|
|
|
|
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
/** |
285
|
|
|
* @return bool |
286
|
|
|
*/ |
287
|
|
|
protected function shouldReplaceRawAttributesToArray() |
288
|
|
|
{ |
289
|
|
|
return property_exists($this, 'replaceRawAttributesToArray') ? $this->replaceRawAttributesToArray : false; |
|
|
|
|
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
/** |
293
|
|
|
* Return revaluated value of attribute. |
294
|
|
|
* |
295
|
|
|
* @param string $attribute |
296
|
|
|
* |
297
|
|
|
* @return mixed |
298
|
|
|
*/ |
299
|
|
|
protected function getStorableValue($attribute) |
300
|
|
|
{ |
301
|
|
|
if ($valuator = $this->getAttributeValuator($attribute)) { |
302
|
|
|
if (is_callable($valuator, 'toStorableValue')) { |
303
|
|
|
$value = forward_static_call([$valuator, 'toStorableValue'], $this->attributes[$attribute]); |
|
|
|
|
304
|
|
|
} |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
return $value; |
|
|
|
|
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* Get attribute valuator. |
312
|
|
|
* |
313
|
|
|
* @param string $attribute |
314
|
|
|
* |
315
|
|
|
* @return string |
316
|
|
|
*/ |
317
|
|
|
protected function getAttributeValuator($attribute) |
318
|
|
|
{ |
319
|
|
|
return array_get($this->getRevaluableAttributes(), $attribute); |
320
|
|
|
} |
321
|
|
|
} |
322
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.