* @file
*/
+use MediaWiki\Session\SessionManager;
+
/**
* The WebRequest class encapsulates getting at data passed in the
* URL or via a POSTed form stripping illegal input characters and
* normalizing Unicode sequences.
*
- * Usually this is used via a global singleton, $wgRequest. You should
- * not create a second WebRequest object; make a FauxRequest object if
- * you want to pass arbitrary data to some function in place of the web
- * input.
- *
* @ingroup HTTP
*/
class WebRequest {
*/
protected $protocol;
+ /**
+ * @var \\MediaWiki\\Session\\SessionId|null Session ID to use for this
+ * request. We can't save the session directly due to reference cycles not
+ * working too well (slow GC in Zend and never collected in HHVM).
+ */
+ protected $sessionId = null;
+
public function __construct() {
$this->requestTime = isset( $_SERVER['REQUEST_TIME_FLOAT'] )
? $_SERVER['REQUEST_TIME_FLOAT'] : microtime( true );
}
/**
- * Returns true if there is a session cookie set.
+ * Return the session for this request
+ * @since 1.27
+ * @note For performance, keep the session locally if you will be making
+ * much use of it instead of calling this method repeatedly.
+ * @return MediaWiki\\Session\\Session
+ */
+ public function getSession() {
+ if ( $this->sessionId !== null ) {
+ $session = SessionManager::singleton()->getSessionById( (string)$this->sessionId, true, $this );
+ if ( $session ) {
+ return $session;
+ }
+ }
+
+ $session = SessionManager::singleton()->getSessionForRequest( $this );
+ $this->sessionId = $session->getSessionId();
+ return $session;
+ }
+
+ /**
+ * Set the session for this request
+ * @since 1.27
+ * @private For use by MediaWiki\\Session classes only
+ * @param MediaWiki\\Session\\SessionId $sessionId
+ */
+ public function setSessionId( MediaWiki\Session\SessionId $sessionId ) {
+ $this->sessionId = $sessionId;
+ }
+
+ /**
+ * Returns true if the request has a persistent session.
* This does not necessarily mean that the user is logged in!
*
- * If you want to check for an open session, use session_id()
- * instead; that will also tell you if the session was opened
- * during the current request (in which case the cookie will
- * be sent back to the client at the end of the script run).
- *
+ * @deprecated since 1.27, use
+ * \\MediaWiki\\Session\\SessionManager::singleton()->getPersistedSessionId()
+ * instead.
* @return bool
*/
public function checkSessionCookie() {
- return isset( $_COOKIE[session_name()] );
+ global $wgInitialSessionId;
+ wfDeprecated( __METHOD__, '1.27' );
+ return $wgInitialSessionId !== null &&
+ $this->getSession()->getId() === (string)$wgInitialSessionId;
}
/**
return wfExpandUrl( $this->getRequestURL(), PROTO_CURRENT );
}
- /**
- * Take an arbitrary query and rewrite the present URL to include it
- * @deprecated Use appendQueryValue/appendQueryArray instead
- * @param string $query Query string fragment; do not include initial '?'
- * @return string
- */
- public function appendQuery( $query ) {
- wfDeprecated( __METHOD__, '1.25' );
- return $this->appendQueryArray( wfCgiToArray( $query ) );
- }
-
/**
* @param string $key
* @param string $value
- * @param bool $onlyquery [deprecated]
* @return string
*/
- public function appendQueryValue( $key, $value, $onlyquery = true ) {
- return $this->appendQueryArray( array( $key => $value ), $onlyquery );
+ public function appendQueryValue( $key, $value ) {
+ return $this->appendQueryArray( array( $key => $value ) );
}
/**
* Appends or replaces value of query variables.
*
* @param array $array Array of values to replace/add to query
- * @param bool $onlyquery Whether to only return the query string
- * and not the complete URL [deprecated]
* @return string
*/
- public function appendQueryArray( $array, $onlyquery = true ) {
- global $wgTitle;
+ public function appendQueryArray( $array ) {
$newquery = $this->getQueryValues();
unset( $newquery['title'] );
$newquery = array_merge( $newquery, $array );
- $query = wfArrayToCgi( $newquery );
- if ( !$onlyquery ) {
- wfDeprecated( __METHOD__, '1.25' );
- return $wgTitle->getLocalURL( $query );
- }
- return $query;
+ return wfArrayToCgi( $newquery );
}
/**
}
/**
- * Get data from $_SESSION
+ * Get data from the session
*
- * @param string $key Name of key in $_SESSION
+ * @note Prefer $this->getSession() instead if making multiple calls.
+ * @param string $key Name of key in the session
* @return mixed
*/
public function getSessionData( $key ) {
- if ( !isset( $_SESSION[$key] ) ) {
- return null;
- }
- return $_SESSION[$key];
+ return $this->getSession()->get( $key );
}
/**
* Set session data
*
- * @param string $key Name of key in $_SESSION
+ * @note Prefer $this->getSession() instead if making multiple calls.
+ * @param string $key Name of key in the session
* @param mixed $data
*/
public function setSessionData( $key, $data ) {
- $_SESSION[$key] = $data;
+ return $this->getSession()->set( $key, $data );
}
/**
$this->ip = $ip;
}
}
-
-/**
- * WebRequest clone which takes values from a provided array.
- *
- * @ingroup HTTP
- */
-class FauxRequest extends WebRequest {
- private $wasPosted = false;
- private $session = array();
- private $requestUrl;
- protected $cookies = array();
-
- /**
- * @param array $data Array of *non*-urlencoded key => value pairs, the
- * fake GET/POST values
- * @param bool $wasPosted Whether to treat the data as POST
- * @param array|null $session Session array or null
- * @param string $protocol 'http' or 'https'
- * @throws MWException
- */
- public function __construct( $data = array(), $wasPosted = false,
- $session = null, $protocol = 'http'
- ) {
- $this->requestTime = microtime( true );
-
- if ( is_array( $data ) ) {
- $this->data = $data;
- } else {
- throw new MWException( "FauxRequest() got bogus data" );
- }
- $this->wasPosted = $wasPosted;
- if ( $session ) {
- $this->session = $session;
- }
- $this->protocol = $protocol;
- }
-
- /**
- * Initialise the header list
- */
- protected function initHeaders() {
- // Nothing to init
- }
-
- /**
- * @param string $name
- * @param string $default
- * @return string
- */
- public function getText( $name, $default = '' ) {
- # Override; don't recode since we're using internal data
- return (string)$this->getVal( $name, $default );
- }
-
- /**
- * @return array
- */
- public function getValues() {
- return $this->data;
- }
-
- /**
- * @return array
- */
- public function getQueryValues() {
- if ( $this->wasPosted ) {
- return array();
- } else {
- return $this->data;
- }
- }
-
- public function getMethod() {
- return $this->wasPosted ? 'POST' : 'GET';
- }
-
- /**
- * @return bool
- */
- public function wasPosted() {
- return $this->wasPosted;
- }
-
- public function getCookie( $key, $prefix = null, $default = null ) {
- if ( $prefix === null ) {
- global $wgCookiePrefix;
- $prefix = $wgCookiePrefix;
- }
- $name = $prefix . $key;
- return isset( $this->cookies[$name] ) ? $this->cookies[$name] : $default;
- }
-
- /**
- * @since 1.26
- * @param string $name Unprefixed name of the cookie to set
- * @param string|null $value Value of the cookie to set
- * @param string|null $prefix Cookie prefix. Defaults to $wgCookiePrefix
- */
- public function setCookie( $key, $value, $prefix = null ) {
- $this->setCookies( array( $key => $value ), $prefix );
- }
-
- /**
- * @since 1.26
- * @param array $cookies
- * @param string|null $prefix Cookie prefix. Defaults to $wgCookiePrefix
- */
- public function setCookies( $cookies, $prefix = null ) {
- if ( $prefix === null ) {
- global $wgCookiePrefix;
- $prefix = $wgCookiePrefix;
- }
- foreach ( $cookies as $key => $value ) {
- $name = $prefix . $key;
- $this->cookies[$name] = $value;
- }
- }
-
- public function checkSessionCookie() {
- return false;
- }
-
- public function setRequestURL( $url ) {
- $this->requestUrl = $url;
- }
-
- public function getRequestURL() {
- if ( $this->requestUrl === null ) {
- throw new MWException( 'Request URL not set' );
- }
- return $this->requestUrl;
- }
-
- public function getProtocol() {
- return $this->protocol;
- }
-
- /**
- * @param string $name
- * @param string $val
- */
- public function setHeader( $name, $val ) {
- $this->setHeaders( array( $name => $val ) );
- }
-
- /**
- * @since 1.26
- * @param array $headers
- */
- public function setHeaders( $headers ) {
- foreach ( $headers as $name => $val ) {
- $name = strtoupper( $name );
- $this->headers[$name] = $val;
- }
- }
-
- /**
- * @param string $key
- * @return array|null
- */
- public function getSessionData( $key ) {
- if ( isset( $this->session[$key] ) ) {
- return $this->session[$key];
- }
- return null;
- }
-
- /**
- * @param string $key
- * @param array $data
- */
- public function setSessionData( $key, $data ) {
- $this->session[$key] = $data;
- }
-
- /**
- * @return array|mixed|null
- */
- public function getSessionArray() {
- return $this->session;
- }
-
- /**
- * FauxRequests shouldn't depend on raw request data (but that could be implemented here)
- * @return string
- */
- public function getRawQueryString() {
- return '';
- }
-
- /**
- * FauxRequests shouldn't depend on raw request data (but that could be implemented here)
- * @return string
- */
- public function getRawPostString() {
- return '';
- }
-
- /**
- * FauxRequests shouldn't depend on raw request data (but that could be implemented here)
- * @return string
- */
- public function getRawInput() {
- return '';
- }
-
- /**
- * @param array $extWhitelist
- * @return bool
- */
- public function checkUrlExtension( $extWhitelist = array() ) {
- return true;
- }
-
- /**
- * @return string
- */
- protected function getRawIP() {
- return '127.0.0.1';
- }
-}
-
-/**
- * Similar to FauxRequest, but only fakes URL parameters and method
- * (POST or GET) and use the base request for the remaining stuff
- * (cookies, session and headers).
- *
- * @ingroup HTTP
- * @since 1.19
- */
-class DerivativeRequest extends FauxRequest {
- private $base;
-
- /**
- * @param WebRequest $base
- * @param array $data Array of *non*-urlencoded key => value pairs, the
- * fake GET/POST values
- * @param bool $wasPosted Whether to treat the data as POST
- */
- public function __construct( WebRequest $base, $data, $wasPosted = false ) {
- $this->base = $base;
- parent::__construct( $data, $wasPosted );
- }
-
- public function getCookie( $key, $prefix = null, $default = null ) {
- return $this->base->getCookie( $key, $prefix, $default );
- }
-
- public function checkSessionCookie() {
- return $this->base->checkSessionCookie();
- }
-
- public function getHeader( $name, $flags = 0 ) {
- return $this->base->getHeader( $name, $flags );
- }
-
- public function getAllHeaders() {
- return $this->base->getAllHeaders();
- }
-
- public function getSessionData( $key ) {
- return $this->base->getSessionData( $key );
- }
-
- public function setSessionData( $key, $data ) {
- $this->base->setSessionData( $key, $data );
- }
-
- public function getAcceptLang() {
- return $this->base->getAcceptLang();
- }
-
- public function getIP() {
- return $this->base->getIP();
- }
-
- public function getProtocol() {
- return $this->base->getProtocol();
- }
-
- public function getElapsedTime() {
- return $this->base->getElapsedTime();
- }
-}