Clean up old title on move before reset article id
[lhc/web/wiklou.git] / includes / StubObject.php
index 615bcb5..a3970f3 100644 (file)
  * 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" );