* Implement MW_VERSION constant in Defines.php and use it in preference to $wgVersion...
[lhc/web/wiklou.git] / includes / Setup.php
1 <?php
2 /**
3 * Include most things that's need to customize the site
4 *
5 * @file
6 */
7
8 /**
9 * This file is not a valid entry point, perform no further processing unless
10 * MEDIAWIKI is defined
11 */
12 if ( !defined( 'MEDIAWIKI' ) ) {
13 exit( 1 );
14 }
15
16 # The main wiki script and things like database
17 # conversion and maintenance scripts all share a
18 # common setup of including lots of classes and
19 # setting up a few globals.
20 #
21
22 $fname = 'Setup.php';
23 wfProfileIn( $fname );
24
25 // Check to see if we are at the file scope
26 // FIXME: use a different test here, maybe a constant defined at the top of DefaultSettings.php?
27 if ( !isset( $wgVersion ) ) {
28 echo "Error, Setup.php must be included from the file scope, after DefaultSettings.php\n";
29 die( 1 );
30 }
31
32 // Set various default paths sensibly...
33 if ( $wgScript === false ) $wgScript = "$wgScriptPath/index$wgScriptExtension";
34 if ( $wgRedirectScript === false ) $wgRedirectScript = "$wgScriptPath/redirect$wgScriptExtension";
35 if ( $wgLoadScript === false ) $wgLoadScript = "$wgScriptPath/load$wgScriptExtension";
36
37 if ( $wgArticlePath === false ) {
38 if ( $wgUsePathInfo ) {
39 $wgArticlePath = "$wgScript/$1";
40 } else {
41 $wgArticlePath = "$wgScript?title=$1";
42 }
43 }
44
45 if ( $wgStylePath === false ) $wgStylePath = "$wgScriptPath/skins";
46 if ( $wgLocalStylePath === false ) $wgLocalStylePath = "$wgScriptPath/skins";
47 if ( $wgStyleDirectory === false ) $wgStyleDirectory = "$IP/skins";
48 if ( $wgExtensionAssetsPath === false ) $wgExtensionAssetsPath = "$wgScriptPath/extensions";
49
50 if ( $wgLogo === false ) $wgLogo = "$wgStylePath/common/images/wiki.png";
51
52 if ( $wgUploadPath === false ) $wgUploadPath = "$wgScriptPath/images";
53 if ( $wgUploadDirectory === false ) $wgUploadDirectory = "$IP/images";
54
55 if ( $wgTmpDirectory === false ) $wgTmpDirectory = "{$wgUploadDirectory}/tmp";
56
57 if ( $wgReadOnlyFile === false ) $wgReadOnlyFile = "{$wgUploadDirectory}/lock_yBgMBwiR";
58 if ( $wgFileCacheDirectory === false ) $wgFileCacheDirectory = "{$wgUploadDirectory}/cache";
59 if ( $wgDeletedDirectory === false ) $wgDeletedDirectory = "{$wgUploadDirectory}/deleted";
60
61 if ( isset( $wgFileStore['deleted']['directory'] ) ) {
62 $wgDeletedDirectory = $wgFileStore['deleted']['directory'];
63 }
64
65 if ( isset( $wgFooterIcons['copyright'] ) &&
66 isset( $wgFooterIcons['copyright']['copyright'] ) &&
67 $wgFooterIcons['copyright']['copyright'] === array() )
68 {
69 if ( isset( $wgCopyrightIcon ) && $wgCopyrightIcon ) {
70 $wgFooterIcons['copyright']['copyright'] = $wgCopyrightIcon;
71 } elseif ( $wgRightsIcon || $wgRightsText ) {
72 $wgFooterIcons['copyright']['copyright'] = array(
73 'url' => $wgRightsUrl,
74 'src' => $wgRightsIcon,
75 'alt' => $wgRightsText,
76 );
77 } else {
78 unset( $wgFooterIcons['copyright']['copyright'] );
79 }
80 }
81
82 if ( isset( $wgFooterIcons['poweredby'] ) &&
83 isset( $wgFooterIcons['poweredby']['mediawiki'] ) &&
84 $wgFooterIcons['poweredby']['mediawiki']['src'] === null )
85 {
86 $wgFooterIcons['poweredby']['mediawiki']['src'] = "$wgStylePath/common/images/poweredby_mediawiki_88x31.png";
87 }
88
89 /**
90 * Unconditional protection for NS_MEDIAWIKI since otherwise it's too easy for a
91 * sysadmin to set $wgNamespaceProtection incorrectly and leave the wiki insecure.
92 *
93 * Note that this is the definition of editinterface and it can be granted to
94 * all users if desired.
95 */
96 $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface';
97
98 /**
99 * The canonical names of namespaces 6 and 7 are, as of v1.14, "File"
100 * and "File_talk". The old names "Image" and "Image_talk" are
101 * retained as aliases for backwards compatibility.
102 */
103 $wgNamespaceAliases['Image'] = NS_FILE;
104 $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK;
105
106 /**
107 * Initialise $wgLocalFileRepo from backwards-compatible settings
108 */
109 if ( !$wgLocalFileRepo ) {
110 if ( isset( $wgFileStore['deleted']['hash'] ) ) {
111 $deletedHashLevel = $wgFileStore['deleted']['hash'];
112 } else {
113 $deletedHashLevel = $wgHashedUploadDirectory ? 3 : 0;
114 }
115 $wgLocalFileRepo = array(
116 'class' => 'LocalRepo',
117 'name' => 'local',
118 'directory' => $wgUploadDirectory,
119 'scriptDirUrl' => $wgScriptPath,
120 'scriptExtension' => $wgScriptExtension,
121 'url' => $wgUploadBaseUrl ? $wgUploadBaseUrl . $wgUploadPath : $wgUploadPath,
122 'hashLevels' => $wgHashedUploadDirectory ? 2 : 0,
123 'thumbScriptUrl' => $wgThumbnailScriptPath,
124 'transformVia404' => !$wgGenerateThumbnailOnParse,
125 'deletedDir' => $wgDeletedDirectory,
126 'deletedHashLevels' => $deletedHashLevel
127 );
128 }
129 /**
130 * Initialise shared repo from backwards-compatible settings
131 */
132 if ( $wgUseSharedUploads ) {
133 if ( $wgSharedUploadDBname ) {
134 $wgForeignFileRepos[] = array(
135 'class' => 'ForeignDBRepo',
136 'name' => 'shared',
137 'directory' => $wgSharedUploadDirectory,
138 'url' => $wgSharedUploadPath,
139 'hashLevels' => $wgHashedSharedUploadDirectory ? 2 : 0,
140 'thumbScriptUrl' => $wgSharedThumbnailScriptPath,
141 'transformVia404' => !$wgGenerateThumbnailOnParse,
142 'dbType' => $wgDBtype,
143 'dbServer' => $wgDBserver,
144 'dbUser' => $wgDBuser,
145 'dbPassword' => $wgDBpassword,
146 'dbName' => $wgSharedUploadDBname,
147 'dbFlags' => ( $wgDebugDumpSql ? DBO_DEBUG : 0 ) | DBO_DEFAULT,
148 'tablePrefix' => $wgSharedUploadDBprefix,
149 'hasSharedCache' => $wgCacheSharedUploads,
150 'descBaseUrl' => $wgRepositoryBaseUrl,
151 'fetchDescription' => $wgFetchCommonsDescriptions,
152 );
153 } else {
154 $wgForeignFileRepos[] = array(
155 'class' => 'FSRepo',
156 'name' => 'shared',
157 'directory' => $wgSharedUploadDirectory,
158 'url' => $wgSharedUploadPath,
159 'hashLevels' => $wgHashedSharedUploadDirectory ? 2 : 0,
160 'thumbScriptUrl' => $wgSharedThumbnailScriptPath,
161 'transformVia404' => !$wgGenerateThumbnailOnParse,
162 'descBaseUrl' => $wgRepositoryBaseUrl,
163 'fetchDescription' => $wgFetchCommonsDescriptions,
164 );
165 }
166 }
167 if ( $wgUseInstantCommons ) {
168 $wgForeignFileRepos[] = array(
169 'class' => 'ForeignAPIRepo',
170 'name' => 'wikimediacommons',
171 'apibase' => 'http://commons.wikimedia.org/w/api.php',
172 'hashLevels' => 2,
173 'fetchDescription' => true,
174 'descriptionCacheExpiry' => 43200,
175 'apiThumbCacheExpiry' => 86400,
176 );
177 }
178
179 if ( $wgRCFilterByAge ) {
180 # # Trim down $wgRCLinkDays so that it only lists links which are valid
181 # # as determined by $wgRCMaxAge.
182 # # Note that we allow 1 link higher than the max for things like 56 days but a 60 day link.
183 sort( $wgRCLinkDays );
184 for ( $i = 0; $i < count( $wgRCLinkDays ); $i++ ) {
185 if ( $wgRCLinkDays[$i] >= $wgRCMaxAge / ( 3600 * 24 ) ) {
186 $wgRCLinkDays = array_slice( $wgRCLinkDays, 0, $i + 1, false );
187 break;
188 }
189 }
190 }
191
192 if ( $wgSkipSkin ) {
193 $wgSkipSkins[] = $wgSkipSkin;
194 }
195
196 # Set default shared prefix
197 if ( $wgSharedPrefix === false ) {
198 $wgSharedPrefix = $wgDBprefix;
199 }
200
201 if ( !$wgCookiePrefix ) {
202 if ( $wgSharedDB && $wgSharedPrefix && in_array( 'user', $wgSharedTables ) ) {
203 $wgCookiePrefix = $wgSharedDB . '_' . $wgSharedPrefix;
204 } elseif ( $wgSharedDB && in_array( 'user', $wgSharedTables ) ) {
205 $wgCookiePrefix = $wgSharedDB;
206 } elseif ( $wgDBprefix ) {
207 $wgCookiePrefix = $wgDBname . '_' . $wgDBprefix;
208 } else {
209 $wgCookiePrefix = $wgDBname;
210 }
211 }
212 $wgCookiePrefix = strtr( $wgCookiePrefix, '=,; +."\'\\[', '__________' );
213
214 $wgUseEnotif = $wgEnotifUserTalk || $wgEnotifWatchlist;
215
216 if ( $wgMetaNamespace === false ) {
217 $wgMetaNamespace = str_replace( ' ', '_', $wgSitename );
218 }
219
220 /**
221 * Definitions of the NS_ constants are in Defines.php
222 * @private
223 */
224 $wgCanonicalNamespaceNames = array(
225 NS_MEDIA => 'Media',
226 NS_SPECIAL => 'Special',
227 NS_TALK => 'Talk',
228 NS_USER => 'User',
229 NS_USER_TALK => 'User_talk',
230 NS_PROJECT => 'Project',
231 NS_PROJECT_TALK => 'Project_talk',
232 NS_FILE => 'File',
233 NS_FILE_TALK => 'File_talk',
234 NS_MEDIAWIKI => 'MediaWiki',
235 NS_MEDIAWIKI_TALK => 'MediaWiki_talk',
236 NS_TEMPLATE => 'Template',
237 NS_TEMPLATE_TALK => 'Template_talk',
238 NS_HELP => 'Help',
239 NS_HELP_TALK => 'Help_talk',
240 NS_CATEGORY => 'Category',
241 NS_CATEGORY_TALK => 'Category_talk',
242 );
243
244 /// @todo UGLY UGLY
245 if( is_array( $wgExtraNamespaces ) ) {
246 $wgCanonicalNamespaceNames = $wgCanonicalNamespaceNames + $wgExtraNamespaces;
247 }
248
249 # These are now the same, always
250 # To determine the user language, use $wgLang->getCode()
251 $wgContLanguageCode = $wgLanguageCode;
252
253 # Easy to forget to falsify $wgShowIPinHeader for static caches.
254 # If file cache or squid cache is on, just disable this (DWIMD).
255 if ( $wgUseFileCache || $wgUseSquid ) {
256 $wgShowIPinHeader = false;
257 }
258
259 # $wgAllowRealName and $wgAllowUserSkin were removed in 1.16
260 # in favor of $wgHiddenPrefs, handle b/c here
261 if ( !$wgAllowRealName ) {
262 $wgHiddenPrefs[] = 'realname';
263 }
264
265 # Doesn't make sense to have if disabled.
266 if ( !$wgEnotifMinorEdits ) {
267 $wgHiddenPrefs[] = 'enotifminoredits';
268 }
269
270 # $wgDisabledActions is deprecated as of 1.18
271 foreach( $wgDisabledActions as $action ){
272 $wgActions[$action] = false;
273 }
274 if( !$wgAllowPageInfo ){
275 $wgActions['info'] = false;
276 }
277
278 if ( !$wgHtml5Version && $wgHtml5 && $wgAllowRdfaAttributes ) {
279 # see http://www.w3.org/TR/rdfa-in-html/#document-conformance
280 if ( $wgMimeType == 'application/xhtml+xml' ) {
281 $wgHtml5Version = 'XHTML+RDFa 1.0';
282 } else {
283 $wgHtml5Version = 'HTML+RDFa 1.0';
284 }
285 }
286
287 # Blacklisted file extensions shouldn't appear on the "allowed" list
288 $wgFileExtensions = array_diff ( $wgFileExtensions, $wgFileBlacklist );
289
290 if ( $wgInvalidateCacheOnLocalSettingsChange ) {
291 $wgCacheEpoch = max( $wgCacheEpoch, gmdate( 'YmdHis', @filemtime( "$IP/LocalSettings.php" ) ) );
292 }
293
294 if ( $wgAjaxUploadDestCheck ) {
295 $wgAjaxExportList[] = 'SpecialUpload::ajaxGetExistsWarning';
296 }
297
298 if ( $wgNewUserLog ) {
299 # Add a new log type
300 $wgLogTypes[] = 'newusers';
301 $wgLogNames['newusers'] = 'newuserlogpage';
302 $wgLogHeaders['newusers'] = 'newuserlogpagetext';
303 $wgLogActions['newusers/newusers'] = 'newuserlogentry'; // For compatibility with older log entries
304 $wgLogActions['newusers/create'] = 'newuserlog-create-entry';
305 $wgLogActions['newusers/create2'] = 'newuserlog-create2-entry';
306 $wgLogActions['newusers/autocreate'] = 'newuserlog-autocreate-entry';
307 }
308
309 if ( !defined( 'MW_COMPILED' ) ) {
310 if ( !MWInit::classExists( 'AutoLoader' ) ) {
311 require_once( "$IP/includes/AutoLoader.php" );
312 }
313
314 wfProfileIn( $fname . '-exception' );
315 require_once( "$IP/includes/Exception.php" );
316 wfInstallExceptionHandler();
317 wfProfileOut( $fname . '-exception' );
318
319 wfProfileIn( $fname . '-includes' );
320 require_once( "$IP/includes/GlobalFunctions.php" );
321 require_once( "$IP/includes/Hooks.php" );
322 require_once( "$IP/includes/ProxyTools.php" );
323 require_once( "$IP/includes/ImageFunctions.php" );
324 wfProfileOut( $fname . '-includes' );
325 }
326 wfProfileIn( $fname . '-misc1' );
327
328 # Raise the memory limit if it's too low
329 wfMemoryLimit();
330
331 /**
332 * Set up the timezone, suppressing the pseudo-security warning in PHP 5.1+
333 * that happens whenever you use a date function without the timezone being
334 * explicitly set. Inspired by phpMyAdmin's treatment of the problem.
335 */
336 wfSuppressWarnings();
337 date_default_timezone_set( date_default_timezone_get() );
338 wfRestoreWarnings();
339
340 # Can't stub this one, it sets up $_GET and $_REQUEST in its constructor
341 $wgRequest = new WebRequest;
342
343 # Useful debug output
344 global $wgCommandLineMode;
345 if ( $wgCommandLineMode ) {
346 wfDebug( "\n\nStart command line script $self\n" );
347 } else {
348 $debug = "Start request\n\n{$_SERVER['REQUEST_METHOD']} {$wgRequest->getRequestURL()}";
349
350 if ( $wgDebugPrintHttpHeaders ) {
351 $debug .= "\nHTTP HEADERS:\n";
352
353 foreach ( $wgRequest->getAllHeaders() as $name => $value ) {
354 $debug .= "$name: $value\n";
355 }
356 }
357 wfDebug( "$debug\n" );
358 }
359
360 wfProfileOut( $fname . '-misc1' );
361 wfProfileIn( $fname . '-memcached' );
362
363 $wgMemc = wfGetMainCache();
364 $messageMemc = wfGetMessageCacheStorage();
365 $parserMemc = wfGetParserCacheStorage();
366
367 wfDebug( 'CACHES: ' . get_class( $wgMemc ) . '[main] ' .
368 get_class( $messageMemc ) . '[message] ' .
369 get_class( $parserMemc ) . "[parser]\n" );
370
371 wfProfileOut( $fname . '-memcached' );
372
373 # # Most of the config is out, some might want to run hooks here.
374 wfRunHooks( 'SetupAfterCache' );
375
376 wfProfileIn( $fname . '-session' );
377
378 # If session.auto_start is there, we can't touch session name
379 if ( !wfIniGetBool( 'session.auto_start' ) ) {
380 session_name( $wgSessionName ? $wgSessionName : $wgCookiePrefix . '_session' );
381 }
382
383 if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
384 if ( $wgRequest->checkSessionCookie() || isset( $_COOKIE[$wgCookiePrefix . 'Token'] ) ) {
385 wfIncrStats( 'request_with_session' );
386 wfSetupSession();
387 $wgSessionStarted = true;
388 } else {
389 wfIncrStats( 'request_without_session' );
390 $wgSessionStarted = false;
391 }
392 }
393
394 wfProfileOut( $fname . '-session' );
395 wfProfileIn( $fname . '-globals' );
396
397 $wgContLang = Language::factory( $wgLanguageCode );
398 $wgContLang->initEncoding();
399 $wgContLang->initContLang();
400
401 // Now that variant lists may be available...
402 $wgRequest->interpolateTitle();
403 $wgUser = RequestContext::getMain()->getUser(); # BackCompat
404
405 /**
406 * @var Language
407 */
408 $wgLang = new StubUserLang;
409
410 /**
411 * @var OutputPage
412 */
413 $wgOut = RequestContext::getMain()->getOutput(); # BackCompat
414
415 /**
416 * @var Parser
417 */
418 $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) );
419
420 if ( !is_object( $wgAuth ) ) {
421 $wgAuth = new StubObject( 'wgAuth', 'AuthPlugin' );
422 wfRunHooks( 'AuthPluginSetup', array( &$wgAuth ) );
423 }
424
425 # Placeholders in case of DB error
426 $wgTitle = null;
427 $wgArticle = null;
428
429 $wgDeferredUpdateList = array();
430
431 wfProfileOut( $fname . '-globals' );
432 wfProfileIn( $fname . '-extensions' );
433
434 # Extension setup functions for extensions other than skins
435 # Entries should be added to this variable during the inclusion
436 # of the extension file. This allows the extension to perform
437 # any necessary initialisation in the fully initialised environment
438 foreach ( $wgExtensionFunctions as $func ) {
439 # Allow closures in PHP 5.3+
440 if ( is_object( $func ) && $func instanceof Closure ) {
441 $profName = $fname . '-extensions-closure';
442 } elseif ( is_array( $func ) ) {
443 if ( is_object( $func[0] ) )
444 $profName = $fname . '-extensions-' . get_class( $func[0] ) . '::' . $func[1];
445 else
446 $profName = $fname . '-extensions-' . implode( '::', $func );
447 } else {
448 $profName = $fname . '-extensions-' . strval( $func );
449 }
450
451 wfProfileIn( $profName );
452 call_user_func( $func );
453 wfProfileOut( $profName );
454 }
455
456 wfDebug( "Fully initialised\n" );
457 $wgFullyInitialised = true;
458 wfProfileOut( $fname . '-extensions' );
459
460 require_once( MWInit::compiledPath( 'includes/normal/UtfNormalDefines.php' ) );
461
462 wfProfileOut( $fname );