[ 'name' => 'RSS0.91', 'mime' => 'text/xml; charset=utf-8', ], 'rss1' => [ 'name' => 'RSS1.0', 'mime' => 'text/xml; charset=utf-8', ], 'rss2' => [ 'name' => 'RSS2.0', 'mime' => 'text/xml; charset=utf-8', ], 'atom' => [ 'name' => 'ATOM0.3', 'mime' => 'application/xml; charset=utf-8', ], 'atom1' => [ 'name' => 'ATOM1.0', 'mime' => 'application/atom+xml; charset=utf-8', ], ]; /** @var array[] the set options */ public $options = [ 'type' => 'rss', 'feed_mode' => 'recent', 'link_to' => 'page', 'item_content' => 'diff', 'namespace' => '', 'items' => 15, 'show_minor' => false, 'show_deleted' => false, 'show_summary' => false, 'only_new' => false, 'sort' => 'natural', 'search_query' => '', 'content_type' => 'pages', 'guardmail' => 'none', 'title' => '', 'cache_allow' => false, 'cache_key' => '', ]; /** * Initialize the options from the request, falling back to config defaults * * @triggers FEED_OPTS_POSTPROCESS * @param array $options additional options to set (for testing) */ public function __construct($options = []) { global $conf; global $INPUT; $this->options['type'] = $INPUT->valid( 'type', array_keys($this->types), $conf['rss_type'] ); // we only support 'list', 'search', 'recent' but accept anything so plugins can take over $this->options['feed_mode'] = $INPUT->str('mode', 'recent'); $this->options['link_to'] = $INPUT->valid( 'linkto', ['diff', 'page', 'rev', 'current'], $conf['rss_linkto'] ); $this->options['item_content'] = $INPUT->valid( 'content', ['abstract', 'diff', 'htmldiff', 'html'], $conf['rss_content'] ); $this->options['namespace'] = $INPUT->filter('cleanID')->str('ns'); $this->options['items'] = $INPUT->int('num', $conf['recent']); $this->options['show_minor'] = $INPUT->bool('minor'); $this->options['show_deleted'] = $conf['rss_show_deleted']; $this->options['show_summary'] = $conf['rss_show_summary']; $this->options['only_new'] = $INPUT->bool('onlynewpages'); $this->options['sort'] = $INPUT->valid( 'sort', ['natural', 'date'], 'natural' ); $this->options['search_query'] = $INPUT->str('q'); $this->options['content_type'] = $INPUT->valid( 'view', ['pages', 'media', 'both'], $conf['rss_media'] ); $this->options['guardmail'] = $conf['mailguard']; $this->options['title'] = $conf['title']; if ($this->options['namespace']) { $this->options['title'] .= ' - ' . $this->options['namespace']; } $this->options['subtitle'] = $conf['tagline']; $this->options = array_merge($this->options, $options); // clamp items to a reasonable range to prevent cache DoS via arbitrary num values $this->options['items'] = min(max(1, (int)$this->options['items']), $conf['recent'] * 5); // only the recent mode is cached by default to prevent cache DoS; // plugins can enable caching for their modes via FEED_OPTS_POSTPROCESS $this->options['cache_allow'] = ($this->options['feed_mode'] === 'recent'); // initialization finished, let plugins know $eventData = [ 'opt' => &$this->options, ]; Event::createAndTrigger('FEED_OPTS_POSTPROCESS', $eventData); } /** * The cache key to use for a feed with these options * * Only includes options that affect the current mode's output. * * @param string[] $additional additional key parts (e.g. user, host, port) * @return string|null null if the feed should not be cached */ public function getCacheKey(array $additional = []): ?string { if (!$this->options['cache_allow']) { return null; } return implode('$', array_merge([ $this->options['feed_mode'], $this->options['type'], $this->options['link_to'], $this->options['item_content'], $this->options['show_summary'], $this->options['guardmail'], $this->options['namespace'], $this->options['items'], $this->options['show_minor'], $this->options['show_deleted'], $this->options['only_new'], $this->options['content_type'], $this->options['cache_key'], ], $additional)); } /** * Return a feed option by name * * @param string $option The name of the option * @param mixed $default default value if option is not set (should usually not happen) * @return mixed */ public function get($option, $default = null) { return $this->options[$option] ?? $default; } /** * Return the feed type for UniversalFeedCreator * * This returns the apropriate type for UniversalFeedCreator * * @return string */ public function getType() { return $this->types[$this->options['type']]['name']; } /** * Return the feed mime type * * @return string */ public function getMimeType() { return $this->types[$this->options['type']]['mime']; } }