-
-
Save thiagolcks/0e6abee34e5f744b9d60b3ad3fc9a141 to your computer and use it in GitHub Desktop.
PHP: DecoratorAbstract - Allows the creation of flexible nested decorators.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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