silverstripe-framework/core/Extension.php
Hamish Friedlander fa37c448a5 API Reverse config extra statics control flow
Config system used to provide an add_static_source method, which was intended for
use by Extensions to add statics. But extensions for a class arent initialised
until at least one instance of that class is created, so before that the
Config system didnt include values from extensions

This patch reverses the control flow, so that the Config system explictly asks
each Object for its additional config sources via the new method
get_extra_config_sources. This method returns an array that can contain
string names of classes and also raw associative arrays.

The developer visible change is that Extension#add_to_class has been
deprecated. Instead there is a new method, get_extra_config, which has
the same method signature but needs to guarantee that it doesnt
cause side effects. Additionally there is no need to call
parent::get_extra_config - this is handled automatically.
2012-08-23 09:29:13 +12:00

103 lines
2.8 KiB
PHP

<?php
/**
* Add extension that can be added to an object with {@link Object::add_extension()}.
* For {@link DataObject} extensions, use {@link DataExtension}.
* Each extension instance has an "owner" instance, accessible through
* {@link getOwner()}.
* Every object instance gets its own set of extension instances,
* meaning you can set parameters specific to the "owner instance"
* in new Extension instances.
*
* @package framework
* @subpackage core
*/
abstract class Extension {
/**
* This is used by extensions designed to be applied to controllers.
* It works the same way as {@link Controller::$allowed_actions}.
*/
public static $allowed_actions = null;
/**
* The object this extension is applied to.
*
* @var Object
*/
protected $owner;
/**
* The base class that this extension was applied to; $this->owner must be one of these
* @var DataObject
*/
protected $ownerBaseClass;
/**
* Reference counter to ensure that the owner isn't cleared until clearOwner() has
* been called as many times as setOwner()
*/
private $ownerRefs = 0;
public $class;
function __construct() {
$this->class = get_class($this);
}
/**
* Called when this extension is added to a particular class
*
* @static
* @param $class
*/
static function add_to_class($class, $extensionClass, $args = null) {
// NOP
}
/**
* Set the owner of this extension.
* @param Object $owner The owner object,
* @param string $ownerBaseClass The base class that the extension is applied to; this may be
* the class of owner, or it may be a parent. For example, if Versioned was applied to SiteTree,
* and then a Page object was instantiated, $owner would be a Page object, but $ownerBaseClass
* would be 'SiteTree'.
*/
function setOwner($owner, $ownerBaseClass = null) {
if($owner) $this->ownerRefs++;
$this->owner = $owner;
if($ownerBaseClass) $this->ownerBaseClass = $ownerBaseClass;
else if(!$this->ownerBaseClass && $owner) $this->ownerBaseClass = $owner->class;
}
function clearOwner() {
if($this->ownerRefs <= 0) user_error("clearOwner() called more than setOwner()", E_USER_WARNING);
$this->ownerRefs--;
if($this->ownerRefs == 0) $this->owner = null;
}
/**
* Returns the owner of this extension.
*
* @return Object
*/
public function getOwner() {
return $this->owner;
}
/**
* Helper method to strip eval'ed arguments from a string
* thats passed to {@link DataObject::$extensions} or
* {@link Object::add_extension()}.
*
* @param string $extensionStr E.g. "Versioned('Stage','Live')"
* @return string Extension classname, e.g. "Versioned"
*/
public static function get_classname_without_arguments($extensionStr) {
return (($p = strpos($extensionStr, '(')) !== false) ? substr($extensionStr, 0, $p) : $extensionStr;
}
}