* @return bool
*/
public function isParserCacheUsed( ParserOptions $parserOptions, $oldid ) {
- global $wgEnableParserCache;
-
- return $wgEnableParserCache
- && $parserOptions->getStubThreshold() == 0
+ return $parserOptions->getStubThreshold() == 0
&& $this->exists()
&& ( $oldid === null || $oldid === 0 || $oldid === $this->getLatest() )
&& $this->getContentHandler()->isParserCacheSupported();
$useParserCache = $this->isParserCacheUsed( $parserOptions, $oldid );
wfDebug( __METHOD__ . ': using parser cache: ' . ( $useParserCache ? 'yes' : 'no' ) . "\n" );
if ( $parserOptions->getStubThreshold() ) {
- wfIncrStats( 'pcache_miss_stub' );
+ wfIncrStats( 'pcache.miss.stub' );
}
if ( $useParserCache ) {
$status->value['revision'] = $revision;
$hook_args = array( &$this, &$user, $content, $summary,
- $flags & EDIT_MINOR, null, null, &$flags, $revision, &$status, $baseRevId );
+ $flags & EDIT_MINOR, null, null, &$flags, $revision, &$status, $baseRevId );
ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $hook_args );
Hooks::run( 'PageContentSaveComplete', $hook_args );
// Promote user to any groups they meet the criteria for
- $dbw->onTransactionIdle( function () use ( $user ) {
+ DeferredUpdates::addCallableUpdate( function () use ( $user ) {
$user->addAutopromoteOnceGroups( 'onEdit' );
$user->addAutopromoteOnceGroups( 'onView' ); // b/c
} );
* - 'no-change': don't update the article count, ever
*/
public function doEditUpdates( Revision $revision, User $user, array $options = array() ) {
- global $wgEnableParserCache;
-
$options += array(
'changed' => true,
'created' => false,
}
// Save it to the parser cache
- if ( $wgEnableParserCache ) {
- $parserCache = ParserCache::singleton();
- $parserCache->save(
- $editInfo->output, $this, $editInfo->popts, $editInfo->timestamp, $editInfo->revid
- );
- }
+ ParserCache::singleton()->save(
+ $editInfo->output, $this, $editInfo->popts, $editInfo->timestamp, $editInfo->revid
+ );
// Update the links tables and other secondary data
if ( $content ) {
$dbw->begin( __METHOD__ );
if ( $id == 0 ) {
- $this->loadPageData( 'forupdate' );
+ // T98706: lock the page from various other updates but avoid using
+ // WikiPage::READ_LOCKING as that will carry over the FOR UPDATE to
+ // the revisions queries (which also JOIN on user). Only lock the page
+ // row and CAS check on page_latest to see if the trx snapshot matches.
+ $latest = $this->lock();
+
+ $this->loadPageData( WikiPage::READ_LATEST );
$id = $this->getID();
- if ( $id == 0 ) {
+ if ( $id == 0 || $this->getLatest() != $latest ) {
+ // Page not there or trx snapshot is stale
$dbw->rollback( __METHOD__ );
$status->error( 'cannotdelete', wfEscapeWikiText( $this->getTitle()->getPrefixedText() ) );
return $status;
return $status;
}
+ /**
+ * Lock the page row for this title and return page_latest (or 0)
+ *
+ * @return integer
+ */
+ protected function lock() {
+ return (int)wfGetDB( DB_MASTER )->selectField(
+ 'page',
+ 'page_latest',
+ array(
+ 'page_namespace' => $this->getTitle()->getNamespace(),
+ 'page_title' => $this->getTitle()->getDBkey()
+ ),
+ __METHOD__,
+ array( 'FOR UPDATE' )
+ );
+ }
+
/**
* Do some database updates after deletion
*