Accesseurs et Mutateurs avec Laravel 4

Avec Laravel 4 et plus particulièrement Eloquent nous avons un système d’accesseurs et de mutateurs : les getteurs et les setteurs; voir la doc.

Le principe est simple, définir les méthodes publiques getMapropriétéAttribute() et setMaPropriétéAttribute(). Seulement ce système ne fonctionne qu’avec Eloquent. Il m’arrive une fois sur 100 projets :) de créer mes propres classes qui ne sont pas des modèles. Pour ces classes, il m’a semblé normal d’utiliser la même syntaxe que les modèles Eloquent pour une plus grande homogénéité du code.

<?php namespace App\Services;

Class BaseGetter {

    /**
	 * Appel aux attributs comme un model.
	 *
	 * @param  string  $prop propriété
	 * @return mixed
	 */
	public function __get ( $prop )
	{ 
		$method='get'.snake_case($prop).'Attribute';
		if (method_exists($this,$method))
			return call_user_func_array(array($this, $method),array());
		else{
			//return ''; //exception ou non ??
            throw new \Exception('Call to undefined property '.$prop.'');
		}
	}

    /**
     * Changer la valeur d'un attribut comme un model.
     * @param string $prop propriété
     * @param  undef $value value
     * @return Class $this
     */
    public function  __set ( $prop , $value ){
        $method='set'.snake_case($prop).'Attribute';
        if (method_exists($this,$method)) {
            call_user_func_array(array($this, $method),array($value));
            return $this;
        }
        else {
            if (property_exists($this,$prop))
                throw new \Exception('propriété '.$prop.' en lecture seule');
            else
                throw new \Exception('Call to undefined property '.$prop.'');

        }
    }

}

Pour l’utilisation rien de plus simple :

use App\Services\BaseGetter;

class Item extends BaseGetter
{  
    protected $label;
    protected $value=-1;

    public function getLabelAttribute()
    {
        return ($this->label) ? $this->label : '';
    }    

    public function getValueAttribute()
    {
        return $this->value;
    }	
    public function setValueAttribute($value)
    {
        $this->value=trim($value);
    }
}

Ici, nous nous retrouvons avec une classe avec 2 propriétés : label et value; label est accessible uniquement en lecture seule, et value est elle, en lecture/écriture. Et bien sur, les accès se font par $item->value=666;

Nous avons donc, les mêmes fonctionnalités d’accès et d’écriture avec nos propres classes et avec nos modèles Eloquent.

Share Button

Vous devriez aimer...