/**
  * Make a nested call to the API to request watchlist items in the last $hours.
  * Wrap the result as an RSS/Atom feed.
  */
 public function execute()
 {
     $config = $this->getConfig();
     $feedClasses = $config->get('FeedClasses');
     try {
         $params = $this->extractRequestParams();
         if (!$config->get('Feed')) {
             $this->dieUsage('Syndication feeds are not available', 'feed-unavailable');
         }
         if (!isset($feedClasses[$params['feedformat']])) {
             $this->dieUsage('Invalid subscription feed type', 'feed-invalid');
         }
         // limit to the number of hours going from now back
         $endTime = wfTimestamp(TS_MW, time() - intval($params['hours'] * 60 * 60));
         // Prepare parameters for nested request
         $fauxReqArr = array('action' => 'query', 'meta' => 'siteinfo', 'siprop' => 'general', 'list' => 'watchlist', 'wlprop' => 'title|user|comment|timestamp|ids', 'wldir' => 'older', 'wlend' => $endTime, 'wllimit' => min(50, $this->getConfig()->get('FeedLimit')));
         if ($params['wlowner'] !== null) {
             $fauxReqArr['wlowner'] = $params['wlowner'];
         }
         if ($params['wltoken'] !== null) {
             $fauxReqArr['wltoken'] = $params['wltoken'];
         }
         if ($params['wlexcludeuser'] !== null) {
             $fauxReqArr['wlexcludeuser'] = $params['wlexcludeuser'];
         }
         if ($params['wlshow'] !== null) {
             $fauxReqArr['wlshow'] = $params['wlshow'];
         }
         if ($params['wltype'] !== null) {
             $fauxReqArr['wltype'] = $params['wltype'];
         }
         // Support linking directly to sections when possible
         // (possible only if section name is present in comment)
         if ($params['linktosections']) {
             $this->linkToSections = true;
         }
         // Check for 'allrev' parameter, and if found, show all revisions to each page on wl.
         if ($params['allrev']) {
             $fauxReqArr['wlallrev'] = '';
         }
         // Create the request
         $fauxReq = new FauxRequest($fauxReqArr);
         // Execute
         $module = new ApiMain($fauxReq);
         $module->execute();
         $data = $module->getResult()->getResultData(array('query', 'watchlist'));
         $feedItems = array();
         foreach ((array) $data as $key => $info) {
             if (ApiResult::isMetadataKey($key)) {
                 continue;
             }
             $feedItem = $this->createFeedItem($info);
             if ($feedItem) {
                 $feedItems[] = $feedItem;
             }
         }
         $msg = wfMessage('watchlist')->inContentLanguage()->text();
         $feedTitle = $this->getConfig()->get('Sitename') . ' - ' . $msg . ' [' . $this->getConfig()->get('LanguageCode') . ']';
         $feedUrl = SpecialPage::getTitleFor('Watchlist')->getFullURL();
         $feed = new $feedClasses[$params['feedformat']]($feedTitle, htmlspecialchars($msg), $feedUrl);
         ApiFormatFeedWrapper::setResult($this->getResult(), $feed, $feedItems);
     } catch (Exception $e) {
         // Error results should not be cached
         $this->getMain()->setCacheMaxAge(0);
         // @todo FIXME: Localise  brackets
         $feedTitle = $this->getConfig()->get('Sitename') . ' - Error - ' . wfMessage('watchlist')->inContentLanguage()->text() . ' [' . $this->getConfig()->get('LanguageCode') . ']';
         $feedUrl = SpecialPage::getTitleFor('Watchlist')->getFullURL();
         $feedFormat = isset($params['feedformat']) ? $params['feedformat'] : 'rss';
         $msg = wfMessage('watchlist')->inContentLanguage()->escaped();
         $feed = new $feedClasses[$feedFormat]($feedTitle, $msg, $feedUrl);
         if ($e instanceof UsageException) {
             $errorCode = $e->getCodeString();
         } else {
             // Something is seriously wrong
             $errorCode = 'internal_api_error';
         }
         $errorText = $e->getMessage();
         $feedItems[] = new FeedItem("Error ({$errorCode})", $errorText, '', '', '');
         ApiFormatFeedWrapper::setResult($this->getResult(), $feed, $feedItems);
     }
 }
Example #2
0
 /**
  * This method takes an array and converts it to XML.
  *
  * @param string|null $name Tag name
  * @param mixed $value Tag value (attributes/content/subelements)
  * @param int|null $indent Indentation
  * @param array $attributes Additional attributes
  * @return string
  */
 public static function recXmlPrint($name, $value, $indent, $attributes = [])
 {
     $retval = '';
     if ($indent !== null) {
         if ($name !== null) {
             $indent += 2;
         }
         $indstr = "\n" . str_repeat(' ', $indent);
     } else {
         $indstr = '';
     }
     if (is_object($value)) {
         $value = (array) $value;
     }
     if (is_array($value)) {
         $contentKey = isset($value[ApiResult::META_CONTENT]) ? $value[ApiResult::META_CONTENT] : '*';
         $subelementKeys = isset($value[ApiResult::META_SUBELEMENTS]) ? $value[ApiResult::META_SUBELEMENTS] : [];
         if (isset($value[ApiResult::META_BC_SUBELEMENTS])) {
             $subelementKeys = array_merge($subelementKeys, $value[ApiResult::META_BC_SUBELEMENTS]);
         }
         $preserveKeys = isset($value[ApiResult::META_PRESERVE_KEYS]) ? $value[ApiResult::META_PRESERVE_KEYS] : [];
         $indexedTagName = isset($value[ApiResult::META_INDEXED_TAG_NAME]) ? self::mangleName($value[ApiResult::META_INDEXED_TAG_NAME], $preserveKeys) : '_v';
         $bcBools = isset($value[ApiResult::META_BC_BOOLS]) ? $value[ApiResult::META_BC_BOOLS] : [];
         $indexSubelements = isset($value[ApiResult::META_TYPE]) ? $value[ApiResult::META_TYPE] !== 'array' : false;
         $content = null;
         $subelements = [];
         $indexedSubelements = [];
         foreach ($value as $k => $v) {
             if (ApiResult::isMetadataKey($k) && !in_array($k, $preserveKeys, true)) {
                 continue;
             }
             $oldv = $v;
             if (is_bool($v) && !in_array($k, $bcBools, true)) {
                 $v = $v ? 'true' : 'false';
             }
             if ($name !== null && $k === $contentKey) {
                 $content = $v;
             } elseif (is_int($k)) {
                 $indexedSubelements[$k] = $v;
             } elseif (is_array($v) || is_object($v)) {
                 $subelements[self::mangleName($k, $preserveKeys)] = $v;
             } elseif (in_array($k, $subelementKeys, true) || $name === null) {
                 $subelements[self::mangleName($k, $preserveKeys)] = ['content' => $v, ApiResult::META_CONTENT => 'content', ApiResult::META_TYPE => 'assoc'];
             } elseif (is_bool($oldv)) {
                 if ($oldv) {
                     $attributes[self::mangleName($k, $preserveKeys)] = '';
                 }
             } elseif ($v !== null) {
                 $attributes[self::mangleName($k, $preserveKeys)] = $v;
             }
         }
         if ($content !== null) {
             if ($subelements || $indexedSubelements) {
                 $subelements[self::mangleName($contentKey, $preserveKeys)] = ['content' => $content, ApiResult::META_CONTENT => 'content', ApiResult::META_TYPE => 'assoc'];
                 $content = null;
             } elseif (is_scalar($content)) {
                 // Add xml:space="preserve" to the element so XML parsers
                 // will leave whitespace in the content alone
                 $attributes += ['xml:space' => 'preserve'];
             }
         }
         if ($content !== null) {
             if (is_scalar($content)) {
                 $retval .= $indstr . Xml::element($name, $attributes, $content);
             } else {
                 if ($name !== null) {
                     $retval .= $indstr . Xml::element($name, $attributes, null);
                 }
                 $retval .= static::recXmlPrint(null, $content, $indent);
                 if ($name !== null) {
                     $retval .= $indstr . Xml::closeElement($name);
                 }
             }
         } elseif (!$indexedSubelements && !$subelements) {
             if ($name !== null) {
                 $retval .= $indstr . Xml::element($name, $attributes);
             }
         } else {
             if ($name !== null) {
                 $retval .= $indstr . Xml::element($name, $attributes, null);
             }
             foreach ($subelements as $k => $v) {
                 $retval .= static::recXmlPrint($k, $v, $indent);
             }
             foreach ($indexedSubelements as $k => $v) {
                 $retval .= static::recXmlPrint($indexedTagName, $v, $indent, $indexSubelements ? ['_idx' => $k] : []);
             }
             if ($name !== null) {
                 $retval .= $indstr . Xml::closeElement($name);
             }
         }
     } else {
         // to make sure null value doesn't produce unclosed element,
         // which is what Xml::element( $name, null, null ) returns
         if ($value === null) {
             $retval .= $indstr . Xml::element($name, $attributes);
         } else {
             $retval .= $indstr . Xml::element($name, $attributes, $value);
         }
     }
     return $retval;
 }