Localisation updates from https://translatewiki.net.
[mediawiki.git] / includes / revisiondelete / RevDelRevisionList.php
blob38678f97a02f72f512da0347e990253cf37e5a58
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
18 * @file
19 * @ingroup RevisionDelete
22 use MediaWiki\Cache\HTMLCacheUpdater;
23 use MediaWiki\Context\IContextSource;
24 use MediaWiki\HookContainer\HookContainer;
25 use MediaWiki\HookContainer\HookRunner;
26 use MediaWiki\MediaWikiServices;
27 use MediaWiki\Page\PageIdentity;
28 use MediaWiki\Revision\RevisionRecord;
29 use MediaWiki\Revision\RevisionStore;
30 use MediaWiki\Status\Status;
31 use MediaWiki\Title\Title;
32 use Wikimedia\Rdbms\FakeResultWrapper;
33 use Wikimedia\Rdbms\IResultWrapper;
34 use Wikimedia\Rdbms\LBFactory;
36 /**
37 * List for revision table items
39 * This will check both the 'revision' table for live revisions and the
40 * 'archive' table for traditionally-deleted revisions that have an
41 * ar_rev_id saved.
43 * See RevDelRevisionItem and RevDelArchivedRevisionItem for items.
45 class RevDelRevisionList extends RevDelList {
47 /** @var LBFactory */
48 private $lbFactory;
50 /** @var HookRunner */
51 private $hookRunner;
53 /** @var HTMLCacheUpdater */
54 private $htmlCacheUpdater;
56 /** @var RevisionStore */
57 private $revisionStore;
59 /** @var int */
60 public $currentRevId;
62 /**
63 * @param IContextSource $context
64 * @param PageIdentity $page
65 * @param array $ids
66 * @param LBFactory $lbFactory
67 * @param HookContainer $hookContainer
68 * @param HTMLCacheUpdater $htmlCacheUpdater
69 * @param RevisionStore $revisionStore
71 public function __construct(
72 IContextSource $context,
73 PageIdentity $page,
74 array $ids,
75 LBFactory $lbFactory,
76 HookContainer $hookContainer,
77 HTMLCacheUpdater $htmlCacheUpdater,
78 RevisionStore $revisionStore
79 ) {
80 parent::__construct( $context, $page, $ids, $lbFactory );
81 $this->lbFactory = $lbFactory;
82 $this->hookRunner = new HookRunner( $hookContainer );
83 $this->htmlCacheUpdater = $htmlCacheUpdater;
84 $this->revisionStore = $revisionStore;
87 public function getType() {
88 return 'revision';
91 public static function getRelationType() {
92 return 'rev_id';
95 public static function getRestriction() {
96 return 'deleterevision';
99 public static function getRevdelConstant() {
100 return RevisionRecord::DELETED_TEXT;
103 public static function suggestTarget( $target, array $ids ) {
104 $revisionRecord = MediaWikiServices::getInstance()
105 ->getRevisionLookup()
106 ->getRevisionById( $ids[0] );
108 if ( $revisionRecord ) {
109 return Title::newFromLinkTarget( $revisionRecord->getPageAsLinkTarget() );
111 return $target;
115 * @param \Wikimedia\Rdbms\IReadableDatabase $db
116 * @return IResultWrapper
118 public function doQuery( $db ) {
119 $ids = array_map( 'intval', $this->ids );
120 $queryBuilder = $this->revisionStore->newSelectQueryBuilder( $db )
121 ->joinComment()
122 ->joinUser()
123 ->joinPage()
124 ->where( [ 'rev_page' => $this->page->getId(), 'rev_id' => $ids ] )
125 ->orderBy( 'rev_id', \Wikimedia\Rdbms\SelectQueryBuilder::SORT_DESC )
126 // workaround for MySQL bug (T104313)
127 ->useIndex( [ 'revision' => 'PRIMARY' ] );
129 MediaWikiServices::getInstance()->getChangeTagsStore()->modifyDisplayQueryBuilder( $queryBuilder, 'revision' );
131 $live = $queryBuilder->caller( __METHOD__ )->fetchResultSet();
132 if ( $live->numRows() >= count( $ids ) ) {
133 // All requested revisions are live, keeps things simple!
134 return $live;
137 $queryBuilder = $this->revisionStore->newArchiveSelectQueryBuilder( $db )
138 ->joinComment()
139 ->where( [ 'ar_rev_id' => $ids ] )
140 ->orderBy( 'ar_rev_id', \Wikimedia\Rdbms\SelectQueryBuilder::SORT_DESC );
142 MediaWikiServices::getInstance()->getChangeTagsStore()->modifyDisplayQueryBuilder( $queryBuilder, 'archive' );
144 // Check if any requested revisions are available fully deleted.
145 $archived = $queryBuilder->caller( __METHOD__ )->fetchResultSet();
147 if ( $archived->numRows() == 0 ) {
148 return $live;
149 } elseif ( $live->numRows() == 0 ) {
150 return $archived;
151 } else {
152 // Combine the two! Whee
153 $rows = [];
154 foreach ( $live as $row ) {
155 $rows[$row->rev_id] = $row;
157 foreach ( $archived as $row ) {
158 $rows[$row->ar_rev_id] = $row;
160 krsort( $rows );
161 return new FakeResultWrapper( array_values( $rows ) );
165 public function newItem( $row ) {
166 if ( isset( $row->rev_id ) ) {
167 return new RevDelRevisionItem( $this, $row );
168 } elseif ( isset( $row->ar_rev_id ) ) {
169 return new RevDelArchivedRevisionItem( $this, $row, $this->lbFactory );
170 } else {
171 // This shouldn't happen. :)
172 throw new InvalidArgumentException( 'Invalid row type in RevDelRevisionList' );
176 public function getCurrent() {
177 if ( $this->currentRevId === null ) {
178 $dbw = $this->lbFactory->getPrimaryDatabase();
179 $this->currentRevId = $dbw->newSelectQueryBuilder()
180 ->select( 'page_latest' )
181 ->from( 'page' )
182 ->where( [ 'page_namespace' => $this->page->getNamespace(), 'page_title' => $this->page->getDBkey() ] )
183 ->caller( __METHOD__ )->fetchField();
185 return $this->currentRevId;
188 public function doPreCommitUpdates() {
189 Title::newFromPageIdentity( $this->page )->invalidateCache();
190 return Status::newGood();
193 public function doPostCommitUpdates( array $visibilityChangeMap ) {
194 $this->htmlCacheUpdater->purgeTitleUrls(
195 $this->page,
196 HTMLCacheUpdater::PURGE_INTENT_TXROUND_REFLECTED
198 // Extensions that require referencing previous revisions may need this
199 $this->hookRunner->onArticleRevisionVisibilitySet(
200 Title::newFromPageIdentity( $this->page ),
201 $this->ids,
202 $visibilityChangeMap
205 return Status::newGood();