Index: trunk/phase3/skins/monobook/main.css |
— | — | @@ -1154,10 +1154,6 @@ |
1155 | 1155 | span.newpage, span.minor, span.bot { |
1156 | 1156 | font-weight: bold; |
1157 | 1157 | } |
1158 | | -span.unpatrolled { |
1159 | | - font-weight: bold; |
1160 | | - color: red; |
1161 | | -} |
1162 | 1158 | |
1163 | 1159 | .sharedUploadNotice { |
1164 | 1160 | font-style: italic; |
Index: trunk/phase3/skins/modern/main.css |
— | — | @@ -650,10 +650,6 @@ |
651 | 651 | span.newpage, span.minor, span.searchmatch, span.bot { |
652 | 652 | font-weight: bold; |
653 | 653 | } |
654 | | -span.unpatrolled { |
655 | | - font-weight: bold; |
656 | | - color: red; |
657 | | -} |
658 | 654 | |
659 | 655 | span.searchmatch { |
660 | 656 | color: red; |
Index: trunk/phase3/skins/common/oldshared.css |
— | — | @@ -212,6 +212,10 @@ |
213 | 213 | font-weight:bold; |
214 | 214 | color:red; |
215 | 215 | } |
| 216 | +span.newuser { |
| 217 | + font-weight:bold; |
| 218 | + color:orange; |
| 219 | +} |
216 | 220 | |
217 | 221 | span.updatedmarker { |
218 | 222 | color:black; |
Index: trunk/phase3/skins/common/shared.css |
— | — | @@ -56,8 +56,20 @@ |
57 | 57 | } |
58 | 58 | |
59 | 59 | /* |
60 | | - * rev_deleted stuff |
| 60 | + * Recent changes |
61 | 61 | */ |
| 62 | +span.unpatrolled { |
| 63 | + font-weight: bold; |
| 64 | + color: red; |
| 65 | +} |
| 66 | +span.newuser { |
| 67 | + font-weight:bold; |
| 68 | + color:orange; |
| 69 | +} |
| 70 | + |
| 71 | +/* |
| 72 | + * RevisionDelete stuff |
| 73 | + */ |
62 | 74 | li span.deleted, span.history-deleted { |
63 | 75 | text-decoration: line-through; |
64 | 76 | color: #888; |
Index: trunk/phase3/docs/hooks.txt |
— | — | @@ -1218,6 +1218,7 @@ |
1219 | 1219 | &$tables: array of tables to be queried |
1220 | 1220 | &$join_conds: join conditions for the tables |
1221 | 1221 | $opts: FormOptions for this request |
| 1222 | +&$fields: select fields |
1222 | 1223 | |
1223 | 1224 | 'SpecialSearchNogomatch': called when user clicked the "Go" button but the target doesn't exist |
1224 | 1225 | $title: title object generated from the text entred by the user |
Index: trunk/phase3/includes/RecentChange.php |
— | — | @@ -49,15 +49,13 @@ |
50 | 50 | |
51 | 51 | # Factory methods |
52 | 52 | |
53 | | - public static function newFromRow( $row ) |
54 | | - { |
| 53 | + public static function newFromRow( $row ) { |
55 | 54 | $rc = new RecentChange; |
56 | 55 | $rc->loadFromRow( $row ); |
57 | 56 | return $rc; |
58 | 57 | } |
59 | 58 | |
60 | | - public static function newFromCurRow( $row ) |
61 | | - { |
| 59 | + public static function newFromCurRow( $row ) { |
62 | 60 | $rc = new RecentChange; |
63 | 61 | $rc->loadFromCurRow( $row ); |
64 | 62 | $rc->notificationtimestamp = false; |
— | — | @@ -110,26 +108,22 @@ |
111 | 109 | |
112 | 110 | # Accessors |
113 | 111 | |
114 | | - function setAttribs( $attribs ) |
115 | | - { |
| 112 | + function setAttribs( $attribs ) { |
116 | 113 | $this->mAttribs = $attribs; |
117 | 114 | } |
118 | 115 | |
119 | | - function setExtra( $extra ) |
120 | | - { |
| 116 | + function setExtra( $extra ) { |
121 | 117 | $this->mExtra = $extra; |
122 | 118 | } |
123 | 119 | |
124 | | - function &getTitle() |
125 | | - { |
| 120 | + function &getTitle() { |
126 | 121 | if ( $this->mTitle === false ) { |
127 | 122 | $this->mTitle = Title::makeTitle( $this->mAttribs['rc_namespace'], $this->mAttribs['rc_title'] ); |
128 | 123 | } |
129 | 124 | return $this->mTitle; |
130 | 125 | } |
131 | 126 | |
132 | | - function getMovedToTitle() |
133 | | - { |
| 127 | + function getMovedToTitle() { |
134 | 128 | if ( $this->mMovedToTitle === false ) { |
135 | 129 | $this->mMovedToTitle = Title::makeTitle( $this->mAttribs['rc_moved_to_ns'], |
136 | 130 | $this->mAttribs['rc_moved_to_title'] ); |
— | — | @@ -138,8 +132,7 @@ |
139 | 133 | } |
140 | 134 | |
141 | 135 | # Writes the data in this object to the database |
142 | | - function save() |
143 | | - { |
| 136 | + function save() { |
144 | 137 | global $wgLocalInterwiki, $wgPutIPinRC, $wgRC2UDPAddress, |
145 | 138 | $wgRC2UDPPort, $wgRC2UDPPrefix, $wgRC2UDPOmitBots; |
146 | 139 | $fname = 'RecentChange::save'; |
— | — | @@ -178,35 +171,6 @@ |
179 | 172 | # Update old rows, if necessary |
180 | 173 | if ( $this->mAttribs['rc_type'] == RC_EDIT ) { |
181 | 174 | $lastTime = $this->mExtra['lastTimestamp']; |
182 | | - #$now = $this->mAttribs['rc_timestamp']; |
183 | | - #$curId = $this->mAttribs['rc_cur_id']; |
184 | | - |
185 | | - # Don't bother looking for entries that have probably |
186 | | - # been purged, it just locks up the indexes needlessly. |
187 | | - global $wgRCMaxAge; |
188 | | - $age = time() - wfTimestamp( TS_UNIX, $lastTime ); |
189 | | - if( $age < $wgRCMaxAge ) { |
190 | | - # live hack, will commit once tested - kate |
191 | | - # Update rc_this_oldid for the entries which were current |
192 | | - # |
193 | | - #$oldid = $this->mAttribs['rc_last_oldid']; |
194 | | - #$ns = $this->mAttribs['rc_namespace']; |
195 | | - #$title = $this->mAttribs['rc_title']; |
196 | | - # |
197 | | - #$dbw->update( 'recentchanges', |
198 | | - # array( /* SET */ |
199 | | - # 'rc_this_oldid' => $oldid |
200 | | - # ), array( /* WHERE */ |
201 | | - # 'rc_namespace' => $ns, |
202 | | - # 'rc_title' => $title, |
203 | | - # 'rc_timestamp' => $dbw->timestamp( $lastTime ) |
204 | | - # ), $fname |
205 | | - #); |
206 | | - } |
207 | | - |
208 | | - # Update rc_cur_time |
209 | | - #$dbw->update( 'recentchanges', array( 'rc_cur_time' => $now ), |
210 | | - # array( 'rc_cur_id' => $curId ), $fname ); |
211 | 175 | } |
212 | 176 | |
213 | 177 | # Notify external application via UDP |
— | — | @@ -576,13 +540,43 @@ |
577 | 541 | public function getAttribute( $name ) { |
578 | 542 | return isset( $this->mAttribs[$name] ) ? $this->mAttribs[$name] : NULL; |
579 | 543 | } |
| 544 | + |
| 545 | + /* |
| 546 | + * Get RC select fields for changes lists |
| 547 | + */ |
| 548 | + public static function getSelectFields() { |
| 549 | + return array( |
| 550 | + 'rc_timestamp', |
| 551 | + 'rc_cur_time', |
| 552 | + 'rc_user', |
| 553 | + 'rc_user_text', |
| 554 | + 'rc_namespace', |
| 555 | + 'rc_title', |
| 556 | + 'rc_comment', |
| 557 | + 'rc_minor', |
| 558 | + 'rc_type', |
| 559 | + 'rc_cur_id', |
| 560 | + 'rc_this_oldid', |
| 561 | + 'rc_last_oldid', |
| 562 | + 'rc_bot', |
| 563 | + 'rc_moved_to_ns', |
| 564 | + 'rc_moved_to_title', |
| 565 | + 'rc_patrolled', |
| 566 | + 'rc_old_len', |
| 567 | + 'rc_new_len', |
| 568 | + 'rc_params', |
| 569 | + 'rc_log_type', |
| 570 | + 'rc_log_action', |
| 571 | + 'rc_log_id', |
| 572 | + 'rc_deleted' // this one REALLY should be set... |
| 573 | + ); |
| 574 | + } |
580 | 575 | |
581 | 576 | /** |
582 | 577 | * Gets the end part of the diff URL associated with this object |
583 | 578 | * Blank if no diff link should be displayed |
584 | 579 | */ |
585 | | - function diffLinkTrail( $forceCur ) |
586 | | - { |
| 580 | + function diffLinkTrail( $forceCur ) { |
587 | 581 | if ( $this->mAttribs['rc_type'] == RC_EDIT ) { |
588 | 582 | $trail = "curid=" . (int)($this->mAttribs['rc_cur_id']) . |
589 | 583 | "&oldid=" . (int)($this->mAttribs['rc_last_oldid']); |
Index: trunk/phase3/includes/ChangesList.php |
— | — | @@ -75,17 +75,38 @@ |
76 | 76 | * @param bool $patrolled |
77 | 77 | * @param string $nothing, string to use for empty space |
78 | 78 | * @param bool $bot |
| 79 | + * @param bool $newbie |
79 | 80 | * @return string |
80 | 81 | */ |
81 | | - protected function recentChangesFlags( $new, $minor, $patrolled, $nothing = ' ', $bot = false ) { |
| 82 | + protected function recentChangesFlags( $new, $minor, $patrolled, $nothing = ' ', $bot = false, $newbie = false ) { |
82 | 83 | $f = $new ? '<span class="newpage">' . $this->message['newpageletter'] . '</span>' |
83 | 84 | : $nothing; |
84 | 85 | $f .= $minor ? '<span class="minor">' . $this->message['minoreditletter'] . '</span>' |
85 | 86 | : $nothing; |
86 | 87 | $f .= $bot ? '<span class="bot">' . $this->message['boteditletter'] . '</span>' : $nothing; |
87 | 88 | $f .= $patrolled ? '<span class="unpatrolled">!</span>' : $nothing; |
| 89 | + $f .= $newbie ? '<span class="newuser">*</span>' : $nothing; |
88 | 90 | return $f; |
89 | 91 | } |
| 92 | + |
| 93 | + protected static function userIsNew( Array $attribs ) { |
| 94 | + global $wgAutoConfirmCount, $wgAutoConfirmAge; |
| 95 | + if( !array_key_exists('user_editcount',$attribs) || !array_key_exists('user_registration',$attribs) ) { |
| 96 | + return false; // missing input! |
| 97 | + } |
| 98 | + static $time; |
| 99 | + $time = time(); |
| 100 | + $edits = $attribs['user_editcount']; |
| 101 | + $age = $attribs['user_registration']; |
| 102 | + if( $wgAutoConfirmCount && !$edits || $wgAutoConfirmAge && !$age ) { |
| 103 | + return true; |
| 104 | + } else if( $wgAutoConfirmCount && $edits < $wgAutoConfirmCount ) { |
| 105 | + return true; |
| 106 | + } else if( $wgAutoConfirmAge && ($time - wfTimestampOrNull(TS_UNIX,$age)) < $wgAutoConfirmAge ) { |
| 107 | + return true; |
| 108 | + } |
| 109 | + return false; |
| 110 | + } |
90 | 111 | |
91 | 112 | /** |
92 | 113 | * Returns text for the start of the tabular part of RC |
— | — | @@ -343,9 +364,10 @@ |
344 | 365 | wfProfileIn($fname.'-page'); |
345 | 366 | |
346 | 367 | $this->insertDiffHist($s, $rc, $unpatrolled); |
347 | | - |
348 | 368 | # M, N, b and ! (minor, new, bot and unpatrolled) |
349 | | - $s .= $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $unpatrolled, '', $rc_bot ); |
| 369 | + $newbie = self::userIsNew( $rcObj->mAttribs ); |
| 370 | + $s .= $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $unpatrolled, '', |
| 371 | + $rc_bot, $newbie ); |
350 | 372 | $this->insertArticleLink($s, $rc, $unpatrolled, $watched); |
351 | 373 | |
352 | 374 | wfProfileOut($fname.'-page'); |
— | — | @@ -542,15 +564,14 @@ |
543 | 565 | # Collate list of users |
544 | 566 | $userlinks = array(); |
545 | 567 | # Other properties |
546 | | - $unpatrolled = false; |
547 | | - $isnew = false; |
| 568 | + $unpatrolled = $isnew = $newbie = false; |
548 | 569 | $curId = $currentRevision = 0; |
549 | 570 | # Some catalyst variables... |
550 | 571 | $namehidden = true; |
551 | 572 | $alllogs = true; |
552 | 573 | foreach( $block as $rcObj ) { |
553 | 574 | $oldid = $rcObj->mAttribs['rc_last_oldid']; |
554 | | - if( $rcObj->mAttribs['rc_new'] ) { |
| 575 | + if( $rcObj->mAttribs['rc_type'] == RC_NEW ) { |
555 | 576 | $isnew = true; |
556 | 577 | } |
557 | 578 | // If all log actions to this page were hidden, then don't |
— | — | @@ -568,6 +589,9 @@ |
569 | 590 | if( $rcObj->mAttribs['rc_type'] != RC_LOG ) { |
570 | 591 | $alllogs = false; |
571 | 592 | } |
| 593 | + if( self::userIsNew( $rcObj->mAttribs ) ) { |
| 594 | + $newbie = true; |
| 595 | + } |
572 | 596 | # Get the latest entry with a page_id and oldid |
573 | 597 | # since logs may not have these. |
574 | 598 | if( !$curId && $rcObj->mAttribs['rc_cur_id'] ) { |
— | — | @@ -606,7 +630,7 @@ |
607 | 631 | $r .= '<td valign="top" style="white-space: nowrap"><tt>'.$tl.' '; |
608 | 632 | |
609 | 633 | # Main line |
610 | | - $r .= $this->recentChangesFlags( $isnew, false, $unpatrolled, ' ', $bot ); |
| 634 | + $r .= $this->recentChangesFlags( $isnew, false, $unpatrolled, ' ', $bot, $newbie ); |
611 | 635 | |
612 | 636 | # Timestamp |
613 | 637 | $r .= ' '.$block[0]->timestamp.' </tt></td><td>'; |
— | — | @@ -689,7 +713,8 @@ |
690 | 714 | #$r .= '<tr><td valign="top">'.$this->spacerArrow(); |
691 | 715 | $r .= '<tr><td valign="top">'; |
692 | 716 | $r .= '<tt>'.$this->spacerIndent() . $this->spacerIndent(); |
693 | | - $r .= $this->recentChangesFlags( $rc_new, $rc_minor, $rcObj->unpatrolled, ' ', $rc_bot ); |
| 717 | + $newbie = self::userIsNew( $rcObj->mAttribs ); |
| 718 | + $r .= $this->recentChangesFlags( $rc_new, $rc_minor, $rcObj->unpatrolled, ' ', $rc_bot, $newbie ); |
694 | 719 | $r .= ' </tt></td><td valign="top">'; |
695 | 720 | |
696 | 721 | $o = ''; |
— | — | @@ -815,14 +840,15 @@ |
816 | 841 | $curIdEq = 'curid='.$rc_cur_id; |
817 | 842 | |
818 | 843 | $r = '<table cellspacing="0" cellpadding="0" border="0" style="background: none"><tr>'; |
819 | | - |
820 | 844 | $r .= '<td valign="top" style="white-space: nowrap"><tt>' . $this->spacerArrow() . ' '; |
821 | 845 | |
822 | 846 | # Flag and Timestamp |
823 | 847 | if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) { |
824 | 848 | $r .= ' '; // 4 flags -> 4 spaces |
825 | 849 | } else { |
826 | | - $r .= $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $rcObj->unpatrolled, ' ', $rc_bot ); |
| 850 | + $newbie = self::userIsNew( $rcObj->mAttribs ); |
| 851 | + $r .= $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $rcObj->unpatrolled, |
| 852 | + ' ', $rc_bot, $newbie ); |
827 | 853 | } |
828 | 854 | $r .= ' '.$rcObj->timestamp.' </tt></td><td>'; |
829 | 855 | |
— | — | @@ -838,7 +864,7 @@ |
839 | 865 | } |
840 | 866 | |
841 | 867 | # Diff and hist links |
842 | | - if ( $rc_type != RC_LOG ) { |
| 868 | + if( $rc_type != RC_LOG ) { |
843 | 869 | $r .= ' ('. $rcObj->difflink . $this->message['semicolon-separator']; |
844 | 870 | $r .= $this->skin->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' ) . ')'; |
845 | 871 | } |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -1383,7 +1383,7 @@ |
1384 | 1384 | * to ensure that client-side caches don't keep obsolete copies of global |
1385 | 1385 | * styles. |
1386 | 1386 | */ |
1387 | | -$wgStyleVersion = '172'; |
| 1387 | +$wgStyleVersion = '173'; |
1388 | 1388 | |
1389 | 1389 | |
1390 | 1390 | # Server-side caching: |
Index: trunk/phase3/includes/specials/SpecialRecentchanges.php |
— | — | @@ -264,8 +264,11 @@ |
265 | 265 | public function doMainQuery( $conds, $opts ) { |
266 | 266 | global $wgUser; |
267 | 267 | |
268 | | - $tables = array( 'recentchanges' ); |
269 | | - $join_conds = array(); |
| 268 | + $tables = array( 'recentchanges', 'user' ); |
| 269 | + $join_conds = array( 'user' => array('LEFT JOIN','rc_user != 0 AND user_id = rc_user') ); |
| 270 | + $fields = RecentChange::getSelectFields(); |
| 271 | + $fields[] = 'user_editcount'; |
| 272 | + $fields[] = 'user_registration'; |
270 | 273 | |
271 | 274 | $uid = $wgUser->getId(); |
272 | 275 | $dbr = wfGetDB( DB_SLAVE ); |
— | — | @@ -276,10 +279,10 @@ |
277 | 280 | // JOIN on watchlist for users |
278 | 281 | if( $uid ) { |
279 | 282 | $tables[] = 'watchlist'; |
280 | | - $join_conds = array( 'watchlist' => array('LEFT JOIN',"wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace") ); |
| 283 | + $join_conds['watchlist'] = array('LEFT JOIN',"wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace"); |
281 | 284 | } |
282 | 285 | |
283 | | - wfRunHooks('SpecialRecentChangesQuery', array( &$conds, &$tables, &$join_conds, $opts ) ); |
| 286 | + wfRunHooks('SpecialRecentChangesQuery', array( &$conds, &$tables, &$join_conds, $opts, &$fields ) ); |
284 | 287 | |
285 | 288 | // Is there either one namespace selected or excluded? |
286 | 289 | // Also, if this is "all" or main namespace, just use timestamp index. |
— | — | @@ -313,7 +316,7 @@ |
314 | 317 | } |
315 | 318 | |
316 | 319 | /** |
317 | | - * Send output to $wgOut, only called if not used feeds |
| 320 | + * Send output to $wgOut, only called if not using feeds |
318 | 321 | * |
319 | 322 | * @param $rows array of database rows |
320 | 323 | * @param $opts FormOptions |