1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
<?php
/**
* Some functions that are useful during startup.
*/
class MWInit {
static $compilerVersion;
/**
* Get the version of HipHop used to compile, or false if MediaWiki was not
* compiled. This works by having our build script insert a special function
* into the compiled code.
*/
static function getCompilerVersion() {
if ( self::$compilerVersion === null ) {
if ( self::functionExists( 'wfHipHopCompilerVersion' ) ) {
self::$compilerVersion = wfHipHopCompilerVersion();
} else {
self::$compilerVersion = false;
}
}
return self::$compilerVersion;
}
/**
* Returns true if we are running under HipHop, whether in compiled or
* interpreted mode.
*
* @return bool
*/
static function isHipHop() {
return function_exists( 'hphp_thread_set_warmup_enabled' );
}
/**
* Get a fully-qualified path for a source file relative to $IP. Including
* such a path under HipHop will force the file to be interpreted. This is
* useful for configuration files.
*
* @param $file string
*
* @return string
*/
static function interpretedPath( $file ) {
global $IP;
return "$IP/$file";
}
/**
* If we are running code compiled by HipHop, this will pass through the
* input path, assumed to be relative to $IP. If the code is interpreted,
* it will converted to a fully qualified path. It is necessary to use a
* path which is relative to $IP in order to make HipHop use its compiled
* code.
*
* @param $file string
*
* @return string
*/
static function compiledPath( $file ) {
global $IP;
if ( defined( 'MW_COMPILED' ) ) {
return "phase3/$file";
} else {
return "$IP/$file";
}
}
/**
* The equivalent of MWInit::interpretedPath() but for files relative to the
* extensions directory.
*
* @param $file string
* @return string
*/
static function extInterpretedPath( $file ) {
return self::getExtensionsDirectory() . '/' . $file;
}
/**
* The equivalent of MWInit::compiledPath() but for files relative to the
* extensions directory. Any files referenced in this way must be registered
* for compilation by including them in $wgCompiledFiles.
* @param $file string
* @return string
*/
static function extCompiledPath( $file ) {
if ( defined( 'MW_COMPILED' ) ) {
return "extensions/$file";
} else {
return self::getExtensionsDirectory() . '/' . $file;
}
}
/**
* Register an extension setup file and return its path for compiled
* inclusion. Use this function in LocalSettings.php to add extensions
* to the build. For example:
*
* require( MWInit::extSetupPath( 'ParserFunctions/ParserFunctions.php' ) );
*
* @param $extRel string The path relative to the extensions directory, as defined by
* $wgExtensionsDirectory.
*
* @return string
*/
static function extSetupPath( $extRel ) {
$baseRel = "extensions/$extRel";
if ( defined( 'MW_COMPILED' ) ) {
return $baseRel;
} else {
global $wgCompiledFiles;
$wgCompiledFiles[] = $baseRel;
return self::getExtensionsDirectory() . '/' . $extRel;
}
}
/**
* @return bool|string
*/
static function getExtensionsDirectory() {
global $wgExtensionsDirectory, $IP;
if ( $wgExtensionsDirectory === false ) {
$wgExtensionsDirectory = "$IP/../extensions";
}
return $wgExtensionsDirectory;
}
/**
* Determine whether a class exists, using a method which works under HipHop.
*
* Note that it's not possible to implement this with any variant of
* class_exists(), because class_exists() returns false for classes which
* are compiled in.
*
* Calling class_exists() on a literal string causes the class to be made
* "volatile", which means (as of March 2011) that the class is broken and
* can't be used at all. So don't do that. See
* https://github.com/facebook/hiphop-php/issues/314
*
* @param $class string
*
* @return bool
*/
static function classExists( $class ) {
try {
$r = new ReflectionClass( $class );
} catch( ReflectionException $r ) {
$r = false;
}
return $r !== false;
}
/**
* Determine wether a method exists within a class, using a method which works
* under HipHop.
*
* Note that under HipHop when method_exists is given a string for it's class
* such as to test for a static method has the same issues as class_exists does.
*
* @param $class string
* @param $method string
*
* @return bool
*/
static function methodExists( $class, $method ) {
try {
$r = new ReflectionMethod( $class, $method );
} catch( ReflectionException $r ) {
$r = false;
}
return $r !== false;
}
/**
* Determine whether a function exists, using a method which works under
* HipHop.
*
* @param $function string
*
* @return bool
*/
static function functionExists( $function ) {
try {
$r = new ReflectionFunction( $function );
} catch( ReflectionException $r ) {
$r = false;
}
return $r !== false;
}
/**
* Call a static method of a class with variable arguments without causing
* it to become volatile.
* @param $className string
* @param $methodName string
* @param $args array
*
*/
static function callStaticMethod( $className, $methodName, $args ) {
$r = new ReflectionMethod( $className, $methodName );
return $r->invokeArgs( null, $args );
}
}
|