Merged revisions 51462 via svnmerge from

svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/2.2.2

........
  r51462 | sminnee | 2008-03-19 18:01:55 +1300 (Wed, 19 Mar 2008) | 1 line
  
  Make Object::hasMethod() and Object::__call() case-insensitive, and added tests for it
........


git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@51468 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sam Minnee 2008-03-19 20:39:07 +00:00
parent 3f8a2a95c2
commit 3014401e11
2 changed files with 95 additions and 10 deletions

View File

@ -152,6 +152,7 @@ class Object {
* Returns true if the given method exists.
*/
public function hasMethod($methodName) {
$methodName = strtolower($methodName);
if(!isset($this->class)) $this->class = get_class($this);
if(!isset(Object::$builtInMethods['_set'][$this->class])) $this->buildMethodList();
@ -165,8 +166,9 @@ class Object {
* Extra methods can be hooked to a class using
*/
public function __call($methodName, $args) {
if(isset(Object::$extraMethods[$this->class][$methodName])) {
$config = Object::$extraMethods[$this->class][$methodName];
$lowerMethodName = strtolower($methodName);
if(isset(Object::$extraMethods[$this->class][$lowerMethodName])) {
$config = Object::$extraMethods[$this->class][$lowerMethodName];
if(isset($config['parameterName'])) {
if(isset($config['arrayIndex'])) $obj = $this->{$config['parameterName']}[$config['arrayIndex']];
else $obj = $this->{$config['parameterName']};
@ -179,7 +181,7 @@ class Object {
}
} else if(isset($config['wrap'])) {
array_unshift($args, $methodName);
array_unshift($args, $config['methodName']);
return call_user_func_array(array(&$this, $config['wrap']), $args);
} else if(isset($config['function'])) {
@ -187,7 +189,7 @@ class Object {
return $function($this, $args);
} else if($config['function_str']) {
$function = Object::$extraMethods[$this->class][$methodName]['function'] = create_function('$obj, $args', $config['function_str']);
$function = Object::$extraMethods[$this->class][strtolower($methodName)]['function'] = create_function('$obj, $args', $config['function_str']);
return $function($this, $args);
} else {
@ -211,7 +213,7 @@ class Object {
if(method_exists($obj, 'allMethodNames')) {
$methodNames = $obj->allMethodNames(true);
foreach($methodNames as $methodName) {
Object::$extraMethods[$this->class][$methodName] = array("parameterName" => $parameterName, "arrayIndex" => $arrayIndex);
Object::$extraMethods[$this->class][strtolower($methodName)] = array("parameterName" => $parameterName, "arrayIndex" => $arrayIndex);
}
}
}
@ -221,7 +223,7 @@ class Object {
* For example, Thumbnail($arg, $arg) can be defined to call generateImage("Thumbnail", $arg, $arg)
*/
protected function addWrapperMethod($methodName, $wrapperMethod) {
Object::$extraMethods[$this->class][$methodName] = array("wrap" => $wrapperMethod);
Object::$extraMethods[$this->class][strtolower($methodName)] = array("wrap" => $wrapperMethod, "methodName" => $methodName);
}
/**
@ -232,7 +234,7 @@ class Object {
* any protected methods; the method is actually contained in an external function.
*/
protected function createMethod($methodName, $methodCode) {
Object::$extraMethods[$this->class][$methodName] = array("function_str" => $methodCode);
Object::$extraMethods[$this->class][strtolower($methodName)] = array("function_str" => $methodCode);
}
/**
@ -258,7 +260,7 @@ class Object {
$methods = $reflection->getMethods();
foreach($methods as $method) {
$name = $method->getName();
$methodNames[$name] = $name;
$methodNames[strtolower($name)] = $name;
}
Object::$builtInMethods[$this->class] = $methodNames;
Object::$builtInMethods['_set'][$this->class] = true ;

View File

@ -14,10 +14,93 @@ class ObjectTest extends SapphireTest {
$this->assertTrue($st->hasMethod('MiGratEVersIOn'), "Test SiteTree has MiGratEVersIOn");
// Check that SiteTree methods exist on ContentController (test failover)
$this->assertTrue($cc->hasMethod);
$this->assertTrue($cc->hasMethod('canView'), "Test ContentController has canView");
$this->assertTrue($cc->hasMethod('linkorcurrent'), "Test ContentController has linkorcurrent");
$this->assertTrue($cc->hasMethod('MiGratEVersIOn'), "Test ContentController has MiGratEVersIOn");
// Make use of the test object below. 1st instantiation is different from subsequent, so create a few
$objs = array();
$objs[] = new ObjectTest_T2();
$objs[] = new ObjectTest_T2();
$objs[] = new ObjectTest_T2();
// All these methods should exist and return true
$trueMethods = array('testMethod','otherMethod','someMethod','t1cMethod','normalMethod');
foreach($objs as $i => $obj) {
foreach($trueMethods as $method) {
$methodU = strtoupper($method);
$methodL = strtoupper($method);
$this->assertTrue($obj->hasMethod($method), "Test that obj#$i has method $method");
$this->assertTrue($obj->hasMethod($methodU), "Test that obj#$i has method $methodU");
$this->assertTrue($obj->hasMethod($methodL), "Test that obj#$i has method $methodL");
$this->assertTrue($obj->$method(), "Test that obj#$i can call method $method");
$this->assertTrue($obj->$methodU(), "Test that obj#$i can call method $methodU");
$this->assertTrue($obj->$methodL(), "Test that obj#$i can call method $methodL");
}
$this->assertTrue($obj->hasMethod('Wrapping'), "Test that obj#$i has method Wrapping");
$this->assertTrue($obj->hasMethod('WRAPPING'), "Test that obj#$i has method WRAPPING");
$this->assertTrue($obj->hasMethod('wrapping'), "Test that obj#$i has method wrapping");
$this->assertEquals("Wrapping", $obj->Wrapping(), "Test that obj#$i can call method Wrapping");
$this->assertEquals("Wrapping", $obj->WRAPPING(), "Test that obj#$i can call method WRAPPIGN");
$this->assertEquals("Wrapping", $obj->wrapping(), "Test that obj#$i can call method wrapping");
}
}
}
class ObjectTest_T1A extends Object {
function testMethod() {
return true;
}
function otherMethod() {
return true;
}
}
class ObjectTest_T1B extends Object {
function someMethod() {
return true;
}
}
class ObjectTest_T1C extends Object {
function t1cMethod() {
return true;
}
}
class ObjectTest_T2 extends Object {
protected $failover;
protected $failoverArr = array();
function __construct() {
$this->failover = new ObjectTest_T1A();
$this->failoverArr[0] = new ObjectTest_T1B();
$this->failoverArr[1] = new ObjectTest_T1C();
parent::__construct();
}
function defineMethods() {
$this->addWrapperMethod('Wrapping', 'wrappedMethod');
$this->addMethodsFrom('failover');
$this->addMethodsFrom('failoverArr',0);
$this->addMethodsFrom('failoverArr',1);
$this->createMethod('testCreateMethod', 'return "created";');
}
}
function wrappedMethod($val) {
return $val;
}
function normalMethod() {
return true;
}
}