0a79228043e0e45b24349576c6d4b9e0f8081e6f
[lhc/web/wiklou.git] / includes / RecentChange.php
1 <?php
2 /**
3 *
4 * @package MediaWiki
5 */
6
7 /**
8 * Various globals
9 */
10 define( 'RC_EDIT', 0);
11 define( 'RC_NEW', 1);
12 define( 'RC_MOVE', 2);
13 define( 'RC_LOG', 3);
14 define( 'RC_MOVE_OVER_REDIRECT', 4);
15 define( "RC_EDIT_COMMENT", 5);
16
17
18 /**
19 * Utility class for creating new RC entries
20 * mAttributes:
21 * rc_id id of the row in the recentchanges table
22 * rc_timestamp time the entry was made
23 * rc_cur_time timestamp on the cur row
24 * rc_namespace namespace #
25 * rc_title non-prefixed db key
26 * rc_type is new entry, used to determine whether updating is necessary
27 * rc_minor is minor
28 * rc_cur_id id of associated cur entry
29 * rc_user user id who made the entry
30 * rc_user_text user name who made the entry
31 * rc_comment edit summary
32 * rc_this_oldid old_id associated with this entry (or zero)
33 * rc_last_oldid old_id associated with the entry before this one (or zero)
34 * rc_bot is bot, hidden
35 * rc_ip IP address of the user in dotted quad notation
36 * rc_new obsolete, use rc_type==RC_NEW
37 * rc_patrolled boolean whether or not someone has marked this edit as patrolled
38 *
39 * mExtra:
40 * prefixedDBkey prefixed db key, used by external app via msg queue
41 * lastTimestamp timestamp of previous entry, used in WHERE clause during update
42 * lang the interwiki prefix, automatically set in save()
43 *
44 * @todo document functions and variables
45 * @package MediaWiki
46 */
47 class RecentChange
48 {
49 var $mAttribs = array(), $mExtra = array();
50 var $mTitle = false, $mMovedToTitle = false;
51
52 # Factory methods
53
54 /* static */ function newFromRow( $row )
55 {
56 $rc = new RecentChange;
57 $rc->loadFromRow( $row );
58 return $rc;
59 }
60
61 /* static */ function newFromCurRow( $row )
62 {
63 $rc = new RecentChange;
64 $rc->loadFromCurRow( $row );
65 return $rc;
66 }
67
68 # Accessors
69
70 function setAttribs( $attribs )
71 {
72 $this->mAttribs = $attribs;
73 }
74
75 function setExtra( $extra )
76 {
77 $this->mExtra = $extra;
78 }
79
80 function &getTitle()
81 {
82 if ( $this->mTitle === false ) {
83 $this->mTitle = Title::makeTitle( $this->mAttribs['rc_namespace'], $this->mAttribs['rc_title'] );
84 }
85 return $this->mTitle;
86 }
87
88 function getMovedToTitle()
89 {
90 if ( $this->mMovedToTitle === false ) {
91 $this->mMovedToTitle = Title::makeTitle( $this->mAttribs['rc_moved_to_ns'],
92 $this->mAttribs['rc_moved_to_title'] );
93 }
94 return $this->mMovedToTitle;
95 }
96
97 # Writes the data in this object to the database
98 function save()
99 {
100 global $wgUseRCQueue, $wgRCQueueID, $wgLocalInterwiki, $wgPutIPinRC;
101 $fname = 'RecentChange::save';
102
103 $dbw =& wfGetDB( DB_MASTER );
104 if ( !is_array($this->mExtra) ) {
105 $this->mExtra = array();
106 }
107 $this->mExtra['lang'] = $wgLocalInterwiki;
108
109 if ( !$wgPutIPinRC ) {
110 $this->mAttribs['rc_ip'] = '';
111 }
112
113 # Fixup database timestamps
114 $this->mAttribs['rc_timestamp']=$dbw->timestamp($this->mAttribs['rc_timestamp']);
115 $this->mAttribs['rc_cur_time']=$dbw->timestamp($this->mAttribs['rc_cur_time']);
116
117 # Insert new row
118 $dbw->insert( 'recentchanges', $this->mAttribs, $fname );
119
120 # Update old rows, if necessary
121 if ( $this->mAttribs['rc_type'] == RC_EDIT ) {
122 $oldid = $this->mAttribs['rc_last_oldid'];
123 $ns = $this->mAttribs['rc_namespace'];
124 $title = $this->mAttribs['rc_title'];
125 $lastTime = $this->mExtra['lastTimestamp'];
126 $now = $this->mAttribs['rc_timestamp'];
127 $curId = $this->mAttribs['rc_cur_id'];
128
129 # Update rc_this_oldid for the entries which were current
130 $dbw->update( 'recentchanges',
131 array( /* SET */
132 'rc_this_oldid' => $oldid
133 ), array( /* WHERE */
134 'rc_namespace' => $ns,
135 'rc_title' => $title,
136 'rc_timestamp' => $dbw->timestamp($lastTime)
137 ), $fname
138 );
139
140 # Update rc_cur_time
141 $dbw->update( 'recentchanges', array( 'rc_cur_time' => $now ),
142 array( 'rc_cur_id' => $curId ), $fname );
143 }
144
145 # Notify external application
146 if ( $wgUseRCQueue ) {
147 $queue = msg_get_queue( $wgRCQueueID );
148 if (!msg_send( $queue, array_merge( $this->mAttribs, 1, $this->mExtra ),
149 true, false, $error ))
150 {
151 wfDebug( "Error sending message to RC queue, code $error\n" );
152 }
153 }
154 }
155
156 # Marks a certain row as patrolled
157 function markPatrolled( $rcid )
158 {
159 $fname = 'RecentChange::markPatrolled';
160
161 $dbw =& wfGetDB( DB_MASTER );
162
163 $dbw->update( 'recentchanges',
164 array( /* SET */
165 'rc_patrolled' => 1
166 ), array( /* WHERE */
167 'rc_id' => $rcid
168 ), $fname
169 );
170 }
171
172 # Makes an entry in the database corresponding to an edit
173 /*static*/ function notifyEdit( $timestamp, &$title, $minor, &$user, $comment,
174 $oldId, $lastTimestamp, $bot = "default", $ip = '' )
175 {
176 if ( $bot == 'default ' ) {
177 $bot = $user->isBot();
178 }
179
180 if ( !$ip ) {
181 global $wgIP;
182 $ip = empty( $wgIP ) ? '' : $wgIP;
183 }
184
185 $rc = new RecentChange;
186 $rc->mAttribs = array(
187 'rc_timestamp' => $timestamp,
188 'rc_cur_time' => $timestamp,
189 'rc_namespace' => $title->getNamespace(),
190 'rc_title' => $title->getDBkey(),
191 'rc_type' => RC_EDIT,
192 'rc_minor' => $minor ? 1 : 0,
193 'rc_cur_id' => $title->getArticleID(),
194 'rc_user' => $user->getID(),
195 'rc_user_text' => $user->getName(),
196 'rc_comment' => $comment,
197 'rc_this_oldid' => 0,
198 'rc_last_oldid' => $oldId,
199 'rc_bot' => $bot ? 1 : 0,
200 'rc_moved_to_ns' => 0,
201 'rc_moved_to_title' => '',
202 'rc_ip' => $ip,
203 'rc_patrolled' => 0,
204 'rc_new' => 0 # obsolete
205 );
206
207 $rc->mExtra = array(
208 'prefixedDBkey' => $title->getPrefixedDBkey(),
209 'lastTimestamp' => $lastTimestamp
210 );
211 $rc->save();
212 }
213
214 # Makes an entry in the database corresponding to page creation
215 # Note: the title object must be loaded with the new id using resetArticleID()
216 /*static*/ function notifyNew( $timestamp, &$title, $minor, &$user, $comment, $bot = "default", $ip='' )
217 {
218 if ( !$ip ) {
219 global $wgIP;
220 $ip = empty( $wgIP ) ? '' : $wgIP;
221 }
222 if ( $bot == 'default' ) {
223 $bot = $user->isBot();
224 }
225
226 $rc = new RecentChange;
227 $rc->mAttribs = array(
228 'rc_timestamp' => $timestamp,
229 'rc_cur_time' => $timestamp,
230 'rc_namespace' => $title->getNamespace(),
231 'rc_title' => $title->getDBkey(),
232 'rc_type' => RC_NEW,
233 'rc_minor' => $minor ? 1 : 0,
234 'rc_cur_id' => $title->getArticleID(),
235 'rc_user' => $user->getID(),
236 'rc_user_text' => $user->getName(),
237 'rc_comment' => $comment,
238 'rc_this_oldid' => 0,
239 'rc_last_oldid' => 0,
240 'rc_bot' => $bot ? 1 : 0,
241 'rc_moved_to_ns' => 0,
242 'rc_moved_to_title' => '',
243 'rc_ip' => $ip,
244 'rc_patrolled' => 0,
245 'rc_new' => 1 # obsolete
246 );
247
248 $rc->mExtra = array(
249 'prefixedDBkey' => $title->getPrefixedDBkey(),
250 'lastTimestamp' => 0
251 );
252 $rc->save();
253 }
254
255 # Makes an entry in the database corresponding to a rename
256 /*static*/ function notifyMove( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='', $overRedir = false )
257 {
258 if ( !$ip ) {
259 global $wgIP;
260 $ip = empty( $wgIP ) ? '' : $wgIP;
261 }
262 $rc = new RecentChange;
263 $rc->mAttribs = array(
264 'rc_timestamp' => $timestamp,
265 'rc_cur_time' => $timestamp,
266 'rc_namespace' => $oldTitle->getNamespace(),
267 'rc_title' => $oldTitle->getDBkey(),
268 'rc_type' => $overRedir ? RC_MOVE_OVER_REDIRECT : RC_MOVE,
269 'rc_minor' => 0,
270 'rc_cur_id' => $oldTitle->getArticleID(),
271 'rc_user' => $user->getID(),
272 'rc_user_text' => $user->getName(),
273 'rc_comment' => $comment,
274 'rc_this_oldid' => 0,
275 'rc_last_oldid' => 0,
276 'rc_bot' => $user->isBot() ? 1 : 0,
277 'rc_moved_to_ns' => $newTitle->getNamespace(),
278 'rc_moved_to_title' => $newTitle->getDBkey(),
279 'rc_ip' => $ip,
280 'rc_new' => 0, # obsolete
281 'rc_patrolled' => 1
282 );
283
284 $rc->mExtra = array(
285 'prefixedDBkey' => $oldTitle->getPrefixedDBkey(),
286 'lastTimestamp' => 0,
287 'prefixedMoveTo' => $newTitle->getPrefixedDBkey()
288 );
289 $rc->save();
290 }
291
292 /* static */ function notifyMoveToNew( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='' ) {
293 RecentChange::notifyMove( $timestamp, $oldTitle, $newTitle, $user, $comment, $ip, false );
294 }
295
296 /* static */ function notifyMoveOverRedirect( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='' ) {
297 RecentChange::notifyMove( $timestamp, $oldTitle, $newTitle, $user, $comment, $ip='', true );
298 }
299
300 # A log entry is different to an edit in that previous revisions are
301 # not kept
302 /*static*/ function notifyLog( $timestamp, &$title, &$user, $comment, $ip='' )
303 {
304 if ( !$ip ) {
305 global $wgIP;
306 $ip = empty( $wgIP ) ? '' : $wgIP;
307 }
308 $rc = new RecentChange;
309 $rc->mAttribs = array(
310 'rc_timestamp' => $timestamp,
311 'rc_cur_time' => $timestamp,
312 'rc_namespace' => $title->getNamespace(),
313 'rc_title' => $title->getDBkey(),
314 'rc_type' => RC_LOG,
315 'rc_minor' => 0,
316 'rc_cur_id' => $title->getArticleID(),
317 'rc_user' => $user->getID(),
318 'rc_user_text' => $user->getName(),
319 'rc_comment' => $comment,
320 'rc_this_oldid' => 0,
321 'rc_last_oldid' => 0,
322 'rc_bot' => 0,
323 'rc_moved_to_ns' => 0,
324 'rc_moved_to_title' => '',
325 'rc_ip' => $ip,
326 'rc_patrolled' => 1,
327 'rc_new' => 0 # obsolete
328 );
329 $rc->mExtra = array(
330 'prefixedDBkey' => $title->getPrefixedDBkey(),
331 'lastTimestamp' => 0
332 );
333 $rc->save();
334 }
335
336 # Makes an entry in the database corresponding to editing a comment.
337 # Note: This code saves the old comment in 'rc_moved_to_title', which is only used
338 # for logging move operations.
339 /*static*/ function notifyEditComment( $timestamp, &$title, $minor, &$user, $comment, $oldComment,
340 $revId, $lastTimestamp, $ip = '' )
341 {
342 if ( !$ip ) {
343 global $wgIP;
344 $ip = empty( $wgIP ) ? '' : $wgIP;
345 }
346
347 $rc = new RecentChange;
348 $rc->mAttribs = array(
349 'rc_timestamp' => $timestamp,
350 'rc_cur_time' => $timestamp,
351 'rc_namespace' => $title->getNamespace(),
352 'rc_title' => $title->getDBkey(),
353 'rc_type' => RC_EDIT_COMMENT,
354 'rc_minor' => $minor ? 1 : 0,
355 'rc_cur_id' => $title->getArticleID(),
356 'rc_user' => $user->getID(),
357 'rc_user_text' => $user->getName(),
358 'rc_comment' => $comment,
359 'rc_this_oldid' => $revId,
360 'rc_last_oldid' => 0,
361 'rc_bot' => 0,
362 'rc_moved_to_ns' => 0,
363 'rc_moved_to_title' => $oldComment,
364 'rc_ip' => $ip,
365 'rc_patrolled' => 1,
366 'rc_new' => 0 # obsolete
367 );
368
369 $rc->mExtra = array(
370 'prefixedDBkey' => $title->getPrefixedDBkey(),
371 'lastTimestamp' => $lastTimestamp
372 );
373 $rc->save();
374 }
375
376 # Initialises the members of this object from a mysql row object
377 function loadFromRow( $row )
378 {
379 $this->mAttribs = get_object_vars( $row );
380 $this->mExtra = array();
381 }
382
383 # Makes a pseudo-RC entry from a cur row, for watchlists and things
384 function loadFromCurRow( $row )
385 {
386 $this->mAttribs = array(
387 'rc_timestamp' => $row->cur_timestamp,
388 'rc_cur_time' => $row->cur_timestamp,
389 'rc_user' => $row->cur_user,
390 'rc_user_text' => $row->cur_user_text,
391 'rc_namespace' => $row->cur_namespace,
392 'rc_title' => $row->cur_title,
393 'rc_comment' => $row->cur_comment,
394 'rc_minor' => !!$row->cur_minor_edit,
395 'rc_type' => $row->cur_is_new ? RC_NEW : RC_EDIT,
396 'rc_cur_id' => $row->cur_id,
397 'rc_this_oldid' => 0,
398 'rc_last_oldid' => 0,
399 'rc_bot' => 0,
400 'rc_moved_to_ns' => 0,
401 'rc_moved_to_title' => '',
402 'rc_ip' => '',
403 'rc_patrolled' => '1', # we can't support patrolling on the Watchlist
404 # currently because it uses cur, not recentchanges
405 'rc_new' => $row->cur_is_new # obsolete
406 );
407
408 $this->mExtra = array();
409 }
410
411
412 /**
413 * Gets the end part of the diff URL assoicated with this object
414 * Blank if no diff link should be displayed
415 */
416 function diffLinkTrail( $forceCur )
417 {
418 if ( $this->mAttribs['rc_type'] == RC_EDIT ) {
419 $trail = "curid=" . (int)($this->mAttribs['rc_cur_id']) .
420 "&oldid=" . (int)($this->mAttribs['rc_last_oldid']);
421 if ( $forceCur ) {
422 $trail .= '&diff=0' ;
423 } else {
424 $trail .= '&diff=' . (int)($this->mAttribs['rc_this_oldid']);
425 }
426 } else {
427 $trail = '';
428 }
429 return $trail;
430 }
431 }
432 ?>