X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fpage%2FWikiPage.php;h=e7352af4e06dca38d691051da97686d90e30512a;hb=3a922d36d8741e34d9ce46cb601e1f356dcf844d;hp=8d9d5a8628383d91bd0920bbd0359d3acf7070fe;hpb=267f63db658dab6592830e1299f9564ece328e36;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index 8d9d5a8628..e7352af4e0 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -20,6 +20,8 @@ * @file */ +use \MediaWiki\Logger\LoggerFactory; + /** * Class representing a MediaWiki article and history. * @@ -1101,15 +1103,10 @@ class WikiPage implements Page, IDBAccessObject { return false; } - $title = $this->mTitle; - wfGetDB( DB_MASTER )->onTransactionIdle( function() use ( $title ) { - // Invalidate the cache in auto-commit mode - $title->invalidateCache(); - } ); - + $this->mTitle->invalidateCache(); // Send purge after above page_touched update was committed DeferredUpdates::addUpdate( - new CdnCacheUpdate( $title->getCdnUrls() ), + new CdnCacheUpdate( $this->mTitle->getCdnUrls() ), DeferredUpdates::PRESEND ); @@ -1813,30 +1810,31 @@ class WikiPage implements Page, IDBAccessObject { } // Do secondary updates once the main changes have been committed... - $that = $this; - $dbw->onTransactionIdle( - function () use ( - $dbw, &$that, $revision, &$user, $content, $summary, &$flags, - $changed, $meta, &$status - ) { - // Do per-page updates in a transaction - $dbw->setFlag( DBO_TRX ); - // Update links tables, site stats, etc. - $that->doEditUpdates( - $revision, - $user, - [ - 'changed' => $changed, - 'oldcountable' => $meta['oldCountable'], - 'oldrevision' => $meta['oldRevision'] - ] - ); - // Trigger post-save hook - $params = [ &$that, &$user, $content, $summary, $flags & EDIT_MINOR, - null, null, &$flags, $revision, &$status, $meta['baseRevId'] ]; - ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $params ); - Hooks::run( 'PageContentSaveComplete', $params ); - } + DeferredUpdates::addUpdate( + new AtomicSectionUpdate( + $dbw, + __METHOD__, + function () use ( + $revision, &$user, $content, $summary, &$flags, + $changed, $meta, &$status + ) { + // Update links tables, site stats, etc. + $this->doEditUpdates( + $revision, + $user, + [ + 'changed' => $changed, + 'oldcountable' => $meta['oldCountable'], + 'oldrevision' => $meta['oldRevision'] + ] + ); + // Trigger post-save hook + $params = [ &$this, &$user, $content, $summary, $flags & EDIT_MINOR, + null, null, &$flags, $revision, &$status, $meta['baseRevId'] ]; + ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $params ); + Hooks::run( 'PageContentSaveComplete', $params ); + } + ) ); return $status; @@ -1941,26 +1939,27 @@ class WikiPage implements Page, IDBAccessObject { $status->value['revision'] = $revision; // Do secondary updates once the main changes have been committed... - $that = $this; - $dbw->onTransactionIdle( - function () use ( - &$that, $dbw, $revision, &$user, $content, $summary, &$flags, $meta, &$status - ) { - // Do per-page updates in a transaction - $dbw->setFlag( DBO_TRX ); - // Update links, etc. - $that->doEditUpdates( $revision, $user, [ 'created' => true ] ); - // Trigger post-create hook - $params = [ &$that, &$user, $content, $summary, - $flags & EDIT_MINOR, null, null, &$flags, $revision ]; - ContentHandler::runLegacyHooks( 'ArticleInsertComplete', $params ); - Hooks::run( 'PageContentInsertComplete', $params ); - // Trigger post-save hook - $params = array_merge( $params, [ &$status, $meta['baseRevId'] ] ); - ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $params ); - Hooks::run( 'PageContentSaveComplete', $params ); + DeferredUpdates::addUpdate( + new AtomicSectionUpdate( + $dbw, + __METHOD__, + function () use ( + $revision, &$user, $content, $summary, &$flags, $meta, &$status + ) { + // Update links, etc. + $this->doEditUpdates( $revision, $user, [ 'created' => true ] ); + // Trigger post-create hook + $params = [ &$this, &$user, $content, $summary, + $flags & EDIT_MINOR, null, null, &$flags, $revision ]; + ContentHandler::runLegacyHooks( 'ArticleInsertComplete', $params ); + Hooks::run( 'PageContentInsertComplete', $params ); + // Trigger post-save hook + $params = array_merge( $params, [ &$status, $meta['baseRevId'] ] ); + ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $params ); + Hooks::run( 'PageContentSaveComplete', $params ); - } + } + ) ); return $status; @@ -2106,6 +2105,16 @@ class WikiPage implements Page, IDBAccessObject { } } ); + } else { + // Try to avoid a second parse if {{REVISIONID}} is used + $edit->popts->setSpeculativeRevIdCallback( function () { + return 1 + (int)wfGetDB( DB_MASTER )->selectField( + 'revision', + 'MAX(rev_id)', + [], + __METHOD__ + ); + } ); } $edit->output = $edit->pstContent ? $edit->pstContent->getParserOutput( $this->mTitle, $revid, $edit->popts ) @@ -2168,14 +2177,20 @@ class WikiPage implements Page, IDBAccessObject { ]; $content = $revision->getContent(); + $logger = LoggerFactory::getInstance( 'SaveParse' ); + // See if the parser output before $revision was inserted is still valid $editInfo = false; if ( !$this->mPreparedEdit ) { - wfDebug( __METHOD__ . ": No prepared edit...\n" ); + $logger->debug( __METHOD__ . ": No prepared edit...\n" ); } elseif ( $this->mPreparedEdit->output->getFlag( 'vary-revision' ) ) { - wfDebug( __METHOD__ . ": Prepared edit has vary-revision...\n" ); + $logger->info( __METHOD__ . ": Prepared edit has vary-revision...\n" ); + } elseif ( $this->mPreparedEdit->output->getFlag( 'vary-revision-id' ) + && $this->mPreparedEdit->output->getSpeculativeRevIdUsed() !== $revision->getId() + ) { + $logger->info( __METHOD__ . ": Prepared edit has vary-revision-id with wrong ID...\n" ); } elseif ( $this->mPreparedEdit->output->getFlag( 'vary-user' ) && !$options['changed'] ) { - wfDebug( __METHOD__ . ": Prepared edit has vary-user and is null...\n" ); + $logger->info( __METHOD__ . ": Prepared edit has vary-user and is null...\n" ); } else { wfDebug( __METHOD__ . ": Using prepared edit...\n" ); $editInfo = $this->mPreparedEdit; @@ -3261,6 +3276,14 @@ class WikiPage implements Page, IDBAccessObject { $title->touchLinks(); $title->purgeSquid(); $title->deleteTitleProtection(); + + if ( $title->getNamespace() == NS_CATEGORY ) { + // Load the Category object, which will schedule a job to create + // the category table row if necessary. Checking a slave is ok + // here, in the worst case it'll run an unnecessary recount job on + // a category that probably doesn't have many members. + Category::newFromTitle( $title )->getID(); + } } /** @@ -3427,16 +3450,16 @@ class WikiPage implements Page, IDBAccessObject { * * @param array $added The names of categories that were added * @param array $deleted The names of categories that were deleted + * @param integer $id Page ID (this should be the original deleted page ID) */ - public function updateCategoryCounts( array $added, array $deleted ) { - $that = $this; - $method = __METHOD__; + public function updateCategoryCounts( array $added, array $deleted, $id = 0 ) { + $id = $id ?: $this->getId(); $dbw = wfGetDB( DB_MASTER ); - + $method = __METHOD__; // Do this at the end of the commit to reduce lock wait timeouts $dbw->onTransactionPreCommitOrIdle( - function () use ( $dbw, $that, $method, $added, $deleted ) { - $ns = $that->getTitle()->getNamespace(); + function () use ( $dbw, $added, $deleted, $id, $method ) { + $ns = $this->getTitle()->getNamespace(); $addFields = [ 'cat_pages = cat_pages + 1' ]; $removeFields = [ 'cat_pages = cat_pages - 1' ]; @@ -3453,7 +3476,7 @@ class WikiPage implements Page, IDBAccessObject { 'category', 'cat_title', [ 'cat_title' => $added ], - __METHOD__ + $method ); // For category rows that already exist, do a plain @@ -3464,7 +3487,7 @@ class WikiPage implements Page, IDBAccessObject { 'category', $addFields, [ 'cat_title' => $existingAdded ], - __METHOD__ + $method ); } @@ -3500,12 +3523,28 @@ class WikiPage implements Page, IDBAccessObject { foreach ( $added as $catName ) { $cat = Category::newFromName( $catName ); - Hooks::run( 'CategoryAfterPageAdded', [ $cat, $that ] ); + Hooks::run( 'CategoryAfterPageAdded', [ $cat, $this ] ); } foreach ( $deleted as $catName ) { $cat = Category::newFromName( $catName ); - Hooks::run( 'CategoryAfterPageRemoved', [ $cat, $that ] ); + Hooks::run( 'CategoryAfterPageRemoved', [ $cat, $this, $id ] ); + } + + // Refresh counts on categories that should be empty now, to + // trigger possible deletion. Check master for the most + // up-to-date cat_pages. + if ( count( $deleted ) ) { + $rows = $dbw->select( + 'category', + [ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ], + [ 'cat_title' => $deleted, 'cat_pages <= 0' ], + $method + ); + foreach ( $rows as $row ) { + $cat = Category::newFromRow( $row ); + $cat->refreshCounts(); + } } } );