X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Fpage%2FWikiPage.php;h=dd78d198529c4a7dd8c55a558ad105244d206dbb;hp=c7915877817ff33d0d6c0002e4803680f8bcd4cf;hb=939199bcea28a3b13c49c0f808d11d415660b924;hpb=a90d652c509436aaa0eecfaf140bb87e0cc2a12d diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index c791587781..dd78d19852 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -121,6 +121,11 @@ class WikiPage implements Page, IDBAccessObject { throw new MWException( "Invalid or virtual namespace $ns given." ); } + $page = null; + if ( !Hooks::run( 'WikiPageFactory', [ $title, &$page ] ) ) { + return $page; + } + switch ( $ns ) { case NS_FILE: $page = new WikiFilePage( $title ); @@ -2394,6 +2399,10 @@ class WikiPage implements Page, IDBAccessObject { } elseif ( $options['changed'] ) { // bug 50785 self::onArticleEdit( $this->mTitle, $revision ); } + + ResourceLoaderWikiModule::invalidateModuleCache( + $this->mTitle, $options['oldrevision'], $revision, wfWikiID() + ); } /** @@ -2476,13 +2485,13 @@ class WikiPage implements Page, IDBAccessObject { } if ( !$protect ) { // No protection at all means unprotection - $revCommentMsg = 'unprotectedarticle'; + $revCommentMsg = 'unprotectedarticle-comment'; $logAction = 'unprotect'; } elseif ( $isProtected ) { - $revCommentMsg = 'modifiedarticleprotection'; + $revCommentMsg = 'modifiedarticleprotection-comment'; $logAction = 'modify'; } else { - $revCommentMsg = 'protectedarticle'; + $revCommentMsg = 'protectedarticle-comment'; $logAction = 'protect'; } @@ -2666,16 +2675,14 @@ class WikiPage implements Page, IDBAccessObject { public function insertProtectNullRevision( $revCommentMsg, array $limit, array $expiry, $cascade, $reason, $user = null ) { - global $wgContLang; $dbw = wfGetDB( DB_MASTER ); // Prepare a null revision to be added to the history - $editComment = $wgContLang->ucfirst( - wfMessage( - $revCommentMsg, - $this->mTitle->getPrefixedText() - )->inContentLanguage()->text() - ); + $editComment = wfMessage( + $revCommentMsg, + $this->mTitle->getPrefixedText(), + $user ? $user->getName() : '' + )->inContentLanguage()->text(); if ( $reason ) { $editComment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason; } @@ -2907,6 +2914,7 @@ class WikiPage implements Page, IDBAccessObject { // unless they actually try to catch exceptions (which is rare). // we need to remember the old content so we can use it to generate all deletion updates. + $revision = $this->getRevision(); try { $content = $this->getContent( Revision::RAW ); } catch ( Exception $ex ) { @@ -2916,17 +2924,13 @@ class WikiPage implements Page, IDBAccessObject { $content = null; } + $fields = Revision::selectFields(); + $bitfield = false; + // Bitfields to further suppress the content if ( $suppress ) { - $bitfield = 0; - // This should be 15... - $bitfield |= Revision::DELETED_TEXT; - $bitfield |= Revision::DELETED_COMMENT; - $bitfield |= Revision::DELETED_USER; - $bitfield |= Revision::DELETED_RESTRICTED; - $deletionFields = [ $dbw->addQuotes( $bitfield ) . ' AS deleted' ]; - } else { - $deletionFields = [ 'rev_deleted AS deleted' ]; + $bitfield = Revision::SUPPRESSED_ALL; + $fields = array_diff( $fields, [ 'rev_deleted' ] ); } // For now, shunt the revision data into the archive table. @@ -2937,10 +2941,9 @@ class WikiPage implements Page, IDBAccessObject { // the rev_deleted field, which is reserved for this purpose. // Get all of the page revisions - $fields = array_diff( Revision::selectFields(), [ 'rev_deleted' ] ); $res = $dbw->select( 'revision', - array_merge( $fields, $deletionFields ), + $fields, [ 'rev_page' => $id ], __METHOD__, 'FOR UPDATE' @@ -2963,7 +2966,7 @@ class WikiPage implements Page, IDBAccessObject { 'ar_flags' => '', 'ar_len' => $row->rev_len, 'ar_page_id' => $id, - 'ar_deleted' => $row->deleted, + 'ar_deleted' => $suppress ? $bitfield : $row->rev_deleted, 'ar_sha1' => $row->rev_sha1, ]; if ( $wgContentHandlerUseDB ) { @@ -3006,7 +3009,7 @@ class WikiPage implements Page, IDBAccessObject { $dbw->endAtomic( __METHOD__ ); - $this->doDeleteUpdates( $id, $content ); + $this->doDeleteUpdates( $id, $content, $revision ); Hooks::run( 'ArticleDeleteComplete', [ &$wikiPageBeforeDelete, @@ -3053,11 +3056,12 @@ class WikiPage implements Page, IDBAccessObject { * Do some database updates after deletion * * @param int $id The page_id value of the page being deleted - * @param Content $content Optional page content to be used when determining + * @param Content|null $content Optional page content to be used when determining * the required updates. This may be needed because $this->getContent() * may already return null when the page proper was deleted. + * @param Revision|null $revision The latest page revision */ - public function doDeleteUpdates( $id, Content $content = null ) { + public function doDeleteUpdates( $id, Content $content = null, Revision $revision = null ) { try { $countable = $this->isCountable(); } catch ( Exception $ex ) { @@ -3085,6 +3089,9 @@ class WikiPage implements Page, IDBAccessObject { // Clear caches WikiPage::onArticleDelete( $this->mTitle ); + ResourceLoaderWikiModule::invalidateModuleCache( + $this->mTitle, $revision, null, wfWikiID() + ); // Reset this object and the Title object $this->loadFromRow( false, self::READ_LATEST ); @@ -3542,107 +3549,103 @@ class WikiPage implements Page, IDBAccessObject { * Update all the appropriate counts in the category table, given that * we've added the categories $added and deleted the categories $deleted. * + * This should only be called from deferred updates or jobs to avoid contention. + * * @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, $id = 0 ) { $id = $id ?: $this->getId(); + $ns = $this->getTitle()->getNamespace(); + + $addFields = [ 'cat_pages = cat_pages + 1' ]; + $removeFields = [ 'cat_pages = cat_pages - 1' ]; + if ( $ns == NS_CATEGORY ) { + $addFields[] = 'cat_subcats = cat_subcats + 1'; + $removeFields[] = 'cat_subcats = cat_subcats - 1'; + } elseif ( $ns == NS_FILE ) { + $addFields[] = 'cat_files = cat_files + 1'; + $removeFields[] = 'cat_files = cat_files - 1'; + } + $dbw = wfGetDB( DB_MASTER ); - $method = __METHOD__; - // Do this at the end of the commit to reduce lock wait timeouts - $dbw->onTransactionPreCommitOrIdle( - function () use ( $dbw, $added, $deleted, $id, $method ) { - $ns = $this->getTitle()->getNamespace(); - - $addFields = [ 'cat_pages = cat_pages + 1' ]; - $removeFields = [ 'cat_pages = cat_pages - 1' ]; - if ( $ns == NS_CATEGORY ) { - $addFields[] = 'cat_subcats = cat_subcats + 1'; - $removeFields[] = 'cat_subcats = cat_subcats - 1'; - } elseif ( $ns == NS_FILE ) { - $addFields[] = 'cat_files = cat_files + 1'; - $removeFields[] = 'cat_files = cat_files - 1'; - } - if ( count( $added ) ) { - $existingAdded = $dbw->selectFieldValues( - 'category', - 'cat_title', - [ 'cat_title' => $added ], - $method - ); + if ( count( $added ) ) { + $existingAdded = $dbw->selectFieldValues( + 'category', + 'cat_title', + [ 'cat_title' => $added ], + __METHOD__ + ); - // For category rows that already exist, do a plain - // UPDATE instead of INSERT...ON DUPLICATE KEY UPDATE - // to avoid creating gaps in the cat_id sequence. - if ( count( $existingAdded ) ) { - $dbw->update( - 'category', - $addFields, - [ 'cat_title' => $existingAdded ], - $method - ); - } + // For category rows that already exist, do a plain + // UPDATE instead of INSERT...ON DUPLICATE KEY UPDATE + // to avoid creating gaps in the cat_id sequence. + if ( count( $existingAdded ) ) { + $dbw->update( + 'category', + $addFields, + [ 'cat_title' => $existingAdded ], + __METHOD__ + ); + } - $missingAdded = array_diff( $added, $existingAdded ); - if ( count( $missingAdded ) ) { - $insertRows = []; - foreach ( $missingAdded as $cat ) { - $insertRows[] = [ - 'cat_title' => $cat, - 'cat_pages' => 1, - 'cat_subcats' => ( $ns == NS_CATEGORY ) ? 1 : 0, - 'cat_files' => ( $ns == NS_FILE ) ? 1 : 0, - ]; - } - $dbw->upsert( - 'category', - $insertRows, - [ 'cat_title' ], - $addFields, - $method - ); - } + $missingAdded = array_diff( $added, $existingAdded ); + if ( count( $missingAdded ) ) { + $insertRows = []; + foreach ( $missingAdded as $cat ) { + $insertRows[] = [ + 'cat_title' => $cat, + 'cat_pages' => 1, + 'cat_subcats' => ( $ns == NS_CATEGORY ) ? 1 : 0, + 'cat_files' => ( $ns == NS_FILE ) ? 1 : 0, + ]; } + $dbw->upsert( + 'category', + $insertRows, + [ 'cat_title' ], + $addFields, + __METHOD__ + ); + } + } - if ( count( $deleted ) ) { - $dbw->update( - 'category', - $removeFields, - [ 'cat_title' => $deleted ], - $method - ); - } + if ( count( $deleted ) ) { + $dbw->update( + 'category', + $removeFields, + [ 'cat_title' => $deleted ], + __METHOD__ + ); + } - foreach ( $added as $catName ) { - $cat = Category::newFromName( $catName ); - Hooks::run( 'CategoryAfterPageAdded', [ $cat, $this ] ); - } + foreach ( $added as $catName ) { + $cat = Category::newFromName( $catName ); + Hooks::run( 'CategoryAfterPageAdded', [ $cat, $this ] ); + } - foreach ( $deleted as $catName ) { - $cat = Category::newFromName( $catName ); - Hooks::run( 'CategoryAfterPageRemoved', [ $cat, $this, $id ] ); - } + foreach ( $deleted as $catName ) { + $cat = Category::newFromName( $catName ); + 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(); - } - } - }, - __METHOD__ - ); + // 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(); + } + } } /**