2012-08-06 14:18:02 +00:00
|
|
|
<?php
|
|
|
|
|
/**
|
2012-09-01 19:56:38 +00:00
|
|
|
* Parser cache specific expiry check.
|
2012-08-06 14:18:02 +00:00
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
|
|
|
*
|
|
|
|
|
* @file
|
|
|
|
|
* @ingroup Parser
|
|
|
|
|
*/
|
2012-09-01 19:56:38 +00:00
|
|
|
|
2024-10-03 18:39:06 +00:00
|
|
|
namespace MediaWiki\Parser;
|
|
|
|
|
|
2024-05-04 08:58:57 +00:00
|
|
|
use MediaWiki\Json\JsonDeserializable;
|
|
|
|
|
use MediaWiki\Json\JsonDeserializableTrait;
|
|
|
|
|
use MediaWiki\Json\JsonDeserializer;
|
2022-04-26 15:48:03 +00:00
|
|
|
use MediaWiki\MainConfigNames;
|
2022-01-06 18:44:56 +00:00
|
|
|
use MediaWiki\MediaWikiServices;
|
2023-08-19 03:35:06 +00:00
|
|
|
use MediaWiki\Utils\MWTimestamp;
|
2020-11-05 17:04:37 +00:00
|
|
|
use Wikimedia\Reflection\GhostFieldAccessTrait;
|
2020-09-23 21:31:14 +00:00
|
|
|
|
2012-09-01 19:56:38 +00:00
|
|
|
/**
|
|
|
|
|
* Parser cache specific expiry check.
|
|
|
|
|
*
|
|
|
|
|
* @ingroup Parser
|
|
|
|
|
*/
|
2024-05-04 08:58:57 +00:00
|
|
|
class CacheTime implements ParserCacheMetadata, JsonDeserializable {
|
2020-11-05 17:04:37 +00:00
|
|
|
use GhostFieldAccessTrait;
|
2024-05-04 08:58:57 +00:00
|
|
|
use JsonDeserializableTrait;
|
2020-09-23 21:31:14 +00:00
|
|
|
|
2018-04-18 12:31:13 +00:00
|
|
|
/**
|
2020-11-05 17:05:40 +00:00
|
|
|
* @var true[] ParserOptions which have been taken into account
|
|
|
|
|
* to produce output, option names stored in array keys.
|
2013-11-16 21:11:49 +00:00
|
|
|
*/
|
2020-11-05 17:05:40 +00:00
|
|
|
protected $mParseUsedOptions = [];
|
2012-08-06 14:18:02 +00:00
|
|
|
|
2018-04-18 12:31:13 +00:00
|
|
|
/**
|
2018-10-04 10:32:06 +00:00
|
|
|
* @var string|int TS_MW timestamp when this object was generated, or -1 for not cacheable. Used
|
2018-04-18 12:31:13 +00:00
|
|
|
* in ParserCache.
|
|
|
|
|
*/
|
2020-11-10 01:47:09 +00:00
|
|
|
protected $mCacheTime = '';
|
2015-09-26 17:17:49 +00:00
|
|
|
|
2018-04-18 12:31:13 +00:00
|
|
|
/**
|
2018-10-04 10:32:06 +00:00
|
|
|
* @var int|null Seconds after which the object should expire, use 0 for not cacheable. Used in
|
2018-04-18 12:31:13 +00:00
|
|
|
* ParserCache.
|
|
|
|
|
*/
|
2020-11-10 01:47:09 +00:00
|
|
|
protected $mCacheExpiry = null;
|
2015-09-26 17:17:49 +00:00
|
|
|
|
2018-04-18 12:31:13 +00:00
|
|
|
/**
|
|
|
|
|
* @var int|null Revision ID that was parsed
|
|
|
|
|
*/
|
2020-11-10 01:47:09 +00:00
|
|
|
protected $mCacheRevisionId = null;
|
2012-08-06 14:18:02 +00:00
|
|
|
|
2013-11-28 06:43:00 +00:00
|
|
|
/**
|
2020-09-23 21:31:14 +00:00
|
|
|
* @return string|int TS_MW timestamp
|
2013-11-28 06:43:00 +00:00
|
|
|
*/
|
2014-08-11 20:24:54 +00:00
|
|
|
public function getCacheTime() {
|
2018-10-04 10:32:06 +00:00
|
|
|
// NOTE: keep support for undocumented used of -1 to mean "not cacheable".
|
|
|
|
|
if ( $this->mCacheTime === '' ) {
|
|
|
|
|
$this->mCacheTime = MWTimestamp::now();
|
|
|
|
|
}
|
|
|
|
|
return $this->mCacheTime;
|
2013-12-30 21:00:22 +00:00
|
|
|
}
|
2012-08-06 14:18:02 +00:00
|
|
|
|
Add ParserOutput::{get,set}RenderId() and set render id in ContentRenderer
Set the render ID for each parse stored into cache so that we are able
to identify a specific parse when there are dependencies (for example
in an edit based on that parse). This is recorded as a property added
to the ParserOutput, not the parent CacheTime interface. Even though
the render ID is /related/ to the CacheTime interface, CacheTime is
also used directly as a parser cache key, and the UUID should not be
part of the lookup key.
In general we are trying to move the location where these cache
properties are set as early as possible, so we check at each location
to ensure we don't overwrite a previously-set value. Eventually we
can convert most of these checks into assertions that the cache
properties have already been set (T350538). The primary location for
setting cache properties is the ContentRenderer.
Moved setting the revision timestamp into ContentRenderer as well, as
it was set along the same code paths. An extra parameter was added to
ContentRenderer::getParserOutput() to support this.
Added merge code to ParserOutput::mergeInternalMetaDataFrom() which
should ensure that cache time, revision, timestamp, and render id are
all set properly when multiple slots are combined together in MCR.
In order to ensure the render ID is set on all codepaths we needed to
plumb the GlobalIdGenerator service into ContentRenderer, ParserCache,
ParserCacheFactory, and RevisionOutputCache. Eventually (T350538) it
should only be necessary in the ContentRenderer.
Bug: T350538
Bug: T349868
Followup-To: Ic9b7cc0fcf365e772b7d080d76a065e3fd585f80
Change-Id: I72c5e6f86b7f081ab5ce7a56f5365d2f75067a78
2023-09-14 16:11:20 +00:00
|
|
|
/**
|
|
|
|
|
* @return bool true if a cache time has been set
|
|
|
|
|
*/
|
|
|
|
|
public function hasCacheTime(): bool {
|
|
|
|
|
return $this->mCacheTime !== '';
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-06 14:18:02 +00:00
|
|
|
/**
|
|
|
|
|
* setCacheTime() sets the timestamp expressing when the page has been rendered.
|
2013-11-28 06:43:00 +00:00
|
|
|
* This does not control expiry, see updateCacheExpiry() for that!
|
2015-06-08 23:05:54 +00:00
|
|
|
* @param string $t TS_MW timestamp
|
2012-08-06 14:18:02 +00:00
|
|
|
* @return string
|
|
|
|
|
*/
|
2014-08-11 20:24:54 +00:00
|
|
|
public function setCacheTime( $t ) {
|
2018-10-04 10:32:06 +00:00
|
|
|
// NOTE: keep support for undocumented used of -1 to mean "not cacheable".
|
|
|
|
|
if ( is_string( $t ) && $t !== '-1' ) {
|
|
|
|
|
$t = MWTimestamp::convert( TS_MW, $t );
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-24 00:17:40 +00:00
|
|
|
if ( $t === -1 || $t === '-1' ) {
|
|
|
|
|
wfDeprecatedMsg( __METHOD__ . ' called with -1 as an argument', '1.36' );
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-30 21:00:22 +00:00
|
|
|
return wfSetVar( $this->mCacheTime, $t );
|
|
|
|
|
}
|
2012-08-06 14:18:02 +00:00
|
|
|
|
2014-04-01 14:52:24 +00:00
|
|
|
/**
|
|
|
|
|
* @since 1.23
|
|
|
|
|
* @return int|null Revision id, if any was set
|
|
|
|
|
*/
|
2020-09-23 21:31:14 +00:00
|
|
|
public function getCacheRevisionId(): ?int {
|
2014-04-01 14:52:24 +00:00
|
|
|
return $this->mCacheRevisionId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @since 1.23
|
2018-04-18 12:31:13 +00:00
|
|
|
* @param int|null $id Revision ID
|
2014-04-01 14:52:24 +00:00
|
|
|
*/
|
2014-08-11 20:24:54 +00:00
|
|
|
public function setCacheRevisionId( $id ) {
|
2014-04-01 14:52:24 +00:00
|
|
|
$this->mCacheRevisionId = $id;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-06 14:18:02 +00:00
|
|
|
/**
|
|
|
|
|
* Sets the number of seconds after which this object should expire.
|
2016-06-15 01:25:36 +00:00
|
|
|
*
|
2012-08-06 14:18:02 +00:00
|
|
|
* This value is used with the ParserCache.
|
|
|
|
|
* If called with a value greater than the value provided at any previous call,
|
|
|
|
|
* the new call has no effect. The value returned by getCacheExpiry is smaller
|
|
|
|
|
* or equal to the smallest number that was provided as an argument to
|
|
|
|
|
* updateCacheExpiry().
|
|
|
|
|
*
|
2016-06-15 01:25:36 +00:00
|
|
|
* Avoid using 0 if at all possible. Consider JavaScript for highly dynamic content.
|
|
|
|
|
*
|
WikiPage: Document triggerOpportunisticLinksUpdate and related code
== History of WikiPage::triggerOpportunisticLinksUpdate ==
* 2007 (r19095; T10575; b3a8d488a8)
Introduces the "cascading protection" feature.
This commit added code to Article.php, in a conditional branch
where we encountered a ParserCache "miss" and thus have done a
fresh parse. The code in question would query which templates
we ended up using, and if that differed from what the database
said (e.g. stored during the last actual edit or links update),
then a new LinksUpdate is ad-hoc constructed and executed.
I could not find it anywhere explicitly spelled out, but my best
guess is that the reason for this is to make sure that if the page
in question contains wikitext that trancludes a different page based
on the current date and time (such as how most Wikipedia main pages
transclude news information and "Did you know" information based on
dated subpages that are prepared in advance), then we don't just
want to re-render the page after a day has passed, we also want to
re-do the links update to ensure the search index, category links,
and "WhatLinksHere" is correct, and thus by extent, to make sure
that cascading protection from the main page does in fact apply
to the "current" set of subpages and templates actually in-use.
* 2007 (r19227; 0c0c0eff81)
This adds an optimisation to the added logic that limits it to
pages that satisfy `mTitle->areRestrictionsCascading()`.
Thus for most articles, which aren't protected at all, we don't
run LinksUpdate mid-request after a cache miss page view.
Because of this commit, the pre-2007 status quo remained unaltered
and has remains unaltered to this very day: We don't re-index
categories and WhatLinksHere etc, unless an article edit or
propagating template edit takes place.
* 2009 (r52888; 1353a8ba29)
Introduces the PoolCounter feature.
The logic in question moves to Article::doCascadeProtectionUpdates().
* 2015 (Iea952d4d2e66; df5ef8b5d7).
The logic in question is changed, motivated by wanting to avoid
DB writes during page views.
* Instead of executing LinksUpdate mid-request, we now queue a
RefreshLinksJob on the JobQueue, and utilize a newly added
`prioritize => true` parameter.
This commit also introduces a new feature, which is to queue
RefreshLinksJob also for pages that do not have cascading
protection, but that do satisfy a new boolean method
called `$parserOutput->hasDynamicContent()`, which is set when
the Parser encounters TTL-reducing magic words and functions
such as {{CURRENTDAY}} and {{#time}}. For this new case, however,
the `prioritize` parameter is not set, and this feature is disabled
in WMF production (and other farms that enable wgMiserMode).
This commit also renamed doCascadeProtectionUpdates()
to triggerOpportunisticLinksUpdate().
This commit also removed various documentation comments, which
I've partly restored in this patch, the patch you're looking at
now.
== Actual changes ==
* Rename hasDynamicContent() to hasReducedExpiry() and keep the
previous method as a non-deprecated wrapper.
This change is motivated by T280605, in which I intent to make use
of a Parser hook that reduces the cache expiry. There are numerous
extensions in WMF production that already do this, and thus the
assumption that these have "dynamic content" is already false in
some cases. I'm not yet sure how or if to refactor this so to allow
reducing of the TTL *without* causing this side-effect, but as a
first step we can make the method more obvious in its impact
and behaviour.
I've also updated two of the callers that I think will benefit from
this more explicit name and (current) implementation detail.
Bug: T280605
Change-Id: I85bdff7f86911f8ea5b866e3639f08ddd3f3bf6f
2021-05-05 01:03:16 +00:00
|
|
|
* NOTE: Beware that reducing the TTL for reasons that do not relate to "dynamic content",
|
|
|
|
|
* may have the side-effect of incurring more RefreshLinksJob executions.
|
|
|
|
|
* See also WikiPage::triggerOpportunisticLinksUpdate.
|
|
|
|
|
*
|
2014-04-21 23:38:39 +00:00
|
|
|
* @param int $seconds
|
2012-08-06 14:18:02 +00:00
|
|
|
*/
|
2014-08-11 20:24:54 +00:00
|
|
|
public function updateCacheExpiry( $seconds ) {
|
2012-08-06 14:18:02 +00:00
|
|
|
$seconds = (int)$seconds;
|
|
|
|
|
|
|
|
|
|
if ( $this->mCacheExpiry === null || $this->mCacheExpiry > $seconds ) {
|
|
|
|
|
$this->mCacheExpiry = $seconds;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the number of seconds after which this object should expire.
|
|
|
|
|
* This method is used by ParserCache to determine how long the ParserOutput can be cached.
|
|
|
|
|
* The timestamp of expiry can be calculated by adding getCacheExpiry() to getCacheTime().
|
|
|
|
|
* The value returned by getCacheExpiry is smaller or equal to the smallest number
|
|
|
|
|
* that was provided to a call of updateCacheExpiry(), and smaller or equal to the
|
|
|
|
|
* value of $wgParserCacheExpireTime.
|
2018-04-18 12:31:13 +00:00
|
|
|
* @return int
|
2012-08-06 14:18:02 +00:00
|
|
|
*/
|
2020-09-23 21:31:14 +00:00
|
|
|
public function getCacheExpiry(): int {
|
2022-04-26 15:48:03 +00:00
|
|
|
$parserCacheExpireTime = MediaWikiServices::getInstance()->getMainConfig()
|
|
|
|
|
->get( MainConfigNames::ParserCacheExpireTime );
|
2012-08-06 14:18:02 +00:00
|
|
|
|
2018-10-04 10:32:06 +00:00
|
|
|
// NOTE: keep support for undocumented used of -1 to mean "not cacheable".
|
2021-01-31 09:39:00 +00:00
|
|
|
if ( $this->mCacheTime !== '' && $this->mCacheTime < 0 ) {
|
2012-08-06 14:18:02 +00:00
|
|
|
return 0;
|
2018-10-04 10:32:06 +00:00
|
|
|
}
|
2012-08-06 14:18:02 +00:00
|
|
|
|
2024-01-20 19:41:21 +00:00
|
|
|
$expire = min( $this->mCacheExpiry ?? $parserCacheExpireTime, $parserCacheExpireTime );
|
|
|
|
|
return $expire > 0 ? $expire : 0;
|
2012-08-06 14:18:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2014-08-11 20:24:54 +00:00
|
|
|
public function isCacheable() {
|
2012-08-06 14:18:02 +00:00
|
|
|
return $this->getCacheExpiry() > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return true if this cached output object predates the global or
|
|
|
|
|
* per-article cache invalidation timestamps, or if it comes from
|
|
|
|
|
* an incompatible older version.
|
|
|
|
|
*
|
2014-04-21 23:38:39 +00:00
|
|
|
* @param string $touched The affected article's last touched timestamp
|
|
|
|
|
* @return bool
|
2012-08-06 14:18:02 +00:00
|
|
|
*/
|
|
|
|
|
public function expired( $touched ) {
|
2022-04-26 15:48:03 +00:00
|
|
|
$cacheEpoch = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::CacheEpoch );
|
2014-05-10 23:03:45 +00:00
|
|
|
|
2018-10-04 10:32:06 +00:00
|
|
|
$expiry = MWTimestamp::convert( TS_MW, MWTimestamp::time() - $this->getCacheExpiry() );
|
|
|
|
|
|
|
|
|
|
return !$this->isCacheable() // parser says it's not cacheable
|
2014-05-10 23:03:45 +00:00
|
|
|
|| $this->getCacheTime() < $touched
|
2022-01-06 18:44:56 +00:00
|
|
|
|| $this->getCacheTime() <= $cacheEpoch
|
2020-12-15 01:29:24 +00:00
|
|
|
|| $this->getCacheTime() < $expiry; // expiry period has passed
|
2012-08-06 14:18:02 +00:00
|
|
|
}
|
|
|
|
|
|
2014-04-01 14:52:24 +00:00
|
|
|
/**
|
|
|
|
|
* Return true if this cached output object is for a different revision of
|
|
|
|
|
* the page.
|
|
|
|
|
*
|
|
|
|
|
* @todo We always return false if $this->getCacheRevisionId() is null;
|
|
|
|
|
* this prevents invalidating the whole parser cache when this change is
|
|
|
|
|
* deployed. Someday that should probably be changed.
|
|
|
|
|
*
|
|
|
|
|
* @since 1.23
|
2014-04-21 23:38:39 +00:00
|
|
|
* @param int $id The affected article's current revision id
|
|
|
|
|
* @return bool
|
2014-04-01 14:52:24 +00:00
|
|
|
*/
|
|
|
|
|
public function isDifferentRevision( $id ) {
|
|
|
|
|
$cached = $this->getCacheRevisionId();
|
|
|
|
|
return $cached !== null && $id !== $cached;
|
|
|
|
|
}
|
2020-09-23 21:31:14 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the options from its ParserOptions which have been taken
|
|
|
|
|
* into account to produce the output.
|
|
|
|
|
* @since 1.36
|
|
|
|
|
* @return string[]
|
|
|
|
|
*/
|
|
|
|
|
public function getUsedOptions(): array {
|
2020-11-05 17:05:40 +00:00
|
|
|
return array_keys( $this->mParseUsedOptions );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Tags a parser option for use in the cache key for this parser output.
|
|
|
|
|
* Registered as a watcher at ParserOptions::registerWatcher() by Parser::clearState().
|
|
|
|
|
* The information gathered here is available via getUsedOptions(),
|
|
|
|
|
* and is used by ParserCache::save().
|
|
|
|
|
*
|
|
|
|
|
* @see ParserCache::getMetadata
|
|
|
|
|
* @see ParserCache::save
|
|
|
|
|
* @see ParserOptions::addExtraKey
|
|
|
|
|
* @see ParserOptions::optionsHash
|
|
|
|
|
* @param string $option
|
|
|
|
|
*/
|
|
|
|
|
public function recordOption( string $option ) {
|
|
|
|
|
$this->mParseUsedOptions[$option] = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Tags a list of parser option names for use in the cache key for this parser output.
|
|
|
|
|
*
|
|
|
|
|
* @see recordOption()
|
|
|
|
|
* @param string[] $options
|
|
|
|
|
*/
|
|
|
|
|
public function recordOptions( array $options ) {
|
|
|
|
|
$this->mParseUsedOptions = array_merge(
|
|
|
|
|
$this->mParseUsedOptions,
|
|
|
|
|
array_fill_keys( $options, true )
|
|
|
|
|
);
|
2020-09-23 21:31:14 +00:00
|
|
|
}
|
2020-09-29 19:18:00 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a JSON serializable structure representing this CacheTime instance.
|
|
|
|
|
* @see newFromJson()
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
2020-10-23 00:17:31 +00:00
|
|
|
protected function toJsonArray(): array {
|
2023-01-03 18:08:22 +00:00
|
|
|
// WARNING: When changing how this class is serialized, follow the instructions
|
|
|
|
|
// at <https://www.mediawiki.org/wiki/Manual:Parser_cache/Serialization_compatibility>!
|
|
|
|
|
|
2020-09-29 19:18:00 +00:00
|
|
|
return [
|
2020-11-05 17:05:40 +00:00
|
|
|
'ParseUsedOptions' => $this->mParseUsedOptions,
|
2020-09-29 19:18:00 +00:00
|
|
|
'CacheExpiry' => $this->mCacheExpiry,
|
|
|
|
|
'CacheTime' => $this->mCacheTime,
|
|
|
|
|
'CacheRevisionId' => $this->mCacheRevisionId,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-04 08:58:57 +00:00
|
|
|
public static function newFromJsonArray( JsonDeserializer $deserializer, array $json ) {
|
2020-09-29 19:18:00 +00:00
|
|
|
$cacheTime = new CacheTime();
|
2024-05-04 08:58:57 +00:00
|
|
|
$cacheTime->initFromJson( $deserializer, $json );
|
2020-09-29 19:18:00 +00:00
|
|
|
return $cacheTime;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialize member fields from an array returned by jsonSerialize().
|
2024-05-04 08:58:57 +00:00
|
|
|
* @param JsonDeserializer $deserializer Unused
|
2020-09-29 19:18:00 +00:00
|
|
|
* @param array $jsonData
|
|
|
|
|
*/
|
2024-05-04 08:58:57 +00:00
|
|
|
protected function initFromJson( JsonDeserializer $deserializer, array $jsonData ) {
|
2023-01-03 18:08:22 +00:00
|
|
|
// WARNING: When changing how this class is serialized, follow the instructions
|
|
|
|
|
// at <https://www.mediawiki.org/wiki/Manual:Parser_cache/Serialization_compatibility>!
|
|
|
|
|
|
2020-11-05 17:05:40 +00:00
|
|
|
if ( array_key_exists( 'AccessedOptions', $jsonData ) ) {
|
|
|
|
|
// Backwards compatibility for ParserOutput
|
|
|
|
|
$this->mParseUsedOptions = $jsonData['AccessedOptions'] ?: [];
|
|
|
|
|
} elseif ( array_key_exists( 'UsedOptions', $jsonData ) ) {
|
|
|
|
|
// Backwards compatibility
|
|
|
|
|
$this->recordOptions( $jsonData['UsedOptions'] ?: [] );
|
2020-11-05 17:04:37 +00:00
|
|
|
} else {
|
2020-11-05 17:05:40 +00:00
|
|
|
$this->mParseUsedOptions = $jsonData['ParseUsedOptions'] ?: [];
|
2020-11-05 17:04:37 +00:00
|
|
|
}
|
2020-09-29 19:18:00 +00:00
|
|
|
$this->mCacheExpiry = $jsonData['CacheExpiry'];
|
|
|
|
|
$this->mCacheTime = $jsonData['CacheTime'];
|
|
|
|
|
$this->mCacheRevisionId = $jsonData['CacheRevisionId'];
|
|
|
|
|
}
|
2020-11-05 17:04:37 +00:00
|
|
|
|
|
|
|
|
public function __wakeup() {
|
2020-11-05 17:05:40 +00:00
|
|
|
// Backwards compatibility, pre 1.36
|
|
|
|
|
$priorOptions = $this->getGhostFieldValue( 'mUsedOptions' );
|
|
|
|
|
if ( $priorOptions ) {
|
|
|
|
|
$this->recordOptions( $priorOptions );
|
2020-11-05 17:04:37 +00:00
|
|
|
}
|
|
|
|
|
}
|
2020-11-10 01:47:09 +00:00
|
|
|
|
|
|
|
|
public function __get( $name ) {
|
|
|
|
|
if ( property_exists( get_called_class(), $name ) ) {
|
|
|
|
|
// Direct access to a public property, deprecated.
|
|
|
|
|
wfDeprecatedMsg( "CacheTime::{$name} public read access deprecated", '1.38' );
|
|
|
|
|
return $this->$name;
|
|
|
|
|
} elseif ( property_exists( $this, $name ) ) {
|
|
|
|
|
// Dynamic property access, deprecated.
|
|
|
|
|
wfDeprecatedMsg( "CacheTime::{$name} dynamic property read access deprecated", '1.38' );
|
|
|
|
|
return $this->$name;
|
|
|
|
|
} else {
|
|
|
|
|
trigger_error( "Inaccessible property via __set(): $name" );
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function __set( $name, $value ) {
|
|
|
|
|
if ( property_exists( get_called_class(), $name ) ) {
|
|
|
|
|
// Direct access to a public property, deprecated.
|
|
|
|
|
wfDeprecatedMsg( "CacheTime::$name public write access deprecated", '1.38' );
|
|
|
|
|
$this->$name = $value;
|
|
|
|
|
} else {
|
|
|
|
|
// Dynamic property access, deprecated.
|
|
|
|
|
wfDeprecatedMsg( "CacheTime::$name dynamic property write access deprecated", '1.38' );
|
|
|
|
|
$this->$name = $value;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-01 19:56:38 +00:00
|
|
|
}
|
2024-10-03 18:39:06 +00:00
|
|
|
|
|
|
|
|
/** @deprecated class alias since 1.43 */
|
|
|
|
|
class_alias( CacheTime::class, 'CacheTime' );
|