1<?php
2
3namespace dokuwiki\plugin\gallery\classes;
4
5use FeedParser;
6use SimplePie\Enclosure;
7
8class FeedGallery extends AbstractGallery
9{
10    protected $feedHost;
11    protected $feedPath;
12
13    /**
14     * @inheritdoc
15     * @param string $url
16     */
17    public function __construct($url, Options $options)
18    {
19        parent::__construct($url, $options);
20        $this->initBaseUrl($url);
21        $this->parseFeed($url);
22    }
23
24    /**
25     * Parses the given feed and adds all images to the gallery
26     *
27     * @param string $url
28     * @return void
29     * @throws \Exception
30     */
31    protected function parseFeed($url)
32    {
33        $feed = new FeedParser();
34        $feed->set_feed_url($url);
35
36        $ok = $feed->init();
37        if (!$ok) throw new \Exception($feed->error());
38
39        foreach ($feed->get_items() as $item) {
40            $enclosure = $item->get_enclosure();
41            if (!$enclosure instanceof Enclosure) continue;
42
43            // skip non-image enclosures
44            if ($enclosure->get_type() && substr($enclosure->get_type(), 0, 5) != 'image') {
45                continue;
46            } elseif (!$this->hasImageExtension($enclosure->get_link())) {
47                continue;
48            }
49
50            $enclosureLink = $this->makeAbsoluteUrl($enclosure->get_link());
51            $detailLink = $this->makeAbsoluteUrl($item->get_link());
52
53            $image = new Image($enclosureLink);
54            $image->setDetaillink($detailLink);
55            $image->setTitle(htmlspecialchars_decode($enclosure->get_title() ?? '', ENT_COMPAT));
56            $image->setDescription(strip_tags(htmlspecialchars_decode(
57                $enclosure->get_description() ?? '',
58                ENT_COMPAT
59            )));
60            $image->setCreated($item->get_date('U'));
61            $image->setModified($item->get_date('U'));
62            $image->setWidth($enclosure->get_width());
63            $image->setHeight($enclosure->get_height());
64
65            $this->images[] = $image;
66        }
67    }
68
69    /**
70     * Make the given URL absolute using feed's URL as base
71     *
72     * @param string $url
73     * @return string
74     */
75    protected function makeAbsoluteUrl($url)
76    {
77
78        if (!preg_match('/^https?:\/\//i', $url)) {
79            if ($url[0] == '/') {
80                $url = $this->feedHost . $url;
81            } else {
82                $url = $this->feedHost . $this->feedPath . $url;
83            }
84        }
85        return $url;
86    }
87
88    /**
89     * Initialize base url to use for broken feeds with non-absolute links
90     * @param string $url The feed URL
91     * @return void
92     */
93    protected function initBaseUrl($url)
94    {
95        $main = parse_url($url);
96        $this->feedHost = $main['scheme'] . '://' . $main['host'] . (empty($main['port']) ? '' : ':' . $main['port']);
97        $this->feedPath = dirname($main['path']) . '/';
98    }
99}
100