X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Fpage%2FWikiPage.php;h=67e4d0d56c6c0b7e50b94fc5fe1fc7912be1baeb;hp=d0a04c0a315461a4410f98918704f5ceae0a354a;hb=acd0ce8e4a1af54ac473e4a9132841a7e4667a1c;hpb=a8379682a46a428320c88702c800a6107c015137 diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index d0a04c0a31..67e4d0d56c 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -88,12 +88,6 @@ class WikiPage implements Page, IDBAccessObject { */ protected $mLinksUpdated = '19700101000000'; - /** @deprecated since 1.29. Added in 1.28 for partial purging, no longer used. */ - const PURGE_CDN_CACHE = 1; - const PURGE_CLUSTER_PCACHE = 2; - const PURGE_GLOBAL_PCACHE = 4; - const PURGE_ALL = 7; - /** * Constructor and clear the article * @param Title $title Reference to a Title object. @@ -164,8 +158,11 @@ class WikiPage implements Page, IDBAccessObject { $from = self::convertSelectType( $from ); $db = wfGetDB( $from === self::READ_LATEST ? DB_MASTER : DB_REPLICA ); + $pageQuery = self::getQueryInfo(); $row = $db->selectRow( - 'page', self::selectFields(), [ 'page_id' => $id ], __METHOD__ ); + $pageQuery['tables'], $pageQuery['fields'], [ 'page_id' => $id ], __METHOD__, + [], $pageQuery['joins'] + ); if ( !$row ) { return null; } @@ -283,11 +280,14 @@ class WikiPage implements Page, IDBAccessObject { * Return the list of revision fields that should be selected to create * a new page. * + * @deprecated since 1.31, use self::getQueryInfo() instead. * @return array */ public static function selectFields() { global $wgContentHandlerUseDB, $wgPageLanguageUseDB; + wfDeprecated( __METHOD__, '1.31' ); + $fields = [ 'page_id', 'page_namespace', @@ -313,6 +313,47 @@ class WikiPage implements Page, IDBAccessObject { return $fields; } + /** + * Return the tables, fields, and join conditions to be selected to create + * a new page object. + * @since 1.31 + * @return array With three keys: + * - tables: (string[]) to include in the `$table` to `IDatabase->select()` + * - fields: (string[]) to include in the `$vars` to `IDatabase->select()` + * - joins: (array) to include in the `$join_conds` to `IDatabase->select()` + */ + public static function getQueryInfo() { + global $wgContentHandlerUseDB, $wgPageLanguageUseDB; + + $ret = [ + 'tables' => [ 'page' ], + 'fields' => [ + 'page_id', + 'page_namespace', + 'page_title', + 'page_restrictions', + 'page_is_redirect', + 'page_is_new', + 'page_random', + 'page_touched', + 'page_links_updated', + 'page_latest', + 'page_len', + ], + 'joins' => [], + ]; + + if ( $wgContentHandlerUseDB ) { + $ret['fields'][] = 'page_content_model'; + } + + if ( $wgPageLanguageUseDB ) { + $ret['fields'][] = 'page_lang'; + } + + return $ret; + } + /** * Fetch a page record with the given conditions * @param IDatabase $dbr @@ -321,14 +362,23 @@ class WikiPage implements Page, IDBAccessObject { * @return object|bool Database result resource, or false on failure */ protected function pageData( $dbr, $conditions, $options = [] ) { - $fields = self::selectFields(); + $pageQuery = self::getQueryInfo(); // Avoid PHP 7.1 warning of passing $this by reference $wikiPage = $this; - Hooks::run( 'ArticlePageDataBefore', [ &$wikiPage, &$fields ] ); + Hooks::run( 'ArticlePageDataBefore', [ + &$wikiPage, &$pageQuery['fields'], &$pageQuery['tables'], &$pageQuery['joins'] + ] ); - $row = $dbr->selectRow( 'page', $fields, $conditions, __METHOD__, $options ); + $row = $dbr->selectRow( + $pageQuery['tables'], + $pageQuery['fields'], + $conditions, + __METHOD__, + $options, + $pageQuery['joins'] + ); Hooks::run( 'ArticlePageDataAfter', [ &$wikiPage, &$row ] ); @@ -512,7 +562,7 @@ class WikiPage implements Page, IDBAccessObject { $cache = ObjectCache::getMainWANInstance(); return $cache->getWithSetCallback( - $cache->makeKey( 'page', 'content-model', $this->getLatest() ), + $cache->makeKey( 'page-content-model', $this->getLatest() ), $cache::TTL_MONTH, function () { $rev = $this->getRevision(); @@ -1134,18 +1184,6 @@ class WikiPage implements Page, IDBAccessObject { return true; } - /** - * Get the last time a user explicitly purged the page via action=purge - * - * @return string|bool TS_MW timestamp or false - * @since 1.28 - * @deprecated since 1.29. It will always return false. - */ - public function getLastPurgeTimestamp() { - wfDeprecated( __METHOD__, '1.29' ); - return false; - } - /** * Insert a new empty page record for this article. * This *must* be followed up by creating a revision @@ -1267,7 +1305,7 @@ class WikiPage implements Page, IDBAccessObject { * Add row to the redirect table if this is a redirect, remove otherwise. * * @param IDatabase $dbw - * @param Title $redirectTitle Title object pointing to the redirect target, + * @param Title|null $redirectTitle Title object pointing to the redirect target, * or NULL if this is not a redirect * @param null|bool $lastRevIsRedirect If given, will optimize adding and * removing rows in redirect table. @@ -1579,13 +1617,20 @@ class WikiPage implements Page, IDBAccessObject { $old_revision = $this->getRevision(); // current revision $old_content = $this->getContent( Revision::RAW ); // current revision's content - if ( $old_content && $old_content->getModel() !== $content->getModel() ) { - $tags[] = 'mw-contentmodelchange'; + $handler = $content->getContentHandler(); + $tag = $handler->getChangeTag( $old_content, $content, $flags ); + // If there is no applicable tag, null is returned, so we need to check + if ( $tag ) { + $tags[] = $tag; } - // Provide autosummaries if one is not provided and autosummaries are enabled + // Check for undo tag + if ( $undidRevId !== 0 && in_array( 'mw-undo', ChangeTags::getSoftwareTags() ) ) { + $tags[] = 'mw-undo'; + } + + // Provide autosummaries if summary is not provided and autosummaries are enabled if ( $wgUseAutomaticEditSummaries && ( $flags & EDIT_AUTOSUMMARY ) && $summary == '' ) { - $handler = $content->getContentHandler(); $summary = $handler->getAutosummary( $old_content, $content, $flags ); } @@ -1667,27 +1712,27 @@ class WikiPage implements Page, IDBAccessObject { throw new MWException( "Could not find text for current revision {$oldid}." ); } - // @TODO: pass content object?! - $revision = new Revision( [ - 'page' => $this->getId(), - 'title' => $this->mTitle, // for determining the default content model - 'comment' => $summary, - 'minor_edit' => $meta['minor'], - 'text' => $meta['serialized'], - 'len' => $newsize, - 'parent_id' => $oldid, - 'user' => $user->getId(), - 'user_text' => $user->getName(), - 'timestamp' => $now, - 'content_model' => $content->getModel(), - 'content_format' => $meta['serialFormat'], - ] ); - $changed = !$content->equals( $oldContent ); $dbw = wfGetDB( DB_MASTER ); if ( $changed ) { + // @TODO: pass content object?! + $revision = new Revision( [ + 'page' => $this->getId(), + 'title' => $this->mTitle, // for determining the default content model + 'comment' => $summary, + 'minor_edit' => $meta['minor'], + 'text' => $meta['serialized'], + 'len' => $newsize, + 'parent_id' => $oldid, + 'user' => $user->getId(), + 'user_text' => $user->getName(), + 'timestamp' => $now, + 'content_model' => $content->getModel(), + 'content_format' => $meta['serialFormat'], + ] ); + $prepStatus = $content->prepareSave( $this, $flags, $oldid, $user ); $status->merge( $prepStatus ); if ( !$status->isOK() ) { @@ -1753,11 +1798,9 @@ class WikiPage implements Page, IDBAccessObject { } else { // T34948: revision ID must be set to page {{REVISIONID}} and // related variables correctly. Likewise for {{REVISIONUSER}} (T135261). - $revision->setId( $this->getLatest() ); - $revision->setUserIdAndName( - $this->getUser( Revision::RAW ), - $this->getUserText( Revision::RAW ) - ); + // Since we don't insert a new revision into the database, the least + // error-prone way is to reuse given old revision. + $revision = $meta['oldRevision']; } if ( $changed ) { @@ -2171,6 +2214,7 @@ class WikiPage implements Page, IDBAccessObject { $this->getTitle(), null, $recursive, $editInfo->output ); foreach ( $updates as $update ) { + $update->setCause( 'edit-page', $user->getName() ); if ( $update instanceof LinksUpdate ) { $update->setRevision( $revision ); $update->setTriggeringUser( $user ); @@ -2805,13 +2849,13 @@ class WikiPage implements Page, IDBAccessObject { $revCommentStore = new CommentStore( 'rev_comment' ); $arCommentStore = new CommentStore( 'ar_comment' ); - $fields = Revision::selectFields(); + $revQuery = Revision::getQueryInfo(); $bitfield = false; // Bitfields to further suppress the content if ( $suppress ) { $bitfield = Revision::SUPPRESSED_ALL; - $fields = array_diff( $fields, [ 'rev_deleted' ] ); + $revQuery['fields'] = array_diff( $revQuery['fields'], [ 'rev_deleted' ] ); } // For now, shunt the revision data into the archive table. @@ -2822,14 +2866,13 @@ class WikiPage implements Page, IDBAccessObject { // the rev_deleted field, which is reserved for this purpose. // Get all of the page revisions - $commentQuery = $revCommentStore->getJoin(); $res = $dbw->select( - [ 'revision' ] + $commentQuery['tables'], - $fields + $commentQuery['fields'], + $revQuery['tables'], + $revQuery['fields'], [ 'rev_page' => $id ], __METHOD__, 'FOR UPDATE', - $commentQuery['joins'] + $revQuery['joins'] ); // Build their equivalent archive rows @@ -2913,7 +2956,7 @@ class WikiPage implements Page, IDBAccessObject { $dbw->endAtomic( __METHOD__ ); - $this->doDeleteUpdates( $id, $content, $revision ); + $this->doDeleteUpdates( $id, $content, $revision, $user ); Hooks::run( 'ArticleDeleteComplete', [ &$wikiPageBeforeDelete, @@ -2964,8 +3007,11 @@ class WikiPage implements Page, IDBAccessObject { * 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 + * @param User|null $user The user that caused the deletion */ - public function doDeleteUpdates( $id, Content $content = null, Revision $revision = null ) { + public function doDeleteUpdates( + $id, Content $content = null, Revision $revision = null, User $user = null + ) { try { $countable = $this->isCountable(); } catch ( Exception $ex ) { @@ -2983,12 +3029,14 @@ class WikiPage implements Page, IDBAccessObject { DeferredUpdates::addUpdate( $update ); } + $causeAgent = $user ? $user->getName() : 'unknown'; // Reparse any pages transcluding this page - LinksUpdate::queueRecursiveJobsForTable( $this->mTitle, 'templatelinks' ); - + LinksUpdate::queueRecursiveJobsForTable( + $this->mTitle, 'templatelinks', 'delete-page', $causeAgent ); // Reparse any pages including this image if ( $this->mTitle->getNamespace() == NS_FILE ) { - LinksUpdate::queueRecursiveJobsForTable( $this->mTitle, 'imagelinks' ); + LinksUpdate::queueRecursiveJobsForTable( + $this->mTitle, 'imagelinks', 'delete-page', $causeAgent ); } // Clear caches @@ -3170,6 +3218,10 @@ class WikiPage implements Page, IDBAccessObject { $targetContent = $target->getContent(); $changingContentModel = $targetContent->getModel() !== $current->getContentModel(); + if ( in_array( 'mw-rollback', ChangeTags::getSoftwareTags() ) ) { + $tags[] = 'mw-rollback'; + } + // Actually store the edit $status = $this->doEditContent( $targetContent, @@ -3246,7 +3298,8 @@ class WikiPage implements Page, IDBAccessObject { 'summary' => $summary, 'current' => $current, 'target' => $target, - 'newid' => $revId + 'newid' => $revId, + 'tags' => $tags ]; return []; @@ -3276,7 +3329,9 @@ class WikiPage implements Page, IDBAccessObject { MediaWikiServices::getInstance()->getLinkCache()->invalidateTitle( $title ); // Invalidate caches of articles which include this page - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'templatelinks' ) ); + DeferredUpdates::addUpdate( + new HTMLCacheUpdate( $title, 'templatelinks', 'page-create' ) + ); if ( $title->getNamespace() == NS_CATEGORY ) { // Load the Category object, which will schedule a job to create @@ -3314,7 +3369,9 @@ class WikiPage implements Page, IDBAccessObject { // Images if ( $title->getNamespace() == NS_FILE ) { - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'imagelinks' ) ); + DeferredUpdates::addUpdate( + new HTMLCacheUpdate( $title, 'imagelinks', 'page-delete' ) + ); } // User talk pages @@ -3337,10 +3394,14 @@ class WikiPage implements Page, IDBAccessObject { */ public static function onArticleEdit( Title $title, Revision $revision = null ) { // Invalidate caches of articles which include this page - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'templatelinks' ) ); + DeferredUpdates::addUpdate( + new HTMLCacheUpdate( $title, 'templatelinks', 'page-edit' ) + ); // Invalidate the caches of all pages which redirect here - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'redirect' ) ); + DeferredUpdates::addUpdate( + new HTMLCacheUpdate( $title, 'redirect', 'page-edit' ) + ); MediaWikiServices::getInstance()->getLinkCache()->invalidateTitle( $title );