MediaWiki REL1_39
RevDelRevisionList.php
Go to the documentation of this file.
1<?php
31
42
44 private $lbFactory;
45
47 private $hookRunner;
48
50 private $htmlCacheUpdater;
51
53 private $revisionStore;
54
56 private $wanObjectCache;
57
60
71 public function __construct(
72 IContextSource $context,
74 array $ids,
75 LBFactory $lbFactory,
76 HookContainer $hookContainer,
77 HtmlCacheUpdater $htmlCacheUpdater,
78 RevisionStore $revisionStore,
79 WANObjectCache $wanObjectCache
80 ) {
81 parent::__construct( $context, $page, $ids, $lbFactory );
82 $this->lbFactory = $lbFactory;
83 $this->hookRunner = new HookRunner( $hookContainer );
84 $this->htmlCacheUpdater = $htmlCacheUpdater;
85 $this->revisionStore = $revisionStore;
86 $this->wanObjectCache = $wanObjectCache;
87 }
88
89 public function getType() {
90 return 'revision';
91 }
92
93 public static function getRelationType() {
94 return 'rev_id';
95 }
96
97 public static function getRestriction() {
98 return 'deleterevision';
99 }
100
101 public static function getRevdelConstant() {
102 return RevisionRecord::DELETED_TEXT;
103 }
104
105 public static function suggestTarget( $target, array $ids ) {
106 $revisionRecord = MediaWikiServices::getInstance()
107 ->getRevisionLookup()
108 ->getRevisionById( $ids[0] );
109
110 if ( $revisionRecord ) {
111 return Title::newFromLinkTarget( $revisionRecord->getPageAsLinkTarget() );
112 }
113 return $target;
114 }
115
120 public function doQuery( $db ) {
121 $ids = array_map( 'intval', $this->ids );
122 $revQuery = $this->revisionStore->getQueryInfo( [ 'page', 'user' ] );
123 $queryInfo = [
124 'tables' => $revQuery['tables'],
125 'fields' => $revQuery['fields'],
126 'conds' => [
127 'rev_page' => $this->page->getId(),
128 'rev_id' => $ids,
129 ],
130 'options' => [
131 'ORDER BY' => 'rev_id DESC',
132 'USE INDEX' => [ 'revision' => 'PRIMARY' ] // workaround for MySQL bug (T104313)
133 ],
134 'join_conds' => $revQuery['joins'],
135 ];
137 $queryInfo['tables'],
138 $queryInfo['fields'],
139 $queryInfo['conds'],
140 $queryInfo['join_conds'],
141 $queryInfo['options'],
142 ''
143 );
144
145 $live = $db->select(
146 $queryInfo['tables'],
147 $queryInfo['fields'],
148 $queryInfo['conds'],
149 __METHOD__,
150 $queryInfo['options'],
151 $queryInfo['join_conds']
152 );
153 if ( $live->numRows() >= count( $ids ) ) {
154 // All requested revisions are live, keeps things simple!
155 return $live;
156 }
157
158 $arQuery = $this->revisionStore->getArchiveQueryInfo();
159 $archiveQueryInfo = [
160 'tables' => $arQuery['tables'],
161 'fields' => $arQuery['fields'],
162 'conds' => [
163 'ar_rev_id' => $ids,
164 ],
165 'options' => [ 'ORDER BY' => 'ar_rev_id DESC' ],
166 'join_conds' => $arQuery['joins'],
167 ];
168
170 $archiveQueryInfo['tables'],
171 $archiveQueryInfo['fields'],
172 $archiveQueryInfo['conds'],
173 $archiveQueryInfo['join_conds'],
174 $archiveQueryInfo['options'],
175 ''
176 );
177
178 // Check if any requested revisions are available fully deleted.
179 $archived = $db->select(
180 $archiveQueryInfo['tables'],
181 $archiveQueryInfo['fields'],
182 $archiveQueryInfo['conds'],
183 __METHOD__,
184 $archiveQueryInfo['options'],
185 $archiveQueryInfo['join_conds']
186 );
187
188 if ( $archived->numRows() == 0 ) {
189 return $live;
190 } elseif ( $live->numRows() == 0 ) {
191 return $archived;
192 } else {
193 // Combine the two! Whee
194 $rows = [];
195 foreach ( $live as $row ) {
196 $rows[$row->rev_id] = $row;
197 }
198 foreach ( $archived as $row ) {
199 $rows[$row->ar_rev_id] = $row;
200 }
201 krsort( $rows );
202 return new FakeResultWrapper( array_values( $rows ) );
203 }
204 }
205
206 public function newItem( $row ) {
207 if ( isset( $row->rev_id ) ) {
208 return new RevDelRevisionItem( $this, $row );
209 } elseif ( isset( $row->ar_rev_id ) ) {
210 return new RevDelArchivedRevisionItem( $this, $row );
211 } else {
212 // This shouldn't happen. :)
213 throw new MWException( 'Invalid row type in RevDelRevisionList' );
214 }
215 }
216
217 public function getCurrent() {
218 if ( $this->currentRevId === null ) {
219 $dbw = $this->lbFactory->getMainLB()->getConnectionRef( DB_PRIMARY );
220 $this->currentRevId = $dbw->selectField(
221 'page',
222 'page_latest',
223 [ 'page_namespace' => $this->page->getNamespace(), 'page_title' => $this->page->getDBkey() ],
224 __METHOD__
225 );
226 }
227 return $this->currentRevId;
228 }
229
230 public function getSuppressBit() {
231 return RevisionRecord::DELETED_RESTRICTED;
232 }
233
234 public function doPreCommitUpdates() {
235 Title::castFromPageIdentity( $this->page )->invalidateCache();
236 return Status::newGood();
237 }
238
239 public function doPostCommitUpdates( array $visibilityChangeMap ) {
240 $this->htmlCacheUpdater->purgeTitleUrls(
241 $this->page,
242 HtmlCacheUpdater::PURGE_INTENT_TXROUND_REFLECTED
243 );
244 // Extensions that require referencing previous revisions may need this
245 $this->hookRunner->onArticleRevisionVisibilitySet(
246 // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here
247 Title::castFromPageIdentity( $this->page ),
248 $this->ids,
249 $visibilityChangeMap
250 );
251 $this->wanObjectCache->touchCheckKey(
252 "RevDelRevisionList:page:{$this->page->getID()}}"
253 );
254
255 return Status::newGood();
256 }
257}
static modifyDisplayQuery(&$tables, &$fields, &$conds, &$join_conds, &$options, $filter_tag='', bool $exclude=false)
Applies all tags-related changes to a query.
Class to invalidate the CDN and HTMLFileCache entries associated with URLs/titles.
MediaWiki exception.
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Service locator for MediaWiki core services.
Page revision base class.
Service for looking up page revisions.
Item class for a archive table row by ar_rev_id – actually used via RevDelRevisionList.
List for revision table items.
getSuppressBit()
Get the integer value of the flag used for suppression.
doPostCommitUpdates(array $visibilityChangeMap)
A hook for setVisibility(): do any necessary updates post-commit.
static getRevdelConstant()
Get the revision deletion constant for this list type Override this function.
static getRelationType()
Get the DB field name associated with the ID list.
static suggestTarget( $target, array $ids)
Suggest a target for the revision deletion Optionally override this function.
static getRestriction()
Get the user right required for this list type Override this function.
doPreCommitUpdates()
A hook for setVisibility(): do batch updates pre-commit.
getType()
Get the internal type name of this list.
newItem( $row)
Create an item object from a DB result row.
__construct(IContextSource $context, PageIdentity $page, array $ids, LBFactory $lbFactory, HookContainer $hookContainer, HtmlCacheUpdater $htmlCacheUpdater, RevisionStore $revisionStore, WANObjectCache $wanObjectCache)
Multi-datacenter aware caching interface.
Overloads the relevant methods of the real ResultWrapper so it doesn't go anywhere near an actual dat...
Interface for objects which can provide a MediaWiki context on request.
Interface for objects (potentially) representing an editable wiki page.
Basic database interface for live and lazy-loaded relation database handles.
Definition IDatabase.php:39
const DB_PRIMARY
Definition defines.php:28