@@ -122,7 +122,7 @@ public function getAttribute($key)
122
122
}
123
123
124
124
// Dot notation support.
125
- if (Str::contains ($ key , '. ' ) && Arr::has ($ this ->attributes , $ key )) {
125
+ if (( Str::contains ($ key , '. ' ) && Arr::has ($ this ->attributes , $ key )) || $ this -> containsCastableField ( $ key )) {
126
126
return $ this ->getAttributeValue ($ key );
127
127
}
128
128
@@ -134,6 +134,25 @@ public function getAttribute($key)
134
134
return parent ::getAttribute ($ key );
135
135
}
136
136
137
+ /**
138
+ * Determine whether an attribute contains castable subfields.
139
+ *
140
+ * @param string $key
141
+ * @return bool
142
+ */
143
+ public function containsCastableField ($ key )
144
+ {
145
+ $ attributes = array_merge (array_keys ($ this ->getCasts ()), $ this ->getDates ());
146
+
147
+ foreach ($ attributes as $ attribute ) {
148
+ if (Str::startsWith ($ attribute , $ key .'. ' )) {
149
+ return true ;
150
+ }
151
+ }
152
+
153
+ return false ;
154
+ }
155
+
137
156
/**
138
157
* @inheritdoc
139
158
*/
@@ -270,6 +289,65 @@ public function originalIsEquivalent($key)
270
289
&& strcmp ((string ) $ attribute , (string ) $ original ) === 0 ;
271
290
}
272
291
292
+ /**
293
+ * @inheritdoc
294
+ */
295
+ protected function transformModelValue ($ key , $ value )
296
+ {
297
+ // If the attribute has a get mutator, we will call that then return what
298
+ // it returns as the value, which is useful for transforming values on
299
+ // retrieval from the model to a form that is more useful for usage.
300
+ if ($ this ->hasGetMutator ($ key )) {
301
+ return $ this ->mutateAttribute ($ key , $ value );
302
+ } elseif ($ this ->hasAttributeGetMutator ($ key )) {
303
+ return $ this ->mutateAttributeMarkedAttribute ($ key , $ value );
304
+ }
305
+
306
+ // If the value is an array, transform the array to cast subfields if necessar
307
+ if (is_array ($ value )) {
308
+ $ value = $ this ->transformModelArrayValue ($ key , $ value );
309
+ }
310
+
311
+ // If the attribute exists within the cast array, we will convert it to
312
+ // an appropriate native PHP type dependent upon the associated value
313
+ // given with the key in the pair. Dayle made this comment line up.
314
+ if ($ this ->hasCast ($ key )) {
315
+ return $ this ->castAttribute ($ key , $ value );
316
+ }
317
+
318
+ // If the attribute is listed as a date, we will convert it to a DateTime
319
+ // instance on retrieval, which makes it quite convenient to work with
320
+ // date fields without having to create a mutator for each property.
321
+ if ($ value !== null
322
+ && \in_array ($ key , $ this ->getDates (), false )) {
323
+ return $ this ->asDateTime ($ value );
324
+ }
325
+
326
+ return $ value ;
327
+ }
328
+
329
+ /**
330
+ * Transform an array model value using mutators, casts, etc.
331
+ *
332
+ * @param string $key
333
+ * @param mixed $value
334
+ * @return mixed
335
+ */
336
+ protected function transformModelArrayValue ($ key , $ array )
337
+ {
338
+ $ values = [];
339
+ foreach ($ array as $ k => $ value ) {
340
+ $ new_key = is_numeric ($ k ) ? $ key : ($ key .'. ' .$ k );
341
+ if (is_array ($ value )) {
342
+ $ values [$ k ] = $ this ->transformModelArrayValue ($ new_key , $ value );
343
+ } else {
344
+ $ values [$ k ] = $ this ->transformModelValue ($ new_key , $ value );
345
+ }
346
+ }
347
+
348
+ return $ values ;
349
+ }
350
+
273
351
/**
274
352
* Remove one or more fields.
275
353
* @param mixed $columns
0 commit comments