/**
  * Generates and outputs the result of this query based upon the provided parameters.
  *
  * @param ApiPageSet $resultPageSet
  */
 public function run($resultPageSet = null)
 {
     $user = $this->getUser();
     /* Get the parameters of the request. */
     $params = $this->extractRequestParams();
     /* Build our basic query. Namely, something along the lines of:
      * SELECT * FROM recentchanges WHERE rc_timestamp > $start
      * 		AND rc_timestamp < $end AND rc_namespace = $namespace
      */
     $this->addTables('recentchanges');
     $index = array('recentchanges' => 'rc_timestamp');
     // May change
     $this->addTimestampWhereRange('rc_timestamp', $params['dir'], $params['start'], $params['end']);
     if (!is_null($params['continue'])) {
         $cont = explode('|', $params['continue']);
         $this->dieContinueUsageIf(count($cont) != 2);
         $db = $this->getDB();
         $timestamp = $db->addQuotes($db->timestamp($cont[0]));
         $id = intval($cont[1]);
         $this->dieContinueUsageIf($id != $cont[1]);
         $op = $params['dir'] === 'older' ? '<' : '>';
         $this->addWhere("rc_timestamp {$op} {$timestamp} OR " . "(rc_timestamp = {$timestamp} AND " . "rc_id {$op}= {$id})");
     }
     $order = $params['dir'] === 'older' ? 'DESC' : 'ASC';
     $this->addOption('ORDER BY', array("rc_timestamp {$order}", "rc_id {$order}"));
     $this->addWhereFld('rc_namespace', $params['namespace']);
     if (!is_null($params['type'])) {
         try {
             $this->addWhereFld('rc_type', RecentChange::parseToRCType($params['type']));
         } catch (Exception $e) {
             ApiBase::dieDebug(__METHOD__, $e->getMessage());
         }
     }
     if (!is_null($params['show'])) {
         $show = array_flip($params['show']);
         /* Check for conflicting parameters. */
         if (isset($show['minor']) && isset($show['!minor']) || isset($show['bot']) && isset($show['!bot']) || isset($show['anon']) && isset($show['!anon']) || isset($show['redirect']) && isset($show['!redirect']) || isset($show['patrolled']) && isset($show['!patrolled']) || isset($show['patrolled']) && isset($show['unpatrolled']) || isset($show['!patrolled']) && isset($show['unpatrolled'])) {
             $this->dieUsageMsg('show');
         }
         // Check permissions
         if (isset($show['patrolled']) || isset($show['!patrolled']) || isset($show['unpatrolled'])) {
             if (!$user->useRCPatrol() && !$user->useNPPatrol()) {
                 $this->dieUsage('You need the patrol right to request the patrolled flag', 'permissiondenied');
             }
         }
         /* Add additional conditions to query depending upon parameters. */
         $this->addWhereIf('rc_minor = 0', isset($show['!minor']));
         $this->addWhereIf('rc_minor != 0', isset($show['minor']));
         $this->addWhereIf('rc_bot = 0', isset($show['!bot']));
         $this->addWhereIf('rc_bot != 0', isset($show['bot']));
         $this->addWhereIf('rc_user = 0', isset($show['anon']));
         $this->addWhereIf('rc_user != 0', isset($show['!anon']));
         $this->addWhereIf('rc_patrolled = 0', isset($show['!patrolled']));
         $this->addWhereIf('rc_patrolled != 0', isset($show['patrolled']));
         $this->addWhereIf('page_is_redirect = 1', isset($show['redirect']));
         if (isset($show['unpatrolled'])) {
             // See ChangesList:isUnpatrolled
             if ($user->useRCPatrol()) {
                 $this->addWhere('rc_patrolled = 0');
             } elseif ($user->useNPPatrol()) {
                 $this->addWhere('rc_patrolled = 0');
                 $this->addWhereFld('rc_type', RC_NEW);
             }
         }
         // Don't throw log entries out the window here
         $this->addWhereIf('page_is_redirect = 0 OR page_is_redirect IS NULL', isset($show['!redirect']));
     }
     if (!is_null($params['user']) && !is_null($params['excludeuser'])) {
         $this->dieUsage('user and excludeuser cannot be used together', 'user-excludeuser');
     }
     if (!is_null($params['user'])) {
         $this->addWhereFld('rc_user_text', $params['user']);
         $index['recentchanges'] = 'rc_user_text';
     }
     if (!is_null($params['excludeuser'])) {
         // We don't use the rc_user_text index here because
         // * it would require us to sort by rc_user_text before rc_timestamp
         // * the != condition doesn't throw out too many rows anyway
         $this->addWhere('rc_user_text != ' . $this->getDB()->addQuotes($params['excludeuser']));
     }
     /* Add the fields we're concerned with to our query. */
     $this->addFields(array('rc_id', 'rc_timestamp', 'rc_namespace', 'rc_title', 'rc_cur_id', 'rc_type', 'rc_deleted'));
     $showRedirects = false;
     /* Determine what properties we need to display. */
     if (!is_null($params['prop'])) {
         $prop = array_flip($params['prop']);
         /* Set up internal members based upon params. */
         $this->initProperties($prop);
         if ($this->fld_patrolled && !$user->useRCPatrol() && !$user->useNPPatrol()) {
             $this->dieUsage('You need the patrol right to request the patrolled flag', 'permissiondenied');
         }
         /* Add fields to our query if they are specified as a needed parameter. */
         $this->addFieldsIf(array('rc_this_oldid', 'rc_last_oldid'), $this->fld_ids);
         $this->addFieldsIf('rc_comment', $this->fld_comment || $this->fld_parsedcomment);
         $this->addFieldsIf('rc_user', $this->fld_user || $this->fld_userid);
         $this->addFieldsIf('rc_user_text', $this->fld_user);
         $this->addFieldsIf(array('rc_minor', 'rc_type', 'rc_bot'), $this->fld_flags);
         $this->addFieldsIf(array('rc_old_len', 'rc_new_len'), $this->fld_sizes);
         $this->addFieldsIf('rc_patrolled', $this->fld_patrolled);
         $this->addFieldsIf(array('rc_logid', 'rc_log_type', 'rc_log_action', 'rc_params'), $this->fld_loginfo);
         $showRedirects = $this->fld_redirect || isset($show['redirect']) || isset($show['!redirect']);
     }
     if ($this->fld_tags) {
         $this->addTables('tag_summary');
         $this->addJoinConds(array('tag_summary' => array('LEFT JOIN', array('rc_id=ts_rc_id'))));
         $this->addFields('ts_tags');
     }
     if ($this->fld_sha1) {
         $this->addTables('revision');
         $this->addJoinConds(array('revision' => array('LEFT JOIN', array('rc_this_oldid=rev_id'))));
         $this->addFields(array('rev_sha1', 'rev_deleted'));
     }
     if ($params['toponly'] || $showRedirects) {
         $this->addTables('page');
         $this->addJoinConds(array('page' => array('LEFT JOIN', array('rc_namespace=page_namespace', 'rc_title=page_title'))));
         $this->addFields('page_is_redirect');
         if ($params['toponly']) {
             $this->addWhere('rc_this_oldid = page_latest');
         }
     }
     if (!is_null($params['tag'])) {
         $this->addTables('change_tag');
         $this->addJoinConds(array('change_tag' => array('INNER JOIN', array('rc_id=ct_rc_id'))));
         $this->addWhereFld('ct_tag', $params['tag']);
     }
     // Paranoia: avoid brute force searches (bug 17342)
     if (!is_null($params['user']) || !is_null($params['excludeuser'])) {
         if (!$user->isAllowed('deletedhistory')) {
             $bitmask = Revision::DELETED_USER;
         } elseif (!$user->isAllowedAny('suppressrevision', 'viewsuppressed')) {
             $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
         } else {
             $bitmask = 0;
         }
         if ($bitmask) {
             $this->addWhere($this->getDB()->bitAnd('rc_deleted', $bitmask) . " != {$bitmask}");
         }
     }
     if ($this->getRequest()->getCheck('namespace')) {
         // LogPage::DELETED_ACTION hides the affected page, too.
         if (!$user->isAllowed('deletedhistory')) {
             $bitmask = LogPage::DELETED_ACTION;
         } elseif (!$user->isAllowedAny('suppressrevision', 'viewsuppressed')) {
             $bitmask = LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED;
         } else {
             $bitmask = 0;
         }
         if ($bitmask) {
             $this->addWhere($this->getDB()->makeList(array('rc_type != ' . RC_LOG, $this->getDB()->bitAnd('rc_deleted', $bitmask) . " != {$bitmask}"), LIST_OR));
         }
     }
     $this->token = $params['token'];
     $this->addOption('LIMIT', $params['limit'] + 1);
     $this->addOption('USE INDEX', $index);
     $count = 0;
     /* Perform the actual query. */
     $res = $this->select(__METHOD__);
     $titles = array();
     $result = $this->getResult();
     /* Iterate through the rows, adding data extracted from them to our query result. */
     foreach ($res as $row) {
         if (++$count > $params['limit']) {
             // We've reached the one extra which shows that there are
             // additional pages to be had. Stop here...
             $this->setContinueEnumParameter('continue', "{$row->rc_timestamp}|{$row->rc_id}");
             break;
         }
         if (is_null($resultPageSet)) {
             /* Extract the data from a single row. */
             $vals = $this->extractRowInfo($row);
             /* Add that row's data to our final output. */
             $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals);
             if (!$fit) {
                 $this->setContinueEnumParameter('continue', "{$row->rc_timestamp}|{$row->rc_id}");
                 break;
             }
         } else {
             $titles[] = Title::makeTitle($row->rc_namespace, $row->rc_title);
         }
     }
     if (is_null($resultPageSet)) {
         /* Format the result */
         $result->addIndexedTagName(array('query', $this->getModuleName()), 'rc');
     } else {
         $resultPageSet->populateFromTitles($titles);
     }
 }
예제 #2
0
 /**
  * Parsing text to RC_* constants
  * @since 1.24
  * @param string|array $type
  * @throws MWException
  * @return int|array RC_TYPE
  */
 public static function parseToRCType($type)
 {
     if (is_array($type)) {
         $retval = array();
         foreach ($type as $t) {
             $retval[] = RecentChange::parseToRCType($t);
         }
         return $retval;
     }
     if (!array_key_exists($type, self::$changeTypes)) {
         throw new MWException("Unknown type '{$type}'");
     }
     return self::$changeTypes[$type];
 }
예제 #3
0
 /**
  * Parsing text to RC_* constants
  * @since 1.24
  * @param string|array $type
  * @throws MWException
  * @return int|array RC_TYPE
  */
 public static function parseToRCType($type)
 {
     if (is_array($type)) {
         $retval = array();
         foreach ($type as $t) {
             $retval[] = RecentChange::parseToRCType($t);
         }
         return $retval;
     }
     switch ($type) {
         case 'edit':
             return RC_EDIT;
         case 'new':
             return RC_NEW;
         case 'log':
             return RC_LOG;
         case 'external':
             return RC_EXTERNAL;
         default:
             throw new MWException("Unknown type '{$type}'");
     }
 }
예제 #4
0
 /**
  * @param ApiPageSet $resultPageSet
  * @return void
  */
 private function run($resultPageSet = null)
 {
     $this->selectNamedDB('watchlist', DB_SLAVE, 'watchlist');
     $params = $this->extractRequestParams();
     $user = $this->getUser();
     $wlowner = $this->getWatchlistUser($params);
     if (!is_null($params['prop']) && is_null($resultPageSet)) {
         $prop = array_flip($params['prop']);
         $this->fld_ids = isset($prop['ids']);
         $this->fld_title = isset($prop['title']);
         $this->fld_flags = isset($prop['flags']);
         $this->fld_user = isset($prop['user']);
         $this->fld_userid = isset($prop['userid']);
         $this->fld_comment = isset($prop['comment']);
         $this->fld_parsedcomment = isset($prop['parsedcomment']);
         $this->fld_timestamp = isset($prop['timestamp']);
         $this->fld_sizes = isset($prop['sizes']);
         $this->fld_patrol = isset($prop['patrol']);
         $this->fld_notificationtimestamp = isset($prop['notificationtimestamp']);
         $this->fld_loginfo = isset($prop['loginfo']);
         if ($this->fld_patrol) {
             if (!$user->useRCPatrol() && !$user->useNPPatrol()) {
                 $this->dieUsage('patrol property is not available', 'patrol');
             }
         }
     }
     $this->addFields(['rc_id', 'rc_namespace', 'rc_title', 'rc_timestamp', 'rc_type', 'rc_deleted']);
     if (is_null($resultPageSet)) {
         $this->addFields(['rc_cur_id', 'rc_this_oldid', 'rc_last_oldid']);
         $this->addFieldsIf(['rc_type', 'rc_minor', 'rc_bot'], $this->fld_flags);
         $this->addFieldsIf('rc_user', $this->fld_user || $this->fld_userid);
         $this->addFieldsIf('rc_user_text', $this->fld_user);
         $this->addFieldsIf('rc_comment', $this->fld_comment || $this->fld_parsedcomment);
         $this->addFieldsIf(['rc_patrolled', 'rc_log_type'], $this->fld_patrol);
         $this->addFieldsIf(['rc_old_len', 'rc_new_len'], $this->fld_sizes);
         $this->addFieldsIf('wl_notificationtimestamp', $this->fld_notificationtimestamp);
         $this->addFieldsIf(['rc_logid', 'rc_log_type', 'rc_log_action', 'rc_params'], $this->fld_loginfo);
     } elseif ($params['allrev']) {
         $this->addFields('rc_this_oldid');
     } else {
         $this->addFields('rc_cur_id');
     }
     $this->addTables(['recentchanges', 'watchlist']);
     $userId = $wlowner->getId();
     $this->addJoinConds(['watchlist' => ['INNER JOIN', ['wl_user' => $userId, 'wl_namespace=rc_namespace', 'wl_title=rc_title']]]);
     $db = $this->getDB();
     $this->addTimestampWhereRange('rc_timestamp', $params['dir'], $params['start'], $params['end']);
     // Include in ORDER BY for uniqueness
     $this->addWhereRange('rc_id', $params['dir'], null, null);
     if (!is_null($params['continue'])) {
         $cont = explode('|', $params['continue']);
         $this->dieContinueUsageIf(count($cont) != 2);
         $op = $params['dir'] === 'newer' ? '>' : '<';
         $continueTimestamp = $db->addQuotes($db->timestamp($cont[0]));
         $continueId = (int) $cont[1];
         $this->dieContinueUsageIf($continueId != $cont[1]);
         $this->addWhere("rc_timestamp {$op} {$continueTimestamp} OR " . "(rc_timestamp = {$continueTimestamp} AND " . "rc_id {$op}= {$continueId})");
     }
     $this->addWhereFld('wl_namespace', $params['namespace']);
     if (!$params['allrev']) {
         $this->addTables('page');
         $this->addJoinConds(['page' => ['LEFT JOIN', 'rc_cur_id=page_id']]);
         $this->addWhere('rc_this_oldid=page_latest OR rc_type=' . RC_LOG);
     }
     if (!is_null($params['show'])) {
         $show = array_flip($params['show']);
         /* Check for conflicting parameters. */
         if (isset($show['minor']) && isset($show['!minor']) || isset($show['bot']) && isset($show['!bot']) || isset($show['anon']) && isset($show['!anon']) || isset($show['patrolled']) && isset($show['!patrolled']) || isset($show['unread']) && isset($show['!unread'])) {
             $this->dieUsageMsg('show');
         }
         // Check permissions.
         if (isset($show['patrolled']) || isset($show['!patrolled'])) {
             if (!$user->useRCPatrol() && !$user->useNPPatrol()) {
                 $this->dieUsage('You need the patrol right to request the patrolled flag', 'permissiondenied');
             }
         }
         /* Add additional conditions to query depending upon parameters. */
         $this->addWhereIf('rc_minor = 0', isset($show['!minor']));
         $this->addWhereIf('rc_minor != 0', isset($show['minor']));
         $this->addWhereIf('rc_bot = 0', isset($show['!bot']));
         $this->addWhereIf('rc_bot != 0', isset($show['bot']));
         $this->addWhereIf('rc_user = 0', isset($show['anon']));
         $this->addWhereIf('rc_user != 0', isset($show['!anon']));
         $this->addWhereIf('rc_patrolled = 0', isset($show['!patrolled']));
         $this->addWhereIf('rc_patrolled != 0', isset($show['patrolled']));
         $this->addWhereIf('rc_timestamp >= wl_notificationtimestamp', isset($show['unread']));
         $this->addWhereIf('wl_notificationtimestamp IS NULL OR rc_timestamp < wl_notificationtimestamp', isset($show['!unread']));
     }
     if (!is_null($params['type'])) {
         try {
             $this->addWhereFld('rc_type', RecentChange::parseToRCType($params['type']));
         } catch (Exception $e) {
             ApiBase::dieDebug(__METHOD__, $e->getMessage());
         }
     }
     if (!is_null($params['user']) && !is_null($params['excludeuser'])) {
         $this->dieUsage('user and excludeuser cannot be used together', 'user-excludeuser');
     }
     if (!is_null($params['user'])) {
         $this->addWhereFld('rc_user_text', $params['user']);
     }
     if (!is_null($params['excludeuser'])) {
         $this->addWhere('rc_user_text != ' . $db->addQuotes($params['excludeuser']));
     }
     // This is an index optimization for mysql, as done in the Special:Watchlist page
     $this->addWhereIf("rc_timestamp > ''", !isset($params['start']) && !isset($params['end']) && $db->getType() == 'mysql');
     // Paranoia: avoid brute force searches (bug 17342)
     if (!is_null($params['user']) || !is_null($params['excludeuser'])) {
         if (!$user->isAllowed('deletedhistory')) {
             $bitmask = Revision::DELETED_USER;
         } elseif (!$user->isAllowedAny('suppressrevision', 'viewsuppressed')) {
             $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
         } else {
             $bitmask = 0;
         }
         if ($bitmask) {
             $this->addWhere($this->getDB()->bitAnd('rc_deleted', $bitmask) . " != {$bitmask}");
         }
     }
     // LogPage::DELETED_ACTION hides the affected page, too. So hide those
     // entirely from the watchlist, or someone could guess the title.
     if (!$user->isAllowed('deletedhistory')) {
         $bitmask = LogPage::DELETED_ACTION;
     } elseif (!$user->isAllowedAny('suppressrevision', 'viewsuppressed')) {
         $bitmask = LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED;
     } else {
         $bitmask = 0;
     }
     if ($bitmask) {
         $this->addWhere($this->getDB()->makeList(['rc_type != ' . RC_LOG, $this->getDB()->bitAnd('rc_deleted', $bitmask) . " != {$bitmask}"], LIST_OR));
     }
     $this->addOption('LIMIT', $params['limit'] + 1);
     $ids = [];
     $count = 0;
     $res = $this->select(__METHOD__);
     foreach ($res as $row) {
         if (++$count > $params['limit']) {
             // We've reached the one extra which shows that there are
             // additional pages to be had. Stop here...
             $this->setContinueEnumParameter('continue', "{$row->rc_timestamp}|{$row->rc_id}");
             break;
         }
         if (is_null($resultPageSet)) {
             $vals = $this->extractRowInfo($row);
             $fit = $this->getResult()->addValue(['query', $this->getModuleName()], null, $vals);
             if (!$fit) {
                 $this->setContinueEnumParameter('continue', "{$row->rc_timestamp}|{$row->rc_id}");
                 break;
             }
         } else {
             if ($params['allrev']) {
                 $ids[] = intval($row->rc_this_oldid);
             } else {
                 $ids[] = intval($row->rc_cur_id);
             }
         }
     }
     if (is_null($resultPageSet)) {
         $this->getResult()->addIndexedTagName(['query', $this->getModuleName()], 'item');
     } elseif ($params['allrev']) {
         $resultPageSet->populateFromRevisionIDs($ids);
     } else {
         $resultPageSet->populateFromPageIDs($ids);
     }
 }
예제 #5
0
 /**
  * @dataProvider provideRCTypes
  * @covers RecentChange::parseToRCType
  */
 public function testParseToRCType($rcType, $type)
 {
     $this->assertEquals($rcType, RecentChange::parseToRCType($type));
 }
예제 #6
0
 /**
  * @param ApiPageSet $resultPageSet
  * @return void
  */
 private function run($resultPageSet = null)
 {
     $this->selectNamedDB('watchlist', DB_REPLICA, 'watchlist');
     $params = $this->extractRequestParams();
     $user = $this->getUser();
     $wlowner = $this->getWatchlistUser($params);
     if (!is_null($params['prop']) && is_null($resultPageSet)) {
         $prop = array_flip($params['prop']);
         $this->fld_ids = isset($prop['ids']);
         $this->fld_title = isset($prop['title']);
         $this->fld_flags = isset($prop['flags']);
         $this->fld_user = isset($prop['user']);
         $this->fld_userid = isset($prop['userid']);
         $this->fld_comment = isset($prop['comment']);
         $this->fld_parsedcomment = isset($prop['parsedcomment']);
         $this->fld_timestamp = isset($prop['timestamp']);
         $this->fld_sizes = isset($prop['sizes']);
         $this->fld_patrol = isset($prop['patrol']);
         $this->fld_notificationtimestamp = isset($prop['notificationtimestamp']);
         $this->fld_loginfo = isset($prop['loginfo']);
         if ($this->fld_patrol) {
             if (!$user->useRCPatrol() && !$user->useNPPatrol()) {
                 $this->dieUsage('patrol property is not available', 'patrol');
             }
         }
     }
     $options = ['dir' => $params['dir'] === 'older' ? WatchedItemQueryService::DIR_OLDER : WatchedItemQueryService::DIR_NEWER];
     if (is_null($resultPageSet)) {
         $options['includeFields'] = $this->getFieldsToInclude();
     } else {
         $options['usedInGenerator'] = true;
     }
     if ($params['start']) {
         $options['start'] = $params['start'];
     }
     if ($params['end']) {
         $options['end'] = $params['end'];
     }
     if (!is_null($params['continue'])) {
         $cont = explode('|', $params['continue']);
         $this->dieContinueUsageIf(count($cont) != 2);
         $continueTimestamp = $cont[0];
         $continueId = (int) $cont[1];
         $this->dieContinueUsageIf($continueId != $cont[1]);
         $options['startFrom'] = [$continueTimestamp, $continueId];
     }
     if ($wlowner !== $user) {
         $options['watchlistOwner'] = $wlowner;
         $options['watchlistOwnerToken'] = $params['token'];
     }
     if (!is_null($params['namespace'])) {
         $options['namespaceIds'] = $params['namespace'];
     }
     if ($params['allrev']) {
         $options['allRevisions'] = true;
     }
     if (!is_null($params['show'])) {
         $show = array_flip($params['show']);
         /* Check for conflicting parameters. */
         if ($this->showParamsConflicting($show)) {
             $this->dieUsageMsg('show');
         }
         // Check permissions.
         if (isset($show[WatchedItemQueryService::FILTER_PATROLLED]) || isset($show[WatchedItemQueryService::FILTER_NOT_PATROLLED])) {
             if (!$user->useRCPatrol() && !$user->useNPPatrol()) {
                 $this->dieUsage('You need the patrol right to request the patrolled flag', 'permissiondenied');
             }
         }
         $options['filters'] = array_keys($show);
     }
     if (!is_null($params['type'])) {
         try {
             $options['rcTypes'] = RecentChange::parseToRCType($params['type']);
         } catch (Exception $e) {
             ApiBase::dieDebug(__METHOD__, $e->getMessage());
         }
     }
     if (!is_null($params['user']) && !is_null($params['excludeuser'])) {
         $this->dieUsage('user and excludeuser cannot be used together', 'user-excludeuser');
     }
     if (!is_null($params['user'])) {
         $options['onlyByUser'] = $params['user'];
     }
     if (!is_null($params['excludeuser'])) {
         $options['notByUser'] = $params['excludeuser'];
     }
     $options['limit'] = $params['limit'] + 1;
     $ids = [];
     $count = 0;
     $watchedItemQuery = MediaWikiServices::getInstance()->getWatchedItemQueryService();
     $items = $watchedItemQuery->getWatchedItemsWithRecentChangeInfo($wlowner, $options);
     foreach ($items as list($watchedItem, $recentChangeInfo)) {
         /** @var WatchedItem $watchedItem */
         if (++$count > $params['limit']) {
             // We've reached the one extra which shows that there are
             // additional pages to be had. Stop here...
             $this->setContinueEnumParameter('continue', $recentChangeInfo['rc_timestamp'] . '|' . $recentChangeInfo['rc_id']);
             break;
         }
         if (is_null($resultPageSet)) {
             $vals = $this->extractOutputData($watchedItem, $recentChangeInfo);
             $fit = $this->getResult()->addValue(['query', $this->getModuleName()], null, $vals);
             if (!$fit) {
                 $this->setContinueEnumParameter('continue', $recentChangeInfo['rc_timestamp'] . '|' . $recentChangeInfo['rc_id']);
                 break;
             }
         } else {
             if ($params['allrev']) {
                 $ids[] = intval($recentChangeInfo['rc_this_oldid']);
             } else {
                 $ids[] = intval($recentChangeInfo['rc_cur_id']);
             }
         }
     }
     if (is_null($resultPageSet)) {
         $this->getResult()->addIndexedTagName(['query', $this->getModuleName()], 'item');
     } elseif ($params['allrev']) {
         $resultPageSet->populateFromRevisionIDs($ids);
     } else {
         $resultPageSet->populateFromPageIDs($ids);
     }
 }