public
Last active

PHP: DecoratorAbstract - Allows the creation of flexible nested decorators.

  • Download Gist
DecoratorAbstract.php
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
<?php
 
/**
* DecoratorAbstract allows the creation of flexible nested decorators. All decorators must extend from DecoratorAbstract.
* Decorators can be stacked. They can also have methods that overwrite each other.
* Decorators can omit methods that parent decorators have defined and/or child decorators have defined.
* Methods will cascade to the original child object.
* Properties will read and set from the original child object except when your instance has the property defined.
*/
abstract class DecoratorAbstract{
 
protected $object;
 
/**
* Gets the original object that all the decorators have wrapped themselves around.
* @return Object
*/
public function get_original_object(){
$object = $this->object;
while(is_a($object, get_class())){
$object = $object->get_original_object();
}
return $object;
}
 
/**
* Magic __call will recursively call itself and cascade through all the methods on the decorators.
* This will work for the child object's methods, and even when methods are missing in between the decorator stack.
* @param String $method
* @param Array $args
* @return Mixed
*/
public function __call($method, $args){
 
return call_user_func_array(array($this->object, $method), $args);
 
}
 
/**
* Magic __get will return the properties from the original object.
* This won't be executed if the current instance has the property defined.
* @param String $property
* @return Mixed
*/
public function __get($property){
 
$object = $this->get_original_object();
if(property_exists($object, $property)){
return $object->$property;
}
return null;
 
}
 
/**
* Magic __set will set a property on the original object.
* This won't be executed if the current instance has the property defined.
* @param String $property
* @param Mixed $value
* @return Object $this
*/
public function __set($property, $value){
 
$object = $this->get_original_object();
$object->$property = $value;
return $this;
 
}
 
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.