Skip to content

Instantly share code, notes, and snippets.

@thiagolcks
Forked from CMCDragonkai/DecoratorAbstract.php
Last active January 31, 2017 16:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thiagolcks/0e6abee34e5f744b9d60b3ad3fc9a141 to your computer and use it in GitHub Desktop.
Save thiagolcks/0e6abee34e5f744b9d60b3ad3fc9a141 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 this class.
* 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 getOriginalObject()
{
$object = $this->object;
while (is_a($object, get_class())) {
$object = $object->getOriginalObject();
}
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->getOriginalObject();
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 void
*/
public function __set($property, $value)
{
$object = $this->getOriginalObject();
$object->$property = $value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment