@@ -37,6 +37,7 @@ abstract class Model implements Arrayable, ArrayAccess, CanBeEscapedWhenCastToSt
37
37
Concerns \GuardsAttributes,
38
38
Concerns \PreventsCircularRecursion,
39
39
ForwardsCalls;
40
+
40
41
/** @use HasCollection<\Illuminate\Database\Eloquent\Collection<array-key, static>> */
41
42
use HasCollection;
42
43
@@ -124,6 +125,13 @@ abstract class Model implements Arrayable, ArrayAccess, CanBeEscapedWhenCastToSt
124
125
*/
125
126
protected $ escapeWhenCastingToString = false ;
126
127
128
+ /**
129
+ * Indicates that the model is frozen and cannot modify properties or load relations.
130
+ *
131
+ * @var bool
132
+ */
133
+ protected $ frozen = false ;
134
+
127
135
/**
128
136
* The connection resolver instance.
129
137
*
@@ -267,7 +275,7 @@ public function __construct(array $attributes = [])
267
275
*/
268
276
protected function bootIfNotBooted ()
269
277
{
270
- if (! isset (static ::$ booted [static ::class])) {
278
+ if (!isset (static ::$ booted [static ::class])) {
271
279
static ::$ booted [static ::class] = true ;
272
280
273
281
$ this ->fireModelEvent ('booting ' , false );
@@ -316,7 +324,7 @@ protected static function bootTraits()
316
324
foreach (class_uses_recursive ($ class ) as $ trait ) {
317
325
$ method = 'boot ' .class_basename ($ trait );
318
326
319
- if (method_exists ($ class , $ method ) && ! in_array ($ method , $ booted )) {
327
+ if (method_exists ($ class , $ method ) && !in_array ($ method , $ booted )) {
320
328
forward_static_call ([$ class , $ method ]);
321
329
322
330
$ booted [] = $ method ;
@@ -405,7 +413,7 @@ public static function isIgnoringTouch($class = null)
405
413
{
406
414
$ class = $ class ?: static ::class;
407
415
408
- if (! get_class_vars ($ class )['timestamps ' ] || ! $ class ::UPDATED_AT ) {
416
+ if (!get_class_vars ($ class )['timestamps ' ] || !$ class ::UPDATED_AT ) {
409
417
return true ;
410
418
}
411
419
@@ -526,6 +534,10 @@ public static function withoutBroadcasting(callable $callback)
526
534
*/
527
535
public function fill (array $ attributes )
528
536
{
537
+ if ($ this ->frozen ) {
538
+ throw FrozenModelException::forFill ($ this );
539
+ }
540
+
529
541
$ totallyGuarded = $ this ->totallyGuarded ();
530
542
531
543
$ fillable = $ this ->fillableFromArray ($ attributes );
@@ -574,7 +586,7 @@ public function fill(array $attributes)
574
586
*/
575
587
public function forceFill (array $ attributes )
576
588
{
577
- return static ::unguarded (fn () => $ this ->fill ($ attributes ));
589
+ return static ::unguarded (fn () => $ this ->fill ($ attributes ));
578
590
}
579
591
580
592
/**
@@ -734,7 +746,7 @@ public function load($relations)
734
746
*/
735
747
public function loadMorph ($ relation , $ relations )
736
748
{
737
- if (! $ this ->{$ relation }) {
749
+ if (!$ this ->{$ relation }) {
738
750
return $ this ;
739
751
}
740
752
@@ -858,7 +870,7 @@ public function loadExists($relations)
858
870
*/
859
871
public function loadMorphAggregate ($ relation , $ relations , $ column , $ function = null )
860
872
{
861
- if (! $ this ->{$ relation }) {
873
+ if (!$ this ->{$ relation }) {
862
874
return $ this ;
863
875
}
864
876
@@ -970,7 +982,7 @@ protected function decrement($column, $amount = 1, array $extra = [])
970
982
*/
971
983
protected function incrementOrDecrement ($ column , $ amount , $ extra , $ method )
972
984
{
973
- if (! $ this ->exists ) {
985
+ if (!$ this ->exists ) {
974
986
return $ this ->newQueryWithoutRelationships ()->{$ method }($ column , $ amount , $ extra );
975
987
}
976
988
@@ -988,13 +1000,14 @@ protected function incrementOrDecrement($column, $amount, $extra, $method)
988
1000
$ amount = (clone $ this )->setAttribute ($ column , $ amount )->getAttributeFromArray ($ column );
989
1001
}
990
1002
991
- return tap ($ this ->setKeysForSaveQuery ($ this ->newQueryWithoutScopes ())->{$ method }($ column , $ amount , $ extra ), function () use ($ column ) {
992
- $ this ->syncChanges ();
1003
+ return tap ($ this ->setKeysForSaveQuery ($ this ->newQueryWithoutScopes ())->{$ method }($ column , $ amount , $ extra ),
1004
+ function () use ($ column ) {
1005
+ $ this ->syncChanges ();
993
1006
994
- $ this ->fireModelEvent ('updated ' , false );
1007
+ $ this ->fireModelEvent ('updated ' , false );
995
1008
996
- $ this ->syncOriginalAttribute ($ column );
997
- });
1009
+ $ this ->syncOriginalAttribute ($ column );
1010
+ });
998
1011
}
999
1012
1000
1013
/**
@@ -1006,7 +1019,7 @@ protected function incrementOrDecrement($column, $amount, $extra, $method)
1006
1019
*/
1007
1020
public function update (array $ attributes = [], array $ options = [])
1008
1021
{
1009
- if (! $ this ->exists ) {
1022
+ if (!$ this ->exists ) {
1010
1023
return false ;
1011
1024
}
1012
1025
@@ -1024,7 +1037,7 @@ public function update(array $attributes = [], array $options = [])
1024
1037
*/
1025
1038
public function updateOrFail (array $ attributes = [], array $ options = [])
1026
1039
{
1027
- if (! $ this ->exists ) {
1040
+ if (!$ this ->exists ) {
1028
1041
return false ;
1029
1042
}
1030
1043
@@ -1040,7 +1053,7 @@ public function updateOrFail(array $attributes = [], array $options = [])
1040
1053
*/
1041
1054
public function updateQuietly (array $ attributes = [], array $ options = [])
1042
1055
{
1043
- if (! $ this ->exists ) {
1056
+ if (!$ this ->exists ) {
1044
1057
return false ;
1045
1058
}
1046
1059
@@ -1085,7 +1098,7 @@ protected function decrementQuietly($column, $amount = 1, array $extra = [])
1085
1098
public function push ()
1086
1099
{
1087
1100
return $ this ->withoutRecursion (function () {
1088
- if (! $ this ->save ()) {
1101
+ if (!$ this ->save ()) {
1089
1102
return false ;
1090
1103
}
1091
1104
@@ -1097,7 +1110,7 @@ public function push()
1097
1110
? $ models ->all () : [$ models ];
1098
1111
1099
1112
foreach (array_filter ($ models ) as $ model ) {
1100
- if (! $ model ->push ()) {
1113
+ if (!$ model ->push ()) {
1101
1114
return false ;
1102
1115
}
1103
1116
}
@@ -1114,7 +1127,7 @@ public function push()
1114
1127
*/
1115
1128
public function pushQuietly ()
1116
1129
{
1117
- return static ::withoutEvents (fn () => $ this ->push ());
1130
+ return static ::withoutEvents (fn () => $ this ->push ());
1118
1131
}
1119
1132
1120
1133
/**
@@ -1125,7 +1138,7 @@ public function pushQuietly()
1125
1138
*/
1126
1139
public function saveQuietly (array $ options = [])
1127
1140
{
1128
- return static ::withoutEvents (fn () => $ this ->save ($ options ));
1141
+ return static ::withoutEvents (fn () => $ this ->save ($ options ));
1129
1142
}
1130
1143
1131
1144
/**
@@ -1161,7 +1174,7 @@ public function save(array $options = [])
1161
1174
else {
1162
1175
$ saved = $ this ->performInsert ($ query );
1163
1176
1164
- if (! $ this ->getConnectionName () &&
1177
+ if (!$ this ->getConnectionName () &&
1165
1178
$ connection = $ query ->getConnection ()) {
1166
1179
$ this ->setConnection ($ connection ->getName ());
1167
1180
}
@@ -1187,7 +1200,7 @@ public function save(array $options = [])
1187
1200
*/
1188
1201
public function saveOrFail (array $ options = [])
1189
1202
{
1190
- return $ this ->getConnection ()->transaction (fn () => $ this ->save ($ options ));
1203
+ return $ this ->getConnection ()->transaction (fn () => $ this ->save ($ options ));
1191
1204
}
1192
1205
1193
1206
/**
@@ -1416,7 +1429,7 @@ public function delete()
1416
1429
// If the model doesn't exist, there is nothing to delete so we'll just return
1417
1430
// immediately and not do anything else. Otherwise, we will continue with a
1418
1431
// deletion process on the model, firing the proper events, and so forth.
1419
- if (! $ this ->exists ) {
1432
+ if (!$ this ->exists ) {
1420
1433
return ;
1421
1434
}
1422
1435
@@ -1446,7 +1459,7 @@ public function delete()
1446
1459
*/
1447
1460
public function deleteQuietly ()
1448
1461
{
1449
- return static ::withoutEvents (fn () => $ this ->delete ());
1462
+ return static ::withoutEvents (fn () => $ this ->delete ());
1450
1463
}
1451
1464
1452
1465
/**
@@ -1458,11 +1471,11 @@ public function deleteQuietly()
1458
1471
*/
1459
1472
public function deleteOrFail ()
1460
1473
{
1461
- if (! $ this ->exists ) {
1474
+ if (!$ this ->exists ) {
1462
1475
return false ;
1463
1476
}
1464
1477
1465
- return $ this ->getConnection ()->transaction (fn () => $ this ->delete ());
1478
+ return $ this ->getConnection ()->transaction (fn () => $ this ->delete ());
1466
1479
}
1467
1480
1468
1481
/**
@@ -1661,8 +1674,8 @@ public function callNamedScope($scope, array $parameters = [])
1661
1674
public function toArray ()
1662
1675
{
1663
1676
return $ this ->withoutRecursion (
1664
- fn () => array_merge ($ this ->attributesToArray (), $ this ->relationsToArray ()),
1665
- fn () => $ this ->attributesToArray (),
1677
+ fn () => array_merge ($ this ->attributesToArray (), $ this ->relationsToArray ()),
1678
+ fn () => $ this ->attributesToArray (),
1666
1679
);
1667
1680
}
1668
1681
@@ -1703,7 +1716,7 @@ public function jsonSerialize(): mixed
1703
1716
*/
1704
1717
public function fresh ($ with = [])
1705
1718
{
1706
- if (! $ this ->exists ) {
1719
+ if (!$ this ->exists ) {
1707
1720
return ;
1708
1721
}
1709
1722
@@ -1720,7 +1733,7 @@ public function fresh($with = [])
1720
1733
*/
1721
1734
public function refresh ()
1722
1735
{
1723
- if (! $ this ->exists ) {
1736
+ if (!$ this ->exists ) {
1724
1737
return $ this ;
1725
1738
}
1726
1739
@@ -1778,7 +1791,7 @@ public function replicate(?array $except = null)
1778
1791
*/
1779
1792
public function replicateQuietly (?array $ except = null )
1780
1793
{
1781
- return static ::withoutEvents (fn () => $ this ->replicate ($ except ));
1794
+ return static ::withoutEvents (fn () => $ this ->replicate ($ except ));
1782
1795
}
1783
1796
1784
1797
/**
@@ -1789,7 +1802,7 @@ public function replicateQuietly(?array $except = null)
1789
1802
*/
1790
1803
public function is ($ model )
1791
1804
{
1792
- return ! is_null ($ model ) &&
1805
+ return !is_null ($ model ) &&
1793
1806
$ this ->getKey () === $ model ->getKey () &&
1794
1807
$ this ->getTable () === $ model ->getTable () &&
1795
1808
$ this ->getConnectionName () === $ model ->getConnectionName ();
@@ -1803,7 +1816,7 @@ public function is($model)
1803
1816
*/
1804
1817
public function isNot ($ model )
1805
1818
{
1806
- return ! $ this ->is ($ model );
1819
+ return !$ this ->is ($ model );
1807
1820
}
1808
1821
1809
1822
/**
@@ -2014,7 +2027,7 @@ public function getQueueableRelations()
2014
2027
$ relations = [];
2015
2028
2016
2029
foreach ($ this ->getRelations () as $ key => $ relation ) {
2017
- if (! method_exists ($ this , $ key )) {
2030
+ if (!method_exists ($ this , $ key )) {
2018
2031
continue ;
2019
2032
}
2020
2033
@@ -2117,6 +2130,25 @@ public function resolveSoftDeletableChildRouteBinding($childType, $value, $field
2117
2130
return $ this ->resolveChildRouteBindingQuery ($ childType , $ value , $ field )->withTrashed ()->first ();
2118
2131
}
2119
2132
2133
+ /**
2134
+ * @param $frozen
2135
+ * @return $this
2136
+ */
2137
+ public function freeze ($ frozen = true )
2138
+ {
2139
+ $ this ->frozen = $ frozen ;
2140
+
2141
+ return $ this ;
2142
+ }
2143
+
2144
+ /**
2145
+ * @return bool
2146
+ */
2147
+ public function isFrozen ()
2148
+ {
2149
+ return $ this ->frozen ;
2150
+ }
2151
+
2120
2152
/**
2121
2153
* Retrieve the child model query for a bound value.
2122
2154
*
@@ -2280,7 +2312,7 @@ public function __set($key, $value)
2280
2312
public function offsetExists ($ offset ): bool
2281
2313
{
2282
2314
try {
2283
- return ! is_null ($ this ->getAttribute ($ offset ));
2315
+ return !is_null ($ this ->getAttribute ($ offset ));
2284
2316
} catch (MissingAttributeException ) {
2285
2317
return false ;
2286
2318
}
0 commit comments