81 protected $sessionId = null;
84 $this->requestTime = isset( $_SERVER[
'REQUEST_TIME_FLOAT'] )
85 ? $_SERVER[
'REQUEST_TIME_FLOAT'] : microtime(
true );
89 $this->
data = $_POST + $_GET;
113 if ( !empty( $_SERVER[
'REQUEST_URI'] ) ) {
115 $url = $_SERVER[
'REQUEST_URI'];
116 if ( !preg_match(
'!^https?://!', $url ) ) {
117 $url =
'http://unused' . $url;
119 MediaWiki\suppressWarnings();
120 $a = parse_url( $url );
121 MediaWiki\restoreWarnings();
123 $path = isset( $a[
'path'] ) ? $a[
'path'] :
'';
126 if (
$path == $wgScript && $want !==
'all' ) {
135 $router->
add(
"$wgScript/$1" );
137 if ( isset( $_SERVER[
'SCRIPT_NAME'] )
138 && preg_match(
'/\.php5?/', $_SERVER[
'SCRIPT_NAME'] )
140 # Check for SCRIPT_NAME, we handle index.php explicitly
141 # But we do have some other .php files such as img_auth.php
142 # Don't let root article paths clober the parsing for them
143 $router->add( $_SERVER[
'SCRIPT_NAME'] .
"/$1" );
147 if ( $wgArticlePath ) {
148 $router->add( $wgArticlePath );
152 if ( $wgActionPaths ) {
153 $router->add( $wgActionPaths, [
'action' =>
'$key' ] );
157 if ( $wgVariantArticlePath ) {
158 $router->add( $wgVariantArticlePath,
159 [
'variant' =>
'$2' ],
160 [
'$2' => $wgContLang->getVariants() ]
164 Hooks::run(
'WebRequestPathInfoRouter', [ $router ] );
168 } elseif ( $wgUsePathInfo ) {
169 if ( isset( $_SERVER[
'ORIG_PATH_INFO'] ) && $_SERVER[
'ORIG_PATH_INFO'] !=
'' ) {
173 $matches[
'title'] = substr( $_SERVER[
'ORIG_PATH_INFO'], 1 );
175 } elseif ( isset( $_SERVER[
'PATH_INFO'] ) && $_SERVER[
'PATH_INFO'] !=
'' ) {
177 $matches[
'title'] = substr( $_SERVER[
'PATH_INFO'], 1 );
193 $proto = self::detectProtocol();
194 $stdPort = $proto ===
'https' ? 443 : 80;
196 $varNames = [
'HTTP_HOST',
'SERVER_NAME',
'HOSTNAME',
'SERVER_ADDR' ];
199 foreach ( $varNames
as $varName ) {
200 if ( !isset( $_SERVER[$varName] ) ) {
211 if ( $wgAssumeProxiesUseDefaultProtocolPorts && isset( $_SERVER[
'HTTP_X_FORWARDED_PROTO'] ) ) {
216 } elseif ( $parts[1] ===
false ) {
217 if ( isset( $_SERVER[
'SERVER_PORT'] ) ) {
218 $port = $_SERVER[
'SERVER_PORT'];
237 if ( ( !empty( $_SERVER[
'HTTPS'] ) && $_SERVER[
'HTTPS'] !==
'off' ) ||
238 ( isset( $_SERVER[
'HTTP_X_FORWARDED_PROTO'] ) &&
239 $_SERVER[
'HTTP_X_FORWARDED_PROTO'] ===
'https' ) ) {
266 if ( !self::$reqId ) {
267 self::$reqId = isset( $_SERVER[
'UNIQUE_ID'] )
290 if ( $this->protocol === null ) {
291 $this->protocol = self::detectProtocol();
305 if ( defined(
'MW_API' ) ) {
309 $matches = self::getPathInfo(
'title' );
329 $baseLen = strlen(
$base );
330 if ( substr(
$path, 0, $baseLen ) ==
$base ) {
331 $raw = substr(
$path, $baseLen );
333 $matches = [
'title' => rawurldecode( $raw ) ];
352 if ( is_array(
$data ) ) {
358 $data = isset( $wgContLang ) ?
359 $wgContLang->normalize(
$data ) :
360 UtfNormal\Validator::cleanUp(
$data );
374 # PHP is so nice to not touch input data, except sometimes:
375 # http://us2.php.net/variables.external#language.variables.external.dot-in-names
376 # Work around PHP *feature* to avoid *bugs* elsewhere.
378 if ( isset( $arr[
$name] ) ) {
381 if ( isset( $_GET[$name] ) && !is_array(
$data ) ) {
382 # Check for alternate/legacy character encoding.
383 if ( isset( $wgContLang ) ) {
384 $data = $wgContLang->checkTitleEncoding(
$data );
406 if ( is_array( $val ) ) {
409 if ( is_null( $val ) ) {
436 if ( !isset( $this->
data[
$key] ) ) {
440 unset( $this->
data[$key] );
456 if ( is_null( $val ) ) {
475 if ( is_array( $val ) ) {
476 $val = array_map(
'intval', $val );
504 return is_numeric( $val )
520 return floatval( $this->
getVal(
$name, $default ) );
558 # Checkboxes and buttons are only present when clicked
559 # Presence connotes truth, absence false
578 return str_replace(
"\r\n",
"\n",
579 $wgContLang->recodeInput( $val ) );
590 $names = func_get_args();
591 if ( count( $names ) == 0 ) {
592 $names = array_keys( $this->
data );
598 if ( !is_null(
$value ) ) {
612 return array_diff( array_keys( $this->
getValues() ), $exclude );
632 return $_SERVER[
'QUERY_STRING'];
656 static $input = null;
657 if ( $input === null ) {
658 $input = file_get_contents(
'php://input' );
669 return isset( $_SERVER[
'REQUEST_METHOD'] ) ? $_SERVER[
'REQUEST_METHOD'] :
'GET';
693 if ( $this->sessionId !== null ) {
694 $session = SessionManager::singleton()->getSessionById( (
string)$this->sessionId,
true, $this );
700 $session = SessionManager::singleton()->getSessionForRequest( $this );
701 $this->sessionId = $session->getSessionId();
737 return $wgInitialSessionId !== null &&
750 if ( $prefix === null ) {
754 return $this->
getGPCVal( $_COOKIE, $prefix .
$key, $default );
765 if ( isset( $_SERVER[
'REQUEST_URI'] ) && strlen( $_SERVER[
'REQUEST_URI'] ) ) {
766 $base = $_SERVER[
'REQUEST_URI'];
767 } elseif ( isset( $_SERVER[
'HTTP_X_ORIGINAL_URL'] )
768 && strlen( $_SERVER[
'HTTP_X_ORIGINAL_URL'] )
771 $base = $_SERVER[
'HTTP_X_ORIGINAL_URL'];
772 } elseif ( isset( $_SERVER[
'SCRIPT_NAME'] ) ) {
773 $base = $_SERVER[
'SCRIPT_NAME'];
774 if ( isset( $_SERVER[
'QUERY_STRING'] ) && $_SERVER[
'QUERY_STRING'] !=
'' ) {
775 $base .=
'?' . $_SERVER[
'QUERY_STRING'];
779 throw new MWException(
"Web server doesn't provide either " .
780 "REQUEST_URI, HTTP_X_ORIGINAL_URL or SCRIPT_NAME. Report details " .
781 "of your web server configuration to https://phabricator.wikimedia.org/" );
787 $hash = strpos(
$base,
'#' );
788 if ( $hash !==
false ) {
792 if (
$base[0] ==
'/' ) {
794 return preg_replace(
'!^/+!',
'/',
$base );
797 return preg_replace(
'!^[^:]+://[^/]+/+!',
'/',
$base );
809 return self::getGlobalRequestURL();
843 unset( $newquery[
'title'] );
844 $newquery = array_merge( $newquery, $array );
865 if ( (
$limit == 0 ) && ( $optionname !=
'' ) ) {
866 $limit = $wgUser->getIntOption( $optionname );
875 $offset = $this->
getInt(
'offset', 0 );
880 return [
$limit, $offset ];
891 return $file->getTempName();
902 return $file->getError();
918 return $file->getName();
939 if ( !is_object( $this->
response ) ) {
940 $class = ( $this instanceof
FauxRequest ) ?
'FauxResponse' :
'WebResponse';
950 if ( count( $this->
headers ) ) {
954 $apacheHeaders = function_exists(
'apache_request_headers' ) ? apache_request_headers() :
false;
955 if ( $apacheHeaders ) {
956 foreach ( $apacheHeaders
as $tempName => $tempValue ) {
957 $this->
headers[strtoupper( $tempName )] = $tempValue;
961 if ( substr(
$name, 0, 5 ) ===
'HTTP_' ) {
962 $name = str_replace(
'_',
'-', substr(
$name, 5 ) );
964 } elseif (
$name ===
'CONTENT_LENGTH' ) {
1000 if (
$flags & self::GETHEADER_LIST ) {
1039 $extWhitelist[] =
'php';
1044 if ( $newUrl !==
false ) {
1050 'Invalid file extension found in the path info or query string.' );
1063 header(
'Location: ' . $url );
1064 header(
'Content-Type: text/html' );
1065 $encUrl = htmlspecialchars( $url );
1074 We can
't serve non-HTML content from the URL you have requested, because
1075 Internet Explorer would interpret it as an incorrect and potentially dangerous
1077 <p>Instead, please use <a href="$encUrl">this URL</a>, which is the same as the
1078 URL you have requested, except that "&*" is appended. This prevents Internet
1079 Explorer from seeing a bogus file extension.
1097 public function getAcceptLang() {
1098 // Modified version of code found at
1099 // http://www.thefutureoftheweb.com/blog/use-accept-language-header
1100 $acceptLang = $this->getHeader( 'Accept-
Language' );
1101 if ( !$acceptLang ) {
1105 // Return the language codes in lower case
1106 $acceptLang = strtolower( $acceptLang );
1108 // Break up string into pieces (languages and q factors)
1111 '/([a-z]{1,8}(-[a-z]{1,8})*|\*)\s*(;\s*q\s*=\s*(1(\.0{0,3})?|0(\.[0-9]{0,3})?)?)?/
',
1116 if ( !count( $lang_parse[1] ) ) {
1120 $langcodes = $lang_parse[1];
1121 $qvalues = $lang_parse[4];
1122 $indices = range( 0, count( $lang_parse[1] ) - 1 );
1124 // Set default q factor to 1
1125 foreach ( $indices as $index ) {
1126 if ( $qvalues[$index] === '' ) {
1127 $qvalues[$index] = 1;
1128 } elseif ( $qvalues[$index] == 0 ) {
1129 unset( $langcodes[$index], $qvalues[$index], $indices[$index] );
1133 // Sort list. First by $qvalues, then by order. Reorder $langcodes the same way
1134 array_multisort( $qvalues, SORT_DESC, SORT_NUMERIC, $indices, $langcodes );
1136 // Create a list like "en" => 0.8
1137 $langs = array_combine( $langcodes, $qvalues );
1150 protected function getRawIP() {
1151 if ( !isset( $_SERVER['REMOTE_ADDR
'] ) ) {
1155 if ( is_array( $_SERVER['REMOTE_ADDR
'] ) || strpos( $_SERVER['REMOTE_ADDR
'], ',
' ) !== false ) {
1156 throw new MWException( __METHOD__
1157 . " : Could not determine the remote IP address due to multiple values." );
1159 $ipchain = $_SERVER['REMOTE_ADDR
'];
1162 return IP::canonicalize( $ipchain );
1174 public function getIP() {
1175 global $wgUsePrivateIPs;
1177 # Return cached result
1178 if ( $this->ip !== null ) {
1182 # collect the originating ips
1183 $ip = $this->getRawIP();
1185 throw new MWException( 'Unable to determine
IP.
' );
1189 $forwardedFor = $this->getHeader( 'X-Forwarded-For
' );
1190 if ( $forwardedFor !== false ) {
1191 $isConfigured = IP::isConfiguredProxy( $ip );
1192 $ipchain = array_map( 'trim
', explode( ',
', $forwardedFor ) );
1193 $ipchain = array_reverse( $ipchain );
1194 array_unshift( $ipchain, $ip );
1196 # Step through XFF list and find the last address in the list which is a
1197 # trusted server. Set $ip to the IP address given by that trusted server,
1198 # unless the address is not sensible (e.g. private). However, prefer private
1199 # IP addresses over proxy servers controlled by this site (more sensible).
1200 # Note that some XFF values might be "unknown" with Squid/Varnish.
1201 foreach ( $ipchain as $i => $curIP ) {
1202 $curIP = IP::sanitizeIP( IP::canonicalize( $curIP ) );
1203 if ( !$curIP || !isset( $ipchain[$i + 1] ) || $ipchain[$i + 1] === 'unknown
'
1204 || !IP::isTrustedProxy( $curIP )
1206 break; // IP is not valid/trusted or does not point to anything
1209 IP::isPublic( $ipchain[$i + 1] ) ||
1211 IP::isConfiguredProxy( $curIP ) // bug 48919; treat IP as sane
1213 // Follow the next IP according to the proxy
1214 $nextIP = IP::canonicalize( $ipchain[$i + 1] );
1215 if ( !$nextIP && $isConfigured ) {
1216 // We have not yet made it past CDN/proxy servers of this site,
1217 // so either they are misconfigured or there is some IP spoofing.
1218 throw new MWException( "Invalid IP given in XFF '$forwardedFor
'." );
1221 // keep traversing the chain
1228 # Allow extensions to improve our guess
1229 Hooks::run( 'GetIP
', [ &$ip ] );
1232 throw new MWException( "Unable to determine IP." );
1235 wfDebug( "IP: $ip\n" );
1245 public function setIP( $ip ) {
and how to run hooks for an and one after Each event has a preferably in CamelCase For ArticleDelete hook A clump of code and data that should be run when an event happens This can be either a function and a chunk of data
float $requestTime
The timestamp of the start of the request, with microsecond precision.
the array() calling protocol came about after MediaWiki 1.4rc1.
getUploadError($key)
Return the upload error or 0.
getRawPostString()
Return the contents of the POST with no decoding.
$wgScript
The URL path to index.php.
magic word the default is to use $key to get the and $key value or $key value text $key value html to format the value $key
I won t presume to tell you how to I m just describing the methods I chose to use for myself If you do choose to follow these it will probably be easier for you to collaborate with others on the but if you want to contribute without by all means do which work well I also use K &R brace matching style I know that s a religious issue for some
static getRequestId()
Get the unique request ID.
getFileTempname($key)
Return the path to the temporary file where PHP has stored the upload.
getFullRequestURL()
Return the request URI with the canonical service and hostname, path, and query string.
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses & $ret
static areServerVarsBad($vars, $extWhitelist=[])
Check a subset of $_SERVER (or the whole of $_SERVER if you like) to see if it indicates that the req...
response()
Return a handle to WebResponse style object, for setting cookies, headers and other stuff...
getUpload($key)
Return a WebRequestUpload object corresponding to the key.
getIntOrNull($name)
Fetch an integer value from the input or return null if empty.
string $protocol
Cached URL protocol.
getFuzzyBool($name, $default=false)
Fetch a boolean value from the input or return $default if not set.
This code would result in ircNotify being run twice when an article is and once for brion Hooks can return three possible true was required This is the default since MediaWiki *some string
getBool($name, $default=false)
Fetch a boolean value from the input or return $default if not set.
getGPCVal($arr, $name, $default)
Fetch a value from the given array or return $default if it's not set.
it s the revision text itself In either if gzip is the revision text is gzipped $flags
const GETHEADER_LIST
Flag to make WebRequest::getHeader return an array of values.
getSession()
Return the session for this request.
when a variable name is used in a it is silently declared as a new local masking the global
wfExpandUrl($url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
add($path, $params=[], $options=[])
Add a new path pattern to the path router.
initHeaders()
Initialise the header list.
string $ip
Cached client IP address.
wfRandomString($length=32)
Get a random string containing a number of pseudo-random hex characters.
doSecurityRedirect($url)
Attempt to redirect to a URL with a QUERY_STRING that's not dangerous in IE 6.
getArray($name, $default=null)
Fetch an array from the input or return $default if it's not set.
Show an error that looks like an HTTP server error.
getAllHeaders()
Get an array containing all request headers.
static detectServer()
Work out an appropriate URL prefix containing scheme and host, based on information detected from $_S...
setVal($key, $value)
Set an arbitrary value into our get/post data.
getHeader($name, $flags=0)
Get a request header, or false if it isn't set.
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add headers
getFloat($name, $default=0.0)
Fetch a floating point value from the input or return $default if not set.
getProtocol()
Get the current URL protocol (http or https)
wasPosted()
Returns true if the present request was reached by a POST operation, false otherwise (GET...
getRequestURL()
Return the path and query string portion of the request URI.
static combineHostAndPort($host, $port, $defaultPort=false)
Given a host name and a port, combine them into host/port string like you might find in a URL...
getSessionData($key)
Get data from the session.
getQueryValues()
Get the values passed in the query string.
unsetVal($key)
Unset an arbitrary value from our get/post data.
getCheck($name)
Return true if the named value is set in the input, whatever that value is (even "0").
$wgUsePathInfo
Whether to support URLs like index.php/Page_title These often break when PHP is set up in CGI mode...
getFileName($key)
Return the original filename of the uploaded file, as reported by the submitting user agent...
bool $wgAssumeProxiesUseDefaultProtocolPorts
When the wiki is running behind a proxy and this is set to true, assumes that the proxy exposes the w...
wfDeprecated($function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
static run($event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
static overrideRequestId($id)
Override the unique request ID.
getValueNames($exclude=[])
Returns the names of all input values excluding those in $exclude.
static detectProtocol()
Detect the protocol from $_SERVER.
getSessionId()
Get the session id for this request, if any.
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
getIntArray($name, $default=null)
Fetch an array of integers, or return $default if it's not set.
getValues()
Extracts the given named values into an array.
setSessionId(SessionId $sessionId)
Set the session for this request.
WebResponse $response
Lazy-init response object.
getVal($name, $default=null)
Fetch a scalar from the input or return $default if it's not set.
static splitHostAndPort($both)
Given a host/port string, like one might find in the host part of a URL per RFC 2732, split the hostname part and the port part and return an array with an element for each.
SessionId null $sessionId
Session ID to use for this request.
A collection of public static functions to play with IP address and IP blocks.
static getGlobalRequestURL()
Return the path and query string portion of the main request URI.
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
if($wgLocalInterwiki) if($wgSharedPrefix===false) if($wgSharedSchema===false) if(!$wgCookiePrefix) $wgCookiePrefix
getMethod()
Get the HTTP method used for this request.
appendQueryValue($key, $value)
wfArrayToCgi($array1, $array2=null, $prefix= '')
This function takes one or two arrays as input, and returns a CGI-style string, e.g.
static extractTitle($path, $bases, $key=false)
URL rewriting function; tries to extract page title and, optionally, one other fixed parameter value ...
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context the output can only depend on parameters provided to this hook not on global state indicating whether full HTML should be generated If generation of HTML may be but other information should still be present in the ParserOutput object to manipulate or replace but no entry for that model exists in $wgContentHandlers if desired whether it is OK to use $contentModel on $title Handler functions that modify $ok should generally return false to prevent further hooks from further modifying $ok inclusive $limit
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the local content language as $wgContLang
getRawInput()
Return the raw request body, with no processing.
interpolateTitle()
Check for title, action, and/or variant data in the URL and interpolate it into the GET variables...
This list may contain false positives That usually means there is additional text with links below the first Each row contains links to the first and second redirect
checkSessionCookie()
Returns true if the request has a persistent session.
getCookie($key, $prefix=null, $default=null)
Get a cookie from the $_COOKIE jar.
static getPathInfo($want= 'all')
Extract relevant query arguments from the http request uri's path to be merged with the normal php pr...
checkUrlExtension($extWhitelist=[])
Check if Internet Explorer will detect an incorrect cache extension in PATH_INFO or QUERY_STRING...
setSessionData($key, $data)
Set session data.
static string $reqId
The unique request ID.
getInt($name, $default=0)
Fetch an integer value from the input or return $default if not set.
appendQueryArray($array)
Appends or replaces value of query variables.
getElapsedTime()
Get the number of seconds to have elapsed since request start, in fractional seconds, with microsecond resolution.
$wgVariantArticlePath
Like $wgArticlePath, but on multi-variant wikis, this provides a path format that describes which par...
getLimitOffset($deflimit=50, $optionname= 'rclimit')
Check for limit and offset parameters on the input, and return sensible defaults if not given...
normalizeUnicode($data)
Recursively normalizes UTF-8 strings in the given array.
Object to access the $_FILES array.
getText($name, $default= '')
Fetch a text string from the given array or return $default if it's not set.
getRawQueryString()
Return the contents of the Query with no decoding.
static fixUrlForIE6($url, $extWhitelist=[])
Returns a variant of $url which will pass isUrlExtensionBad() but has the same GET parameters...
Allows to change the fields on the form that will be generated $name