Index: trunk/phase3/CREDITS |
— | — | @@ -83,6 +83,7 @@ |
84 | 84 | * Marcin Cieślak |
85 | 85 | * Marcus Buck |
86 | 86 | * Marooned |
| 87 | +* Matthew Britton |
87 | 88 | * Max Semenik |
88 | 89 | * Michael De La Rue |
89 | 90 | * Michael Walsh |
Index: trunk/phase3/includes/ChangeTags.php |
— | — | @@ -185,4 +185,35 @@ |
186 | 186 | $wgMemc->set( $key, $emptyTags, 300 ); |
187 | 187 | return $emptyTags; |
188 | 188 | } |
| 189 | + |
| 190 | + /** Returns associative array of tag names and hitcounts */ |
| 191 | + static function getHitCounts() { |
| 192 | + |
| 193 | + global $wgMemc; |
| 194 | + $key = wfMemcKey( 'hitcounts' ); |
| 195 | + |
| 196 | + if ($hitcounts = $wgMemc->get( $key )) |
| 197 | + return $hitcounts; |
| 198 | + |
| 199 | + $dbr = wfGetDB( DB_SLAVE ); |
| 200 | + $hitcounts = array(); |
| 201 | + |
| 202 | + // Fetch defined tags |
| 203 | + $res = $dbr->select( 'valid_tag', 'vt_tag', array(), __METHOD__ ); |
| 204 | + while( $row = $res->fetchObject() ) { |
| 205 | + $hitcounts[$row->vt_tag] = 0; |
| 206 | + } |
| 207 | + |
| 208 | + // Fetch hit counts |
| 209 | + $res = $dbr->select( 'change_tag', array('ct_tag', 'count(*) AS hitcount'), array(), __METHOD__, array('GROUP BY' => 'ct_tag', 'ORDER BY' => 'hitcount DESC') ); |
| 210 | + |
| 211 | + while( $row = $res->fetchObject() ) { |
| 212 | + $hitcounts[$row->ct_tag] = $row->hitcount; |
| 213 | + } |
| 214 | + |
| 215 | + // Short-term caching |
| 216 | + $wgMemc->set( $key, $hitcounts, 300 ); |
| 217 | + return $hitcounts; |
| 218 | + } |
| 219 | + |
189 | 220 | } |
Index: trunk/phase3/includes/api/ApiQueryRecentChanges.php |
— | — | @@ -42,7 +42,7 @@ |
43 | 43 | |
44 | 44 | private $fld_comment = false, $fld_user = false, $fld_flags = false, |
45 | 45 | $fld_timestamp = false, $fld_title = false, $fld_ids = false, |
46 | | - $fld_sizes = false; |
| 46 | + $fld_sizes = false, $fld_tags = false; |
47 | 47 | /** |
48 | 48 | * Get an array mapping token names to their handler functions. |
49 | 49 | * The prototype for a token function is func($pageid, $title, $rc) |
— | — | @@ -174,6 +174,7 @@ |
175 | 175 | $this->fld_redirect = isset($prop['redirect']); |
176 | 176 | $this->fld_patrolled = isset($prop['patrolled']); |
177 | 177 | $this->fld_loginfo = isset($prop['loginfo']); |
| 178 | + $this->fld_tags = isset($prop['tags']); |
178 | 179 | |
179 | 180 | global $wgUser; |
180 | 181 | if($this->fld_patrolled && !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol()) |
— | — | @@ -203,6 +204,17 @@ |
204 | 205 | $this->addFields('page_is_redirect'); |
205 | 206 | } |
206 | 207 | } |
| 208 | + |
| 209 | + if($this->fld_tags || !is_null($params['tag'])) { |
| 210 | + $this->addTables('tag_summary'); |
| 211 | + $this->addJoinConds(array('tag_summary' => array('LEFT JOIN', array('rc_id=ts_rc_id')))); |
| 212 | + $this->addFields('ts_tags'); |
| 213 | + } |
| 214 | + |
| 215 | + if(!is_null($params['tag'])) { |
| 216 | + $this->addWhereFld('ts_tags' , $params['tag']); |
| 217 | + } |
| 218 | + |
207 | 219 | $this->token = $params['token']; |
208 | 220 | $this->addOption('LIMIT', $params['limit'] +1); |
209 | 221 | $this->addOption('USE INDEX', array('recentchanges' => $index)); |
— | — | @@ -335,6 +347,10 @@ |
336 | 348 | $row->rc_log_type, $row->rc_timestamp); |
337 | 349 | } |
338 | 350 | |
| 351 | + if ($this->fld_tags && isset($row->ts_tags)) { |
| 352 | + $vals['tags'] = $row->ts_tags; |
| 353 | + } |
| 354 | + |
339 | 355 | if(!is_null($this->token)) |
340 | 356 | { |
341 | 357 | $tokenFunctions = $this->getTokenFunctions(); |
— | — | @@ -408,6 +424,7 @@ |
409 | 425 | 'redirect', |
410 | 426 | 'patrolled', |
411 | 427 | 'loginfo', |
| 428 | + 'tags', |
412 | 429 | ) |
413 | 430 | ), |
414 | 431 | 'token' => array( |
— | — | @@ -443,7 +460,8 @@ |
444 | 461 | 'new', |
445 | 462 | 'log' |
446 | 463 | ) |
447 | | - ) |
| 464 | + ), |
| 465 | + 'tag' => null, |
448 | 466 | ); |
449 | 467 | } |
450 | 468 | |
— | — | @@ -462,6 +480,7 @@ |
463 | 481 | 'For example, to see only minor edits done by logged-in users, set show=minor|!anon' |
464 | 482 | ), |
465 | 483 | 'type' => 'Which types of changes to show.', |
| 484 | + 'tag' => 'Only list changes with this tag', |
466 | 485 | 'limit' => 'How many total changes to return.' |
467 | 486 | ); |
468 | 487 | } |
Index: trunk/phase3/includes/api/ApiQueryLogEvents.php |
— | — | @@ -51,6 +51,7 @@ |
52 | 52 | $this->fld_timestamp = in_array('timestamp', $prop); |
53 | 53 | $this->fld_comment = in_array('comment', $prop); |
54 | 54 | $this->fld_details = in_array('details', $prop); |
| 55 | + $this->fld_tags = in_array('tags', $prop); |
55 | 56 | |
56 | 57 | list($tbl_logging, $tbl_page, $tbl_user) = $db->tableNamesN('logging', 'page', 'user'); |
57 | 58 | |
— | — | @@ -85,6 +86,16 @@ |
86 | 87 | $this->addFieldsIf('log_comment', $this->fld_comment); |
87 | 88 | $this->addFieldsIf('log_params', $this->fld_details); |
88 | 89 | |
| 90 | + if($this->fld_tags || !is_null($params['tag'])) { |
| 91 | + $this->addTables('tag_summary'); |
| 92 | + $this->addJoinConds(array('tag_summary' => array('LEFT JOIN', 'log_id=ts_log_id'))); |
| 93 | + $this->addFields('ts_tags'); |
| 94 | + } |
| 95 | + |
| 96 | + if( !is_null($params['tag']) ) { |
| 97 | + $this->addWhereFld('ts_tags', $params['tag']); |
| 98 | + } |
| 99 | + |
89 | 100 | if( !is_null($params['type']) ) { |
90 | 101 | $this->addWhereFld('log_type', $params['type']); |
91 | 102 | $index = 'type_time'; |
— | — | @@ -247,6 +258,10 @@ |
248 | 259 | } |
249 | 260 | } |
250 | 261 | |
| 262 | + if ($this->fld_tags && isset($row->ts_tags)) { |
| 263 | + $vals['tags'] = $row->ts_tags; |
| 264 | + } |
| 265 | + |
251 | 266 | return $vals; |
252 | 267 | } |
253 | 268 | |
— | — | @@ -265,6 +280,7 @@ |
266 | 281 | 'timestamp', |
267 | 282 | 'comment', |
268 | 283 | 'details', |
| 284 | + 'tags' |
269 | 285 | ) |
270 | 286 | ), |
271 | 287 | 'type' => array ( |
— | — | @@ -285,6 +301,7 @@ |
286 | 302 | ), |
287 | 303 | 'user' => null, |
288 | 304 | 'title' => null, |
| 305 | + 'tag' => null, |
289 | 306 | 'limit' => array ( |
290 | 307 | ApiBase :: PARAM_DFLT => 10, |
291 | 308 | ApiBase :: PARAM_TYPE => 'limit', |
— | — | @@ -304,6 +321,7 @@ |
305 | 322 | 'dir' => 'In which direction to enumerate.', |
306 | 323 | 'user' => 'Filter entries to those made by the given user.', |
307 | 324 | 'title' => 'Filter entries to those related to a page.', |
| 325 | + 'tag' => 'Only list entries with this tag', |
308 | 326 | 'limit' => 'How many total event entries to return.' |
309 | 327 | ); |
310 | 328 | } |
Index: trunk/phase3/includes/api/ApiQuery.php |
— | — | @@ -74,6 +74,7 @@ |
75 | 75 | 'logevents' => 'ApiQueryLogEvents', |
76 | 76 | 'recentchanges' => 'ApiQueryRecentChanges', |
77 | 77 | 'search' => 'ApiQuerySearch', |
| 78 | + 'tags' => 'ApiQueryTags', |
78 | 79 | 'usercontribs' => 'ApiQueryContributions', |
79 | 80 | 'watchlist' => 'ApiQueryWatchlist', |
80 | 81 | 'watchlistraw' => 'ApiQueryWatchlistRaw', |
Index: trunk/phase3/includes/api/ApiQueryRevisions.php |
— | — | @@ -42,7 +42,7 @@ |
43 | 43 | } |
44 | 44 | |
45 | 45 | private $fld_ids = false, $fld_flags = false, $fld_timestamp = false, $fld_size = false, |
46 | | - $fld_comment = false, $fld_user = false, $fld_content = false; |
| 46 | + $fld_comment = false, $fld_user = false, $fld_content = false, $fld_tags = false; |
47 | 47 | |
48 | 48 | protected function getTokenFunctions() { |
49 | 49 | // tokenname => function |
— | — | @@ -121,9 +121,8 @@ |
122 | 122 | } |
123 | 123 | |
124 | 124 | $db = $this->getDB(); |
125 | | - $this->addTables('revision'); |
| 125 | + $this->addTables(array('page', 'revision')); |
126 | 126 | $this->addFields(Revision::selectFields()); |
127 | | - $this->addTables('page'); |
128 | 127 | $this->addWhere('page_id = rev_page'); |
129 | 128 | |
130 | 129 | $prop = array_flip($params['prop']); |
— | — | @@ -135,6 +134,7 @@ |
136 | 135 | $this->fld_timestamp = isset ($prop['timestamp']); |
137 | 136 | $this->fld_comment = isset ($prop['comment']); |
138 | 137 | $this->fld_size = isset ($prop['size']); |
| 138 | + $this->fld_tags = isset ($prop['tags']); |
139 | 139 | $this->fld_user = isset ($prop['user']); |
140 | 140 | $this->token = $params['token']; |
141 | 141 | $this->diffto = $params['diffto']; |
— | — | @@ -143,6 +143,16 @@ |
144 | 144 | $this->addFields( Revision::selectPageFields() ); |
145 | 145 | } |
146 | 146 | |
| 147 | + if ($this->fld_tags || !is_null($params['tag'])) { |
| 148 | + $this->addTables('tag_summary'); |
| 149 | + $this->addJoinConds(array('tag_summary' => array('LEFT JOIN', array('rev_id=ts_rev_id')))); |
| 150 | + $this->addFields('ts_tags'); |
| 151 | + } |
| 152 | + |
| 153 | + if( !is_null($params['tag']) ) { |
| 154 | + $this->addWhereFld('ts_tags', $params['tag']); |
| 155 | + } |
| 156 | + |
147 | 157 | if (isset ($prop['content'])) { |
148 | 158 | |
149 | 159 | // For each page we will request, the user must have read rights for that page |
— | — | @@ -293,9 +303,9 @@ |
294 | 304 | $this->setContinueEnumParameter('startid', intval($row->rev_id)); |
295 | 305 | break; |
296 | 306 | } |
297 | | - $revision = new Revision( $row ); |
| 307 | + |
298 | 308 | // |
299 | | - $fit = $this->addPageSubItem($revision->getPage(), $this->extractRowInfo($revision), 'rev'); |
| 309 | + $fit = $this->addPageSubItem($row->rev_page, $this->extractRowInfo($row), 'rev'); |
300 | 310 | if(!$fit) |
301 | 311 | { |
302 | 312 | if($enumRevMode) |
— | — | @@ -311,7 +321,8 @@ |
312 | 322 | $db->freeResult($res); |
313 | 323 | } |
314 | 324 | |
315 | | - private function extractRowInfo( $revision ) { |
| 325 | + private function extractRowInfo( $row ) { |
| 326 | + $revision = new Revision( $row ); |
316 | 327 | $title = $revision->getTitle(); |
317 | 328 | $vals = array (); |
318 | 329 | |
— | — | @@ -353,6 +364,9 @@ |
354 | 365 | } |
355 | 366 | } |
356 | 367 | |
| 368 | + if ($this->fld_tags && $row->ts_tags) |
| 369 | + $vals['tags'] = $row->ts_tags; |
| 370 | + |
357 | 371 | if(!is_null($this->token)) |
358 | 372 | { |
359 | 373 | $tokenFunctions = $this->getTokenFunctions(); |
— | — | @@ -427,6 +441,7 @@ |
428 | 442 | 'size', |
429 | 443 | 'comment', |
430 | 444 | 'content', |
| 445 | + 'tags' |
431 | 446 | ) |
432 | 447 | ), |
433 | 448 | 'limit' => array ( |
— | — | @@ -460,6 +475,7 @@ |
461 | 476 | 'excludeuser' => array( |
462 | 477 | ApiBase :: PARAM_TYPE => 'user' |
463 | 478 | ), |
| 479 | + 'tag' => null, |
464 | 480 | 'expandtemplates' => false, |
465 | 481 | 'generatexml' => false, |
466 | 482 | 'section' => null, |
— | — | @@ -483,6 +499,7 @@ |
484 | 500 | 'dir' => 'direction of enumeration - towards "newer" or "older" revisions (enum)', |
485 | 501 | 'user' => 'only include revisions made by user', |
486 | 502 | 'excludeuser' => 'exclude revisions made by user', |
| 503 | + 'tag' => 'only list revisions with this tag', |
487 | 504 | 'expandtemplates' => 'expand templates in revision content', |
488 | 505 | 'generatexml' => 'generate XML parse tree for revision content', |
489 | 506 | 'section' => 'only retrieve the content of this section', |
Index: trunk/phase3/includes/api/ApiQueryTags.php |
— | — | @@ -0,0 +1,167 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * Created on Jul 9, 2009 |
| 6 | + * |
| 7 | + * API for MediaWiki 1.8+ |
| 8 | + * |
| 9 | + * Copyright (C) 2009 Matthew Britton <firstname>.<lastname>@btinternet.com |
| 10 | + * |
| 11 | + * This program is free software; you can redistribute it and/or modify |
| 12 | + * it under the terms of the GNU General Public License as published by |
| 13 | + * the Free Software Foundation; either version 2 of the License, or |
| 14 | + * (at your option) any later version. |
| 15 | + * |
| 16 | + * This program is distributed in the hope that it will be useful, |
| 17 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 19 | + * GNU General Public License for more details. |
| 20 | + * |
| 21 | + * You should have received a copy of the GNU General Public License along |
| 22 | + * with this program; if not, write to the Free Software Foundation, Inc., |
| 23 | + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 24 | + * http://www.gnu.org/copyleft/gpl.html |
| 25 | + */ |
| 26 | + |
| 27 | +if (!defined('MEDIAWIKI')) { |
| 28 | + // Eclipse helper - will be ignored in production |
| 29 | + require_once ('ApiQueryBase.php'); |
| 30 | +} |
| 31 | + |
| 32 | +/** |
| 33 | + * Query module to enumerate change tags. |
| 34 | + * |
| 35 | + * @ingroup API |
| 36 | + */ |
| 37 | +class ApiQueryTags extends ApiQueryBase { |
| 38 | + |
| 39 | + private $limit, $result; |
| 40 | + private $fld_displayname = false, $fld_description = false, |
| 41 | + $fld_hitcount = false; |
| 42 | + |
| 43 | + public function __construct($query, $moduleName) { |
| 44 | + parent :: __construct($query, $moduleName, 'tg'); |
| 45 | + } |
| 46 | + |
| 47 | + public function execute() { |
| 48 | + $params = $this->extractRequestParams(); |
| 49 | + |
| 50 | + $prop = array_flip($params['prop']); |
| 51 | + |
| 52 | + $this->fld_displayname = isset($prop['displayname']); |
| 53 | + $this->fld_description = isset($prop['description']); |
| 54 | + $this->fld_hitcount = isset($prop['hitcount']); |
| 55 | + |
| 56 | + $this->limit = $params['limit']; |
| 57 | + $this->result = $this->getResult(); |
| 58 | + |
| 59 | + $pageSet = $this->getPageSet(); |
| 60 | + $titles = $pageSet->getTitles(); |
| 61 | + $data = array(); |
| 62 | + $ok = true; |
| 63 | + |
| 64 | + if($this->fld_hitcount) { |
| 65 | + foreach( ChangeTags::getHitCounts() as $tag => $count ) { |
| 66 | + if(!$ok) break; |
| 67 | + $ok = $this->doTag( $tag, $count ); |
| 68 | + } |
| 69 | + } else { |
| 70 | + foreach( ChangeTags::listDefinedTags() as $tag ) { |
| 71 | + if(!$ok) break; |
| 72 | + $ok = $this->doTag( $tag, 0 ); |
| 73 | + } |
| 74 | + } |
| 75 | + |
| 76 | + $this->result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'tag'); |
| 77 | + } |
| 78 | + |
| 79 | + private function doTag( $tagName, $hitcount ) { |
| 80 | + static $count = 0; |
| 81 | + static $doneTags = array(); |
| 82 | + |
| 83 | + if ( in_array( $tagName, $doneTags ) ) { |
| 84 | + return true; |
| 85 | + } |
| 86 | + |
| 87 | + if(++$count > $this->limit) |
| 88 | + { |
| 89 | + $this->setContinueEnumParameter('continue', $tagName); |
| 90 | + return false; |
| 91 | + } |
| 92 | + |
| 93 | + $tag = array(); |
| 94 | + $tag['name'] = $tagName; |
| 95 | + |
| 96 | + if($this->fld_displayname) |
| 97 | + $tag['displayname'] = ChangeTags::tagDescription( $tagName ); |
| 98 | + |
| 99 | + if($this->fld_description) |
| 100 | + { |
| 101 | + $msg = wfMsg( "tag-$tagName-description" ); |
| 102 | + $msg = wfEmptyMsg( "tag-$tagName-description", $msg ) ? '' : $msg; |
| 103 | + $tag['description'] = $msg; |
| 104 | + } |
| 105 | + |
| 106 | + if($this->fld_hitcount) |
| 107 | + $tag['hitcount'] = $hitcount; |
| 108 | + |
| 109 | + $doneTags[] = $tagName; |
| 110 | + |
| 111 | + $fit = $this->result->addValue(array('query', $this->getModuleName()), null, $tag); |
| 112 | + if(!$fit) |
| 113 | + { |
| 114 | + $this->setContinueEnumParameter('continue', $tagName); |
| 115 | + return false; |
| 116 | + } |
| 117 | + |
| 118 | + return true; |
| 119 | + } |
| 120 | + |
| 121 | + public function getAllowedParams() { |
| 122 | + return array ( |
| 123 | + 'continue' => array( |
| 124 | + ), |
| 125 | + 'end' => array( |
| 126 | + ), |
| 127 | + 'limit' => array( |
| 128 | + ApiBase :: PARAM_DFLT => 10, |
| 129 | + ApiBase :: PARAM_TYPE => 'limit', |
| 130 | + ApiBase :: PARAM_MIN => 1, |
| 131 | + ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1, |
| 132 | + ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2 |
| 133 | + ), |
| 134 | + 'prop' => array( |
| 135 | + ApiBase :: PARAM_DFLT => 'name', |
| 136 | + ApiBase :: PARAM_TYPE => array( |
| 137 | + 'name', |
| 138 | + 'displayname', |
| 139 | + 'description', |
| 140 | + 'hitcount' |
| 141 | + ), |
| 142 | + ApiBase :: PARAM_ISMULTI => true |
| 143 | + ) |
| 144 | + ); |
| 145 | + } |
| 146 | + |
| 147 | + public function getParamDescription() { |
| 148 | + return array ( |
| 149 | + 'continue' => 'When more results are available, use this to continue', |
| 150 | + 'limit' => 'The maximum number of tags to list', |
| 151 | + 'prop' => 'Which properties to get', |
| 152 | + ); |
| 153 | + } |
| 154 | + |
| 155 | + public function getDescription() { |
| 156 | + return 'List change tags.'; |
| 157 | + } |
| 158 | + |
| 159 | + protected function getExamples() { |
| 160 | + return array ( |
| 161 | + 'api.php?action=query&list=tags&tgprop=displayname|description|hitcount' |
| 162 | + ); |
| 163 | + } |
| 164 | + |
| 165 | + public function getVersion() { |
| 166 | + return __CLASS__ . ': $Id: ApiQueryTags.php'; |
| 167 | + } |
| 168 | +} |
Property changes on: trunk/phase3/includes/api/ApiQueryTags.php |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 169 | + native |
Name: svn:keywords |
2 | 170 | + id |
Index: trunk/phase3/includes/api/ApiQueryUserContributions.php |
— | — | @@ -42,7 +42,7 @@ |
43 | 43 | private $params, $username; |
44 | 44 | private $fld_ids = false, $fld_title = false, $fld_timestamp = false, |
45 | 45 | $fld_comment = false, $fld_flags = false, |
46 | | - $fld_patrolled = false; |
| 46 | + $fld_patrolled = false, $fld_tags = false; |
47 | 47 | |
48 | 48 | public function execute() { |
49 | 49 | |
— | — | @@ -57,6 +57,7 @@ |
58 | 58 | $this->fld_flags = isset($prop['flags']); |
59 | 59 | $this->fld_timestamp = isset($prop['timestamp']); |
60 | 60 | $this->fld_patrolled = isset($prop['patrolled']); |
| 61 | + $this->fld_tags = isset($prop['tags']); |
61 | 62 | |
62 | 63 | // TODO: if the query is going only against the revision table, should this be done? |
63 | 64 | $this->selectNamedDB('contributions', DB_SLAVE, 'contributions'); |
— | — | @@ -141,7 +142,7 @@ |
142 | 143 | private function prepareQuery() { |
143 | 144 | // We're after the revision table, and the corresponding page |
144 | 145 | // row for anything we retrieve. We may also need the |
145 | | - // recentchanges row. |
| 146 | + // recentchanges row and/or tag summary row. |
146 | 147 | global $wgUser; |
147 | 148 | $tables = array('page', 'revision'); // Order may change |
148 | 149 | $this->addWhere('page_id=rev_page'); |
— | — | @@ -245,6 +246,16 @@ |
246 | 247 | $this->addFieldsIf('rev_minor_edit', $this->fld_flags); |
247 | 248 | $this->addFieldsIf('rev_parent_id', $this->fld_flags); |
248 | 249 | $this->addFieldsIf('rc_patrolled', $this->fld_patrolled); |
| 250 | + |
| 251 | + if($this->fld_tags || !is_null($this->params['tag'])) { |
| 252 | + $this->addTables('tag_summary'); |
| 253 | + $this->addJoinConds(array('tag_summary' => array('LEFT JOIN', array('rev_id=ts_rev_id')))); |
| 254 | + $this->addFields('ts_tags'); |
| 255 | + } |
| 256 | + |
| 257 | + if( !is_null($this->params['tag']) ) { |
| 258 | + $this->addWhereFld('ts_tags', $this->params['tag']); |
| 259 | + } |
249 | 260 | } |
250 | 261 | |
251 | 262 | /** |
— | — | @@ -292,6 +303,9 @@ |
293 | 304 | if ($this->fld_size && !is_null($row->rev_len)) |
294 | 305 | $vals['size'] = intval($row->rev_len); |
295 | 306 | |
| 307 | + if ($this->fld_tags && $row->ts_tags) |
| 308 | + $vals['tags'] = $row->ts_tags; |
| 309 | + |
296 | 310 | return $vals; |
297 | 311 | } |
298 | 312 | |
— | — | @@ -343,6 +357,7 @@ |
344 | 358 | 'size', |
345 | 359 | 'flags', |
346 | 360 | 'patrolled', |
| 361 | + 'tags', |
347 | 362 | ) |
348 | 363 | ), |
349 | 364 | 'show' => array ( |
— | — | @@ -354,6 +369,7 @@ |
355 | 370 | '!patrolled', |
356 | 371 | ) |
357 | 372 | ), |
| 373 | + 'tag' => null, |
358 | 374 | ); |
359 | 375 | } |
360 | 376 | |
— | — | @@ -370,6 +386,7 @@ |
371 | 387 | 'prop' => 'Include additional pieces of information', |
372 | 388 | 'show' => array('Show only items that meet this criteria, e.g. non minor edits only: show=!minor', |
373 | 389 | 'NOTE: if show=patrolled or show=!patrolled is set, revisions older than $wgRCMaxAge won\'t be shown',), |
| 390 | + 'tag' => 'Only list contributions with this tag', |
374 | 391 | ); |
375 | 392 | } |
376 | 393 | |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -304,6 +304,7 @@ |
305 | 305 | 'ApiQueryRevisions' => 'includes/api/ApiQueryRevisions.php', |
306 | 306 | 'ApiQuerySearch' => 'includes/api/ApiQuerySearch.php', |
307 | 307 | 'ApiQuerySiteinfo' => 'includes/api/ApiQuerySiteinfo.php', |
| 308 | + 'ApiQueryTags' => 'includes/api/ApiQueryTags.php', |
308 | 309 | 'ApiQueryUserInfo' => 'includes/api/ApiQueryUserInfo.php', |
309 | 310 | 'ApiQueryUsers' => 'includes/api/ApiQueryUsers.php', |
310 | 311 | 'ApiQueryWatchlist' => 'includes/api/ApiQueryWatchlist.php', |
Index: trunk/phase3/includes/specials/SpecialTags.php |
— | — | @@ -25,17 +25,11 @@ |
26 | 26 | Xml::tags( 'th', null, wfMsgExt( 'tags-description-header', 'parseinline' ) ) . |
27 | 27 | Xml::tags( 'th', null, wfMsgExt( 'tags-hitcount-header', 'parseinline' ) ) |
28 | 28 | ); |
29 | | - $dbr = wfGetDB( DB_SLAVE ); |
30 | | - $res = $dbr->select( 'change_tag', array( 'ct_tag', 'count(*) as hitcount' ), array(), __METHOD__, array( 'GROUP BY' => 'ct_tag', 'ORDER BY' => 'hitcount DESC' ) ); |
31 | 29 | |
32 | | - while ( $row = $res->fetchObject() ) { |
33 | | - $html .= $this->doTagRow( $row->ct_tag, $row->hitcount ); |
| 30 | + foreach( ChangeTags::getHitCounts() as $tag => $hitcount ) { |
| 31 | + $html .= $this->doTagRow( $tag, $hitcount ); |
34 | 32 | } |
35 | 33 | |
36 | | - foreach( ChangeTags::listDefinedTags() as $tag ) { |
37 | | - $html .= $this->doTagRow( $tag, 0 ); |
38 | | - } |
39 | | - |
40 | 34 | $wgOut->addHTML( Xml::tags( 'table', array( 'class' => 'wikitable mw-tags-table' ), $html ) ); |
41 | 35 | } |
42 | 36 | |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -426,6 +426,7 @@ |
427 | 427 | * (bug 19907) $wgCrossSiteAJAXdomains added to allow specified (or all) |
428 | 428 | external domains to access api.php via AJAX, if the browser supports the |
429 | 429 | Access-Control-Allow-Origin HTTP header |
| 430 | +* (bug 19004) Added support for tags to the API. |
430 | 431 | |
431 | 432 | === Languages updated in 1.16 === |
432 | 433 | |