|
1
|
|
|
<?php |
|
2
|
|
|
declare(strict_types=1); |
|
3
|
|
|
|
|
4
|
|
|
namespace Thinktomorrow\Chief\DynamicAttributes; |
|
5
|
|
|
|
|
6
|
|
|
trait HasDynamicAttributes |
|
7
|
|
|
{ |
|
8
|
|
|
public function dynamic(string $key, string $index = null) |
|
9
|
|
|
{ |
|
10
|
|
|
return $this->dynamicAttributesInstance()->get($index ? "$index.$key" : $key); |
|
11
|
|
|
} |
|
12
|
|
|
|
|
13
|
|
|
public function setDynamic(string $key, $value, string $index = null) |
|
14
|
|
|
{ |
|
15
|
|
|
return $this->dynamicAttributesInstance()->set($index ? "$index.$key" : $key, $value); |
|
|
|
|
|
|
16
|
|
|
} |
|
17
|
|
|
|
|
18
|
|
|
public function isDynamicAttributeKey($key): bool |
|
19
|
|
|
{ |
|
20
|
|
|
if(array_key_exists($key, $this->attributes)) { |
|
21
|
|
|
return false; |
|
22
|
|
|
} |
|
23
|
|
|
|
|
24
|
|
|
return in_array($key, $this->dynamicAttributeKeys()); |
|
25
|
|
|
} |
|
26
|
|
|
|
|
27
|
|
|
/** |
|
28
|
|
|
* The attribute key which the dynamic attributes is |
|
29
|
|
|
* referenced by as well as the database column name. |
|
30
|
|
|
* |
|
31
|
|
|
* @return string |
|
32
|
|
|
*/ |
|
33
|
|
|
protected function getDynamicAttributesKey(): string |
|
34
|
|
|
{ |
|
35
|
|
|
return 'values'; |
|
36
|
|
|
} |
|
37
|
|
|
|
|
38
|
|
|
/** |
|
39
|
|
|
* The attributes that should be treated as dynamic ones. This |
|
40
|
|
|
* is a list of keys matching the database column names. |
|
41
|
|
|
* @return array |
|
42
|
|
|
*/ |
|
43
|
|
|
protected function dynamicAttributeKeys(): array |
|
44
|
|
|
{ |
|
45
|
|
|
return property_exists($this, 'dynamicAttributes') ? $this->dynamicAttributes : []; |
|
46
|
|
|
} |
|
47
|
|
|
|
|
48
|
|
|
/** |
|
49
|
|
|
* Part of the custom cast. Method used by the save logic on eloquent. We override this so we can |
|
50
|
|
|
* inject an json version of the dynamic attributes for saving into the database. |
|
51
|
|
|
* |
|
52
|
|
|
* @return mixed |
|
53
|
|
|
*/ |
|
54
|
|
|
public function getAttributes() |
|
55
|
|
|
{ |
|
56
|
|
|
return $this->injectDynamicAttributes($this->attributes, false); |
|
57
|
|
|
} |
|
58
|
|
|
|
|
59
|
|
|
/* Part of the custom cast */ |
|
60
|
|
|
public function setRawAttributes(array $attributes, $sync = false) |
|
61
|
|
|
{ |
|
62
|
|
|
return parent::setRawAttributes($this->injectDynamicAttributes($attributes), $sync); |
|
63
|
|
|
} |
|
64
|
|
|
|
|
65
|
|
|
/* Part of the custom cast */ |
|
66
|
|
|
public function fill(array $attributes) |
|
67
|
|
|
{ |
|
68
|
|
|
return parent::fill($this->injectDynamicAttributes($attributes)); |
|
69
|
|
|
} |
|
70
|
|
|
|
|
71
|
|
|
/* Part of the custom cast */ |
|
72
|
|
|
public function getAttribute($key) |
|
73
|
|
|
{ |
|
74
|
|
|
if (!$this->isDynamicAttributeKey($key)){ |
|
75
|
|
|
return parent::getAttribute($key); |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
$locale = app()->getLocale(); |
|
|
|
|
|
|
79
|
|
|
|
|
80
|
|
|
// If the dynamic attributes contain a localized value, this has preference over any non-localized. |
|
81
|
|
|
foreach(["{$locale}.$key", $key] as $k){ |
|
82
|
|
|
if($this->dynamicAttributesInstance()->has($k)){ |
|
83
|
|
|
return $this->dynamic($k); |
|
84
|
|
|
} |
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
return parent::getAttribute($key); |
|
88
|
|
|
} |
|
89
|
|
|
|
|
90
|
|
|
/* Part of the custom cast */ |
|
91
|
|
|
public function setAttribute($key, $value) |
|
92
|
|
|
{ |
|
93
|
|
|
if ($this->isDynamicAttributeKey($key)){ |
|
94
|
|
|
return $this->setDynamic($key, $value); |
|
|
|
|
|
|
95
|
|
|
} |
|
96
|
|
|
|
|
97
|
|
|
return parent::setAttribute($key, $value); |
|
98
|
|
|
} |
|
99
|
|
|
|
|
100
|
|
|
/* Part of the custom cast */ |
|
101
|
|
|
protected function dynamicAttributesInstance(): DynamicAttributes |
|
102
|
|
|
{ |
|
103
|
|
|
if(!isset($this->attributes[$this->getDynamicAttributesKey()])) { |
|
104
|
|
|
$this->attributes[$this->getDynamicAttributesKey()] = DynamicAttributes::fromRawValue([]); |
|
|
|
|
|
|
105
|
|
|
} elseif(!($raw = $this->attributes[$this->getDynamicAttributesKey()]) instanceof DynamicAttributes) { |
|
106
|
|
|
$this->attributes[$this->getDynamicAttributesKey()] = DynamicAttributes::fromRawValue($raw); |
|
107
|
|
|
} |
|
108
|
|
|
|
|
109
|
|
|
return $this->attributes[$this->getDynamicAttributesKey()]; |
|
110
|
|
|
} |
|
111
|
|
|
|
|
112
|
|
|
/** |
|
113
|
|
|
* Inject the dynamic attributes into the attributes array. |
|
114
|
|
|
* Either as a DynamicAttributes instance or back to a json format. |
|
115
|
|
|
* |
|
116
|
|
|
* @param array $attributes |
|
117
|
|
|
* @param bool $castToObject |
|
118
|
|
|
* @return array |
|
119
|
|
|
*/ |
|
120
|
|
|
private function injectDynamicAttributes(array $attributes, bool $castToObject = true): array |
|
121
|
|
|
{ |
|
122
|
|
|
if(isset($attributes[$this->getDynamicAttributesKey()])) { |
|
123
|
|
|
$attributes[$this->getDynamicAttributesKey()] = $castToObject |
|
124
|
|
|
? DynamicAttributes::fromRawValue($attributes[$this->getDynamicAttributesKey()]) |
|
125
|
|
|
: $attributes[$this->getDynamicAttributesKey()]->toJson(); |
|
126
|
|
|
} |
|
127
|
|
|
|
|
128
|
|
|
return $attributes; |
|
129
|
|
|
} |
|
130
|
|
|
} |
|
131
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.