BUGFIX: Fix edge-case bug with application of decorators

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/2.3@77822 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sam Minnee 2009-05-26 03:06:10 +00:00
parent 1c896b192c
commit 3cbf9ae73b
3 changed files with 22 additions and 9 deletions

View File

@ -23,12 +23,23 @@ abstract class Extension extends Object {
* @var DataObject
*/
protected $owner;
/**
* The base class that this extension was applied to; $this->owner must be one of these
* @var DataObject
*/
protected $ownerBaseClass;
/**
* Set the owner of this decorator.
* @param DataObject $owner
* @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(Object $owner) {
function setOwner(Object $owner, $ownerBaseClass = null) {
$this->ownerBaseClass = $ownerBaseClass ? $ownerBaseClass : $owner->class;
$this->owner = $owner;
}

View File

@ -453,7 +453,7 @@ abstract class Object {
// an $extension value can contain parameters as a string,
// e.g. "Versioned('Stage','Live')"
$instance = eval("return new $extension;");
$instance->setOwner($this);
$instance->setOwner($this, $class);
$this->extension_instances[$instance->class] = $instance;
}
}

View File

@ -27,6 +27,8 @@ abstract class DataObjectDecorator extends Extension {
'searchable_fields',
);
private static $extra_statics_loaded = array();
/**
* Set the owner of this decorator.
* @param DataObject $owner
@ -49,23 +51,23 @@ abstract class DataObjectDecorator extends Extension {
* Load the extra database fields defined in extraStatics.
*/
function loadExtraStatics() {
// Don't apply DB fields if the parent object has this extension too
if(Object::has_extension($this->owner->parentClass(), $this->class)) return;
if(!empty(self::$extra_statics_loaded[$this->ownerBaseClass][$this->class])) return;
self::$extra_statics_loaded[$this->ownerBaseClass][$this->class] = true;
if($fields = $this->extraStatics()) {
foreach($fields as $relation => $fields) {
if(in_array($relation, self::$decoratable_statics)) {
// Can't use add_static_var() here as it would merge the array rather than replacing
Object::set_static (
$this->owner->class,
$this->ownerBaseClass,
$relation,
array_merge((array) Object::get_static($this->owner->class, $relation), $fields)
array_merge((array) Object::get_static($this->ownerBaseClass, $relation), $fields)
);
}
}
DataObject::$cache_has_own_table[$this->owner->class] = null;
DataObject::$cache_has_own_table_field[$this->owner->class] = null;
DataObject::$cache_has_own_table[$this->ownerBaseClass] = null;
DataObject::$cache_has_own_table_field[$this->ownerBaseClass] = null;
}
}