1<?php
2
3/**
4 * @see       https://github.com/laminas/laminas-feed for the canonical source repository
5 * @copyright https://github.com/laminas/laminas-feed/blob/master/COPYRIGHT.md
6 * @license   https://github.com/laminas/laminas-feed/blob/master/LICENSE.md New BSD License
7 */
8
9namespace Laminas\Feed\Reader\Extension\Podcast;
10
11use DOMText;
12use Laminas\Feed\Reader\Extension;
13
14class Feed extends Extension\AbstractFeed
15{
16    /**
17     * Get the entry author
18     *
19     * @return string
20     */
21    public function getCastAuthor()
22    {
23        if (isset($this->data['author'])) {
24            return $this->data['author'];
25        }
26
27        $author = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:author)');
28
29        if (! $author) {
30            $author = null;
31        }
32
33        $this->data['author'] = $author;
34
35        return $this->data['author'];
36    }
37
38    /**
39     * Get the entry block
40     *
41     * @return string
42     */
43    public function getBlock()
44    {
45        if (isset($this->data['block'])) {
46            return $this->data['block'];
47        }
48
49        $block = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:block)');
50
51        if (! $block) {
52            $block = null;
53        }
54
55        $this->data['block'] = $block;
56
57        return $this->data['block'];
58    }
59
60    /**
61     * Get the entry category
62     *
63     * @return null|array
64     */
65    public function getItunesCategories()
66    {
67        if (isset($this->data['categories'])) {
68            return $this->data['categories'];
69        }
70
71        $categoryList = $this->xpath->query($this->getXpathPrefix() . '/itunes:category');
72
73        $categories = [];
74
75        if ($categoryList->length > 0) {
76            foreach ($categoryList as $node) {
77                $children = null;
78
79                if ($node->childNodes->length > 0) {
80                    $children = [];
81
82                    foreach ($node->childNodes as $childNode) {
83                        if (! $childNode instanceof DOMText) {
84                            $children[$childNode->getAttribute('text')] = null;
85                        }
86                    }
87                }
88
89                $categories[$node->getAttribute('text')] = $children;
90            }
91        }
92
93        if (! $categories) {
94            $categories = null;
95        }
96
97        $this->data['categories'] = $categories;
98
99        return $this->data['categories'];
100    }
101
102    /**
103     * Get the entry explicit
104     *
105     * @return string
106     */
107    public function getExplicit()
108    {
109        if (isset($this->data['explicit'])) {
110            return $this->data['explicit'];
111        }
112
113        $explicit = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:explicit)');
114
115        if (! $explicit) {
116            $explicit = null;
117        }
118
119        $this->data['explicit'] = $explicit;
120
121        return $this->data['explicit'];
122    }
123
124    /**
125     * Get the feed/podcast image
126     *
127     * @return string
128     */
129    public function getItunesImage()
130    {
131        if (isset($this->data['image'])) {
132            return $this->data['image'];
133        }
134
135        $image = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:image/@href)');
136
137        if (! $image) {
138            $image = null;
139        }
140
141        $this->data['image'] = $image;
142
143        return $this->data['image'];
144    }
145
146    /**
147     * Get the entry keywords
148     *
149     * @deprecated since 2.10.0; itunes:keywords is no longer part of the
150     *     iTunes podcast RSS specification.
151     * @return string
152     */
153    public function getKeywords()
154    {
155        trigger_error(
156            'itunes:keywords has been deprecated in the iTunes podcast RSS specification,'
157            . ' and should not be relied on.',
158            \E_USER_DEPRECATED
159        );
160
161        if (isset($this->data['keywords'])) {
162            return $this->data['keywords'];
163        }
164
165        $keywords = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:keywords)');
166
167        if (! $keywords) {
168            $keywords = null;
169        }
170
171        $this->data['keywords'] = $keywords;
172
173        return $this->data['keywords'];
174    }
175
176    /**
177     * Get the entry's new feed url
178     *
179     * @return string
180     */
181    public function getNewFeedUrl()
182    {
183        if (isset($this->data['new-feed-url'])) {
184            return $this->data['new-feed-url'];
185        }
186
187        $newFeedUrl = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:new-feed-url)');
188
189        if (! $newFeedUrl) {
190            $newFeedUrl = null;
191        }
192
193        $this->data['new-feed-url'] = $newFeedUrl;
194
195        return $this->data['new-feed-url'];
196    }
197
198    /**
199     * Get the entry owner
200     *
201     * @return string
202     */
203    public function getOwner()
204    {
205        if (isset($this->data['owner'])) {
206            return $this->data['owner'];
207        }
208
209        $owner = null;
210
211        $email = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:owner/itunes:email)');
212        $name  = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:owner/itunes:name)');
213
214        if (! empty($email)) {
215            $owner = $email . (empty($name) ? '' : ' (' . $name . ')');
216        } elseif (! empty($name)) {
217            $owner = $name;
218        }
219
220        if (! $owner) {
221            $owner = null;
222        }
223
224        $this->data['owner'] = $owner;
225
226        return $this->data['owner'];
227    }
228
229    /**
230     * Get the entry subtitle
231     *
232     * @return string
233     */
234    public function getSubtitle()
235    {
236        if (isset($this->data['subtitle'])) {
237            return $this->data['subtitle'];
238        }
239
240        $subtitle = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:subtitle)');
241
242        if (! $subtitle) {
243            $subtitle = null;
244        }
245
246        $this->data['subtitle'] = $subtitle;
247
248        return $this->data['subtitle'];
249    }
250
251    /**
252     * Get the entry summary
253     *
254     * @return string
255     */
256    public function getSummary()
257    {
258        if (isset($this->data['summary'])) {
259            return $this->data['summary'];
260        }
261
262        $summary = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:summary)');
263
264        if (! $summary) {
265            $summary = null;
266        }
267
268        $this->data['summary'] = $summary;
269
270        return $this->data['summary'];
271    }
272
273    /**
274     * Get the type of podcast
275     *
276     * @return string One of "episodic" or "serial". Defaults to "episodic"
277     *     if no itunes:type tag is encountered.
278     */
279    public function getPodcastType()
280    {
281        if (isset($this->data['podcastType'])) {
282            return $this->data['podcastType'];
283        }
284
285        $type = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:type)');
286
287        if (! $type) {
288            $type = 'episodic';
289        }
290
291        $this->data['podcastType'] = (string) $type;
292
293        return $this->data['podcastType'];
294    }
295
296    /**
297     * Is the podcast complete (no more episodes will post)?
298     *
299     * @return bool
300     */
301    public function isComplete()
302    {
303        if (isset($this->data['complete'])) {
304            return $this->data['complete'];
305        }
306
307        $complete = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:complete)');
308
309        if (! $complete) {
310            $complete = false;
311        }
312
313        $this->data['complete'] = $complete === 'Yes';
314
315        return $this->data['complete'];
316    }
317
318    /**
319     * Register iTunes namespace
320     */
321    protected function registerNamespaces()
322    {
323        $this->xpath->registerNamespace('itunes', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
324    }
325}
326