[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Delayed loading of global objects. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 * http://www.gnu.org/copyleft/gpl.html 19 * 20 * @file 21 */ 22 23 /** 24 * Class to implement stub globals, which are globals that delay loading the 25 * their associated module code by deferring initialisation until the first 26 * method call. 27 * 28 * Note on reference parameters: 29 * 30 * If the called method takes any parameters by reference, the __call magic 31 * here won't work correctly. The solution is to unstub the object before 32 * calling the method. 33 * 34 * Note on unstub loops: 35 * 36 * Unstub loops (infinite recursion) sometimes occur when a constructor calls 37 * another function, and the other function calls some method of the stub. The 38 * best way to avoid this is to make constructors as lightweight as possible, 39 * deferring any initialisation which depends on other modules. As a last 40 * resort, you can use StubObject::isRealObject() to break the loop, but as a 41 * general rule, the stub object mechanism should be transparent, and code 42 * which refers to it should be kept to a minimum. 43 */ 44 class StubObject { 45 /** @var null|string */ 46 protected $global; 47 48 /** @var null|string */ 49 protected $class; 50 51 /** @var array */ 52 protected $params; 53 54 /** 55 * Constructor. 56 * 57 * @param string $global Name of the global variable. 58 * @param string $class Name of the class of the real object. 59 * @param array $params Parameters to pass to constructor of the real object. 60 */ 61 public function __construct( $global = null, $class = null, $params = array() ) { 62 $this->global = $global; 63 $this->class = $class; 64 $this->params = $params; 65 } 66 67 /** 68 * Returns a bool value whenever $obj is a stub object. Can be used to break 69 * a infinite loop when unstubbing an object. 70 * 71 * @param object $obj Object to check. 72 * @return bool True if $obj is not an instance of StubObject class. 73 */ 74 public static function isRealObject( $obj ) { 75 return is_object( $obj ) && !$obj instanceof StubObject; 76 } 77 78 /** 79 * Unstubs an object, if it is a stub object. Can be used to break a 80 * infinite loop when unstubbing an object or to avoid reference parameter 81 * breakage. 82 * 83 * @param object $obj Object to check. 84 * @return void 85 */ 86 public static function unstub( &$obj ) { 87 if ( $obj instanceof StubObject ) { 88 $obj = $obj->_unstub( 'unstub', 3 ); 89 } 90 } 91 92 /** 93 * Function called if any function exists with that name in this object. 94 * It is used to unstub the object. Only used internally, PHP will call 95 * self::__call() function and that function will call this function. 96 * This function will also call the function with the same name in the real 97 * object. 98 * 99 * @param string $name Name of the function called 100 * @param array $args Arguments 101 * @return mixed 102 */ 103 public function _call( $name, $args ) { 104 $this->_unstub( $name, 5 ); 105 return call_user_func_array( array( $GLOBALS[$this->global], $name ), $args ); 106 } 107 108 /** 109 * Create a new object to replace this stub object. 110 * @return object 111 */ 112 public function _newObject() { 113 return MWFunction::newObj( $this->class, $this->params ); 114 } 115 116 /** 117 * Function called by PHP if no function with that name exists in this 118 * object. 119 * 120 * @param string $name Name of the function called 121 * @param array $args Arguments 122 * @return mixed 123 */ 124 public function __call( $name, $args ) { 125 return $this->_call( $name, $args ); 126 } 127 128 /** 129 * This function creates a new object of the real class and replace it in 130 * the global variable. 131 * This is public, for the convenience of external callers wishing to access 132 * properties, e.g. eval.php 133 * 134 * @param string $name Name of the method called in this object. 135 * @param int $level Level to go in the stack trace to get the function 136 * who called this function. 137 * @return object The unstubbed version of itself 138 * @throws MWException 139 */ 140 public function _unstub( $name = '_unstub', $level = 2 ) { 141 static $recursionLevel = 0; 142 143 if ( !$GLOBALS[$this->global] instanceof StubObject ) { 144 return $GLOBALS[$this->global]; // already unstubbed. 145 } 146 147 if ( get_class( $GLOBALS[$this->global] ) != $this->class ) { 148 $fname = __METHOD__ . '-' . $this->global; 149 wfProfileIn( $fname ); 150 $caller = wfGetCaller( $level ); 151 if ( ++$recursionLevel > 2 ) { 152 wfProfileOut( $fname ); 153 throw new MWException( "Unstub loop detected on call of " 154 . "\${$this->global}->$name from $caller\n" ); 155 } 156 wfDebug( "Unstubbing \${$this->global} on call of " 157 . "\${$this->global}::$name from $caller\n" ); 158 $GLOBALS[$this->global] = $this->_newObject(); 159 --$recursionLevel; 160 wfProfileOut( $fname ); 161 return $GLOBALS[$this->global]; 162 } 163 } 164 } 165 166 /** 167 * Stub object for the user language. It depends of the user preferences and 168 * "uselang" parameter that can be passed to index.php. This object have to be 169 * in $wgLang global. 170 */ 171 class StubUserLang extends StubObject { 172 173 public function __construct() { 174 parent::__construct( 'wgLang' ); 175 } 176 177 public function __call( $name, $args ) { 178 return $this->_call( $name, $args ); 179 } 180 181 /** 182 * @return Language 183 */ 184 public function _newObject() { 185 return RequestContext::getMain()->getLanguage(); 186 } 187 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |