Index: trunk/phase3/includes/SpecialWatchlist.php |
— | — | @@ -18,23 +18,17 @@ |
19 | 19 | $days = $wgUser->getOption( "rcdays" ); |
20 | 20 | if ( ! $days ) { $days = 3; } |
21 | 21 | */ |
22 | | - $days = 7; |
| 22 | + $days = (1.0 / 24.0); # 1 hour... |
23 | 23 | } |
24 | | - $days = (int)$days; |
25 | | - list( $limit, $offset ) = wfCheckLimits( 100, "rclimit" ); |
| 24 | + $days = floatval($days); |
26 | 25 | |
27 | 26 | if ( $days <= 0 ) { |
28 | 27 | $docutoff = ''; |
29 | 28 | } else { |
30 | 29 | $docutoff = "cur_timestamp > '" . |
31 | | - wfUnix2Timestamp( time() - ( $days * 86400 ) ) |
| 30 | + ( $cutoff = wfUnix2Timestamp( time() - intval( $days * 86400 ) ) ) |
32 | 31 | . "' AND"; |
33 | 32 | } |
34 | | - if ( $limit == 0 ) { |
35 | | - $dolimit = ""; |
36 | | - } else { |
37 | | - $dolimit = "LIMIT $limit"; |
38 | | - } |
39 | 33 | |
40 | 34 | $uid = $wgUser->getID(); |
41 | 35 | if( $uid == 0 ) { |
— | — | @@ -42,24 +36,118 @@ |
43 | 37 | return; |
44 | 38 | } |
45 | 39 | |
46 | | - $sql = "SELECT DISTINCT |
47 | | - cur_id,cur_namespace,cur_title,cur_comment, |
| 40 | + global $action,$remove,$id; |
| 41 | + if(($action == "submit") && isset($remove) && is_array($id)) { |
| 42 | + $wgOut->addHTML( wfMsg( "removingchecked" ) ); |
| 43 | + foreach($id as $one) { |
| 44 | + $t = Title::newFromURL( $one ); |
| 45 | + if($t->getDBkey() != "") { |
| 46 | + $sql = "DELETE FROM watchlist WHERE wl_user=$uid AND " . |
| 47 | + "wl_namespace=" . $t->getNamespace() . " AND " . |
| 48 | + "wl_title='" . wfStrencode( $t->getDBkey() ) . "'"; |
| 49 | + $res = wfQuery( $sql ); |
| 50 | + if($res === FALSE) { |
| 51 | + $wgOut->addHTML( "<br />\n" . wfMsg( "couldntremove", htmlspecialchars($one) ) ); |
| 52 | + } else { |
| 53 | + $wgOut->addHTML( " (" . htmlspecialchars($one) . ")" ); |
| 54 | + } |
| 55 | + } else { |
| 56 | + $wgOut->addHTML( "<br />\n" . wfMsg( "iteminvalidname", htmlspecialchars($one) ) ); |
| 57 | + } |
| 58 | + } |
| 59 | + $wgOut->addHTML( "done.\n<p>" ); |
| 60 | + } |
| 61 | + |
| 62 | + $sql = "SELECT COUNT(*) AS n FROM watchlist WHERE wl_user=$uid"; |
| 63 | + $res = wfQuery( $sql ); |
| 64 | + $s = wfFetchObject( $res ); |
| 65 | + $nitems = $s->n; |
| 66 | + |
| 67 | + if($nitems == 0) { |
| 68 | + $wgOut->addHTML( wfMsg( "nowatchlist" ) ); |
| 69 | + return; |
| 70 | + } |
| 71 | + |
| 72 | + $sql = "SELECT COUNT(*) AS n FROM cur WHERE cur_timestamp>'$cutoff'"; |
| 73 | + $res = wfQuery( $sql ); |
| 74 | + $s = wfFetchObject( $res ); |
| 75 | + $npages = $s->n; |
| 76 | + |
| 77 | + |
| 78 | + if(isset($_REQUEST['magic'])) { |
| 79 | + $wgOut->addHTML( wfMsg( "watchlistcontains", $nitems ) . |
| 80 | + "<p>" . wfMsg( "watcheditlist" ) . "</p>\n" ); |
| 81 | + |
| 82 | + $wgOut->addHTML( "<form action='" . |
| 83 | + wfLocalUrl( $wgLang->specialPage( "Watchlist" ), "action=submit" ) . |
| 84 | + "' method='post'>\n" . |
| 85 | + "<ul>\n" ); |
| 86 | + $sql = "SELECT wl_namespace,wl_title FROM watchlist WHERE wl_user=$uid"; |
| 87 | + $res = wfQuery( $sql ); |
| 88 | + global $wgUser, $wgLang; |
| 89 | + $sk = $wgUser->getSkin(); |
| 90 | + while( $s = wfFetchObject( $res ) ) { |
| 91 | + $t = Title::makeTitle( $s->wl_namespace, $s->wl_title ); |
| 92 | + $t = $t->getPrefixedText(); |
| 93 | + $wgOut->addHTML( "<li><input type='checkbox' name='id[]' value=\"" . htmlspecialchars($t) . "\">" . |
| 94 | + $sk->makeKnownLink( $t, $t ) . |
| 95 | + "</li>\n" ); |
| 96 | + } |
| 97 | + $wgOut->addHTML( "</ul>\n" . |
| 98 | + "<input type='submit' name='remove' value='" . |
| 99 | + wfMsg( "removechecked" ) . "'>\n" . |
| 100 | + "</form>\n" ); |
| 101 | + |
| 102 | + return; |
| 103 | + } |
| 104 | + |
| 105 | + # If the watchlist is relatively short, it's simplest to zip |
| 106 | + # down its entirety and then sort the results. |
| 107 | + |
| 108 | + # If it's relatively long, it may be worth our while to zip |
| 109 | + # through the time-sorted page list checking for |
| 110 | + |
| 111 | + # Up estimate of watched items by 15% to compensate for talk pages... |
| 112 | + if( ( $nitems*1.15 > $npages ) ) { |
| 113 | + $x = "cur_timestamp"; |
| 114 | + $y = wfMsg( "watchmethod-recent" ); |
| 115 | + $z = "wl_namespace=cur_namespace&65534"; |
| 116 | + } else { |
| 117 | + $x = "name_title_timestamp"; |
| 118 | + $y = wfMsg( "watchmethod-list" ); |
| 119 | + $z = "(wl_namespace=cur_namespace OR wl_namespace+1=cur_namespace)"; |
| 120 | + } |
| 121 | + |
| 122 | + $wgOut->addHTML( "<i>" . wfMsg( "watchdetails", $nitems, $npages, $y, |
| 123 | + wfLocalUrl( $wgLang->specialPage("Watchlist"),"magic=yes" ) ) . "</i><br>\n" ); |
| 124 | + |
| 125 | + |
| 126 | + $sql = "SELECT |
| 127 | + cur_namespace,cur_title,cur_comment, |
48 | 128 | cur_user,cur_user_text,cur_timestamp,cur_minor_edit,cur_is_new |
49 | | - FROM cur,watchlist |
50 | | - WHERE wl_user={$uid} AND wl_title=cur_title |
51 | | - AND {$docutoff} (cur_namespace=wl_namespace OR cur_namespace=wl_namespace+1) |
52 | | - ORDER BY inverse_timestamp {$dolimit}"; |
| 129 | + FROM watchlist,cur USE INDEX ($x) |
| 130 | + WHERE wl_user=$uid |
| 131 | + AND $z |
| 132 | + AND wl_title=cur_title |
| 133 | + AND cur_timestamp>'$cutoff' |
| 134 | + ORDER BY cur_timestamp DESC"; |
| 135 | + |
| 136 | + |
53 | 137 | $res = wfQuery( $sql, $fname ); |
| 138 | + |
| 139 | + if($days >= 1) |
| 140 | + $note = wfMsg( "rcnote", $limit, $days ); |
| 141 | + else |
| 142 | + $note = wfMsg( "wlnote", $limit, round($days*24) ); |
| 143 | + $wgOut->addHTML( "\n<hr>\n{$note}\n<br>" ); |
| 144 | + $note = wlCutoffLinks( $days, $limit ); |
| 145 | + $wgOut->addHTML( "{$note}\n" ); |
| 146 | + |
54 | 147 | if ( wfNumRows( $res ) == 0 ) { |
55 | | - $wgOut->addHTML( wfMsg( "nowatchlist" ) ); |
| 148 | + $wgOut->addHTML( "<p><i>" . wfMsg( "watchnochange" ) . "</i></p>" ); |
56 | 149 | return; |
57 | 150 | } |
58 | 151 | |
59 | | - $note = wfMsg( "rcnote", $limit, $days ); |
60 | | - $wgOut->addHTML( "\n<hr>\n{$note}\n<br>" ); |
61 | | - $note = rcDayLimitlinks( $days, $limit, "Watchlist", "", true ); |
62 | | - $wgOut->addHTML( "{$note}\n" ); |
63 | | - |
64 | 152 | $sk = $wgUser->getSkin(); |
65 | 153 | $s = $sk->beginRecentChangesList(); |
66 | 154 | |
— | — | @@ -82,4 +170,44 @@ |
83 | 171 | $wgOut->addHTML( $s ); |
84 | 172 | } |
85 | 173 | |
| 174 | + |
| 175 | +function wlHoursLink( $h, $page ) { |
| 176 | + global $wgUser, $wgLang; |
| 177 | + $sk = $wgUser->getSkin(); |
| 178 | + $s = $sk->makeKnownLink( |
| 179 | + $wgLang->specialPage( $page ), |
| 180 | + $h, "days=" . ($h / 24.0) ); |
| 181 | + return $s; |
| 182 | +} |
| 183 | + |
| 184 | + |
| 185 | +function wlDaysLink( $d, $page ) { |
| 186 | + global $wgUser, $wgLang; |
| 187 | + $sk = $wgUser->getSkin(); |
| 188 | + $s = $sk->makeKnownLink( |
| 189 | + $wgLang->specialPage( $page ), |
| 190 | + $d, "days=$d" ); |
| 191 | + return $s; |
| 192 | +} |
| 193 | + |
| 194 | +function wlCutoffLinks( $days, $limit, $page = "Watchlist" ) |
| 195 | +{ |
| 196 | + $hours = array( 1, 2, 6, 12 ); |
| 197 | + $days = array( 1, 3, 7 ); |
| 198 | + $cl = ""; |
| 199 | + $i = 0; |
| 200 | + foreach( $hours as $h ) { |
| 201 | + $hours[$i++] = wlHoursLink( $h, $page ); |
| 202 | + } |
| 203 | + $i = 0; |
| 204 | + foreach( $days as $d ) { |
| 205 | + $days[$i++] = wlDaysLink( $d, $page ); |
| 206 | + } |
| 207 | + return |
| 208 | + "Show last " . |
| 209 | + implode(" | ", $hours) . " hours " . |
| 210 | + implode(" | ", $days) . " days"; |
| 211 | +# $note = wfMsg( "rclinks", $cl, $dl, $mlink ); |
| 212 | +} |
| 213 | + |
86 | 214 | ?> |
Index: trunk/phase3/languages/Language.php |
— | — | @@ -919,6 +919,24 @@ |
920 | 920 | "watchthispage" => "Watch this page", |
921 | 921 | "unwatchthispage" => "Stop watching", |
922 | 922 | "notanarticle" => "Not an article", |
| 923 | +"watchnochange" => "None of your watched items were edited in the time period displayed.", |
| 924 | +"watchdetails" => "($1 pages watched not counting talk pages; |
| 925 | +$2 total pages edited since cutoff; |
| 926 | +$3... |
| 927 | +<a href='$4'>show and edit complete list</a>.)", |
| 928 | +"watchmethod-recent" => "checking recent edits for watched pages", |
| 929 | +"watchmethod-list" => "checking watched pages for recent edits", |
| 930 | +"removechecked" => "Remove checked items from watchlist", |
| 931 | +"watchlistcontains" => "Your watchlist contains $1 pages.", |
| 932 | +"watcheditlist" => "Here's an alphabetical list of your |
| 933 | +watched pages. Check the boxes of pages you want to remove |
| 934 | +from your watchlist and click the 'remove checked' button |
| 935 | +at the bottom of the screen.", |
| 936 | +"removingchecked" => "Removing requested items from watchlist...", |
| 937 | +"couldntremove" => "Couldn't remove item '$1'...", |
| 938 | +"iteminvalidname" => "Problem with item '$1', invalid name...", |
| 939 | +"wlnote" => "Below are the last $1 changes in the last <b>$2</b> hours.", |
| 940 | + |
923 | 941 | |
924 | 942 | # Delete/protect/revert |
925 | 943 | # |