Skip to content

Instantly share code, notes, and snippets.

@lucasdinonolte
Created October 6, 2012 10:31
Show Gist options
  • Save lucasdinonolte/3844566 to your computer and use it in GitHub Desktop.
Save lucasdinonolte/3844566 to your computer and use it in GitHub Desktop.
Laravel Model Decorator
<?php
/**
* ModelDecorator Class
* Decorate Models to seperate out common logic
*
* @author Lucas Nolte <hello@lucas-nolte.com>
*/
class Modeldecorator {
/**
* The Model to Decorate
* @var Object
*/
protected $parent = null;
/**
* Attributes of the Decorator
* @var array
*/
public $attributes = array();
/**
* Fields of the Decorator (when using form building)
* @var array
*/
public $fields = array();
/**
* instantiate a new Model
* @param Object $parent Model-Instance to decorate
*/
public function __construct($parent) {
// Set the parent
$this->parent = $parent;
// Add attributes and their default value to the model
foreach($this->attributes as $key => $val) {
$this->parent->attributes[$key] = $val;
}
}
/**
* Calls function on the original model
* @param string $name name of the function to call
* @param array $args arguments of the functino
* @return mixed output of the original function
*/
public function __call($name, $args) {
call_user_func_array(array($this->parent, $name), $args);
}
/**
* Set Attributes on the original model
* @param string $name name of the attribute
* @param mixed $value value to set
*/
public function __set($name, $value) {
// Generate method name for custom setter
$method = 'set_'.$name;
// Check if custom setter exists on the decorator
if(method_exists($this, $method)) {
$this->{$method}($value);
}
// Check if custom setter exists on the original model
elseif(method_exists($this->parent, $method)) {
$this->parent->{$method}($value);
}
// If not, just set the attribute
else {
$this->parent->set_attribute($name, $value);
}
}
/**
* Redirect gets to the original model
* @param string $name attribute to get
* @return mixed value of attribute
*/
public function __get($name) {
return $this->parent->{$name};
}
}
<?php
class Publishable extends Modeldecorator {
public $attributes = array(
'published' => 0,
'published_at' => 0
);
public function publish() {
$this->parent->set_attribute('published', 1);
$this->parent->set_attribute('published_at', new \DateTime);
$this->parent->save();
}
public function unpublish() {
$this->parent->set_attribute('published', 0);
$this->parent->save();
}
}
<?php
class User extends Eloquent {
public static function forge() {
// Create instance
$user = new self;
// Decorate it
$user = new Publishable($user);
// Return it
return $user;
}
public $fields = array(
'email' => 'text',
'password' => 'password'
);
public function set_password($password) {
$this->set_attribute('password', Hash::make($password));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment