Passed
Branch master (c87ba8)
by Christian
16:02
created

RssWidget::getRssItems()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 29
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 19
nc 4
nop 0
dl 0
loc 29
rs 9.6333
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace TYPO3\CMS\Dashboard\Widgets;
19
20
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface as Cache;
21
use TYPO3\CMS\Core\Utility\GeneralUtility;
22
use TYPO3\CMS\Fluid\View\StandaloneView;
23
24
/**
25
 * Concrete RSS widget implementation
26
 *
27
 * The widget will show a certain number of items of the given RSS feed. The feed will be set by the feedUrl option. You
28
 * can add a button to the widget by defining a button provider.
29
 *
30
 * The following options are available during registration:
31
 * - feedUrl        string                      Defines the URL or file providing the RSS Feed.
32
 *                                              This is read by the widget in order to fetch entries to show.
33
 * - limit          int     default: 5          Defines how many RSS items should be shown.
34
 * - lifetime       int     default: 43200      Defines how long to wait, in seconds, until fetching RSS Feed again
35
 *
36
 * @see ButtonProviderInterface
37
 */
38
class RssWidget implements WidgetInterface
39
{
40
    /**
41
     * @var WidgetConfigurationInterface
42
     */
43
    private $configuration;
44
45
    /**
46
     * @var StandaloneView
47
     */
48
    private $view;
49
50
    /**
51
     * @var Cache
52
     */
53
    private $cache;
54
55
    /**
56
     * @var array
57
     */
58
    private $options;
59
60
    /**
61
     * @var ButtonProviderInterface|null
62
     */
63
    private $buttonProvider;
64
65
    public function __construct(
66
        WidgetConfigurationInterface $configuration,
67
        Cache $cache,
68
        StandaloneView $view,
69
        $buttonProvider = null,
70
        array $options = []
71
    ) {
72
        $this->configuration = $configuration;
73
        $this->view = $view;
74
        $this->cache = $cache;
75
        $this->options = array_merge(
76
            [
77
            'limit' => 5,
78
            'lifeTime' => 43200
79
            ],
80
            $options
81
        );
82
        $this->buttonProvider = $buttonProvider;
83
    }
84
85
    public function renderWidgetContent(): string
86
    {
87
        $this->view->setTemplate('Widget/RssWidget');
88
        $this->view->assignMultiple([
89
            'items' => $this->getRssItems(),
90
            'options' => $this->options,
91
            'button' => $this->buttonProvider,
92
            'configuration' => $this->configuration,
93
        ]);
94
        return $this->view->render();
95
    }
96
97
    protected function getRssItems(): array
98
    {
99
        $cacheHash = md5($this->options['feedUrl']);
100
        if ($items = $this->cache->get($cacheHash)) {
101
            return $items;
102
        }
103
104
        $rssContent = GeneralUtility::getUrl($this->options['feedUrl']);
105
        if ($rssContent === false) {
106
            throw new \RuntimeException('RSS URL could not be fetched', 1573385431);
107
        }
108
        $rssFeed = simplexml_load_string($rssContent);
109
        $items = [];
110
        foreach ($rssFeed->channel->item as $item) {
111
            $items[] = [
112
                'title' => trim((string)$item->title),
113
                'link' => trim((string)$item->link),
114
                'pubDate' => trim((string)$item->pubDate),
115
                'description' => trim((string)$item->description),
116
            ];
117
        }
118
        usort($items, function ($item1, $item2) {
119
            return new \DateTime($item2['pubDate']) <=> new \DateTime($item1['pubDate']);
120
        });
121
        $items = array_slice($items, 0, $this->options['limit']);
122
123
        $this->cache->set($cacheHash, $items, ['dashboard_rss'], $this->options['lifeTime']);
124
125
        return $items;
126
    }
127
}
128