]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/StubObject.php
MediaWiki 1.11.0
[autoinstallsdev/mediawiki.git] / includes / StubObject.php
1 <?php
2
3 /**
4  * Class to implement stub globals, which are globals that delay loading the
5  * their associated module code by deferring initialisation until the first 
6  * method call. 
7  *
8  * Note on unstub loops: 
9  *
10  * Unstub loops (infinite recursion) sometimes occur when a constructor calls 
11  * another function, and the other function calls some method of the stub. The 
12  * best way to avoid this is to make constructors as lightweight as possible,
13  * deferring any initialisation which depends on other modules. As a last 
14  * resort, you can use StubObject::isRealObject() to break the loop, but as a 
15  * general rule, the stub object mechanism should be transparent, and code 
16  * which refers to it should be kept to a minimum.
17  */
18 class StubObject {
19         var $mGlobal, $mClass, $mParams;
20         function __construct( $global = null, $class = null, $params = array() ) {
21                 $this->mGlobal = $global;
22                 $this->mClass = $class;
23                 $this->mParams = $params;
24         }
25
26         static function isRealObject( $obj ) {
27                 return is_object( $obj ) && !($obj instanceof StubObject);
28         }
29
30         function _call( $name, $args ) {
31                 $this->_unstub( $name, 5 );
32                 return call_user_func_array( array( $GLOBALS[$this->mGlobal], $name ), $args );
33         }
34
35         function _newObject() {
36                 return wfCreateObject( $this->mClass, $this->mParams );
37         }
38
39         function __call( $name, $args ) {
40                 return $this->_call( $name, $args );
41         }
42
43         /**
44          * This is public, for the convenience of external callers wishing to access 
45          * properties, e.g. eval.php
46          */
47         function _unstub( $name = '_unstub', $level = 2 ) {
48                 static $recursionLevel = 0;
49                 if ( get_class( $GLOBALS[$this->mGlobal] ) != $this->mClass ) {
50                         $fname = __METHOD__.'-'.$this->mGlobal;
51                         wfProfileIn( $fname );
52                         $caller = wfGetCaller( $level );
53                         if ( ++$recursionLevel > 2 ) {
54                                 throw new MWException( "Unstub loop detected on call of \${$this->mGlobal}->$name from $caller\n" );
55                         }
56                         wfDebug( "Unstubbing \${$this->mGlobal} on call of \${$this->mGlobal}->$name from $caller\n" );
57                         $GLOBALS[$this->mGlobal] = $this->_newObject();
58                         --$recursionLevel;
59                         wfProfileOut( $fname );
60                 }
61         }
62 }
63
64 class StubContLang extends StubObject {
65         function __construct() {
66                 parent::__construct( 'wgContLang' );
67         }
68
69         function __call( $name, $args ) {
70                 return StubObject::_call( $name, $args );
71         }
72
73         function _newObject() {
74                 global $wgContLanguageCode;
75                 $obj = Language::factory( $wgContLanguageCode );
76                 $obj->initEncoding();
77                 $obj->initContLang();
78                 return $obj;
79         }
80 }
81 class StubUserLang extends StubObject {
82         function __construct() {
83                 parent::__construct( 'wgLang' );
84         }
85
86         function __call( $name, $args ) {
87                 return $this->_call( $name, $args );
88         }
89
90         function _newObject() {
91                 global $wgContLanguageCode, $wgRequest, $wgUser, $wgContLang;
92                 $code = $wgRequest->getVal('uselang', $wgUser->getOption('language') );
93
94                 // if variant is explicitely selected, use it instead the one from wgUser
95                 // see bug #7605
96                 if($wgContLang->hasVariants()){
97                         $variant = $wgContLang->getPreferredVariant();
98                         if($variant != $wgContLanguageCode)
99                                 $code = $variant;
100                 }        
101
102                 # Validate $code
103                 if( empty( $code ) || !preg_match( '/^[a-z-]+$/', $code ) ) {
104                         wfDebug( "Invalid user language code\n" );
105                         $code = $wgContLanguageCode;
106                 }
107
108                 if( $code == $wgContLanguageCode ) {
109                         return $wgContLang;
110                 } else {
111                         $obj = Language::factory( $code );
112                         return $obj;
113                 }
114         }
115 }
116 class StubUser extends StubObject {
117         function __construct() {
118                 parent::__construct( 'wgUser' );
119         }
120
121         function __call( $name, $args ) {
122                 return $this->_call( $name, $args );
123         }
124         
125         function _newObject() {
126                 global $wgCommandLineMode;
127                 if( $wgCommandLineMode ) {
128                         $user = new User;
129                 } else {
130                         $user = User::newFromSession();
131                         wfRunHooks('AutoAuthenticate',array(&$user));
132                 }
133                 return $user;
134         }
135 }
136
137