// If an item is renewed, mind the cache TTL determined by config and parser functions
$since = time() - wfTimestamp( TS_UNIX, $parserOutput->getTimestamp() );
$ttl = min( $parserOutput->getCacheExpiry() - $since, 5 * 60 );
- if ( $ttl > 0 && !$parserOutput->getFlag( 'vary-revision' ) ) {
+
+ // Note: ParserOutput with that contains secondary data update callbacks can not be
+ // stashed, since the callbacks are not serializable (see ParserOtput::__sleep).
+ // The first data update returned by getSecondaryDataUpdates() is always a LinksUpdate
+ // instance generated on the fly, so it can be ignored in this context.
+ $hasCustomDataUpdates = count( $parserOutput->getSecondaryDataUpdates() ) > 1;
+
+ if ( $ttl > 0 && !$parserOutput->getFlag( 'vary-revision' ) && !$hasCustomDataUpdates ) {
// Only store what is actually needed
$stashInfo = (object)array(
'pstContent' => $pstContent,
$mTOCEnabled = true; # Whether TOC should be shown, can't override __NOTOC__
private $mIndexPolicy = ''; # 'index' or 'noindex'? Any other value will result in no change.
private $mAccessedOptions = array(); # List of ParserOptions (stored in the keys)
- private $mSecondaryDataUpdates = array(); # List of DataUpdate, used to save info from the page somewhere else.
+ private $mSecondaryDataUpdates = null; # List of DataUpdate, used to save info from the page somewhere else.
private $mExtensionData = array(); # extra data used by extensions
private $mLimitReportData = array(); # Parser limit report data
private $mParseStartTime = array(); # Timestamps for getTimeSinceStart()
$this->mCategories = $categoryLinks;
$this->mContainsOldMagic = $containsOldMagic;
$this->mTitleText = $titletext;
+
+ $this->mSecondaryDataUpdates = array();
}
public function getText() {
* be created based on $this->getTitleText()
* @param bool $recursive Queue jobs for recursive updates?
*
+ * @throws MWException if called on a ParserOutput instance that was restored from serialization.
+ * DataUpdates are generally not serializable, so after serialization, they are undefined.
+ *
* @return array An array of instances of DataUpdate
*/
public function getSecondaryDataUpdates( Title $title = null, $recursive = true ) {
$title = Title::newFromText( $this->getTitleText() );
}
+ if ( $this->mSecondaryDataUpdates === null ) {
+ //NOTE: This happens when mSecondaryDataUpdates are lost during serialization
+ // (see __sleep below). After (un)serialization, getSecondaryDataUpdates()
+ // has no defined behavior, and should throw an exception.
+ throw new MWException( 'getSecondaryDataUpdates() must not be called on ParserOutput restored from serialization.' );
+ }
+
+ // NOTE: ApiStashEdit knows about this "magic" update object. If this goes away,
+ // ApiStashEdit::buildStashValue needs to be adjusted.
$linksUpdate = new LinksUpdate( $title, $this, $recursive );
return array_merge( $this->mSecondaryDataUpdates, array( $linksUpdate ) );