* Added generic Rev_List revision listing class and refactored RevDelete_List stuff...
[lhc/web/wiklou.git] / includes / RevisionList.php
1 <?php
2 /**
3 * List for revision table items for a single page
4 */
5 abstract class Rev_List {
6 /**
7 * @var Title
8 */
9 var $title;
10 /**
11 * @var RequestContext
12 */
13 var $context;
14
15 var $ids, $res, $current;
16
17 function __construct( RequestContext $context, Title $title, array $ids ) {
18 $this->context = $context;
19 $this->title = $title;
20 $this->ids = $ids;
21 }
22
23 /**
24 * Get the internal type name of this list. Equal to the table name.
25 * Override this function.
26 */
27 public function getType() {
28 return null;
29 }
30
31 /**
32 * Initialise the current iteration pointer
33 */
34 protected function initCurrent() {
35 $row = $this->res->current();
36 if ( $row ) {
37 $this->current = $this->newItem( $row );
38 } else {
39 $this->current = false;
40 }
41 }
42
43 /**
44 * Start iteration. This must be called before current() or next().
45 * @return First list item
46 */
47 public function reset() {
48 if ( !$this->res ) {
49 $this->res = $this->doQuery( wfGetDB( DB_SLAVE ) );
50 } else {
51 $this->res->rewind();
52 }
53 $this->initCurrent();
54 return $this->current;
55 }
56
57 /**
58 * Get the current list item, or false if we are at the end
59 */
60 public function current() {
61 return $this->current;
62 }
63
64 /**
65 * Move the iteration pointer to the next list item, and return it.
66 */
67 public function next() {
68 $this->res->next();
69 $this->initCurrent();
70 return $this->current;
71 }
72
73 /**
74 * Get the number of items in the list.
75 */
76 public function length() {
77 if( !$this->res ) {
78 return 0;
79 } else {
80 return $this->res->numRows();
81 }
82 }
83
84 /**
85 * Do the DB query to iterate through the objects.
86 * @param $db DatabaseBase object to use for the query
87 */
88 abstract public function doQuery( $db );
89
90 /**
91 * Create an item object from a DB result row
92 * @param $row stdclass
93 */
94 abstract public function newItem( $row );
95
96 /**
97 * Get the language of the user doing the action
98 *
99 * @return Language object
100 */
101 public function getLang() {
102 return $this->context->getLang();
103 }
104
105 /**
106 * Get the user doing the action
107 *
108 * @return User object
109 */
110 public function getUser() {
111 return $this->context->getUser();
112 }
113 }
114
115 /**
116 * Abstract base class for revision items
117 */
118 abstract class Rev_Item {
119 /** The parent Rev_List */
120 var $list;
121
122 /** The DB result row */
123 var $row;
124
125 /**
126 * @param $list Rev_List
127 * @param $row DB result row
128 */
129 public function __construct( $list, $row ) {
130 $this->list = $list;
131 $this->row = $row;
132 }
133
134 /**
135 * Get the DB field name associated with the ID list.
136 * Override this function.
137 */
138 public function getIdField() {
139 return null;
140 }
141
142 /**
143 * Get the DB field name storing timestamps.
144 * Override this function.
145 */
146 public function getTimestampField() {
147 return false;
148 }
149
150 /**
151 * Get the DB field name storing user ids.
152 * Override this function.
153 */
154 public function getAuthorIdField() {
155 return false;
156 }
157
158 /**
159 * Get the DB field name storing user names.
160 * Override this function.
161 */
162 public function getAuthorNameField() {
163 return false;
164 }
165
166 /**
167 * Get the ID, as it would appear in the ids URL parameter
168 */
169 public function getId() {
170 $field = $this->getIdField();
171 return $this->row->$field;
172 }
173
174 /**
175 * Get the date, formatted with $wgLang
176 */
177 public function formatDate() {
178 global $wgLang;
179 return $wgLang->date( $this->getTimestamp() );
180 }
181
182 /**
183 * Get the time, formatted with $wgLang
184 */
185 public function formatTime() {
186 global $wgLang;
187 return $wgLang->time( $this->getTimestamp() );
188 }
189
190 /**
191 * Get the timestamp in MW 14-char form
192 */
193 public function getTimestamp() {
194 $field = $this->getTimestampField();
195 return wfTimestamp( TS_MW, $this->row->$field );
196 }
197
198 /**
199 * Get the author user ID
200 */
201 public function getAuthorId() {
202 $field = $this->getAuthorIdField();
203 return intval( $this->row->$field );
204 }
205
206 /**
207 * Get the author user name
208 */
209 public function getAuthorName() {
210 $field = $this->getAuthorNameField();
211 return strval( $this->row->$field );
212 }
213
214 /**
215 * Returns true if the current user can view the item
216 */
217 abstract public function canView();
218
219 /**
220 * Returns true if the current user can view the item text/file
221 */
222 abstract public function canViewContent();
223
224 /**
225 * Get the HTML of the list item. Should be include <li></li> tags.
226 * This is used to show the list in HTML form, by the special page.
227 */
228 abstract public function getHTML();
229 }
230
231 class RevisionList extends Rev_List {
232 public function getType() {
233 return 'revision';
234 }
235
236 /**
237 * @param $db DatabaseBase
238 * @return mixed
239 */
240 public function doQuery( $db ) {
241 $ids = array_map( 'intval', $this->ids );
242 return $db->select( array('revision','page'), '*',
243 array(
244 'rev_page' => $this->title->getArticleID(),
245 'rev_id' => array_map( 'intval', $this->ids ),
246 'rev_page = page_id'
247 ),
248 __METHOD__,
249 array( 'ORDER BY' => 'rev_id DESC' )
250 );
251 }
252
253 public function newItem( $row ) {
254 return new RevisionItem( $this, $row );
255 }
256 }
257
258 /**
259 * Item class for a live revision table row
260 */
261 class RevisionItem extends Rev_Item {
262 var $revision, $context;
263
264 public function __construct( $list, $row ) {
265 parent::__construct( $list, $row );
266 $this->revision = new Revision( $row );
267 $this->context = $list->context;
268 }
269
270 public function getIdField() {
271 return 'rev_id';
272 }
273
274 public function getTimestampField() {
275 return 'rev_timestamp';
276 }
277
278 public function getAuthorIdField() {
279 return 'rev_user';
280 }
281
282 public function getAuthorNameField() {
283 return 'rev_user_text';
284 }
285
286 public function canView() {
287 return $this->revision->userCan( Revision::DELETED_RESTRICTED );
288 }
289
290 public function canViewContent() {
291 return $this->revision->userCan( Revision::DELETED_TEXT );
292 }
293
294 public function isDeleted() {
295 return $this->revision->isDeleted( Revision::DELETED_TEXT );
296 }
297
298 /**
299 * Get the HTML link to the revision text.
300 * Overridden by RevDel_ArchiveItem.
301 */
302 protected function getRevisionLink() {
303 $date = $this->list->getLang()->timeanddate( $this->revision->getTimestamp(), true );
304 if ( $this->isDeleted() && !$this->canViewContent() ) {
305 return $date;
306 }
307 return Linker::link(
308 $this->list->title,
309 $date,
310 array(),
311 array(
312 'oldid' => $this->revision->getId(),
313 'unhide' => 1
314 )
315 );
316 }
317
318 /**
319 * Get the HTML link to the diff.
320 * Overridden by RevDel_ArchiveItem
321 */
322 protected function getDiffLink() {
323 if ( $this->isDeleted() && !$this->canViewContent() ) {
324 return wfMsgHtml('diff');
325 } else {
326 return
327 Linker::link(
328 $this->list->title,
329 wfMsgHtml('diff'),
330 array(),
331 array(
332 'diff' => $this->revision->getId(),
333 'oldid' => 'prev',
334 'unhide' => 1
335 ),
336 array(
337 'known',
338 'noclasses'
339 )
340 );
341 }
342 }
343
344 public function getHTML() {
345 $difflink = $this->getDiffLink();
346 $revlink = $this->getRevisionLink();
347 $userlink = Linker::revUserLink( $this->revision );
348 $comment = Linker::revComment( $this->revision );
349 if ( $this->isDeleted() ) {
350 $revlink = "<span class=\"history-deleted\">$revlink</span>";
351 }
352 return "<li>($difflink) $revlink $userlink $comment</li>";
353 }
354 }