Index: trunk/phase3/maintenance/language/messages.inc |
— | — | @@ -2141,6 +2141,8 @@ |
2142 | 2142 | 'watchlistedit-raw-titles', |
2143 | 2143 | 'watchlistedit-raw-submit', |
2144 | 2144 | 'watchlistedit-raw-done', |
| 2145 | + 'watchlistedit-raw-added', |
| 2146 | + 'watchlistedit-raw-removed', |
2145 | 2147 | ), |
2146 | 2148 | ); |
2147 | 2149 | /** Comments for each block */ |
Index: trunk/phase3/includes/WatchlistEditor.php |
— | — | @@ -43,11 +43,23 @@ |
44 | 44 | case self::EDIT_RAW: |
45 | 45 | $output->setPageTitle( wfMsg( 'watchlistedit-raw-title' ) ); |
46 | 46 | if( $request->wasPosted() && $this->checkToken( $request, $user ) ) { |
47 | | - $titles = $this->extractTitles( $request->getText( 'titles' ) ); |
48 | | - $this->clearWatchlist( $user ); |
49 | | - $this->watchTitles( $titles, $user ); |
| 47 | + $current = $this->getWatchlist( $user ); |
| 48 | + $wanted = $this->extractTitles( $request->getText( 'titles' ) ); |
| 49 | + $toWatch = array_diff( $wanted, $current ); |
| 50 | + $toUnwatch = array_diff( $current, $wanted ); |
| 51 | + $this->watchTitles( $toWatch, $user ); |
| 52 | + $this->unwatchTitles( $toUnwatch, $user ); |
50 | 53 | $user->invalidateCache(); |
51 | | - $output->addHtml( wfMsgExt( 'watchlistedit-raw-done', 'parse' ) ); |
| 54 | + if( count( $toWatch ) > 0 || count( $toUnwatch ) > 0 ) |
| 55 | + $output->addHtml( wfMsgExt( 'watchlistedit-raw-done', 'parse' ) ); |
| 56 | + if( ( $count = count( $toWatch ) ) > 0 ) { |
| 57 | + $output->addHtml( wfMsgExt( 'watchlistedit-raw-added', 'parse', $count ) ); |
| 58 | + $this->showTitles( $toWatch, $output, $user->getSkin() ); |
| 59 | + } |
| 60 | + if( ( $count = count( $toUnwatch ) ) > 0 ) { |
| 61 | + $output->addHtml( wfMsgExt( 'watchlistedit-raw-removed', 'parse', $count ) ); |
| 62 | + $this->showTitles( $toUnwatch, $output, $user->getSkin() ); |
| 63 | + } |
52 | 64 | } |
53 | 65 | $this->showRawForm( $output, $user ); |
54 | 66 | break; |
— | — | @@ -78,7 +90,7 @@ |
79 | 91 | |
80 | 92 | /** |
81 | 93 | * Extract a list of titles from a text list; if we're given |
82 | | - * an array, convert each item into a Title |
| 94 | + * an array, convert each item into a Title (ignores unwatchable titles) |
83 | 95 | * |
84 | 96 | * @param mixed $list |
85 | 97 | * @return array |
— | — | @@ -94,7 +106,7 @@ |
95 | 107 | $text = trim( $text ); |
96 | 108 | if( strlen( $text ) > 0 ) { |
97 | 109 | $title = Title::newFromText( $text ); |
98 | | - if( $title instanceof Title ) |
| 110 | + if( $title instanceof Title && $title->isWatchable() ) |
99 | 111 | $titles[] = $title; |
100 | 112 | } |
101 | 113 | } |
— | — | @@ -139,6 +151,27 @@ |
140 | 152 | } |
141 | 153 | |
142 | 154 | /** |
| 155 | + * Get a list of titles on a user's watchlist, excluding talk pages |
| 156 | + * |
| 157 | + * @param User $user |
| 158 | + * @return array |
| 159 | + */ |
| 160 | + private function getWatchlist( $user ) { |
| 161 | + $titles = array(); |
| 162 | + $dbr = wfGetDB( DB_SLAVE ); |
| 163 | + $res = $dbr->select( 'watchlist', '*', array( 'wl_user' => $user->getId() ), __METHOD__ ); |
| 164 | + if( $res && $dbr->numRows( $res ) > 0 ) { |
| 165 | + while( $row = $dbr->fetchObject( $res ) ) { |
| 166 | + $title = Title::makeTitleSafe( $row->wl_namespace, $row->wl_title ); |
| 167 | + if( $title instanceof Title && !$title->isTalkPage() ) |
| 168 | + $titles[] = $title; |
| 169 | + } |
| 170 | + $dbr->freeResult( $res ); |
| 171 | + } |
| 172 | + return $titles; |
| 173 | + } |
| 174 | + |
| 175 | + /** |
143 | 176 | * Get a list of titles on a user's watchlist, excluding talk pages, |
144 | 177 | * and return as a two-dimensional array with namespace, title and |
145 | 178 | * redirect status |
— | — | @@ -146,7 +179,7 @@ |
147 | 180 | * @param User $user |
148 | 181 | * @return array |
149 | 182 | */ |
150 | | - private function getWatchlist( $user ) { |
| 183 | + private function getWatchlistInfo( $user ) { |
151 | 184 | $titles = array(); |
152 | 185 | $dbr = wfGetDB( DB_SLAVE ); |
153 | 186 | $uid = intval( $user->getId() ); |
— | — | @@ -293,7 +326,7 @@ |
294 | 327 | $form .= Xml::hidden( 'token', $user->editToken( 'watchlistedit' ) ); |
295 | 328 | $form .= '<fieldset><legend>' . wfMsgHtml( 'watchlistedit-normal-legend' ) . '</legend>'; |
296 | 329 | $form .= wfMsgExt( 'watchlistedit-normal-explain', 'parse' ); |
297 | | - foreach( $this->getWatchlist( $user ) as $namespace => $pages ) { |
| 330 | + foreach( $this->getWatchlistInfo( $user ) as $namespace => $pages ) { |
298 | 331 | $form .= '<h2>' . $this->getNamespaceHeading( $namespace ) . '</h2>'; |
299 | 332 | $form .= '<ul>'; |
300 | 333 | foreach( $pages as $dbkey => $redirect ) { |
— | — | @@ -359,13 +392,8 @@ |
360 | 393 | $form .= Xml::label( wfMsg( 'watchlistedit-raw-titles' ), 'titles' ); |
361 | 394 | $form .= Xml::openElement( 'textarea', array( 'id' => 'titles', 'name' => 'titles', |
362 | 395 | 'rows' => 6, 'cols' => 80 ) ); |
363 | | - foreach( $this->getWatchlist( $user ) as $namespace => $pages ) { |
364 | | - foreach( $pages as $dbkey => $redirect ) { |
365 | | - $title = Title::makeTitleSafe( $namespace, $dbkey ); |
366 | | - if( $title instanceof Title ) |
367 | | - $form .= htmlspecialchars( $title->getPrefixedText() ) . "\n"; |
368 | | - } |
369 | | - } |
| 396 | + foreach( $this->getWatchlist( $user ) as $title ) |
| 397 | + $form .= htmlspecialchars( $title->getPrefixedText() ) . "\n"; |
370 | 398 | $form .= '</textarea>'; |
371 | 399 | $form .= '<p>' . Xml::submitButton( wfMsg( 'watchlistedit-raw-submit' ) ) . '</p>'; |
372 | 400 | $form .= '</fieldset></form>'; |
Index: trunk/phase3/includes/Title.php |
— | — | @@ -2305,6 +2305,16 @@ |
2306 | 2306 | # Return true if there was no history |
2307 | 2307 | return $row === false; |
2308 | 2308 | } |
| 2309 | + |
| 2310 | + /** |
| 2311 | + * Can this title be added to a user's watchlist? |
| 2312 | + * |
| 2313 | + * @return bool |
| 2314 | + */ |
| 2315 | + public function isWatchable() { |
| 2316 | + return !$this->isExternal() |
| 2317 | + && Namespace::isWatchable( $this->getNamespace() ); |
| 2318 | + } |
2309 | 2319 | |
2310 | 2320 | /** |
2311 | 2321 | * Get categories to which this Title belongs and return an array of |
— | — | @@ -2429,6 +2439,15 @@ |
2430 | 2440 | && $this->getNamespace() == $title->getNamespace() |
2431 | 2441 | && $this->getDbkey() === $title->getDbkey(); |
2432 | 2442 | } |
| 2443 | + |
| 2444 | + /** |
| 2445 | + * Return a string representation of this title |
| 2446 | + * |
| 2447 | + * @return string |
| 2448 | + */ |
| 2449 | + public function __toString() { |
| 2450 | + return $this->getPrefixedText(); |
| 2451 | + } |
2433 | 2452 | |
2434 | 2453 | /** |
2435 | 2454 | * Check if page exists |
Index: trunk/phase3/includes/Namespace.php |
— | — | @@ -134,7 +134,17 @@ |
135 | 135 | public static function isContent( $index ) { |
136 | 136 | global $wgContentNamespaces; |
137 | 137 | return $index == NS_MAIN || in_array( $index, $wgContentNamespaces ); |
138 | | - } |
| 138 | + } |
| 139 | + |
| 140 | + /** |
| 141 | + * Can pages in a namespace be watched? |
| 142 | + * |
| 143 | + * @param int $index |
| 144 | + * @return bool |
| 145 | + */ |
| 146 | + public static function isWatchable( $index ) { |
| 147 | + return $index >= NS_MAIN; |
| 148 | + } |
139 | 149 | |
140 | 150 | } |
141 | 151 | |
Index: trunk/phase3/languages/messages/MessagesEn.php |
— | — | @@ -2909,5 +2909,7 @@ |
2910 | 2910 | 'watchlistedit-raw-titles' => 'Titles:', |
2911 | 2911 | 'watchlistedit-raw-submit' => 'Update Watchlist', |
2912 | 2912 | 'watchlistedit-raw-done' => 'Your watchlist has been updated.', |
| 2913 | +'watchlistedit-raw-added' => '{{PLURAL:$1|1 title was|$1 titles were}} added:', |
| 2914 | +'watchlistedit-raw-removed' => '{{PLURAL:$1|1 title was|$1 titles were}} removed:', |
2913 | 2915 | |
2914 | 2916 | ); |
\ No newline at end of file |