diff --git a/core/Object.php b/core/Object.php index 4f9efe63e..9451998e8 100755 --- a/core/Object.php +++ b/core/Object.php @@ -5,6 +5,25 @@ */ class Object { + /** + * This DataObjects extensions, eg Versioned. + * @var array + */ + protected $extension_instances = array(); + + /** + * Extensions to be used on this object. An array of extension names + * and parameters eg: + * + * static $extensions = array( + * "Hierarchy", + * "Versioned('Stage', 'Live')", + * ); + * + * @var array + */ + public static $extensions = null; + protected static $extraStatics = array(); protected static $classConstructed = array(); @@ -17,6 +36,8 @@ class Object { private static $custom_classes = array(); private static $strong_classes = array(); + + /** * This function allows you to overload class creation methods, so certain classes are * always created correctly over your system. @@ -94,6 +115,16 @@ class Object { function __construct() { $this->class = get_class($this); + + // Set up the extensions + if($extensions = $this->stat('extensions')) { + foreach($extensions as $extension) { + $instance = eval("return new $extension;"); + $instance->setOwner($this); + $this->extension_instances[$instance->class] = $instance; + } + } + if(!isset(Object::$classConstructed[$this->class])) { $this->defineMethods(); Object::$classConstructed[$this->class] = true; @@ -228,6 +259,10 @@ class Object { * You can overload it with methods for setting up the class - for example, extra methods. */ protected function defineMethods() { + if($this->extension_instances) foreach($this->extension_instances as $i => $instance) { + $this->addMethodsFrom('extension_instances', $i); + } + if(isset($_REQUEST['debugmethods']) && isset(Object::$builtInMethods[$this->class])) { echo "

Methods defined for $this->class

"; foreach(Object::$builtInMethods[$this->class] as $name => $info) { @@ -316,6 +351,61 @@ class Object { public function __toString() { return $this->class; } + + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // EXTENSION METHODS + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Run the given function on all of this object's extensions + * + * @param string $funcName The name of the function. + * @param mixed $arg An Argument to be passed to each of the extension functions. + */ + public function extend($funcName, &$arg) { + if($this->extension_instances) { + foreach($this->extension_instances as $extension) { + if($extension->hasMethod($funcName)) { + $extension->$funcName($arg); + } + } + } + } + + /** + * Get an extension on this DataObject + * + * @param string $name Classname of the Extension (e.g. 'Versioned') + * + * @return DataObjectDecorator The instance of the extension + */ + public function getExtension($name) { + return $this->extension_instances[$name]; + } + + /** + * Returns true if the given extension class is attached to this object + * + * @param string $requiredExtension Classname of the extension + * + * @return boolean True if the given extension class is attached to this object + */ + public function hasExtension($requiredExtension) { + return isset($this->extension_instances[$requiredExtension]) ? true : false; + } + + /** + * Add an extension to the given object. + * This can be used to add extensions to built-in objects, such as role decorators on Member + */ + public static function add_extension($className, $extensionName) { + Object::addStaticVars($className, array( + 'extensions' => array( + $extensionName, + ), + )); + } } /**