diff --git a/core/Object.php b/core/Object.php index 77719988b..ccac23b69 100755 --- a/core/Object.php +++ b/core/Object.php @@ -280,6 +280,19 @@ abstract class Object { if($parentProp == $classProp) $classProp = null; } + // Add data from extra_statics if it has been applied to this specific class (it + // wouldn't make sense to have them inherit in this method). This is kept separate + // from the equivalent get_static code because it's so much simpler + if(isset(self::$extra_statics[$class][$name])) { + $toMerge = self::$extra_statics[$class][$name]; + + if(is_array($toMerge) && is_array($classProp)) { + $classProp = array_merge($toMerge, $classProp); + } elseif(!$classProp) { + $classProp = $toMerge; + } + } + self::$cached_uninherited_statics[$class][$name] = true; self::$uninherited_statics[$class][$name] = $classProp; } @@ -355,8 +368,11 @@ abstract class Object { if ($replace) { self::set_static($class, $name, $value); self::$replaced_statics[$class][$name] = true; + + // Clear caches } else { self::$cached_statics[$class][$name] = null; + self::$cached_uninherited_statics[$class][$name] = null; } } diff --git a/tests/ObjectStaticTest.php b/tests/ObjectStaticTest.php index c006f6692..79a9f1f5d 100644 --- a/tests/ObjectStaticTest.php +++ b/tests/ObjectStaticTest.php @@ -70,14 +70,25 @@ class ObjectStaticTest extends SapphireTest { } /** - * Confirms that Object::add_static_var() doesn't work for uninherited stats + * Checks that Object::add_static_var() also works for uninherited stats */ - public function testAddStaticVarDoesntWorkFor() { + public function testAddStaticVarWorksForUninheritedStatics() { Object::add_static_var('ObjectStaticTest_First', 'first', array('test_1b')); Object::add_static_var('ObjectStaticTest_Second', 'first', array('test_2b')); - $this->assertNotContains('test_1b', Object::uninherited_static('ObjectStaticTest_First', 'first')); - $this->assertNotContains('test_2b', Object::uninherited_static('ObjectStaticTest_Second', 'first')); + // Check that it can be applied to parent and subclasses, and queried directly + $this->assertContains('test_1b', Object::uninherited_static('ObjectStaticTest_First', 'first')); + $this->assertContains('test_2b', Object::uninherited_static('ObjectStaticTest_Second', 'first')); + + // But it won't affect subclasses - this is *uninherited* static + $this->assertNotContains('test_2b', Object::uninherited_static('ObjectStaticTest_Third', 'first')); + $this->assertNotContains('test_2b', Object::uninherited_static('ObjectStaticTest_Fourth', 'first')); + + // Subclasses that don't have the static explicitly defined should allow definition, also + // This also checks that add_static_var can be called after the first uninherited_static() + // call (which can be buggy due to caching) + Object::add_static_var('ObjectStaticTest_Fourth', 'first', array('test_4b')); + $this->assertContains('test_4b', Object::uninherited_static('ObjectStaticTest_Fourth', 'first')); } }