MediaWiki REL1_27
WebRequest.php
Go to the documentation of this file.
1<?php
29
38 protected $data, $headers = [];
39
44 const GETHEADER_LIST = 1;
45
50 private static $reqId;
51
56 private $response;
57
62 private $ip;
63
68 protected $requestTime;
69
74 protected $protocol;
75
81 protected $sessionId = null;
82
83 public function __construct() {
84 $this->requestTime = isset( $_SERVER['REQUEST_TIME_FLOAT'] )
85 ? $_SERVER['REQUEST_TIME_FLOAT'] : microtime( true );
86
87 // POST overrides GET data
88 // We don't use $_REQUEST here to avoid interference from cookies...
89 $this->data = $_POST + $_GET;
90 }
91
107 public static function getPathInfo( $want = 'all' ) {
109 // PATH_INFO is mangled due to http://bugs.php.net/bug.php?id=31892
110 // And also by Apache 2.x, double slashes are converted to single slashes.
111 // So we will use REQUEST_URI if possible.
112 $matches = [];
113 if ( !empty( $_SERVER['REQUEST_URI'] ) ) {
114 // Slurp out the path portion to examine...
115 $url = $_SERVER['REQUEST_URI'];
116 if ( !preg_match( '!^https?://!', $url ) ) {
117 $url = 'http://unused' . $url;
118 }
119 MediaWiki\suppressWarnings();
120 $a = parse_url( $url );
121 MediaWiki\restoreWarnings();
122 if ( $a ) {
123 $path = isset( $a['path'] ) ? $a['path'] : '';
124
126 if ( $path == $wgScript && $want !== 'all' ) {
127 // Script inside a rewrite path?
128 // Abort to keep from breaking...
129 return $matches;
130 }
131
132 $router = new PathRouter;
133
134 // Raw PATH_INFO style
135 $router->add( "$wgScript/$1" );
136
137 if ( isset( $_SERVER['SCRIPT_NAME'] )
138 && preg_match( '/\.php5?/', $_SERVER['SCRIPT_NAME'] )
139 ) {
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" );
144 }
145
147 if ( $wgArticlePath ) {
148 $router->add( $wgArticlePath );
149 }
150
152 if ( $wgActionPaths ) {
153 $router->add( $wgActionPaths, [ 'action' => '$key' ] );
154 }
155
157 if ( $wgVariantArticlePath ) {
158 $router->add( $wgVariantArticlePath,
159 [ 'variant' => '$2' ],
160 [ '$2' => $wgContLang->getVariants() ]
161 );
162 }
163
164 Hooks::run( 'WebRequestPathInfoRouter', [ $router ] );
165
166 $matches = $router->parse( $path );
167 }
168 } elseif ( $wgUsePathInfo ) {
169 if ( isset( $_SERVER['ORIG_PATH_INFO'] ) && $_SERVER['ORIG_PATH_INFO'] != '' ) {
170 // Mangled PATH_INFO
171 // http://bugs.php.net/bug.php?id=31892
172 // Also reported when ini_get('cgi.fix_pathinfo')==false
173 $matches['title'] = substr( $_SERVER['ORIG_PATH_INFO'], 1 );
174
175 } elseif ( isset( $_SERVER['PATH_INFO'] ) && $_SERVER['PATH_INFO'] != '' ) {
176 // Regular old PATH_INFO yay
177 $matches['title'] = substr( $_SERVER['PATH_INFO'], 1 );
178 }
179 }
180
181 return $matches;
182 }
183
190 public static function detectServer() {
192
193 $proto = self::detectProtocol();
194 $stdPort = $proto === 'https' ? 443 : 80;
195
196 $varNames = [ 'HTTP_HOST', 'SERVER_NAME', 'HOSTNAME', 'SERVER_ADDR' ];
197 $host = 'localhost';
198 $port = $stdPort;
199 foreach ( $varNames as $varName ) {
200 if ( !isset( $_SERVER[$varName] ) ) {
201 continue;
202 }
203
204 $parts = IP::splitHostAndPort( $_SERVER[$varName] );
205 if ( !$parts ) {
206 // Invalid, do not use
207 continue;
208 }
209
210 $host = $parts[0];
211 if ( $wgAssumeProxiesUseDefaultProtocolPorts && isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) {
212 // Bug 70021: Assume that upstream proxy is running on the default
213 // port based on the protocol. We have no reliable way to determine
214 // the actual port in use upstream.
215 $port = $stdPort;
216 } elseif ( $parts[1] === false ) {
217 if ( isset( $_SERVER['SERVER_PORT'] ) ) {
218 $port = $_SERVER['SERVER_PORT'];
219 } // else leave it as $stdPort
220 } else {
221 $port = $parts[1];
222 }
223 break;
224 }
225
226 return $proto . '://' . IP::combineHostAndPort( $host, $port, $stdPort );
227 }
228
236 public static function detectProtocol() {
237 if ( ( !empty( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ) ||
238 ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) &&
239 $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) ) {
240 return 'https';
241 } else {
242 return 'http';
243 }
244 }
245
253 public function getElapsedTime() {
254 return microtime( true ) - $this->requestTime;
255 }
256
265 public static function getRequestId() {
266 if ( !self::$reqId ) {
267 self::$reqId = isset( $_SERVER['UNIQUE_ID'] )
268 ? $_SERVER['UNIQUE_ID'] : wfRandomString( 24 );
269 }
270
271 return self::$reqId;
272 }
273
281 public static function overrideRequestId( $id ) {
282 self::$reqId = $id;
283 }
284
289 public function getProtocol() {
290 if ( $this->protocol === null ) {
291 $this->protocol = self::detectProtocol();
292 }
293 return $this->protocol;
294 }
295
303 public function interpolateTitle() {
304 // bug 16019: title interpolation on API queries is useless and sometimes harmful
305 if ( defined( 'MW_API' ) ) {
306 return;
307 }
308
309 $matches = self::getPathInfo( 'title' );
310 foreach ( $matches as $key => $val ) {
311 $this->data[$key] = $_GET[$key] = $_REQUEST[$key] = $val;
312 }
313 }
314
325 static function extractTitle( $path, $bases, $key = false ) {
326 foreach ( (array)$bases as $keyValue => $base ) {
327 // Find the part after $wgArticlePath
328 $base = str_replace( '$1', '', $base );
329 $baseLen = strlen( $base );
330 if ( substr( $path, 0, $baseLen ) == $base ) {
331 $raw = substr( $path, $baseLen );
332 if ( $raw !== '' ) {
333 $matches = [ 'title' => rawurldecode( $raw ) ];
334 if ( $key ) {
335 $matches[$key] = $keyValue;
336 }
337 return $matches;
338 }
339 }
340 }
341 return [];
342 }
343
351 function normalizeUnicode( $data ) {
352 if ( is_array( $data ) ) {
353 foreach ( $data as $key => $val ) {
354 $data[$key] = $this->normalizeUnicode( $val );
355 }
356 } else {
358 $data = isset( $wgContLang ) ?
359 $wgContLang->normalize( $data ) :
360 UtfNormal\Validator::cleanUp( $data );
361 }
362 return $data;
363 }
364
373 private function getGPCVal( $arr, $name, $default ) {
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.
377 $name = strtr( $name, '.', '_' );
378 if ( isset( $arr[$name] ) ) {
380 $data = $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 );
385 }
386 }
387 $data = $this->normalizeUnicode( $data );
388 return $data;
389 } else {
390 return $default;
391 }
392 }
393
404 public function getVal( $name, $default = null ) {
405 $val = $this->getGPCVal( $this->data, $name, $default );
406 if ( is_array( $val ) ) {
407 $val = $default;
408 }
409 if ( is_null( $val ) ) {
410 return $val;
411 } else {
412 return (string)$val;
413 }
414 }
415
423 public function setVal( $key, $value ) {
424 $ret = isset( $this->data[$key] ) ? $this->data[$key] : null;
425 $this->data[$key] = $value;
426 return $ret;
427 }
428
435 public function unsetVal( $key ) {
436 if ( !isset( $this->data[$key] ) ) {
437 $ret = null;
438 } else {
439 $ret = $this->data[$key];
440 unset( $this->data[$key] );
441 }
442 return $ret;
443 }
444
454 public function getArray( $name, $default = null ) {
455 $val = $this->getGPCVal( $this->data, $name, $default );
456 if ( is_null( $val ) ) {
457 return null;
458 } else {
459 return (array)$val;
460 }
461 }
462
473 public function getIntArray( $name, $default = null ) {
474 $val = $this->getArray( $name, $default );
475 if ( is_array( $val ) ) {
476 $val = array_map( 'intval', $val );
477 }
478 return $val;
479 }
480
490 public function getInt( $name, $default = 0 ) {
491 return intval( $this->getVal( $name, $default ) );
492 }
493
502 public function getIntOrNull( $name ) {
503 $val = $this->getVal( $name );
504 return is_numeric( $val )
505 ? intval( $val )
506 : null;
507 }
508
519 public function getFloat( $name, $default = 0.0 ) {
520 return floatval( $this->getVal( $name, $default ) );
521 }
522
532 public function getBool( $name, $default = false ) {
533 return (bool)$this->getVal( $name, $default );
534 }
535
545 public function getFuzzyBool( $name, $default = false ) {
546 return $this->getBool( $name, $default ) && strcasecmp( $this->getVal( $name ), 'false' ) !== 0;
547 }
548
557 public function getCheck( $name ) {
558 # Checkboxes and buttons are only present when clicked
559 # Presence connotes truth, absence false
560 return $this->getVal( $name, null ) !== null;
561 }
562
575 public function getText( $name, $default = '' ) {
577 $val = $this->getVal( $name, $default );
578 return str_replace( "\r\n", "\n",
579 $wgContLang->recodeInput( $val ) );
580 }
581
589 public function getValues() {
590 $names = func_get_args();
591 if ( count( $names ) == 0 ) {
592 $names = array_keys( $this->data );
593 }
594
595 $retVal = [];
596 foreach ( $names as $name ) {
597 $value = $this->getGPCVal( $this->data, $name, null );
598 if ( !is_null( $value ) ) {
599 $retVal[$name] = $value;
600 }
601 }
602 return $retVal;
603 }
604
611 public function getValueNames( $exclude = [] ) {
612 return array_diff( array_keys( $this->getValues() ), $exclude );
613 }
614
621 public function getQueryValues() {
622 return $_GET;
623 }
624
631 public function getRawQueryString() {
632 return $_SERVER['QUERY_STRING'];
633 }
634
641 public function getRawPostString() {
642 if ( !$this->wasPosted() ) {
643 return '';
644 }
645 return $this->getRawInput();
646 }
647
655 public function getRawInput() {
656 static $input = null;
657 if ( $input === null ) {
658 $input = file_get_contents( 'php://input' );
659 }
660 return $input;
661 }
662
668 public function getMethod() {
669 return isset( $_SERVER['REQUEST_METHOD'] ) ? $_SERVER['REQUEST_METHOD'] : 'GET';
670 }
671
681 public function wasPosted() {
682 return $this->getMethod() == 'POST';
683 }
684
692 public function getSession() {
693 if ( $this->sessionId !== null ) {
694 $session = SessionManager::singleton()->getSessionById( (string)$this->sessionId, true, $this );
695 if ( $session ) {
696 return $session;
697 }
698 }
699
700 $session = SessionManager::singleton()->getSessionForRequest( $this );
701 $this->sessionId = $session->getSessionId();
702 return $session;
703 }
704
711 public function setSessionId( SessionId $sessionId ) {
712 $this->sessionId = $sessionId;
713 }
714
721 public function getSessionId() {
722 return $this->sessionId;
723 }
724
734 public function checkSessionCookie() {
736 wfDeprecated( __METHOD__, '1.27' );
737 return $wgInitialSessionId !== null &&
738 $this->getSession()->getId() === (string)$wgInitialSessionId;
739 }
740
749 public function getCookie( $key, $prefix = null, $default = null ) {
750 if ( $prefix === null ) {
752 $prefix = $wgCookiePrefix;
753 }
754 return $this->getGPCVal( $_COOKIE, $prefix . $key, $default );
755 }
756
764 public static function getGlobalRequestURL() {
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'] )
769 ) {
770 // Probably IIS; doesn't set REQUEST_URI
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'];
776 }
777 } else {
778 // This shouldn't happen!
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/" );
782 }
783 // User-agents should not send a fragment with the URI, but
784 // if they do, and the web server passes it on to us, we
785 // need to strip it or we get false-positive redirect loops
786 // or weird output URLs
787 $hash = strpos( $base, '#' );
788 if ( $hash !== false ) {
789 $base = substr( $base, 0, $hash );
790 }
791
792 if ( $base[0] == '/' ) {
793 // More than one slash will look like it is protocol relative
794 return preg_replace( '!^/+!', '/', $base );
795 } else {
796 // We may get paths with a host prepended; strip it.
797 return preg_replace( '!^[^:]+://[^/]+/+!', '/', $base );
798 }
799 }
800
808 public function getRequestURL() {
809 return self::getGlobalRequestURL();
810 }
811
822 public function getFullRequestURL() {
823 return wfExpandUrl( $this->getRequestURL(), PROTO_CURRENT );
824 }
825
831 public function appendQueryValue( $key, $value ) {
832 return $this->appendQueryArray( [ $key => $value ] );
833 }
834
841 public function appendQueryArray( $array ) {
842 $newquery = $this->getQueryValues();
843 unset( $newquery['title'] );
844 $newquery = array_merge( $newquery, $array );
845
846 return wfArrayToCgi( $newquery );
847 }
848
858 public function getLimitOffset( $deflimit = 50, $optionname = 'rclimit' ) {
860
861 $limit = $this->getInt( 'limit', 0 );
862 if ( $limit < 0 ) {
863 $limit = 0;
864 }
865 if ( ( $limit == 0 ) && ( $optionname != '' ) ) {
866 $limit = $wgUser->getIntOption( $optionname );
867 }
868 if ( $limit <= 0 ) {
869 $limit = $deflimit;
870 }
871 if ( $limit > 5000 ) {
872 $limit = 5000; # We have *some* limits...
873 }
874
875 $offset = $this->getInt( 'offset', 0 );
876 if ( $offset < 0 ) {
877 $offset = 0;
878 }
879
880 return [ $limit, $offset ];
881 }
882
889 public function getFileTempname( $key ) {
890 $file = new WebRequestUpload( $this, $key );
891 return $file->getTempName();
892 }
893
900 public function getUploadError( $key ) {
901 $file = new WebRequestUpload( $this, $key );
902 return $file->getError();
903 }
904
916 public function getFileName( $key ) {
917 $file = new WebRequestUpload( $this, $key );
918 return $file->getName();
919 }
920
927 public function getUpload( $key ) {
928 return new WebRequestUpload( $this, $key );
929 }
930
937 public function response() {
938 /* Lazy initialization of response object for this request */
939 if ( !is_object( $this->response ) ) {
940 $class = ( $this instanceof FauxRequest ) ? 'FauxResponse' : 'WebResponse';
941 $this->response = new $class();
942 }
943 return $this->response;
944 }
945
949 protected function initHeaders() {
950 if ( count( $this->headers ) ) {
951 return;
952 }
953
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;
958 }
959 } else {
960 foreach ( $_SERVER as $name => $value ) {
961 if ( substr( $name, 0, 5 ) === 'HTTP_' ) {
962 $name = str_replace( '_', '-', substr( $name, 5 ) );
963 $this->headers[$name] = $value;
964 } elseif ( $name === 'CONTENT_LENGTH' ) {
965 $this->headers['CONTENT-LENGTH'] = $value;
966 }
967 }
968 }
969 }
970
976 public function getAllHeaders() {
977 $this->initHeaders();
978 return $this->headers;
979 }
980
993 public function getHeader( $name, $flags = 0 ) {
994 $this->initHeaders();
995 $name = strtoupper( $name );
996 if ( !isset( $this->headers[$name] ) ) {
997 return false;
998 }
999 $value = $this->headers[$name];
1000 if ( $flags & self::GETHEADER_LIST ) {
1001 $value = array_map( 'trim', explode( ',', $value ) );
1002 }
1003 return $value;
1004 }
1005
1013 public function getSessionData( $key ) {
1014 return $this->getSession()->get( $key );
1015 }
1016
1024 public function setSessionData( $key, $data ) {
1025 return $this->getSession()->set( $key, $data );
1026 }
1027
1038 public function checkUrlExtension( $extWhitelist = [] ) {
1039 $extWhitelist[] = 'php';
1040 if ( IEUrlExtension::areServerVarsBad( $_SERVER, $extWhitelist ) ) {
1041 if ( !$this->wasPosted() ) {
1043 $this->getFullRequestURL(), $extWhitelist );
1044 if ( $newUrl !== false ) {
1045 $this->doSecurityRedirect( $newUrl );
1046 return false;
1047 }
1048 }
1049 throw new HttpError( 403,
1050 'Invalid file extension found in the path info or query string.' );
1051 }
1052 return true;
1053 }
1054
1062 protected function doSecurityRedirect( $url ) {
1063 header( 'Location: ' . $url );
1064 header( 'Content-Type: text/html' );
1065 $encUrl = htmlspecialchars( $url );
1066 echo <<<HTML
1067<html>
1068<head>
1069<title>Security redirect</title>
1070</head>
1071<body>
1072<h1>Security redirect</h1>
1073<p>
1074We can't serve non-HTML content from the URL you have requested, because
1075Internet Explorer would interpret it as an incorrect and potentially dangerous
1076content type.</p>
1077<p>Instead, please use <a href="$encUrl">this URL</a>, which is the same as the
1078URL you have requested, except that "&amp;*" is appended. This prevents Internet
1079Explorer from seeing a bogus file extension.
1080</p>
1081</body>
1082</html>
1083HTML;
1084 echo "\n";
1085 return true;
1086 }
1087
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 ) {
1102 return [];
1103 }
1104
1105 // Return the language codes in lower case
1106 $acceptLang = strtolower( $acceptLang );
1107
1108 // Break up string into pieces (languages and q factors)
1109 $lang_parse = null;
1110 preg_match_all(
1111 '/([a-z]{1,8}(-[a-z]{1,8})*|\*)\s*(;\s*q\s*=\s*(1(\.0{0,3})?|0(\.[0-9]{0,3})?)?)?/',
1112 $acceptLang,
1113 $lang_parse
1114 );
1115
1116 if ( !count( $lang_parse[1] ) ) {
1117 return [];
1118 }
1119
1120 $langcodes = $lang_parse[1];
1121 $qvalues = $lang_parse[4];
1122 $indices = range( 0, count( $lang_parse[1] ) - 1 );
1123
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] );
1130 }
1131 }
1132
1133 // Sort list. First by $qvalues, then by order. Reorder $langcodes the same way
1134 array_multisort( $qvalues, SORT_DESC, SORT_NUMERIC, $indices, $langcodes );
1135
1136 // Create a list like "en" => 0.8
1137 $langs = array_combine( $langcodes, $qvalues );
1138
1139 return $langs;
1140 }
1141
1150 protected function getRawIP() {
1151 if ( !isset( $_SERVER['REMOTE_ADDR'] ) ) {
1152 return null;
1153 }
1154
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." );
1158 } else {
1159 $ipchain = $_SERVER['REMOTE_ADDR'];
1160 }
1161
1162 return IP::canonicalize( $ipchain );
1163 }
1164
1174 public function getIP() {
1175 global $wgUsePrivateIPs;
1176
1177 # Return cached result
1178 if ( $this->ip !== null ) {
1179 return $this->ip;
1180 }
1181
1182 # collect the originating ips
1183 $ip = $this->getRawIP();
1184 if ( !$ip ) {
1185 throw new MWException( 'Unable to determine IP.' );
1186 }
1187
1188 # Append XFF
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 );
1195
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 )
1205 ) {
1206 break; // IP is not valid/trusted or does not point to anything
1207 }
1208 if (
1209 IP::isPublic( $ipchain[$i + 1] ) ||
1210 $wgUsePrivateIPs ||
1211 IP::isConfiguredProxy( $curIP ) // bug 48919; treat IP as sane
1212 ) {
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'." );
1219 }
1220 $ip = $nextIP;
1221 // keep traversing the chain
1222 continue;
1223 }
1224 break;
1225 }
1226 }
1227
1228 # Allow extensions to improve our guess
1229 Hooks::run( 'GetIP', [ &$ip ] );
1230
1231 if ( !$ip ) {
1232 throw new MWException( "Unable to determine IP." );
1233 }
1234
1235 wfDebug( "IP: $ip\n" );
1236 $this->ip = $ip;
1237 return $ip;
1238 }
1239
1245 public function setIP( $ip ) {
1246 $this->ip = $ip;
1247 }
1248}
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
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
$wgUsePathInfo
Whether to support URLs like index.php/Page_title These often break when PHP is set up in CGI mode.
$wgScript
The URL path to index.php.
bool $wgAssumeProxiesUseDefaultProtocolPorts
When the wiki is running behind a proxy and this is set to true, assumes that the proxy exposes the w...
$wgVariantArticlePath
Like $wgArticlePath, but on multi-variant wikis, this provides a path format that describes which par...
$wgCookiePrefix
Cookies generated by MediaWiki have names starting with this prefix.
wfRandomString( $length=32)
Get a random string containing a number of pseudo-random hex characters.
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e....
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
$wgUser
Definition Setup.php:794
$wgInitialSessionId
Definition Setup.php:730
WebRequest clone which takes values from a provided array.
Show an error that looks like an HTTP server error.
Definition HttpError.php:30
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...
static fixUrlForIE6( $url, $extWhitelist=[])
Returns a variant of $url which will pass isUrlExtensionBad() but has the same GET parameters,...
A collection of public static functions to play with IP address and IP blocks.
Definition IP.php:67
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.
Definition IP.php:303
static splitHostAndPort( $both)
Given a host/port string, like one might find in the host part of a URL per RFC 2732,...
Definition IP.php:254
Internationalisation code.
Definition Language.php:39
MediaWiki exception.
Value object holding the session ID in a manner that can be globally updated.
Definition SessionId.php:38
This serves as the entry point to the MediaWiki session handling system.
Manages data for an an authenticated session.
Definition Session.php:48
PathRouter class.
add( $path, $params=[], $options=[])
Add a new path pattern to the path router.
Object to access the $_FILES array.
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
getIntOrNull( $name)
Fetch an integer value from the input or return null if empty.
getValueNames( $exclude=[])
Returns the names of all input values excluding those in $exclude.
getUpload( $key)
Return a WebRequestUpload object corresponding to the key.
checkSessionCookie()
Returns true if the request has a persistent session.
string $protocol
Cached URL protocol.
getArray( $name, $default=null)
Fetch an array from the input or return $default if it's not set.
interpolateTitle()
Check for title, action, and/or variant data in the URL and interpolate it into the GET variables.
static detectProtocol()
Detect the protocol from $_SERVER.
getSession()
Return the session for this request.
getRawInput()
Return the raw request body, with no processing.
getRawQueryString()
Return the contents of the Query with no decoding.
getFileTempname( $key)
Return the path to the temporary file where PHP has stored the upload.
getVal( $name, $default=null)
Fetch a scalar from the input or return $default if it's not set.
getFloat( $name, $default=0.0)
Fetch a floating point value from the input or return $default if not set.
WebResponse $response
Lazy-init response object.
getUploadError( $key)
Return the upload error or 0.
getAllHeaders()
Get an array containing all request headers.
getFuzzyBool( $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.
static getRequestId()
Get the unique request ID.
getProtocol()
Get the current URL protocol (http or https)
getMethod()
Get the HTTP method used for this request.
initHeaders()
Initialise the header list.
getBool( $name, $default=false)
Fetch a boolean value from the input or return $default if not set.
string $ip
Cached client IP address.
static getGlobalRequestURL()
Return the path and query string portion of the main request URI.
setVal( $key, $value)
Set an arbitrary value into our get/post data.
static string $reqId
The unique request ID.
getFullRequestURL()
Return the request URI with the canonical service and hostname, path, and query string.
checkUrlExtension( $extWhitelist=[])
Check if Internet Explorer will detect an incorrect cache extension in PATH_INFO or QUERY_STRING.
getElapsedTime()
Get the number of seconds to have elapsed since request start, in fractional seconds,...
float $requestTime
The timestamp of the start of the request, with microsecond precision.
getCheck( $name)
Return true if the named value is set in the input, whatever that value is (even "0").
appendQueryArray( $array)
Appends or replaces value of query variables.
static detectServer()
Work out an appropriate URL prefix containing scheme and host, based on information detected from $_S...
getSessionId()
Get the session id for this request, if any.
getRawPostString()
Return the contents of the POST with no decoding.
getQueryValues()
Get the values passed in the query string.
response()
Return a handle to WebResponse style object, for setting cookies, headers and other stuff,...
getInt( $name, $default=0)
Fetch an integer value from the input or return $default if not set.
wasPosted()
Returns true if the present request was reached by a POST operation, false otherwise (GET,...
setSessionData( $key, $data)
Set session data.
doSecurityRedirect( $url)
Attempt to redirect to a URL with a QUERY_STRING that's not dangerous in IE 6.
getFileName( $key)
Return the original filename of the uploaded file, as reported by the submitting user agent.
const GETHEADER_LIST
Flag to make WebRequest::getHeader return an array of values.
getIntArray( $name, $default=null)
Fetch an array of integers, or return $default if it's not set.
appendQueryValue( $key, $value)
normalizeUnicode( $data)
Recursively normalizes UTF-8 strings in the given array.
static overrideRequestId( $id)
Override the unique request ID.
unsetVal( $key)
Unset an arbitrary value from our get/post data.
static getPathInfo( $want='all')
Extract relevant query arguments from the http request uri's path to be merged with the normal php pr...
SessionId null $sessionId
Session ID to use for this request.
setSessionId(SessionId $sessionId)
Set the session for this request.
getCookie( $key, $prefix=null, $default=null)
Get a cookie from the $_COOKIE jar.
getLimitOffset( $deflimit=50, $optionname='rclimit')
Check for limit and offset parameters on the input, and return sensible defaults if not given.
static extractTitle( $path, $bases, $key=false)
URL rewriting function; tries to extract page title and, optionally, one other fixed parameter value ...
getText( $name, $default='')
Fetch a text string from the given array or return $default if it's not set.
getRequestURL()
Return the path and query string portion of the request URI.
getHeader( $name, $flags=0)
Get a request header, or false if it isn't set.
getSessionData( $key)
Get data from the session.
getValues()
Extracts the given named values into an array.
Allow programs to request this object from WebRequest::response() and handle all outputting (or lack ...
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
Definition design.txt:57
when a variable name is used in a it is silently declared as a new local masking the global
Definition design.txt:95
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
Definition design.txt:79
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
Definition design.txt:18
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
const PROTO_CURRENT
Definition Defines.php:265
the array() calling protocol came about after MediaWiki 1.4rc1.
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
Definition hooks.txt:183
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
Definition hooks.txt:1810
it s the revision text itself In either if gzip is the revision text is gzipped $flags
Definition hooks.txt:2555
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
Definition hooks.txt:1081
this hook is for auditing only $response
Definition hooks.txt:765
Allows to change the fields on the form that will be generated $name
Definition hooks.txt:314
$wgActionPaths
Definition img_auth.php:46
$wgArticlePath
Definition img_auth.php:45
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
Definition injection.txt:37
title
This document describes the state of Postgres support in and is fairly well maintained The main code is very well while extensions are very hit and miss it is probably the most supported database after MySQL Much of the work in making MediaWiki database agnostic came about through the work of creating Postgres as and are nearing end of but without copying over all the usage comments General notes on the but these can almost always be programmed around *Although Postgres has a true BOOLEAN boolean columns are always mapped to as the code does not always treat the column as a and VARBINARY columns should simply be TEXT The only exception is when VARBINARY is used to store true binary data
Definition postgres.txt:43