Oleg Shakhov
Oleg Shakhov

Reputation: 445

Laravel 5.3 custom model cast type

I developing system where money is basic thing, for now to show any price i am using accessors in model:

public function getFormattedPriceAttribute()
{
    return '$' . number_format($this->attributes['price'], 2); // TODO: implement currencies
}

But soon I will start implementing multicurrency and i want to make price showing as easy as define:

protected $casts = [
'price' => 'currency',
];

And custom cast for currency will format it as set in configuration.

Is this possible withot dancing with a tambourine?

Upvotes: 0

Views: 1739

Answers (1)

DevK
DevK

Reputation: 9942

Expanding on my comment:

Cool

I would create a Currency class, something like this:

class Currency {
    $value;

    public function __construct($value) 
    {
        $this->value = $value;
    }

    public function formatted()
    {
        return '$' . number_format($this->value, 2);
    }

    // more methods

}

Then override the Model castAttribute methods, to include the new castable class:

protected function castAttribute($key, $value)
{
    if (is_null($value)) {
        return $value;
    }

    switch ($this->getCastType($key)) {
        case 'int':
        case 'integer':
            return (int) $value;
        case 'real':
        case 'float':
        case 'double':
            return (float) $value;
        case 'string':
            return (string) $value;
        case 'bool':
        case 'boolean':
            return (bool) $value;
        case 'object':
            return $this->fromJson($value, true);
        case 'array':
        case 'json':
            return $this->fromJson($value);
        case 'collection':
            return new BaseCollection($this->fromJson($value));
        case 'date':
        case 'datetime':
            return $this->asDateTime($value);
        case 'timestamp':
            return $this->asTimeStamp($value);

        case 'currency': // Look here
            return Currency($value);
        default:
            return $value;
    }
}

Simple

Of course you could make things much simpler and just do this in the castAttribute method:

// ...
case 'dollar':
    return  '$' . number_format($value, 2);
// ...

Upvotes: 3

Related Questions