Skip to content

Instantly share code, notes, and snippets.

@CMCDragonkai
Last active June 23, 2019 22:58
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save CMCDragonkai/6896642 to your computer and use it in GitHub Desktop.
Save CMCDragonkai/6896642 to your computer and use it in GitHub Desktop.
PHP: DecoratorAbstract - Allows the creation of flexible nested decorators.
<?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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment