22
33namespace Jenssegers \Mongodb \Eloquent ;
44
5+ use function array_key_exists ;
56use DateTimeInterface ;
7+ use function explode ;
68use Illuminate \Contracts \Queue \QueueableCollection ;
79use Illuminate \Contracts \Queue \QueueableEntity ;
10+ use Illuminate \Contracts \Support \Arrayable ;
811use Illuminate \Database \Eloquent \Model as BaseModel ;
912use Illuminate \Database \Eloquent \Relations \Relation ;
1013use Illuminate \Support \Arr ;
1114use Illuminate \Support \Facades \Date ;
1215use Illuminate \Support \Str ;
16+ use function in_array ;
1317use Jenssegers \Mongodb \Query \Builder as QueryBuilder ;
1418use MongoDB \BSON \Binary ;
1519use MongoDB \BSON \ObjectID ;
1620use MongoDB \BSON \UTCDateTime ;
21+ use function uniqid ;
1722
1823abstract class Model extends BaseModel
1924{
@@ -94,7 +99,7 @@ public function fromDateTime($value)
9499 $ value = parent ::asDateTime ($ value );
95100 }
96101
97- return new UTCDateTime ($ value-> format ( ' Uv ' ) );
102+ return new UTCDateTime ($ value );
98103 }
99104
100105 /**
@@ -191,13 +196,14 @@ public function setAttribute($key, $value)
191196 $ value = $ builder ->convertKey ($ value );
192197 } // Support keys in dot notation.
193198 elseif (Str::contains ($ key , '. ' )) {
194- if ( in_array ( $ key , $ this -> getDates ()) && $ value ) {
195- $ value = $ this -> fromDateTime ( $ value );
196- }
199+ // Store to a temporary key, then move data to the actual key
200+ $ uniqueKey = uniqid ( $ key );
201+ parent :: setAttribute ( $ uniqueKey , $ value );
197202
198- Arr::set ($ this ->attributes , $ key , $ value );
203+ Arr::set ($ this ->attributes , $ key , $ this ->attributes [$ uniqueKey ] ?? null );
204+ unset($ this ->attributes [$ uniqueKey ]);
199205
200- return ;
206+ return $ this ;
201207 }
202208
203209 return parent ::setAttribute ($ key , $ value );
@@ -222,13 +228,6 @@ public function attributesToArray()
222228 }
223229 }
224230
225- // Convert dot-notation dates.
226- foreach ($ this ->getDates () as $ key ) {
227- if (Str::contains ($ key , '. ' ) && Arr::has ($ attributes , $ key )) {
228- Arr::set ($ attributes , $ key , (string ) $ this ->asDateTime (Arr::get ($ attributes , $ key )));
229- }
230- }
231-
232231 return $ attributes ;
233232 }
234233
@@ -515,4 +514,62 @@ public function __call($method, $parameters)
515514
516515 return parent ::__call ($ method , $ parameters );
517516 }
517+
518+ /**
519+ * Add the casted attributes to the attributes array.
520+ *
521+ * @param array $attributes
522+ * @param array $mutatedAttributes
523+ * @return array
524+ */
525+ protected function addCastAttributesToArray (array $ attributes , array $ mutatedAttributes )
526+ {
527+ foreach ($ this ->getCasts () as $ key => $ castType ) {
528+ if (! Arr::has ($ attributes , $ key ) || Arr::has ($ mutatedAttributes , $ key )) {
529+ continue ;
530+ }
531+
532+ $ originalValue = Arr::get ($ attributes , $ key );
533+
534+ // Here we will cast the attribute. Then, if the cast is a date or datetime cast
535+ // then we will serialize the date for the array. This will convert the dates
536+ // to strings based on the date format specified for these Eloquent models.
537+ $ castValue = $ this ->castAttribute (
538+ $ key , $ originalValue
539+ );
540+
541+ // If the attribute cast was a date or a datetime, we will serialize the date as
542+ // a string. This allows the developers to customize how dates are serialized
543+ // into an array without affecting how they are persisted into the storage.
544+ if ($ castValue !== null && in_array ($ castType , ['date ' , 'datetime ' , 'immutable_date ' , 'immutable_datetime ' ])) {
545+ $ castValue = $ this ->serializeDate ($ castValue );
546+ }
547+
548+ if ($ castValue !== null && ($ this ->isCustomDateTimeCast ($ castType ) ||
549+ $ this ->isImmutableCustomDateTimeCast ($ castType ))) {
550+ $ castValue = $ castValue ->format (explode (': ' , $ castType , 2 )[1 ]);
551+ }
552+
553+ if ($ castValue instanceof DateTimeInterface &&
554+ $ this ->isClassCastable ($ key )) {
555+ $ castValue = $ this ->serializeDate ($ castValue );
556+ }
557+
558+ if ($ castValue !== null && $ this ->isClassSerializable ($ key )) {
559+ $ castValue = $ this ->serializeClassCastableAttribute ($ key , $ castValue );
560+ }
561+
562+ if ($ this ->isEnumCastable ($ key ) && (! $ castValue instanceof Arrayable)) {
563+ $ castValue = $ castValue !== null ? $ this ->getStorableEnumValue ($ attributes [$ key ]) : null ;
564+ }
565+
566+ if ($ castValue instanceof Arrayable) {
567+ $ castValue = $ castValue ->toArray ();
568+ }
569+
570+ Arr::set ($ attributes , $ key , $ castValue );
571+ }
572+
573+ return $ attributes ;
574+ }
518575}
0 commit comments