diff options
Diffstat (limited to 'includes/StubObject.php')
-rw-r--r-- | includes/StubObject.php | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/includes/StubObject.php b/includes/StubObject.php index 615bcb5f..a3970f34 100644 --- a/includes/StubObject.php +++ b/includes/StubObject.php @@ -25,6 +25,12 @@ * their associated module code by deferring initialisation until the first * method call. * + * Note on reference parameters: + * + * If the called method takes any parameters by reference, the __call magic + * here won't work correctly. The solution is to unstub the object before + * calling the method. + * * Note on unstub loops: * * Unstub loops (infinite recursion) sometimes occur when a constructor calls @@ -41,9 +47,9 @@ class StubObject { /** * Constructor. * - * @param $global String: name of the global variable. - * @param $class String: name of the class of the real object. - * @param $params Array: parameters to pass to contructor of the real + * @param string $global name of the global variable. + * @param string $class name of the class of the real object. + * @param array $params parameters to pass to constructor of the real * object. */ function __construct( $global = null, $class = null, $params = array() ) { @@ -53,14 +59,28 @@ class StubObject { } /** - * Returns a bool value whetever $obj is a stub object. Can be used to break + * Returns a bool value whenever $obj is a stub object. Can be used to break * a infinite loop when unstubbing an object. * * @param $obj Object to check. * @return Boolean: true if $obj is not an instance of StubObject class. */ static function isRealObject( $obj ) { - return is_object( $obj ) && !($obj instanceof StubObject); + return is_object( $obj ) && !$obj instanceof StubObject; + } + + /** + * Unstubs an object, if it is a stub object. Can be used to break a + * infinite loop when unstubbing an object or to avoid reference parameter + * breakage. + * + * @param $obj Object to check. + * @return void + */ + static function unstub( $obj ) { + if ( $obj instanceof StubObject ) { + $obj->_unstub( 'unstub', 3 ); + } } /** @@ -70,8 +90,8 @@ class StubObject { * This function will also call the function with the same name in the real * object. * - * @param $name String: name of the function called - * @param $args Array: arguments + * @param string $name name of the function called + * @param array $args arguments * @return mixed */ function _call( $name, $args ) { @@ -91,8 +111,8 @@ class StubObject { * Function called by PHP if no function with that name exists in this * object. * - * @param $name String: name of the function called - * @param $args Array: arguments + * @param string $name name of the function called + * @param array $args arguments * @return mixed */ function __call( $name, $args ) { @@ -105,22 +125,24 @@ class StubObject { * This is public, for the convenience of external callers wishing to access * properties, e.g. eval.php * - * @param $name String: name of the method called in this object. - * @param $level Integer: level to go in the stact trace to get the function + * @param string $name name of the method called in this object. + * @param $level Integer: level to go in the stack trace to get the function * who called this function. + * @throws MWException */ function _unstub( $name = '_unstub', $level = 2 ) { static $recursionLevel = 0; - if ( !($GLOBALS[$this->mGlobal] instanceof StubObject) ) { + if ( !$GLOBALS[$this->mGlobal] instanceof StubObject ) { return $GLOBALS[$this->mGlobal]; // already unstubbed. } if ( get_class( $GLOBALS[$this->mGlobal] ) != $this->mClass ) { - $fname = __METHOD__.'-'.$this->mGlobal; + $fname = __METHOD__ . '-' . $this->mGlobal; wfProfileIn( $fname ); $caller = wfGetCaller( $level ); if ( ++$recursionLevel > 2 ) { + wfProfileOut( $fname ); throw new MWException( "Unstub loop detected on call of \${$this->mGlobal}->$name from $caller\n" ); } wfDebug( "Unstubbing \${$this->mGlobal} on call of \${$this->mGlobal}::$name from $caller\n" ); |