Skip to content

Commit 6c18db4

Browse files
[9.x] Add Eloquent mode to prevent prevently silently discarding fills for attributes not in $fillable (#43893)
* Update Model.php * Rework to not use container * Update Model.php * Style * Update comment * formatting Co-authored-by: Taylor Otwell <[email protected]>
1 parent 331757f commit 6c18db4

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

src/Illuminate/Database/Eloquent/Model.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,13 @@ abstract class Model implements Arrayable, ArrayAccess, CanBeEscapedWhenCastToSt
174174
*/
175175
protected static $lazyLoadingViolationCallback;
176176

177+
/**
178+
* Indicates if an exception should be thrown instead of silently discarding non-fillable attributes.
179+
*
180+
* @var bool
181+
*/
182+
protected static $modelsShouldPreventSilentlyDiscardingAttributes = false;
183+
177184
/**
178185
* Indicates if broadcasting is currently enabled.
179186
*
@@ -392,6 +399,17 @@ public static function handleLazyLoadingViolationUsing(?callable $callback)
392399
static::$lazyLoadingViolationCallback = $callback;
393400
}
394401

402+
/**
403+
* Prevent non-fillable attributes from being silently discarded.
404+
*
405+
* @param bool $value
406+
* @return void
407+
*/
408+
public static function preventSilentlyDiscardingAttributes($value = true)
409+
{
410+
static::$modelsShouldPreventSilentlyDiscardingAttributes = $value;
411+
}
412+
395413
/**
396414
* Execute a callback without broadcasting any model events for all model types.
397415
*
@@ -429,7 +447,7 @@ public function fill(array $attributes)
429447
// the model, and all others will just get ignored for security reasons.
430448
if ($this->isFillable($key)) {
431449
$this->setAttribute($key, $value);
432-
} elseif ($totallyGuarded) {
450+
} elseif ($totallyGuarded || static::preventsSilentlyDiscardingAttributes()) {
433451
throw new MassAssignmentException(sprintf(
434452
'Add [%s] to fillable property to allow mass assignment on [%s].',
435453
$key, get_class($this)
@@ -2061,6 +2079,16 @@ public static function preventsLazyLoading()
20612079
return static::$modelsShouldPreventLazyLoading;
20622080
}
20632081

2082+
/**
2083+
* Determine if discarding guarded attribute fills is disabled.
2084+
*
2085+
* @return bool
2086+
*/
2087+
public static function preventsSilentlyDiscardingAttributes()
2088+
{
2089+
return static::$modelsShouldPreventSilentlyDiscardingAttributes;
2090+
}
2091+
20642092
/**
20652093
* Get the broadcast channel route definition that is associated with the given entity.
20662094
*

tests/Database/DatabaseEloquentModelTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,15 @@ public function testGuarded()
12801280
$model->guard(['name', 'age']);
12811281
$model->fill(['Foo' => 'bar']);
12821282
$this->assertFalse(isset($model->Foo));
1283+
1284+
$handledMassAssignmentExceptions = 0;
1285+
1286+
Model::preventSilentlyDiscardingAttributes();
1287+
1288+
$this->expectException(MassAssignmentException::class);
1289+
$model = new EloquentModelStub;
1290+
$model->guard(['name', 'age']);
1291+
$model->fill(['Foo' => 'bar']);
12831292
}
12841293

12851294
public function testFillableOverridesGuarded()

0 commit comments

Comments
 (0)