1<?php
2
3namespace dokuwiki\Feed;
4
5use dokuwiki\Extension\Event;
6
7/**
8 * Hold the options for feed generation
9 */
10class FeedCreatorOptions
11{
12    /** @var array[] supported feed types */
13    protected $types = [
14        'rss' => [
15            'name' => 'RSS0.91',
16            'mime' => 'text/xml; charset=utf-8',
17        ],
18        'rss1' => [
19            'name' => 'RSS1.0',
20            'mime' => 'text/xml; charset=utf-8',
21        ],
22        'rss2' => [
23            'name' => 'RSS2.0',
24            'mime' => 'text/xml; charset=utf-8',
25        ],
26        'atom' => [
27            'name' => 'ATOM0.3',
28            'mime' => 'application/xml; charset=utf-8',
29        ],
30        'atom1' => [
31            'name' => 'ATOM1.0',
32            'mime' => 'application/atom+xml; charset=utf-8',
33        ],
34    ];
35
36    /** @var array[] the set options */
37    public $options = [
38        'type' => 'rss',
39        'feed_mode' => 'recent',
40        'link_to' => 'page',
41        'item_content' => 'diff',
42        'namespace' => '',
43        'items' => 15,
44        'show_minor' => false,
45        'show_deleted' => false,
46        'show_summary' => false,
47        'only_new' => false,
48        'sort' => 'natural',
49        'search_query' => '',
50        'content_type' => 'pages',
51        'guardmail' => 'none',
52        'title' => '',
53    ];
54
55    /**
56     * Initialize the options from the request, falling back to config defaults
57     *
58     * @triggers FEED_OPTS_POSTPROCESS
59     * @param array $options additional options to set (for testing)
60     */
61    public function __construct($options = [])
62    {
63        global $conf;
64        global $INPUT;
65
66        $this->options['type'] = $INPUT->valid(
67            'type',
68            array_keys($this->types),
69            $conf['rss_type']
70        );
71        // we only support 'list', 'search', 'recent' but accept anything so plugins can take over
72        $this->options['feed_mode'] = $INPUT->str('mode', 'recent');
73        $this->options['link_to'] = $INPUT->valid(
74            'linkto',
75            ['diff', 'page', 'rev', 'current'],
76            $conf['rss_linkto']
77        );
78        $this->options['item_content'] = $INPUT->valid(
79            'content',
80            ['abstract', 'diff', 'htmldiff', 'html'],
81            $conf['rss_content']
82        );
83        $this->options['namespace'] = $INPUT->filter('cleanID')->str('ns');
84        $this->options['items'] = max(0, $INPUT->int('num', $conf['recent']));
85        $this->options['show_minor'] = $INPUT->bool('minor');
86        $this->options['show_deleted'] = $conf['rss_show_deleted'];
87        $this->options['show_summary'] = $conf['rss_show_summary'];
88        $this->options['only_new'] = $INPUT->bool('onlynewpages');
89        $this->options['sort'] = $INPUT->valid(
90            'sort',
91            ['natural', 'date'],
92            'natural'
93        );
94        $this->options['search_query'] = $INPUT->str('q');
95        $this->options['content_type'] = $INPUT->valid(
96            'view',
97            ['pages', 'media', 'both'],
98            $conf['rss_media']
99        );
100        $this->options['guardmail'] = $conf['mailguard'];
101        $this->options['title'] = $conf['title'];
102        if ($this->options['namespace']) {
103            $this->options['title'] .= ' - ' . $this->options['namespace'];
104        }
105        $this->options['subtitle'] = $conf['tagline'];
106
107        $this->options = array_merge($this->options, $options);
108
109        // initialization finished, let plugins know
110        $eventData = [
111            'opt' => &$this->options,
112        ];
113        Event::createAndTrigger('FEED_OPTS_POSTPROCESS', $eventData);
114    }
115
116    /**
117     * The cache key to use for a feed with these options
118     *
119     * Does not contain user or host specific information yet
120     *
121     * @return string
122     */
123    public function getCacheKey()
124    {
125        return implode('', array_values($this->options));
126    }
127
128    /**
129     * Return a feed option by name
130     *
131     * @param string $option The name of the option
132     * @param mixed $default default value if option is not set (should usually not happen)
133     * @return mixed
134     */
135    public function get($option, $default = null)
136    {
137        return $this->options[$option] ?? $default;
138    }
139
140    /**
141     * Return the feed type for UniversalFeedCreator
142     *
143     * This returns the apropriate type for UniversalFeedCreator
144     *
145     * @return string
146     */
147    public function getType()
148    {
149        return $this->types[$this->options['type']]['name'];
150    }
151
152    /**
153     * Return the feed mime type
154     *
155     * @return string
156     */
157    public function getMimeType()
158    {
159        return $this->types[$this->options['type']]['mime'];
160    }
161}
162