@@ -1159,10 +1159,9 @@ public function save(array $options = [])
11591159 try {
11601160 /** We will try to optimize the execution by caching $dirty array BUT,
11611161 multiple set calls will be needed (https://github.com/laravel/framework/discussions/31778)
1162- WHEN $this->usesTimestamps() or WHEN there are listeners for the following events:
1163- - updating event can do changes so, $this->getDirtyForUpdate() and $this->syncChanges() will call
1164- $this->getDirty(),
1165- - updated/saved events can do changes so, $this->syncOriginal() will call $this->getAttributes() */
1162+ WHEN $this->usesTimestamps() or WHEN there are listeners for updating event because they can do changes
1163+ so, $this->getDirtyForUpdate() and $this->syncChanges() will call $this->getDirty() which will call
1164+ getAttributes() */
11661165 if (!$ this ->getEventDispatcher ()->hasListeners ('eloquent.updating: ' . $ this ::class)) {
11671166 $ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts = $ dirty ;
11681167 unset($ dirty );
@@ -1177,6 +1176,7 @@ public function save(array $options = [])
11771176 return false ;
11781177 } finally {
11791178 $ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts = null ;
1179+ $ this ->tmpOriginalBeforeAfterEvents = null ;
11801180 }
11811181 }
11821182
@@ -1185,20 +1185,24 @@ public function save(array $options = [])
11851185
11861186 /** Multiple set calls are needed (https://github.com/laravel/framework/discussions/31778) because:
11871187 - $this->performInsert can do changes,
1188- - creating event can do changes so, $this->getAttributesForInsert() will call $this->getAttributes(),
1189- - created/saved events can do changes so, $this->syncOriginal() will call $this->getAttributes() */
1188+ - creating event can do changes so,
1189+ $this->getAttributesForInsert() and $this->syncOriginal() will call $this->getAttributes() */
11901190
1191- $ saved = $ this ->performInsert ($ query );
1191+ try {
1192+ $ saved = $ this ->performInsert ($ query );
11921193
1193- if (
1194- '' === (string )$ this ->getConnectionName () &&
1195- ($ connection = $ query ->getConnection ()) instanceof Connection
1196- ) {
1197- $ this ->setConnection ($ connection ->getName ());
1198- }
1194+ if (
1195+ '' === (string )$ this ->getConnectionName () &&
1196+ ($ connection = $ query ->getConnection ()) instanceof Connection
1197+ ) {
1198+ $ this ->setConnection ($ connection ->getName ());
1199+ }
11991200
1200- if ($ saved ) {
1201- $ this ->finishSave ($ options + ['touch ' => $ isDirty ]);
1201+ if ($ saved ) {
1202+ $ this ->finishSave ($ options + ['touch ' => $ isDirty ]);
1203+ }
1204+ } finally {
1205+ $ this ->tmpOriginalBeforeAfterEvents = null ;
12021206 }
12031207
12041208 return $ saved ;
@@ -1225,19 +1229,19 @@ public function saveOrFail(array $options = [])
12251229 */
12261230 protected function finishSave (array $ options )
12271231 {
1228- if (
1229- isset ($ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts )
1230- && $ this ->getEventDispatcher ()->hasListeners ('eloquent.saved: ' . $ this ::class)
1231- ) {
1232- $ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts = null ;
1233- }
1234-
12351232 $ this ->fireModelEvent ('saved ' , false );
12361233
12371234 if ($ options ['touch ' ] ?? true ) {
12381235 $ this ->touchOwners ();
12391236 }
12401237
1238+ if (isset ($ this ->tmpOriginalBeforeAfterEvents )) {
1239+ $ this ->original = $ this ->tmpOriginalBeforeAfterEvents ;
1240+ $ this ->tmpOriginalBeforeAfterEvents = null ;
1241+
1242+ return ;
1243+ }
1244+
12411245 $ this ->syncOriginal ();
12421246 }
12431247
@@ -1274,12 +1278,8 @@ protected function performUpdate(Builder $query)
12741278
12751279 $ this ->syncChanges ();
12761280
1277- if (
1278- isset ($ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts )
1279- && $ this ->getEventDispatcher ()->hasListeners ('eloquent.updated: ' . $ this ::class)
1280- ) {
1281- $ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts = null ;
1282- }
1281+ $ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts = null ;
1282+ $ this ->tmpOriginalBeforeAfterEvents = $ this ->attributes ;
12831283
12841284 $ this ->fireModelEvent ('updated ' , false );
12851285 }
@@ -1374,6 +1374,8 @@ protected function performInsert(Builder $query)
13741374 $ query ->insert ($ attributes );
13751375 }
13761376
1377+ $ this ->tmpOriginalBeforeAfterEvents = $ this ->attributes ;
1378+
13771379 // We will go ahead and set the exists property to true, so that it is set when
13781380 // the created event is fired, just in case the developer tries to update it
13791381 // during the event. This will allow them to do so and run an update here.
0 commit comments