To achieve global mutation or sanitization of properties for all models in Laravel, you can use a combination of a custom base model and overriding the setAttribute method. This approach ensures that any time a property is set on any model, your custom logic will be applied.
Here's a step-by-step solution:
-
Create a BaseModel Class: Create a new base model class that extends
Illuminate\Database\Eloquent\Model. This will be the base class for all your models.namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class BaseModel extends Model { /** * Set a given attribute on the model. * * @param string $key * @param mixed $value * @return $this */ public function setAttribute($key, $value) { // Apply Str::squish() to all string attributes if (is_string($value)) { $value = Str::squish($value); } return parent::setAttribute($key, $value); } } -
Extend Your Models from BaseModel: Ensure that all your models extend this new
BaseModelinstead of the defaultModel.namespace App\Models; class User extends BaseModel { // Your model code here }namespace App\Models; class Post extends BaseModel { // Your model code here } -
Handle Mass Assignment: Since you mentioned that Filament does mass updates and model events do not trigger in that case, you need to ensure that the
setAttributemethod is used during mass assignment. Laravel's mass assignment uses thefillmethod, which in turn usessetAttribute.If you encounter any issues with mass assignment, you can override the
fillmethod in yourBaseModelto ensure your custom logic is applied:namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class BaseModel extends Model { /** * Set a given attribute on the model. * * @param string $key * @param mixed $value * @return $this */ public function setAttribute($key, $value) { // Apply Str::squish() to all string attributes if (is_string($value)) { $value = Str::squish($value); } return parent::setAttribute($key, $value); } /** * Fill the model with an array of attributes. * * @param array $attributes * @return $this */ public function fill(array $attributes) { foreach ($attributes as $key => $value) { $this->setAttribute($key, $value); } return $this; } }
By following these steps, you ensure that all string properties of all models are sanitized using Str::squish() whenever they are set, whether through individual assignments or mass assignments.