23use Liuggio\StatsdClient\Sender\SocketSender;
24use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
28use Psr\Log\LoggerInterface;
31use Wikimedia\ScopedCallback;
37 use ProtectedHookAccessorTrait;
60 $this->context =
$context ?: RequestContext::getMain();
61 $this->config = $this->context->getConfig();
63 if ( $this->config->get(
'CommandLineMode' ) ) {
64 $this->postSendStrategy = self::DEFER_CLI_MODE;
65 } elseif ( function_exists(
'fastcgi_finish_request' ) ) {
66 $this->postSendStrategy = self::DEFER_FASTCGI_FINISH_REQUEST;
68 $this->postSendStrategy = self::DEFER_SET_LENGTH_AND_FLUSH;
79 $request = $this->context->getRequest();
80 $curid = $request->getInt(
'curid' );
81 $title = $request->getText(
'title' );
82 $action = $request->getRawVal(
'action' );
86 $ret = Title::newFromID( $curid );
88 $ret = Title::newFromURL(
$title );
89 if ( $ret !==
null ) {
92 if ( $ret->getNamespace() ===
NS_MEDIA ) {
93 $ret = Title::makeTitle(
NS_FILE, $ret->getDBkey() );
98 $languageConverter = $services
99 ->getLanguageConverterFactory()
100 ->getLanguageConverter( $services->getContentLanguage() );
101 if ( $languageConverter->hasVariants() && !$ret->exists() ) {
102 $languageConverter->findVariantLink(
$title, $ret );
111 if ( $ret ===
null || !$ret->isSpecialPage() ) {
113 $oldid = $request->getInt(
'oldid' );
114 $oldid = $oldid ?: $request->getInt(
'diff' );
118 ->getRevisionLookup()
119 ->getRevisionById( $oldid );
121 $ret = Title::newFromLinkTarget(
122 $revRecord->getPageAsLinkTarget()
128 if ( $ret ===
null && $request->getCheck(
'search' ) ) {
137 && strval(
$title ) ===
''
138 && !$request->getCheck(
'curid' )
141 $ret = Title::newMainPage();
144 if ( $ret ===
null || ( $ret->getDBkey() ==
'' && !$ret->isExternal() ) ) {
147 Title::newFromTextThrow(
$title );
159 if ( !$this->context->hasTitle() ) {
161 $this->context->setTitle( $this->
parseTitle() );
166 return $this->context->getTitle();
175 if ( $this->action === null ) {
176 $this->action = Action::getActionName( $this->context );
179 return $this->action;
197 $request = $this->context->getRequest();
198 $requestTitle =
$title = $this->context->getTitle();
199 $output = $this->context->getOutput();
200 $user = $this->context->getUser();
202 if ( $request->getRawVal(
'printable' ) ===
'yes' ) {
203 $output->setPrintable();
206 $this->getHookRunner()->onBeforeInitialize(
$title,
null, $output, $user, $request, $this );
210 ||
$title->isSpecial(
'Badtitle' )
224 $permissionStatus = PermissionStatus::newEmpty();
225 if ( !$this->context->getAuthority()->authorizeRead(
'read',
$title, $permissionStatus ) ) {
236 $this->context->setTitle( $badTitle );
243 if (
$title->isExternal() ) {
244 $rdfrom = $request->getVal(
'rdfrom' );
246 $url =
$title->getFullURL( [
'rdfrom' => $rdfrom ] );
248 $query = $request->getValues();
249 unset( $query[
'title'] );
250 $url =
$title->getFullURL( $query );
253 if ( !preg_match(
'/^' . preg_quote( $this->config->get(
'Server' ),
'/' ) .
'/', $url )
257 $output->redirect( $url, 301 );
269 } elseif ( !$this->tryNormaliseRedirect(
$title ) ) {
271 $spFactory = MediaWikiServices::getInstance()->getSpecialPageFactory();
272 if (
$title->isSpecialPage() ) {
273 $specialPage = $spFactory->getPage(
$title->getDBkey() );
275 $specialPage->setContext( $this->context );
276 if ( $this->config->get(
'HideIdentifiableRedirects' )
277 && $specialPage->personallyIdentifiableTarget()
279 list( , $subpage ) = $spFactory->resolveAlias(
$title->getDBkey() );
280 $target = $specialPage->getRedirect( $subpage );
282 if ( $target instanceof
Title ) {
283 if ( $target->isExternal() ) {
287 'force/' . $target->getPrefixedDBkey()
291 $query = $specialPage->getRedirectQuery( $subpage ) ?: [];
293 $request->setRequestURL( $this->context->getRequest()->getRequestURL() );
294 $this->context->setRequest( $request );
296 $this->context->getOutput()->lowerCdnMaxage( 0 );
297 $this->context->setTitle( $target );
300 $this->action =
null;
302 $output->addJsConfigVars( [
303 'wgInternalRedirectTargetUrl' => $target->getLinkURL( $query ),
305 $output->addModules(
'mediawiki.action.view.redirect' );
312 if (
$title->isSpecialPage() ) {
314 $spFactory->executePath(
$title, $this->context );
318 $article = $this->initializeArticle();
319 if ( is_object( $article ) ) {
320 $this->performAction( $article, $requestTitle );
321 } elseif ( is_string( $article ) ) {
322 $output->redirect( $article );
324 throw new MWException(
"Shouldn't happen: MediaWiki::initializeArticle()"
325 .
" returned neither an object nor a URL" );
328 $output->considerCacheSettingsFinal();
355 $request = $this->context->getRequest();
356 $output = $this->context->getOutput();
358 if ( $request->getRawVal(
'action',
'view' ) !=
'view'
359 || $request->wasPosted()
360 || ( $request->getCheck(
'title' )
361 &&
$title->getPrefixedDBkey() == $request->getText(
'title' ) )
362 || count( $request->getValueNames( [
'action',
'title' ] ) )
363 || !$this->getHookRunner()->onTestCanonicalRedirect( $request,
$title, $output )
368 if ( $this->config->get(
'MainPageIsDomainRoot' ) && $request->getRequestURL() ===
'/' ) {
372 if (
$title->isSpecialPage() ) {
373 list( $name, $subpage ) = MediaWikiServices::getInstance()->getSpecialPageFactory()->
374 resolveAlias(
$title->getDBkey() );
381 if ( $targetUrl == $request->getFullRequestURL() ) {
382 $message =
"Redirect loop detected!\n\n" .
383 "This means the wiki got confused about what page was " .
384 "requested; this sometimes happens when moving a wiki " .
385 "to a new server or changing the server configuration.\n\n";
387 if ( $this->config->get(
'UsePathInfo' ) ) {
388 $message .=
"The wiki is trying to interpret the page " .
389 "title from the URL path portion (PATH_INFO), which " .
390 "sometimes fails depending on the web server. Try " .
391 "setting \"\$wgUsePathInfo = false;\" in your " .
392 "LocalSettings.php, or check that \$wgArticlePath " .
395 $message .=
"Your web server was detected as possibly not " .
396 "supporting URL path components (PATH_INFO) correctly; " .
397 "check your LocalSettings.php for a customized " .
398 "\$wgArticlePath setting and/or toggle \$wgUsePathInfo " .
403 $output->setCdnMaxage( 1200 );
404 $output->redirect( $targetUrl,
'301' );
415 $title = $this->context->getTitle();
416 $services = MediaWikiServices::getInstance();
417 if ( $this->context->canUseWikiPage() ) {
420 $page = $this->context->getWikiPage();
424 $page = $services->getWikiPageFactory()->newFromTitle(
$title );
425 $this->context->setWikiPage( $page );
426 wfWarn(
"RequestContext::canUseWikiPage() returned false" );
430 $article = Article::newFromWikiPage( $page, $this->context );
433 if ( !$services->getContentHandlerFactory()
434 ->getContentHandler(
$title->getContentModel() )
435 ->supportsRedirects()
440 $request = $this->context->getRequest();
444 $action = $request->getRawVal(
'action',
'view' );
446 if ( ( $action ==
'view' || $action ==
'render' )
447 && !$request->getCheck(
'oldid' )
448 && !$request->getCheck(
'diff' )
449 && $request->getRawVal(
'redirect' ) !==
'no'
451 && !( is_object(
$file ) &&
$file->exists() && !
$file->getRedirected() )
454 $ignoreRedirect = $target =
false;
456 $this->getHookRunner()->onInitializeArticleMaybeRedirect(
$title, $request,
457 $ignoreRedirect, $target, $article );
458 $page = $article->getPage();
462 if ( !$ignoreRedirect && ( $target || $page->isRedirect() ) ) {
464 $target = $target ?: $page->followRedirect();
465 if ( is_string( $target ) && !$this->config->get(
'DisableHardRedirects' ) ) {
469 if ( is_object( $target ) ) {
471 $rpage = $services->getWikiPageFactory()->newFromTitle( $target );
472 $rpage->loadPageData();
473 if ( $rpage->exists() || ( is_object(
$file ) && !
$file->isLocal() ) ) {
474 $rarticle = Article::newFromWikiPage( $rpage, $this->context );
475 $rarticle->setRedirectedFrom(
$title );
477 $article = $rarticle;
478 $this->context->setTitle( $target );
479 $this->context->setWikiPage( $article->getPage() );
484 $this->context->setTitle( $article->getTitle() );
485 $this->context->setWikiPage( $article->getPage() );
499 $request = $this->context->getRequest();
500 $output = $this->context->getOutput();
501 $title = $this->context->getTitle();
502 $user = $this->context->getUser();
503 $services = MediaWikiServices::getInstance();
505 if ( !$this->getHookRunner()->onMediaWikiPerformAction(
506 $output, $article,
$title, $user, $request, $this )
511 $t = microtime(
true );
512 $actionName = $this->getAction();
513 $action = Action::factory( $actionName, $article, $this->context );
515 if ( $action instanceof
Action ) {
517 if ( $action->needsReadRights() && !$user->isAllowed(
'read' ) ) {
522 $trxLimits = $this->config->get(
'TrxProfilerLimits' );
523 $trxProfiler = Profiler::instance()->getTransactionProfiler();
524 if ( $request->wasPosted() && !$action->doesWrites() ) {
525 $trxProfiler->setExpectations( $trxLimits[
'POST-nonwrite'], __METHOD__ );
526 $request->markAsSafeRequest();
529 # Let CDN cache things if we can purge them.
530 if ( $this->config->get(
'UseCdn' ) ) {
531 $htmlCacheUpdater = $services->getHtmlCacheUpdater();
535 $htmlCacheUpdater->getUrls( $requestTitle )
538 $output->setCdnMaxage( $this->config->get(
'CdnMaxAge' ) );
544 $runTime = microtime(
true ) -
$t;
545 $services->getStatsdDataFactory()->timing(
546 'action.' . strtr( $actionName,
'.',
'_' ) .
'.executeTiming',
553 $output->setStatusCode( 404 );
554 $output->showErrorPage(
'nosuchaction',
'nosuchactiontext' );
562 $this->setDBProfilingAgent();
564 }
catch ( Exception $e ) {
565 $context = $this->context;
566 $action = $context->getRequest()->getRawVal(
'action',
'view' );
569 $context->hasTitle() &&
570 $context->getTitle()->canExist() &&
571 in_array( $action, [
'view',
'history' ],
true ) &&
576 if (
$cache->isCached() ) {
582 MWExceptionHandler::handleException( $e, MWExceptionHandler::CAUGHT_BY_ENTRYPOINT );
583 }
catch ( Throwable $e ) {
585 MWExceptionHandler::handleException( $e, MWExceptionHandler::CAUGHT_BY_ENTRYPOINT );
588 $this->doPostOutputShutdown();
595 $services = MediaWikiServices::getInstance();
596 $name = $this->context->getUser()->getName();
597 $services->getDBLoadBalancerFactory()->setAgentName(
598 mb_strlen( $name ) > 15 ? mb_substr( $name, 0, 15 ) .
'...' : $name
606 $jobRunRate = $this->config->get(
'JobRunRate' );
609 $this->
getTitle()->isSpecial(
'RunJobs' ) ||
614 $this->context->getRequest()->getMethod() ===
'HEAD' ||
615 $this->context->getRequest()->getHeader(
'If-Modified-Since' )
621 if ( $jobRunRate < 1 ) {
622 $max = mt_getrandmax();
623 if ( mt_rand( 0, $max ) > $max * $jobRunRate ) {
628 $n = intval( $jobRunRate );
637 $logger = LoggerFactory::getInstance(
'runJobs' );
638 if ( $this->config->get(
'RunJobsAsync' ) ) {
640 $invokedWithSuccess = $this->triggerAsyncJobs( $n, $logger );
641 if ( !$invokedWithSuccess ) {
643 $logger->warning(
"Jobs switched to blocking; Special:RunJobs disabled" );
644 $this->triggerSyncJobs( $n );
647 $this->triggerSyncJobs( $n );
658 self::preOutputCommit( $this->context, $postCommitWork );
678 $services = MediaWikiServices::getInstance();
679 $lbFactory = $services->getDBLoadBalancerFactory();
682 ignore_user_abort(
true );
685 $lbFactory->commitPrimaryChanges(
688 [
'maxWriteDuration' => $config->get(
'MaxUserDBWriteDuration' ) ]
690 wfDebug( __METHOD__ .
': primary transaction round committed' );
693 DeferredUpdates::doUpdates(
'run', DeferredUpdates::PRESEND );
694 wfDebug( __METHOD__ .
': pre-send deferred updates completed' );
697 $request->getSession()->save();
698 wfDebug( __METHOD__ .
': session changes committed' );
704 $isCrossWikiRedirect = (
705 $output->getRedirect() &&
706 $lbFactory->hasOrMadeRecentPrimaryChanges( INF ) &&
707 self::getUrlDomainDistance( $output->getRedirect() ) ===
'remote'
714 $lbFactory->shutdown(
715 $lbFactory::SHUTDOWN_NORMAL,
722 $allowHeaders = !( $output->isDisabled() || headers_sent() );
724 if ( $cpIndex > 0 ) {
725 if ( $allowHeaders ) {
726 $expires = $now + ChronologyProtector::POSITION_COOKIE_TTL;
727 $options = [
'prefix' =>
'' ];
728 $value = $lbFactory::makeCookieValueFromCPIndex( $cpIndex, $now, $cpClientId );
729 $request->response()->setCookie(
'cpPosIndex', $value, $expires, $options );
732 if ( $isCrossWikiRedirect ) {
733 if ( $output->getRedirect() ) {
734 $safeUrl = $lbFactory->appendShutdownCPIndexAsQuery(
735 $output->getRedirect(),
738 $output->redirect( $safeUrl );
740 MWExceptionHandler::logException(
741 new LogicException(
"No redirect; cannot append cpPosIndex parameter." ),
742 MWExceptionHandler::CAUGHT_BY_ENTRYPOINT
748 if ( $allowHeaders ) {
752 if ( $request->wasPosted() && $lbFactory->hasOrMadeRecentPrimaryChanges() ) {
753 $expires = $now + max(
754 ChronologyProtector::POSITION_COOKIE_TTL,
755 $config->get(
'DataCenterUpdateStickTTL' )
757 $options = [
'prefix' =>
'' ];
758 $request->response()->setCookie(
'UseDC',
'master', $expires, $options );
759 $request->response()->setCookie(
'UseCDNCache',
'false', $expires, $options );
764 if ( $lbFactory->laggedReplicaUsed() ) {
765 $maxAge = $config->get(
'CdnMaxageLagged' );
766 $output->lowerCdnMaxage( $maxAge );
767 $request->response()->header(
"X-Database-Lagged: true" );
769 "Lagged DB used; CDN cache TTL limited to $maxAge seconds" );
773 if ( $services->getMessageCache()->isDisabled() ) {
774 $maxAge = $config->get(
'CdnMaxageSubstitute' );
775 $output->lowerCdnMaxage( $maxAge );
776 $request->response()->header(
"X-Response-Substitute: true" );
779 if ( !$output->couldBePublicCached() || $output->haveCacheVaryCookies() ) {
791 $services->getBlockManager()
792 ->trackBlockWithCookie( $user, $request->response() );
802 $clusterWiki = WikiMap::getWikiFromUrl( $url );
803 if ( WikiMap::isCurrentWikiId( $clusterWiki ) ) {
806 if ( $clusterWiki !==
false ) {
824 $timing = $this->context->getTiming();
825 $timing->mark(
'requestShutdown' );
828 if ( $this->postSendStrategy === self::DEFER_FASTCGI_FINISH_REQUEST ) {
830 fastcgi_finish_request();
831 } elseif ( $this->postSendStrategy === self::DEFER_SET_LENGTH_AND_FLUSH ) {
833 if ( ob_get_level() ) {
844 WebResponse::disableForPostSend();
846 ob_start(
static function () {
850 $this->restInPeace();
851 }
catch ( Throwable $e ) {
852 MWExceptionHandler::rollbackPrimaryChangesAndLog(
854 MWExceptionHandler::CAUGHT_BY_ENTRYPOINT
857 $length = ob_get_length();
859 trigger_error( __METHOD__ .
": suppressed $length byte(s)", E_USER_NOTICE );
870 $output = $this->context->getOutput();
871 $request = $this->context->getRequest();
874 if ( $request->getRawVal(
'action' ) ===
'ajax' ) {
876 $title = Title::makeTitle(
NS_SPECIAL,
'Badtitle/performing an AJAX call in '
879 $this->context->setTitle(
$title );
883 $dispatcher->performAction( $this->context->getUser() );
894 $trxLimits = $this->config->get(
'TrxProfilerLimits' );
895 $trxProfiler = Profiler::instance()->getTransactionProfiler();
896 $trxProfiler->setLogger( LoggerFactory::getInstance(
'DBPerformance' ) );
897 if ( $request->hasSafeMethod() ) {
898 $trxProfiler->setExpectations( $trxLimits[
'GET'], __METHOD__ );
900 $trxProfiler->setExpectations( $trxLimits[
'POST'], __METHOD__ );
903 if ( $this->maybeDoHttpsRedirect() ) {
911 $action = $this->getAction();
914 if (
$cache->isCacheGood( ) ) {
916 $timestamp =
$cache->cacheTimestamp();
917 if ( !$output->checkLastModified( $timestamp ) ) {
918 $cache->loadFromFileCache( $this->context );
922 $this->context->getWikiPage()->doViewUpdates( $this->context->getUser() );
932 $this->performRequest();
936 $output->considerCacheSettingsFinal();
944 $outputWork =
static function () use ( $output, &$buffer ) {
945 if ( $buffer ===
null ) {
946 $buffer = $output->output(
true );
955 $this->doPreOutputCommit( $outputWork );
957 $this->schedulePostSendJobs();
959 $this->outputResponsePayload( $outputWork() );
969 $request = $this->context->getRequest();
972 if ( $request->getProtocol() !==
'http' ) {
976 $force = $this->config->get(
'ForceHTTPS' );
982 throw new RuntimeException(
'$wgForceHTTPS is true but the server is not HTTPS' );
993 return $request->getSession()->shouldForceHTTPS() ||
995 $request->getCookie(
'forceHTTPS',
'' ) ||
998 $this->context->getUser()->isRegistered()
999 && $this->context->getUser()->requiresHTTPS()
1013 if ( !$this->shouldDoHttpRedirect() ) {
1017 $request = $this->context->getRequest();
1018 $oldUrl = $request->getFullRequestURL();
1019 $redirUrl = preg_replace(
'#^http://#',
'https://', $oldUrl );
1021 if ( $request->wasPosted() ) {
1030 wfDebugLog(
'RedirectedPosts',
"Redirected from HTTP to HTTPS: $oldUrl" );
1034 $this->context->setTitle(
$title );
1036 $output = $this->context->getOutput();
1037 $output->addVaryHeader(
'X-Forwarded-Proto' );
1038 $output->redirect( $redirUrl );
1057 Profiler::instance()->logDataPageOutputOnly();
1072 if ( function_exists(
'apache_setenv' ) ) {
1074 @apache_setenv(
'no-gzip', 1 );
1079 $this->postSendStrategy === self::DEFER_SET_LENGTH_AND_FLUSH &&
1081 in_array( http_response_code(), [ 200, 404 ],
true ) &&
1083 DeferredUpdates::pendingUpdatesCount() &&
1085 ob_get_level() <= 1 &&
1089 $response = $this->context->getRequest()->response();
1091 $obStatus = ob_get_status();
1092 if ( !isset( $obStatus[
'name'] ) ) {
1094 $response->header(
'Content-Length: ' . strlen(
$content ) );
1095 } elseif ( $obStatus[
'name'] ===
'default output handler' ) {
1098 $response->header(
'Content-Length: ' . ( ob_get_length() + strlen(
$content ) ) );
1110 if ( ( $_SERVER[
'SERVER_PROTOCOL'] ??
'' ) ===
'HTTP/1.1' ) {
1111 $response->header(
'Connection: close' );
1127 ignore_user_abort(
true );
1129 $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
1131 $lbFactory->commitPrimaryChanges( __METHOD__ );
1134 $trxProfiler = Profiler::instance()->getTransactionProfiler();
1135 $trxProfiler->redefineExpectations(
1136 $this->context->getRequest()->hasSafeMethod()
1137 ? $this->config->get(
'TrxProfilerLimits' )[
'PostSend-GET']
1138 : $this->config->get(
'TrxProfilerLimits' )[
'PostSend-POST'],
1143 DeferredUpdates::doUpdates(
'run' );
1149 $lbFactory->commitPrimaryChanges( __METHOD__ );
1150 $lbFactory->shutdown( $lbFactory::SHUTDOWN_NO_CHRONPROT );
1152 wfDebug(
"Request ended normally" );
1166 if ( $config->
get(
'StatsdServer' ) && $stats->
hasData() ) {
1168 $statsdServer = explode(
':', $config->
get(
'StatsdServer' ), 2 );
1169 $statsdHost = $statsdServer[0];
1170 $statsdPort = $statsdServer[1] ?? 8125;
1171 $statsdSender =
new SocketSender( $statsdHost, $statsdPort );
1173 $statsdClient->setSamplingRates( $config->
get(
'StatsdSamplingRates' ) );
1174 $statsdClient->send( $stats->
getData() );
1177 }
catch ( Exception $e ) {
1178 MWExceptionHandler::logException( $e, MWExceptionHandler::CAUGHT_BY_ENTRYPOINT );
1187 $scope = Profiler::instance()->getTransactionProfiler()->silenceForScope();
1188 $runner = MediaWikiServices::getInstance()->getJobRunner();
1189 $runner->run( [
'maxJobs' => $n ] );
1190 ScopedCallback::consume( $scope );
1199 $services = MediaWikiServices::getInstance();
1201 $group = $services->getJobQueueGroupFactory()->makeJobQueueGroup();
1202 if ( !$group->queuesHaveJobs( JobQueueGroup::TYPE_DEFAULT ) ) {
1206 $query = [
'title' =>
'Special:RunJobs',
1207 'tasks' =>
'jobs',
'maxjobs' => $n,
'sigexpiry' => time() + 5 ];
1209 $query, $this->config->get(
'SecretKey' ) );
1211 $errno = $errstr =
null;
1212 $info =
wfParseUrl( $this->config->get(
'CanonicalServer' ) );
1213 $host = $info ? $info[
'host'] :
null;
1215 if ( isset( $info[
'scheme'] ) && $info[
'scheme'] ==
'https' ) {
1216 $host =
"tls://" . $host;
1219 if ( isset( $info[
'port'] ) ) {
1220 $port = $info[
'port'];
1223 Wikimedia\suppressWarnings();
1224 $sock = $host ? fsockopen(
1232 Wikimedia\restoreWarnings();
1234 $invokedWithSuccess =
true;
1236 $special = $services->getSpecialPageFactory()->getPage(
'RunJobs' );
1237 $url = $special->getPageTitle()->getCanonicalURL( $query );
1239 "POST $url HTTP/1.1\r\n" .
1240 "Host: {$info['host']}\r\n" .
1241 "Connection: Close\r\n" .
1242 "Content-Length: 0\r\n\r\n"
1245 $runJobsLogger->info(
"Running $n job(s) via '$url'" );
1248 stream_set_timeout( $sock, 2 );
1249 $bytes = fwrite( $sock, $req );
1250 if ( $bytes !== strlen( $req ) ) {
1251 $invokedWithSuccess =
false;
1252 $runJobsLogger->error(
"Failed to start cron API (socket write error)" );
1256 $start = microtime(
true );
1257 $status = fgets( $sock );
1258 $sec = microtime(
true ) - $start;
1259 if ( !preg_match(
'#^HTTP/\d\.\d 202 #', $status ) ) {
1260 $invokedWithSuccess =
false;
1261 $runJobsLogger->error(
"Failed to start cron API: received '$status' ($sec)" );
1266 $invokedWithSuccess =
false;
1267 $runJobsLogger->error(
"Failed to start cron API (socket error $errno): $errstr" );
1270 return $invokedWithSuccess;
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfParseUrl( $url)
parse_url() work-alike, but non-broken.
wfWarn( $msg, $callerOffset=1, $level=E_USER_NOTICE)
Send a warning either to the debug log or in a PHP error depending on $wgDevelopmentWarnings.
wfReadOnly()
Check whether the wiki is in read-only mode.
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
if(ini_get('mbstring.func_overload')) if(!defined('MW_ENTRY_POINT'))
Pre-config setup: Before loading LocalSettings.php.
Actions are things which can be done to pages (edit, delete, rollback, etc).
Object-Oriented Ajax functions.
Class for viewing MediaWiki article and history.
Show an error page on a badtitle.
Similar to FauxRequest, but only fakes URL parameters and method (POST or GET) and use the base reque...
An error page which can definitely be safely rendered using the OutputPage.
report( $action=self::SEND_OUTPUT)
Page view caching in the file system.
static useFileCache(IContextSource $context, $mode=self::MODE_NORMAL)
Check if pages can be cached for this request/user.
Show an error that looks like an HTTP server error.
static getHTML(Throwable $e)
If $wgShowExceptionDetails is true, return a HTML message with a backtrace to the error,...
Show an error when a user tries to do something they do not have the necessary permissions for.
Shortcut to construct a special page alias.
A statsd client that applies the sampling rate to the data items before sending them.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
static getQuerySignature(array $query, $secretKey)
Represents a title within MediaWiki.
Deferrable update that must run outside of any explicit LBFactory transaction round.
Special handling for file pages.
while(( $__line=Maintenance::readconsole()) !==false) print
Interface for configuration instances.
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
MediaWiki adaptation of StatsdDataFactory that provides buffering functionality.
hasData()
Check whether this data factory has any buffered data.
clearData()
Clear all buffered data from the factory.
getData()
Return the buffered data from the factory.
Interface for objects which can provide a MediaWiki context on request.
getConfig()
Get the site configuration.
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.