Reputation: 932
I've got the function names constructed however I want in an array which are dynamic in nature meaning they could be 2 or 10 like so:
I want them to reside in model class (e.g: User) like this:
public function getEmailVerifiedAtAttribute($value)
{
// ...
}
public function getCreatedAtAttribute($value)
{
// ...
}
public function getUpdatedAtAttribute($value)
{
// ...
}
// ... If there were more in array they would have been constructed dynamically as well.
If we can avoid the eval please!!
Upvotes: 1
Views: 955
Reputation: 40663
You might have some limited success by doing something like this in your model:
public function hasGetMutator($key) {
return parent::hasGetMutator($key) || in_array('get'.Str::studly($key).'Attribute', $youArratOfDynamicMutators);
}
protected function mutateAttribute($key, $value)
{
if (parent::hasGetMutator($key)) {
return parent::mutateAttribute($key, $value);
}
// Mutate your value here
return $value;
}
What this does is override the method hasGetMutator
which usually just checks if the function 'get'.Str::studly($key).'Attribute'
exists in the class to also return true if that function name exists in your array, and also modifies the mutateAttribute
function to do your custom mutation (in addition to doing the default ones).
However if your mutation is a standard one then I do recommend using a custom cast instead:
<?php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class MyCustomCast implements CastsAttributes
{
public function get($model, $key, $value, $attributes) {
// Do the cast
return $value;
}
//Optional
public function set($model, $key, $value, $attributes)
{
// Reverse the cast
return $value;
}
}
To get this to work for dynamic attributes you can add this to your model:
protected function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->casts = array_merge($this->casts, [
'customCastColumn1' => MyCustomCast::class,
// ...
]);
}
This will add the required casts to the model when it gets constructed.
Upvotes: 2