@@ -43,6 +43,55 @@ public function __call($method, $parameters)
4343 return parent ::__call ($ method , $ parameters );
4444 }
4545
46+ /**
47+ * Prevent updates
48+ * Note that relations can be loaded and updated during the lock
49+ */
50+ public function lockUpdates (bool $ checkDirty = true ): bool
51+ {
52+ if (
53+ !$ this ->exists
54+ || $ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts !== null
55+ || ($ checkDirty && $ this ->isDirty ())
56+ ) {
57+ return false ;
58+ }
59+
60+ $ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts = [];
61+
62+ return true ;
63+ }
64+
65+ /**
66+ * Unlock updates
67+ *
68+ * To reset the model's $attributes and get the changes from dirty applied during the lock use:
69+ *
70+ * if ($this->unlockUpdate()) {
71+ * $dirty = $this->getDirty();
72+ * $this->attributes = $this->original;
73+ * $this->classCastCache = [];
74+ * $this->attributeCastCache = [];
75+ * }
76+ *
77+ * Note that relations can be loaded during the lock
78+ */
79+ public function unlockUpdate (): bool
80+ {
81+ if ($ this ->isUnlockedForUpdate ()) {
82+ return false ;
83+ }
84+
85+ $ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts = null ;
86+
87+ return true ;
88+ }
89+
90+ public function isUnlockedForUpdate (): bool
91+ {
92+ return $ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts !== [];
93+ }
94+
4695 /**
4796 * Get all of the current attributes on the model.
4897 * @param bool $withoutMergeAttributesFromCachedCasts
@@ -247,18 +296,18 @@ protected function performUpdate(Builder $query): bool
247296 // Once we have run the update operation, we will fire the "updated" event for
248297 // this model instance. This will allow developers to hook into these after
249298 // models are updated, giving them a chance to do any special processing.
250- $ dirty = $ this ->getDirtyForUpdate ();
299+ if ([] === $ dirty = $ this ->getDirtyForUpdate ()) {
300+ return false ;
301+ }
251302
252- if ([] !== $ dirty ) {
253- $ this ->setKeysForSaveQuery ($ query )->update ($ dirty );
303+ $ this ->setKeysForSaveQuery ($ query )->update ($ dirty );
254304
255- $ this ->syncChanges ();
305+ $ this ->syncChanges ();
256306
257- $ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts = null ;
258- $ this ->tmpOriginalBeforeAfterEvents = $ this ->attributes ;
307+ $ this ->tmpDirtyIfAttributesAreSyncedFromCashedCasts = null ;
308+ $ this ->tmpOriginalBeforeAfterEvents = $ this ->attributes ;
259309
260- $ this ->fireModelEvent ('updated ' , false );
261- }
310+ $ this ->fireModelEvent ('updated ' , false );
262311
263312 return true ;
264313 }
0 commit comments