MediaWiki  REL1_19
ApiQueryWatchlist.php
Go to the documentation of this file.
00001 <?php
00033 class ApiQueryWatchlist extends ApiQueryGeneratorBase {
00034 
00035         public function __construct( $query, $moduleName ) {
00036                 parent::__construct( $query, $moduleName, 'wl' );
00037         }
00038 
00039         public function execute() {
00040                 $this->run();
00041         }
00042 
00043         public function executeGenerator( $resultPageSet ) {
00044                 $this->run( $resultPageSet );
00045         }
00046 
00047         private $fld_ids = false, $fld_title = false, $fld_patrol = false, $fld_flags = false,
00048                         $fld_timestamp = false, $fld_user = false, $fld_comment = false, $fld_parsedcomment = false, $fld_sizes = false,
00049                         $fld_notificationtimestamp = false, $fld_userid = false, $fld_loginfo = false;
00050 
00055         private function run( $resultPageSet = null ) {
00056                 $this->selectNamedDB( 'watchlist', DB_SLAVE, 'watchlist' );
00057 
00058                 $params = $this->extractRequestParams();
00059 
00060                 $user = $this->getWatchlistUser( $params );
00061 
00062                 if ( !is_null( $params['prop'] ) && is_null( $resultPageSet ) ) {
00063                         $prop = array_flip( $params['prop'] );
00064 
00065                         $this->fld_ids = isset( $prop['ids'] );
00066                         $this->fld_title = isset( $prop['title'] );
00067                         $this->fld_flags = isset( $prop['flags'] );
00068                         $this->fld_user = isset( $prop['user'] );
00069                         $this->fld_userid = isset( $prop['userid'] );
00070                         $this->fld_comment = isset( $prop['comment'] );
00071                         $this->fld_parsedcomment = isset ( $prop['parsedcomment'] );
00072                         $this->fld_timestamp = isset( $prop['timestamp'] );
00073                         $this->fld_sizes = isset( $prop['sizes'] );
00074                         $this->fld_patrol = isset( $prop['patrol'] );
00075                         $this->fld_notificationtimestamp = isset( $prop['notificationtimestamp'] );
00076                         $this->fld_loginfo = isset( $prop['loginfo'] );
00077 
00078                         if ( $this->fld_patrol ) {
00079                                 if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
00080                                         $this->dieUsage( 'patrol property is not available', 'patrol' );
00081                                 }
00082                         }
00083                 }
00084 
00085                 $this->addFields( array(
00086                         'rc_namespace',
00087                         'rc_title',
00088                         'rc_timestamp',
00089                         'rc_type',
00090                 ) );
00091 
00092                 if ( is_null( $resultPageSet ) ) {
00093                         $this->addFields( array(
00094                                 'rc_cur_id',
00095                                 'rc_this_oldid',
00096                                 'rc_last_oldid',
00097                         ) );
00098 
00099                         $this->addFieldsIf( array( 'rc_new', 'rc_minor', 'rc_bot' ), $this->fld_flags );
00100                         $this->addFieldsIf( 'rc_user', $this->fld_user || $this->fld_userid );
00101                         $this->addFieldsIf( 'rc_user_text', $this->fld_user );
00102                         $this->addFieldsIf( 'rc_comment', $this->fld_comment || $this->fld_parsedcomment );
00103                         $this->addFieldsIf( 'rc_patrolled', $this->fld_patrol );
00104                         $this->addFieldsIf( array( 'rc_old_len', 'rc_new_len' ), $this->fld_sizes );
00105                         $this->addFieldsIf( 'wl_notificationtimestamp', $this->fld_notificationtimestamp );
00106                         $this->addFieldsIf( array( 'rc_logid', 'rc_log_type', 'rc_log_action', 'rc_params' ), $this->fld_loginfo );
00107                 } elseif ( $params['allrev'] ) {
00108                         $this->addFields( 'rc_this_oldid' );
00109                 } else {
00110                         $this->addFields( 'rc_cur_id' );
00111                 }
00112 
00113                 $this->addTables( array(
00114                         'recentchanges',
00115                         'watchlist',
00116                 ) );
00117 
00118                 $userId = $user->getId();
00119                 $this->addJoinConds( array( 'watchlist' => array('INNER JOIN',
00120                         array(
00121                                 'wl_user' => $userId,
00122                                 'wl_namespace=rc_namespace',
00123                                 'wl_title=rc_title'
00124                 ) ) ) );
00125 
00126                 $this->addWhere( array(
00127                         'rc_deleted' => 0,
00128                 ) );
00129 
00130                 $db = $this->getDB();
00131 
00132                 $this->addTimestampWhereRange( 'rc_timestamp', $params['dir'],
00133                         $params['start'], $params['end'] );
00134                 $this->addWhereFld( 'wl_namespace', $params['namespace'] );
00135 
00136                 if ( !$params['allrev'] ) {
00137                         $this->addTables( 'page' );
00138                         $this->addJoinConds( array( 'page' => array( 'LEFT JOIN','rc_cur_id=page_id' ) ) );
00139                         $this->addWhere( 'rc_this_oldid=page_latest OR rc_type=' . RC_LOG );
00140                 }
00141 
00142                 if ( !is_null( $params['show'] ) ) {
00143                         $show = array_flip( $params['show'] );
00144 
00145                         /* Check for conflicting parameters. */
00146                         if ( ( isset ( $show['minor'] ) && isset ( $show['!minor'] ) )
00147                                         || ( isset ( $show['bot'] ) && isset ( $show['!bot'] ) )
00148                                         || ( isset ( $show['anon'] ) && isset ( $show['!anon'] ) )
00149                                         || ( isset ( $show['patrolled'] ) && isset ( $show['!patrolled'] ) )
00150                         )
00151                         {
00152                                 $this->dieUsageMsg( 'show' );
00153                         }
00154 
00155                         // Check permissions.
00156                         if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ) {
00157                                 $user = $this->getUser();
00158                                 if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
00159                                         $this->dieUsage( 'You need the patrol right to request the patrolled flag', 'permissiondenied' );
00160                                 }
00161                         }
00162 
00163                         /* Add additional conditions to query depending upon parameters. */
00164                         $this->addWhereIf( 'rc_minor = 0', isset( $show['!minor'] ) );
00165                         $this->addWhereIf( 'rc_minor != 0', isset( $show['minor'] ) );
00166                         $this->addWhereIf( 'rc_bot = 0', isset( $show['!bot'] ) );
00167                         $this->addWhereIf( 'rc_bot != 0', isset( $show['bot'] ) );
00168                         $this->addWhereIf( 'rc_user = 0', isset( $show['anon'] ) );
00169                         $this->addWhereIf( 'rc_user != 0', isset( $show['!anon'] ) );
00170                         $this->addWhereIf( 'rc_patrolled = 0', isset( $show['!patrolled'] ) );
00171                         $this->addWhereIf( 'rc_patrolled != 0', isset( $show['patrolled'] ) );
00172                 }
00173 
00174                 if ( !is_null( $params['user'] ) && !is_null( $params['excludeuser'] ) ) {
00175                         $this->dieUsage( 'user and excludeuser cannot be used together', 'user-excludeuser' );
00176                 }
00177                 if ( !is_null( $params['user'] ) ) {
00178                         $this->addWhereFld( 'rc_user_text', $params['user'] );
00179                 }
00180                 if ( !is_null( $params['excludeuser'] ) ) {
00181                         $this->addWhere( 'rc_user_text != ' . $db->addQuotes( $params['excludeuser'] ) );
00182                 }
00183 
00184                 // This is an index optimization for mysql, as done in the Special:Watchlist page
00185                 $this->addWhereIf( "rc_timestamp > ''", !isset( $params['start'] ) && !isset( $params['end'] ) && $db->getType() == 'mysql' );
00186 
00187                 $this->addOption( 'LIMIT', $params['limit'] + 1 );
00188 
00189                 $ids = array();
00190                 $count = 0;
00191                 $res = $this->select( __METHOD__ );
00192 
00193                 foreach ( $res as $row ) {
00194                         if ( ++ $count > $params['limit'] ) {
00195                                 // We've reached the one extra which shows that there are additional pages to be had. Stop here...
00196                                 $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->rc_timestamp ) );
00197                                 break;
00198                         }
00199 
00200                         if ( is_null( $resultPageSet ) ) {
00201                                 $vals = $this->extractRowInfo( $row );
00202                                 $fit = $this->getResult()->addValue( array( 'query', $this->getModuleName() ), null, $vals );
00203                                 if ( !$fit ) {
00204                                         $this->setContinueEnumParameter( 'start',
00205                                                         wfTimestamp( TS_ISO_8601, $row->rc_timestamp ) );
00206                                         break;
00207                                 }
00208                         } else {
00209                                 if ( $params['allrev'] ) {
00210                                         $ids[] = intval( $row->rc_this_oldid );
00211                                 } else {
00212                                         $ids[] = intval( $row->rc_cur_id );
00213                                 }
00214                         }
00215                 }
00216 
00217                 if ( is_null( $resultPageSet ) ) {
00218                         $this->getResult()->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'item' );
00219                 } elseif ( $params['allrev'] ) {
00220                         $resultPageSet->populateFromRevisionIDs( $ids );
00221                 } else {
00222                         $resultPageSet->populateFromPageIDs( $ids );
00223                 }
00224         }
00225 
00226         private function extractRowInfo( $row ) {
00227                 $vals = array();
00228 
00229                 if ( $this->fld_ids ) {
00230                         $vals['pageid'] = intval( $row->rc_cur_id );
00231                         $vals['revid'] = intval( $row->rc_this_oldid );
00232                         $vals['old_revid'] = intval( $row->rc_last_oldid );
00233                 }
00234 
00235                 $title = Title::makeTitle( $row->rc_namespace, $row->rc_title );
00236 
00237                 if ( $this->fld_title ) {
00238                         ApiQueryBase::addTitleInfo( $vals, $title );
00239                 }
00240 
00241                 if ( $this->fld_user || $this->fld_userid ) {
00242 
00243                         if ( $this->fld_user ) {
00244                                 $vals['user'] = $row->rc_user_text;
00245                         }
00246 
00247                         if ( $this->fld_userid ) {
00248                                 $vals['user'] = $row->rc_user;
00249                         }
00250 
00251                         if ( !$row->rc_user ) {
00252                                 $vals['anon'] = '';
00253                         }
00254                 }
00255 
00256                 if ( $this->fld_flags ) {
00257                         if ( $row->rc_new ) {
00258                                 $vals['new'] = '';
00259                         }
00260                         if ( $row->rc_minor ) {
00261                                 $vals['minor'] = '';
00262                         }
00263                         if ( $row->rc_bot ) {
00264                                 $vals['bot'] = '';
00265                         }
00266                 }
00267 
00268                 if ( $this->fld_patrol && isset( $row->rc_patrolled ) ) {
00269                         $vals['patrolled'] = '';
00270                 }
00271 
00272                 if ( $this->fld_timestamp ) {
00273                         $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->rc_timestamp );
00274                 }
00275 
00276                 if ( $this->fld_sizes ) {
00277                         $vals['oldlen'] = intval( $row->rc_old_len );
00278                         $vals['newlen'] = intval( $row->rc_new_len );
00279                 }
00280 
00281                 if ( $this->fld_notificationtimestamp ) {
00282                         $vals['notificationtimestamp'] = ( $row->wl_notificationtimestamp == null )
00283                                 ? ''
00284                                 : wfTimestamp( TS_ISO_8601, $row->wl_notificationtimestamp );
00285                 }
00286 
00287                 if ( $this->fld_comment && isset( $row->rc_comment ) ) {
00288                         $vals['comment'] = $row->rc_comment;
00289                 }
00290 
00291                 if ( $this->fld_parsedcomment && isset( $row->rc_comment ) ) {
00292                         $vals['parsedcomment'] = Linker::formatComment( $row->rc_comment, $title );
00293                 }
00294 
00295                 if ( $this->fld_loginfo && $row->rc_type == RC_LOG ) {
00296                         $vals['logid'] = intval( $row->rc_logid );
00297                         $vals['logtype'] = $row->rc_log_type;
00298                         $vals['logaction'] = $row->rc_log_action;
00299                         ApiQueryLogEvents::addLogParams(
00300                                 $this->getResult(),
00301                                 $vals,
00302                                 $row->rc_params,
00303                                 $row->rc_log_type,
00304                                 $row->rc_log_action,
00305                                 $row->rc_timestamp
00306                         );
00307                 }
00308 
00309                 return $vals;
00310         }
00311 
00312         public function getAllowedParams() {
00313                 return array(
00314                         'allrev' => false,
00315                         'start' => array(
00316                                 ApiBase::PARAM_TYPE => 'timestamp'
00317                         ),
00318                         'end' => array(
00319                                 ApiBase::PARAM_TYPE => 'timestamp'
00320                         ),
00321                         'namespace' => array (
00322                                 ApiBase::PARAM_ISMULTI => true,
00323                                 ApiBase::PARAM_TYPE => 'namespace'
00324                         ),
00325                         'user' => array(
00326                                 ApiBase::PARAM_TYPE => 'user',
00327                         ),
00328                         'excludeuser' => array(
00329                                 ApiBase::PARAM_TYPE => 'user',
00330                         ),
00331                         'dir' => array(
00332                                 ApiBase::PARAM_DFLT => 'older',
00333                                 ApiBase::PARAM_TYPE => array(
00334                                         'newer',
00335                                         'older'
00336                                 )
00337                         ),
00338                         'limit' => array(
00339                                 ApiBase::PARAM_DFLT => 10,
00340                                 ApiBase::PARAM_TYPE => 'limit',
00341                                 ApiBase::PARAM_MIN => 1,
00342                                 ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
00343                                 ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
00344                         ),
00345                         'prop' => array(
00346                                 ApiBase::PARAM_ISMULTI => true,
00347                                 ApiBase::PARAM_DFLT => 'ids|title|flags',
00348                                 ApiBase::PARAM_TYPE => array(
00349                                         'ids',
00350                                         'title',
00351                                         'flags',
00352                                         'user',
00353                                         'userid',
00354                                         'comment',
00355                                         'parsedcomment',
00356                                         'timestamp',
00357                                         'patrol',
00358                                         'sizes',
00359                                         'notificationtimestamp',
00360                                         'loginfo',
00361                                 )
00362                         ),
00363                         'show' => array(
00364                                 ApiBase::PARAM_ISMULTI => true,
00365                                 ApiBase::PARAM_TYPE => array(
00366                                         'minor',
00367                                         '!minor',
00368                                         'bot',
00369                                         '!bot',
00370                                         'anon',
00371                                         '!anon',
00372                                         'patrolled',
00373                                         '!patrolled',
00374                                 )
00375                         ),
00376                         'owner' => array(
00377                                 ApiBase::PARAM_TYPE => 'user'
00378                         ),
00379                         'token' => array(
00380                                 ApiBase::PARAM_TYPE => 'string'
00381                         )
00382                 );
00383         }
00384 
00385         public function getParamDescription() {
00386                 $p = $this->getModulePrefix();
00387                 return array(
00388                         'allrev' => 'Include multiple revisions of the same page within given timeframe',
00389                         'start' => 'The timestamp to start enumerating from',
00390                         'end' => 'The timestamp to end enumerating',
00391                         'namespace' => 'Filter changes to only the given namespace(s)',
00392                         'user' => 'Only list changes by this user',
00393                         'excludeuser' => 'Don\'t list changes by this user',
00394                         'dir' => $this->getDirectionDescription( $p ),
00395                         'limit' => 'How many total results to return per request',
00396                         'prop' => array(
00397                                 'Which additional items to get (non-generator mode only).',
00398                                 ' ids                    - Adds revision ids and page ids',
00399                                 ' title                  - Adds title of the page',
00400                                 ' flags                  - Adds flags for the edit',
00401                                 ' user                   - Adds the user who made the edit',
00402                                 ' userid                 - Adds user id of whom made the edit',
00403                                 ' comment                - Adds comment of the edit',
00404                                 ' parsedcomment          - Adds parsed comment of the edit',
00405                                 ' timestamp              - Adds timestamp of the edit',
00406                                 ' patrol                 - Tags edits that are patrolled',
00407                                 ' sizes                  - Adds the old and new lengths of the page',
00408                                 ' notificationtimestamp  - Adds timestamp of when the user was last notified about the edit',
00409                                 ' loginfo                - Adds log information where appropriate',
00410                         ),
00411                         'show' => array(
00412                                 'Show only items that meet this criteria.',
00413                                 "For example, to see only minor edits done by logged-in users, set {$p}show=minor|!anon"
00414                         ),
00415                         'owner' => 'The name of the user whose watchlist you\'d like to access',
00416                         'token' => 'Give a security token (settable in preferences) to allow access to another user\'s watchlist'
00417                 );
00418         }
00419 
00420         public function getDescription() {
00421                 return "Get all recent changes to pages in the logged in user's watchlist";
00422         }
00423 
00424         public function getPossibleErrors() {
00425                 return array_merge( parent::getPossibleErrors(), array(
00426                         array( 'code' => 'bad_wlowner', 'info' => 'Specified user does not exist' ),
00427                         array( 'code' => 'bad_wltoken', 'info' => 'Incorrect watchlist token provided -- please set a correct token in Special:Preferences' ),
00428                         array( 'code' => 'notloggedin', 'info' => 'You must be logged-in to have a watchlist' ),
00429                         array( 'code' => 'patrol', 'info' => 'patrol property is not available' ),
00430                         array( 'show' ),
00431                         array( 'code' => 'permissiondenied', 'info' => 'You need the patrol right to request the patrolled flag' ),
00432                         array( 'code' => 'user-excludeuser', 'info' => 'user and excludeuser cannot be used together' ),
00433                 ) );
00434         }
00435 
00436         public function getExamples() {
00437                 return array(
00438                         'api.php?action=query&list=watchlist',
00439                         'api.php?action=query&list=watchlist&wlprop=ids|title|timestamp|user|comment',
00440                         'api.php?action=query&list=watchlist&wlallrev=&wlprop=ids|title|timestamp|user|comment',
00441                         'api.php?action=query&generator=watchlist&prop=info',
00442                         'api.php?action=query&generator=watchlist&gwlallrev=&prop=revisions&rvprop=timestamp|user',
00443                         'api.php?action=query&list=watchlist&wlowner=Bob_Smith&wltoken=d8d562e9725ea1512894cdab28e5ceebc7f20237'
00444                 );
00445         }
00446 
00447         public function getHelpUrls() {
00448                 return 'https://www.mediawiki.org/wiki/API:Watchlist';
00449         }
00450 
00451         public function getVersion() {
00452                 return __CLASS__ . ': $Id$';
00453         }
00454 }