Index: trunk/phase3/CREDITS |
— | — | @@ -86,6 +86,7 @@ |
87 | 87 | * Marcin Cieślak |
88 | 88 | * Marcus Buck |
89 | 89 | * Marooned |
| 90 | +* Matthew Britton |
90 | 91 | * Matěj Grabovský |
91 | 92 | * mati |
92 | 93 | * Max Sikström |
Index: trunk/phase3/includes/User.php |
— | — | @@ -3577,7 +3577,7 @@ |
3578 | 3578 | protected function loadOptions() { |
3579 | 3579 | global $wgCookiePrefix; |
3580 | 3580 | $this->load(); |
3581 | | - if ( $this->mOptionsLoaded || !$this->getId() ) |
| 3581 | + if ( $this->mOptionsLoaded ) |
3582 | 3582 | return; |
3583 | 3583 | |
3584 | 3584 | $this->mOptions = self::getDefaultOptions(); |
— | — | @@ -3589,20 +3589,11 @@ |
3590 | 3590 | $this->mOptions[$key] = $value; |
3591 | 3591 | } |
3592 | 3592 | } else { |
3593 | | - wfDebug( "Loading options for user " . $this->getId() . " from database.\n" ); |
3594 | | - // Load from database |
3595 | | - $dbr = wfGetDB( DB_SLAVE ); |
3596 | | - |
3597 | | - $res = $dbr->select( |
3598 | | - 'user_properties', |
3599 | | - '*', |
3600 | | - array( 'up_user' => $this->getId() ), |
3601 | | - __METHOD__ |
3602 | | - ); |
3603 | | - |
3604 | | - while( $row = $dbr->fetchObject( $res ) ) { |
3605 | | - $this->mOptionOverrides[$row->up_property] = $row->up_value; |
3606 | | - $this->mOptions[$row->up_property] = $row->up_value; |
| 3593 | + $this->mOptionOverrides = array(); |
| 3594 | + if ( $this->getId() ) { |
| 3595 | + $this->loadOptionsFromDatabase(); |
| 3596 | + } else { |
| 3597 | + $this->loadOptionsFromCookie(); |
3607 | 3598 | } |
3608 | 3599 | |
3609 | 3600 | //null skin if User::mId is loaded out of session data without persistant credentials |
— | — | @@ -3616,23 +3607,73 @@ |
3617 | 3608 | wfRunHooks( 'UserLoadOptions', array( $this, &$this->mOptions ) ); |
3618 | 3609 | } |
3619 | 3610 | |
| 3611 | + protected function loadOptionsFromDatabase() { |
| 3612 | + wfDebug( "Loading options for user ".$this->getId()." from database.\n" ); |
| 3613 | + // Load from database |
| 3614 | + $dbr = wfGetDB( DB_SLAVE ); |
| 3615 | + |
| 3616 | + $res = $dbr->select( |
| 3617 | + 'user_properties', |
| 3618 | + '*', |
| 3619 | + array('up_user' => $this->getId()), |
| 3620 | + __METHOD__ |
| 3621 | + ); |
| 3622 | + |
| 3623 | + while( $row = $dbr->fetchObject( $res ) ) { |
| 3624 | + $this->mOptionOverrides[$row->up_property] = $row->up_value; |
| 3625 | + $this->mOptions[$row->up_property] = $row->up_value; |
| 3626 | + } |
| 3627 | + } |
| 3628 | + |
| 3629 | + protected function loadOptionsFromCookie() { |
| 3630 | + global $wgCookiePrefix; |
| 3631 | + $cookie = $_COOKIE[$wgCookiePrefix."Options"]; |
| 3632 | + |
| 3633 | + $overrides = json_decode($cookie, true); // Load assoc array from cookie |
| 3634 | + |
| 3635 | + foreach( $overrides as $key => $value ) { |
| 3636 | + $this->mOptions[$key] = $value; |
| 3637 | + $this->mOptionOverrides[$key] = $value; |
| 3638 | + } |
| 3639 | + } |
| 3640 | + |
3620 | 3641 | protected function saveOptions() { |
3621 | 3642 | global $wgAllowPrefChange; |
3622 | 3643 | |
3623 | | - $extuser = ExternalUser::newFromUser( $this ); |
3624 | | - |
3625 | 3644 | $this->loadOptions(); |
3626 | | - $dbw = wfGetDB( DB_MASTER ); |
3627 | 3645 | |
3628 | | - $insert_rows = array(); |
3629 | | - |
3630 | 3646 | $saveOptions = $this->mOptions; |
3631 | 3647 | |
| 3648 | + $extuser = ExternalUser::newFromUser( $this ); |
| 3649 | + foreach( $saveOptions as $key => $value ) { |
| 3650 | + if ( $extuser && isset( $wgAllowPrefChange[$key] ) ) { |
| 3651 | + switch ( $wgAllowPrefChange[$key] ) { |
| 3652 | + case 'local': |
| 3653 | + case 'message': |
| 3654 | + break; |
| 3655 | + case 'semiglobal': |
| 3656 | + case 'global': |
| 3657 | + $extuser->setPref( $key, $value ); |
| 3658 | + } |
| 3659 | + } |
| 3660 | + } |
| 3661 | + |
3632 | 3662 | // Allow hooks to abort, for instance to save to a global profile. |
3633 | 3663 | // Reset options to default state before saving. |
3634 | 3664 | if( !wfRunHooks( 'UserSaveOptions', array( $this, &$saveOptions ) ) ) |
3635 | 3665 | return; |
3636 | 3666 | |
| 3667 | + if ( $this->getId() ) { |
| 3668 | + $this->saveOptionsToDatabase( $saveOptions ); |
| 3669 | + } else { |
| 3670 | + $this->saveOptionsToCookie( $saveOptions ); |
| 3671 | + } |
| 3672 | + } |
| 3673 | + |
| 3674 | + protected function saveOptionsToDatabase( $saveOptions ) { |
| 3675 | + $dbw = wfGetDB( DB_MASTER ); |
| 3676 | + $insert_rows = array(); |
| 3677 | + |
3637 | 3678 | foreach( $saveOptions as $key => $value ) { |
3638 | 3679 | # Don't bother storing default values |
3639 | 3680 | if ( ( is_null( self::getDefaultOption( $key ) ) && |
— | — | @@ -3644,16 +3685,6 @@ |
3645 | 3686 | 'up_value' => $value, |
3646 | 3687 | ); |
3647 | 3688 | } |
3648 | | - if ( $extuser && isset( $wgAllowPrefChange[$key] ) ) { |
3649 | | - switch ( $wgAllowPrefChange[$key] ) { |
3650 | | - case 'local': |
3651 | | - case 'message': |
3652 | | - break; |
3653 | | - case 'semiglobal': |
3654 | | - case 'global': |
3655 | | - $extuser->setPref( $key, $value ); |
3656 | | - } |
3657 | | - } |
3658 | 3689 | } |
3659 | 3690 | |
3660 | 3691 | $dbw->begin(); |
— | — | @@ -3662,6 +3693,12 @@ |
3663 | 3694 | $dbw->commit(); |
3664 | 3695 | } |
3665 | 3696 | |
| 3697 | + protected function saveOptionsToCookie( $saveOptions ) { |
| 3698 | + global $wgRequest; |
| 3699 | + |
| 3700 | + $data = json_encode( $saveOptions ); |
| 3701 | + $wgRequest->response()->setCookie( 'Options', $data, 86400 * 360 ); |
| 3702 | + } |
3666 | 3703 | /** |
3667 | 3704 | * Provide an array of HTML 5 attributes to put on an input element |
3668 | 3705 | * intended for the user to enter a new password. This may include |
Index: trunk/phase3/includes/api/ApiQueryRecentChanges.php |
— | — | @@ -96,6 +96,7 @@ |
97 | 97 | $this->fld_redirect = isset($prop['redirect']); |
98 | 98 | $this->fld_patrolled = isset($prop['patrolled']); |
99 | 99 | $this->fld_loginfo = isset($prop['loginfo']); |
| 100 | + $this->fld_tags = isset($prop['tags']); |
100 | 101 | } |
101 | 102 | |
102 | 103 | /** |
— | — | @@ -211,6 +212,18 @@ |
212 | 213 | $this->addFields('page_is_redirect'); |
213 | 214 | } |
214 | 215 | } |
| 216 | + |
| 217 | + if($this->fld_tags) { |
| 218 | + $this->addTables('tag_summary'); |
| 219 | + $this->addJoinConds(array('tag_summary' => array('LEFT JOIN', array('rc_id=ts_rc_id')))); |
| 220 | + $this->addFields('ts_tags'); |
| 221 | + } |
| 222 | + |
| 223 | + if(!is_null($params['tag'])) { |
| 224 | + $this->addTables('change_tag'); |
| 225 | + $this->addJoinConds(array('change_tag' => array('INNER JOIN', array('rc_id=ct_rc_id')))); |
| 226 | + $this->addWhereFld('ct_tag' , $params['tag']); |
| 227 | + } |
215 | 228 | $this->token = $params['token']; |
216 | 229 | $this->addOption('LIMIT', $params['limit'] +1); |
217 | 230 | $this->addOption('USE INDEX', array('recentchanges' => $index)); |
— | — | @@ -343,6 +356,16 @@ |
344 | 357 | $row->rc_log_type, $row->rc_timestamp); |
345 | 358 | } |
346 | 359 | |
| 360 | + if ($this->fld_tags) { |
| 361 | + if ($row->ts_tags) { |
| 362 | + $tags = explode(',', $row->ts_tags); |
| 363 | + $this->getResult()->setIndexedTagName($tags, 'tag'); |
| 364 | + $vals['tags'] = $tags; |
| 365 | + } else { |
| 366 | + $vals['tags'] = array(); |
| 367 | + } |
| 368 | + } |
| 369 | + |
347 | 370 | if(!is_null($this->token)) |
348 | 371 | { |
349 | 372 | $tokenFunctions = $this->getTokenFunctions(); |
— | — | @@ -416,6 +439,7 @@ |
417 | 440 | 'redirect', |
418 | 441 | 'patrolled', |
419 | 442 | 'loginfo', |
| 443 | + 'tags' |
420 | 444 | ) |
421 | 445 | ), |
422 | 446 | 'token' => array( |
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,18 @@ |
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) { |
| 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->addTables('change_tag'); |
| 98 | + $this->addJoinConds(array('change_tag' => array('INNER JOIN', array('log_id=ct_log_id')))); |
| 99 | + $this->addWhereFld('ct_tag', $params['tag']); |
| 100 | + } |
| 101 | + |
89 | 102 | if( !is_null($params['type']) ) { |
90 | 103 | $this->addWhereFld('log_type', $params['type']); |
91 | 104 | $index = 'type_time'; |
— | — | @@ -247,6 +260,16 @@ |
248 | 261 | } |
249 | 262 | } |
250 | 263 | |
| 264 | + if ($this->fld_tags) { |
| 265 | + if ($row->ts_tags) { |
| 266 | + $tags = explode(',', $row->ts_tags); |
| 267 | + $this->getResult()->setIndexedTagName($tags, 'tag'); |
| 268 | + $vals['tags'] = $tags; |
| 269 | + } else { |
| 270 | + $vals['tags'] = array(); |
| 271 | + } |
| 272 | + } |
| 273 | + |
251 | 274 | return $vals; |
252 | 275 | } |
253 | 276 | |
— | — | @@ -265,6 +288,7 @@ |
266 | 289 | 'timestamp', |
267 | 290 | 'comment', |
268 | 291 | 'details', |
| 292 | + 'tags' |
269 | 293 | ) |
270 | 294 | ), |
271 | 295 | 'type' => array ( |
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', |
— | — | @@ -584,4 +585,4 @@ |
585 | 586 | $vers[] = $psModule->getVersion(); |
586 | 587 | return $vers; |
587 | 588 | } |
588 | | -} |
\ No newline at end of file |
| 589 | +} |
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']); |
— | — | @@ -143,6 +142,19 @@ |
144 | 143 | $this->addFields( Revision::selectPageFields() ); |
145 | 144 | } |
146 | 145 | |
| 146 | + if (isset ($prop['tags'])) { |
| 147 | + $this->fld_tags = true; |
| 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->addTables('change_tag'); |
| 155 | + $this->addJoinConds(array('change_tag' => array('INNER JOIN', array('rev_id=ct_rev_id')))); |
| 156 | + $this->addWhereFld('ct_tag' , $params['tag']); |
| 157 | + } |
| 158 | + |
147 | 159 | if (isset ($prop['content'])) { |
148 | 160 | |
149 | 161 | // For each page we will request, the user must have read rights for that page |
— | — | @@ -293,9 +305,9 @@ |
294 | 306 | $this->setContinueEnumParameter('startid', intval($row->rev_id)); |
295 | 307 | break; |
296 | 308 | } |
297 | | - $revision = new Revision( $row ); |
| 309 | + |
298 | 310 | // |
299 | | - $fit = $this->addPageSubItem($revision->getPage(), $this->extractRowInfo($revision), 'rev'); |
| 311 | + $fit = $this->addPageSubItem($row->rev_page, $this->extractRowInfo($row), 'rev'); |
300 | 312 | if(!$fit) |
301 | 313 | { |
302 | 314 | if($enumRevMode) |
— | — | @@ -311,7 +323,8 @@ |
312 | 324 | $db->freeResult($res); |
313 | 325 | } |
314 | 326 | |
315 | | - private function extractRowInfo( $revision ) { |
| 327 | + private function extractRowInfo( $row ) { |
| 328 | + $revision = new Revision( $row ); |
316 | 329 | $title = $revision->getTitle(); |
317 | 330 | $vals = array (); |
318 | 331 | |
— | — | @@ -353,6 +366,16 @@ |
354 | 367 | } |
355 | 368 | } |
356 | 369 | |
| 370 | + if ($this->fld_tags) { |
| 371 | + if ($row->ts_tags) { |
| 372 | + $tags = explode(',', $row->ts_tags); |
| 373 | + $this->getResult()->setIndexedTagName($tags, 'tag'); |
| 374 | + $vals['tags'] = $tags; |
| 375 | + } else { |
| 376 | + $vals['tags'] = array(); |
| 377 | + } |
| 378 | + } |
| 379 | + |
357 | 380 | if(!is_null($this->token)) |
358 | 381 | { |
359 | 382 | $tokenFunctions = $this->getTokenFunctions(); |
— | — | @@ -427,6 +450,7 @@ |
428 | 451 | 'size', |
429 | 452 | 'comment', |
430 | 453 | 'content', |
| 454 | + 'tags' |
431 | 455 | ) |
432 | 456 | ), |
433 | 457 | 'limit' => array ( |
Index: trunk/phase3/includes/api/ApiQueryTags.php |
— | — | @@ -0,0 +1,177 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * Created on Jul 9, 2009 |
| 6 | + * |
| 7 | + * API for MediaWiki 1.8+ |
| 8 | + * |
| 9 | + * Copyright (C) 2009 |
| 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 | + |
| 63 | + $this->addTables('change_tag'); |
| 64 | + $this->addFields('ct_tag'); |
| 65 | + |
| 66 | + if($this->fld_hitcount) |
| 67 | + $this->addFields('count(*) AS hitcount'); |
| 68 | + |
| 69 | + $this->addOption('LIMIT', $this->limit + 1); |
| 70 | + $this->addOption('GROUP BY', 'ct_tag'); |
| 71 | + $this->addWhereRange('ct_tag', 'newer', $params['continue'], null); |
| 72 | + |
| 73 | + $res = $this->select(__METHOD__); |
| 74 | + |
| 75 | + $ok = true; |
| 76 | + |
| 77 | + while ( $row = $res->fetchObject() ) { |
| 78 | + if(!$ok) break; |
| 79 | + $ok = $this->doTag( $row->ct_tag, $row->hitcount ); |
| 80 | + } |
| 81 | + |
| 82 | + //include tags with no hits yet |
| 83 | + foreach( ChangeTags::listDefinedTags() as $tag ) { |
| 84 | + if(!$ok) break; |
| 85 | + $ok = $this->doTag( $tag, 0 ); |
| 86 | + } |
| 87 | + |
| 88 | + $this->result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'tag'); |
| 89 | + } |
| 90 | + |
| 91 | + private function doTag( $tagName, $hitcount ) { |
| 92 | + static $count = 0; |
| 93 | + static $doneTags = array(); |
| 94 | + |
| 95 | + if ( in_array( $tagName, $doneTags ) ) { |
| 96 | + return true; |
| 97 | + } |
| 98 | + |
| 99 | + if(++$count > $this->limit) |
| 100 | + { |
| 101 | + $this->setContinueEnumParameter('continue', $tagName); |
| 102 | + return false; |
| 103 | + } |
| 104 | + |
| 105 | + $tag = array(); |
| 106 | + $tag['name'] = $tagName; |
| 107 | + |
| 108 | + if($this->fld_displayname) |
| 109 | + $tag['displayname'] = ChangeTags::tagDescription( $tagName ); |
| 110 | + |
| 111 | + if($this->fld_description) |
| 112 | + { |
| 113 | + $msg = wfMsg( "tag-$tagName-description" ); |
| 114 | + $msg = wfEmptyMsg( "tag-$tagName-description", $msg ) ? '' : $msg; |
| 115 | + $tag['description'] = $msg; |
| 116 | + } |
| 117 | + |
| 118 | + if($this->fld_hitcount) |
| 119 | + $tag['hitcount'] = $hitcount; |
| 120 | + |
| 121 | + $doneTags[] = $tagName; |
| 122 | + |
| 123 | + $fit = $this->result->addValue(array('query', $this->getModuleName()), null, $tag); |
| 124 | + if(!$fit) |
| 125 | + { |
| 126 | + $this->setContinueEnumParameter('continue', $tagName); |
| 127 | + return false; |
| 128 | + } |
| 129 | + |
| 130 | + return true; |
| 131 | + } |
| 132 | + |
| 133 | + public function getAllowedParams() { |
| 134 | + return array ( |
| 135 | + 'continue' => array( |
| 136 | + ), |
| 137 | + 'limit' => array( |
| 138 | + ApiBase :: PARAM_DFLT => 10, |
| 139 | + ApiBase :: PARAM_TYPE => 'limit', |
| 140 | + ApiBase :: PARAM_MIN => 1, |
| 141 | + ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1, |
| 142 | + ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2 |
| 143 | + ), |
| 144 | + 'prop' => array( |
| 145 | + ApiBase :: PARAM_DFLT => 'name', |
| 146 | + ApiBase :: PARAM_TYPE => array( |
| 147 | + 'name', |
| 148 | + 'displayname', |
| 149 | + 'description', |
| 150 | + 'hitcount' |
| 151 | + ), |
| 152 | + ApiBase :: PARAM_ISMULTI => true |
| 153 | + ) |
| 154 | + ); |
| 155 | + } |
| 156 | + |
| 157 | + public function getParamDescription() { |
| 158 | + return array ( |
| 159 | + 'continue' => 'When more results are available, use this to continue', |
| 160 | + 'limit' => 'The maximum number of tags to list', |
| 161 | + 'prop' => 'Which properties to get', |
| 162 | + ); |
| 163 | + } |
| 164 | + |
| 165 | + public function getDescription() { |
| 166 | + return 'List change tags.'; |
| 167 | + } |
| 168 | + |
| 169 | + protected function getExamples() { |
| 170 | + return array ( |
| 171 | + 'api.php?action=query&list=tags&tgprop=displayname|description|hitcount' |
| 172 | + ); |
| 173 | + } |
| 174 | + |
| 175 | + public function getVersion() { |
| 176 | + return __CLASS__ . ': $Id: ApiQueryTags.php'; |
| 177 | + } |
| 178 | +} |
Property changes on: trunk/phase3/includes/api/ApiQueryTags.php |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 179 | + native |
Name: svn:keywords |
2 | 180 | + 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,19 @@ |
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) |
| 252 | + { |
| 253 | + $this->addTables('tag_summary'); |
| 254 | + $this->addJoinConds(array('tag_summary' => array('LEFT JOIN', array('rev_id=ts_rev_id')))); |
| 255 | + $this->addFields('ts_tags'); |
| 256 | + } |
| 257 | + |
| 258 | + if( !is_null($this->params['tag']) ) { |
| 259 | + $this->addTables('change_tag'); |
| 260 | + $this->addJoinConds(array('change_tag' => array('INNER JOIN', array('rev_id=ct_rev_id')))); |
| 261 | + $this->addWhereFld('ct_tag', $this->params['tag']); |
| 262 | + } |
249 | 263 | } |
250 | 264 | |
251 | 265 | /** |
— | — | @@ -292,6 +306,16 @@ |
293 | 307 | if ($this->fld_size && !is_null($row->rev_len)) |
294 | 308 | $vals['size'] = intval($row->rev_len); |
295 | 309 | |
| 310 | + if ($this->fld_tags) { |
| 311 | + if ($row->ts_tags) { |
| 312 | + $tags = explode(',', $row->ts_tags); |
| 313 | + $this->getResult()->setIndexedTagName($tags, 'tag'); |
| 314 | + $vals['tags'] = $tags; |
| 315 | + } else { |
| 316 | + $vals['tags'] = array(); |
| 317 | + } |
| 318 | + } |
| 319 | + |
296 | 320 | return $vals; |
297 | 321 | } |
298 | 322 | |
— | — | @@ -343,6 +367,7 @@ |
344 | 368 | 'size', |
345 | 369 | 'flags', |
346 | 370 | 'patrolled', |
| 371 | + 'tags' |
347 | 372 | ) |
348 | 373 | ), |
349 | 374 | 'show' => array ( |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -320,6 +320,7 @@ |
321 | 321 | 'ApiQueryRevisions' => 'includes/api/ApiQueryRevisions.php', |
322 | 322 | 'ApiQuerySearch' => 'includes/api/ApiQuerySearch.php', |
323 | 323 | 'ApiQuerySiteinfo' => 'includes/api/ApiQuerySiteinfo.php', |
| 324 | + 'ApiQueryTags' => 'includes/api/ApiQueryTags.php', |
324 | 325 | 'ApiQueryUserInfo' => 'includes/api/ApiQueryUserInfo.php', |
325 | 326 | 'ApiQueryUsers' => 'includes/api/ApiQueryUsers.php', |
326 | 327 | 'ApiQueryWatchlist' => 'includes/api/ApiQueryWatchlist.php', |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -674,6 +674,7 @@ |
675 | 675 | drcontinue param is passed |
676 | 676 | * (bug 21106) Deprecated parameters now tagged in action=paraminfo |
677 | 677 | * (bug 13453) rebuildrecentchanges maintenance script works on PG again |
| 678 | +* (bug 19004) Added support for tags |
678 | 679 | |
679 | 680 | === Languages updated in 1.16 === |
680 | 681 | |