*/
use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\Session\SessionManager;
use WrappedString\WrappedString;
/**
/** @var string */
private $mPageTitleActionText = '';
- /** @var array */
- private $mParseWarnings = array();
-
/** @var int Cache stuff. Looks like mEnableClientCache */
protected $mCdnMaxage = 0;
/** @var int Upper limit on mCdnMaxage */
* @return ParserOptions
*/
public function parserOptions( $options = null ) {
+ if ( $options !== null && !empty( $options->isBogus ) ) {
+ // Someone is trying to set a bogus pre-$wgUser PO. Check if it has
+ // been changed somehow, and keep it if so.
+ $anonPO = ParserOptions::newFromAnon();
+ $anonPO->setEditSection( false );
+ if ( !$options->matches( $anonPO ) ) {
+ wfLogWarning( __METHOD__ . ': Setting a changed bogus ParserOptions: ' . wfGetAllCallers( 5 ) );
+ $options->isBogus = false;
+ }
+ }
+
if ( !$this->mParserOptions ) {
+ if ( !$this->getContext()->getUser()->isSafeToLoad() ) {
+ // $wgUser isn't unstubbable yet, so don't try to get a
+ // ParserOptions for it. And don't cache this ParserOptions
+ // either.
+ $po = ParserOptions::newFromAnon();
+ $po->setEditSection( false );
+ $po->isBogus = true;
+ if ( $options !== null ) {
+ $this->mParserOptions = empty( $options->isBogus ) ? $options : null;
+ }
+ return $po;
+ }
+
$this->mParserOptions = ParserOptions::newFromContext( $this->getContext() );
$this->mParserOptions->setEditSection( false );
}
- return wfSetVar( $this->mParserOptions, $options );
+
+ if ( $options !== null && !empty( $options->isBogus ) ) {
+ // They're trying to restore the bogus pre-$wgUser PO. Do the right
+ // thing.
+ return wfSetVar( $this->mParserOptions, null, true );
+ } else {
+ return wfSetVar( $this->mParserOptions, $options );
+ }
}
/**
$this->mNewSectionLink = $parserOutput->getNewSection();
$this->mHideNewSectionLink = $parserOutput->getHideNewSection();
- $this->mParseWarnings = $parserOutput->getWarnings();
if ( !$parserOutput->isCacheable() ) {
$this->enableClientCache( false );
}
if ( $cookies === null ) {
$config = $this->getConfig();
$cookies = array_merge(
+ SessionManager::singleton()->getVaryCookies(),
array(
- $config->get( 'CookiePrefix' ) . 'Token',
- $config->get( 'CookiePrefix' ) . 'LoggedOut',
- "forceHTTPS",
- session_name()
+ 'forceHTTPS',
),
$config->get( 'CacheVaryCookies' )
);
* @return string
*/
public function getVaryHeader() {
+ foreach ( SessionManager::singleton()->getVaryHeaders() as $header => $options ) {
+ $this->addVaryHeader( $header, $options );
+ }
return 'Vary: ' . join( ', ', array_keys( $this->mVaryHeader ) );
}
}
$this->addVaryHeader( 'Cookie', $cookiesOption );
+ foreach ( SessionManager::singleton()->getVaryHeaders() as $header => $options ) {
+ $this->addVaryHeader( $header, $options );
+ }
+
$headers = array();
foreach ( $this->mVaryHeader as $header => $option ) {
$newheader = $header;
if ( $this->mEnableClientCache ) {
if (
- $config->get( 'UseSquid' ) && session_id() == '' && !$this->isPrintable() &&
- $this->mCdnMaxage != 0 && !$this->haveCacheVaryCookies()
+ $config->get( 'UseSquid' ) && !SessionManager::getGlobalSession()->isPersistent() &&
+ !$this->isPrintable() && $this->mCdnMaxage != 0 && !$this->haveCacheVaryCookies()
) {
if ( $config->get( 'UseESI' ) ) {
# We'll purge the proxy cache explicitly, but require end user agents
return $link;
}
+ /**
+ * Transform path to web-accessible static resource.
+ *
+ * This is used to add a validation hash as query string.
+ * This aids various behaviors:
+ *
+ * - Put long Cache-Control max-age headers on responses for improved
+ * cache performance.
+ * - Get the correct version of a file as expected by the current page.
+ * - Instantly get the updated version of a file after deployment.
+ *
+ * Avoid using this for urls included in HTML as otherwise clients may get different
+ * versions of a resource when navigating the site depending on when the page was cached.
+ * If changes to the url propagate, this is not a problem (e.g. if the url is in
+ * an external stylesheet).
+ *
+ * @since 1.27
+ * @param Config $config
+ * @param string $path Path-absolute URL to file (from document root, must start with "/")
+ * @return string URL
+ */
+ public static function transformResourcePath( Config $config, $path ) {
+ global $IP;
+ $remotePath = $config->get( 'ResourceBasePath' );
+ if ( strpos( $path, $remotePath ) !== 0 ) {
+ // Path is outside wgResourceBasePath, ignore.
+ return $path;
+ }
+ $path = RelPath\getRelativePath( $path, $remotePath );
+ return self::transformFilePath( $remotePath, $IP, $path );
+ }
+
+ /**
+ * Utility method for transformResourceFilePath().
+ *
+ * Caller is responsible for ensuring the file exists. Emits a PHP warning otherwise.
+ *
+ * @since 1.27
+ * @param string $remotePath URL path that points to $localPath
+ * @param string $localPath File directory exposed at $remotePath
+ * @param string $file Path to target file relative to $localPath
+ * @return string URL
+ */
+ public static function transformFilePath( $remotePath, $localPath, $file ) {
+ $hash = md5_file( "$localPath/$file" );
+ if ( $hash === false ) {
+ wfLogWarning( __METHOD__ . ": Failed to hash $localPath/$file" );
+ $hash = '';
+ }
+ return "$remotePath/$file?" . substr( $hash, 0, 5 );
+ }
+
/**
* Transform "media" attribute based on request parameters
*
$this->getLanguage()->getDir()
);
$this->addModuleStyles( array(
- 'oojs-ui.styles',
+ 'oojs-ui-core.styles',
'oojs-ui.styles.icons',
'oojs-ui.styles.indicators',
'oojs-ui.styles.textures',
'mediawiki.widgets.styles',
) );
+ // Used by 'skipFunction' of the four 'oojs-ui.styles.*' modules. Please don't treat this as a
+ // public API or you'll be severely disappointed when T87871 is fixed and it disappears.
+ $this->addMeta( 'X-OOUI-PHP', '1' );
}
}