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\Feed;
10
11use DateTime;
12use DOMDocument;
13use Laminas\Feed\Reader;
14
15class Atom extends AbstractFeed
16{
17    /**
18     * @param null|string $type
19     */
20    public function __construct(DOMDocument $dom, $type = null)
21    {
22        parent::__construct($dom, $type);
23        $manager = Reader\Reader::getExtensionManager();
24
25        $atomFeed = $manager->get('Atom\Feed');
26        $atomFeed->setDomDocument($dom);
27        $atomFeed->setType($this->data['type']);
28        $atomFeed->setXpath($this->xpath);
29        $this->extensions['Atom\\Feed'] = $atomFeed;
30
31        $atomFeed = $manager->get('DublinCore\Feed');
32        $atomFeed->setDomDocument($dom);
33        $atomFeed->setType($this->data['type']);
34        $atomFeed->setXpath($this->xpath);
35        $this->extensions['DublinCore\\Feed'] = $atomFeed;
36
37        foreach ($this->extensions as $extension) {
38            $extension->setXpathPrefix('/atom:feed');
39        }
40    }
41
42    /**
43     * Get a single author
44     *
45     * @param  int $index
46     * @return null|string
47     */
48    public function getAuthor($index = 0)
49    {
50        $authors = $this->getAuthors();
51
52        if (isset($authors[$index])) {
53            return $authors[$index];
54        }
55
56        return;
57    }
58
59    /**
60     * Get an array with feed authors
61     *
62     * @return array
63     */
64    public function getAuthors()
65    {
66        if (array_key_exists('authors', $this->data)) {
67            return $this->data['authors'];
68        }
69
70        $authors = $this->getExtension('Atom')->getAuthors();
71
72        $this->data['authors'] = $authors;
73
74        return $this->data['authors'];
75    }
76
77    /**
78     * Get the copyright entry
79     *
80     * @return null|string
81     */
82    public function getCopyright()
83    {
84        if (array_key_exists('copyright', $this->data)) {
85            return $this->data['copyright'];
86        }
87
88        $copyright = $this->getExtension('Atom')->getCopyright();
89
90        if (! $copyright) {
91            $copyright = null;
92        }
93
94        $this->data['copyright'] = $copyright;
95
96        return $this->data['copyright'];
97    }
98
99    /**
100     * Get the feed creation date
101     *
102     * @return null|DateTime
103     */
104    public function getDateCreated()
105    {
106        if (array_key_exists('datecreated', $this->data)) {
107            return $this->data['datecreated'];
108        }
109
110        $dateCreated = $this->getExtension('Atom')->getDateCreated();
111
112        if (! $dateCreated) {
113            $dateCreated = null;
114        }
115
116        $this->data['datecreated'] = $dateCreated;
117
118        return $this->data['datecreated'];
119    }
120
121    /**
122     * Get the feed modification date
123     *
124     * @return null|DateTime
125     */
126    public function getDateModified()
127    {
128        if (array_key_exists('datemodified', $this->data)) {
129            return $this->data['datemodified'];
130        }
131
132        $dateModified = $this->getExtension('Atom')->getDateModified();
133
134        if (! $dateModified) {
135            $dateModified = null;
136        }
137
138        $this->data['datemodified'] = $dateModified;
139
140        return $this->data['datemodified'];
141    }
142
143    /**
144     * Get the feed lastBuild date. This is not implemented in Atom.
145     *
146     * @return null|string
147     */
148    public function getLastBuildDate()
149    {
150        return;
151    }
152
153    /**
154     * Get the feed description
155     *
156     * @return null|string
157     */
158    public function getDescription()
159    {
160        if (array_key_exists('description', $this->data)) {
161            return $this->data['description'];
162        }
163
164        $description = $this->getExtension('Atom')->getDescription();
165
166        if (! $description) {
167            $description = null;
168        }
169
170        $this->data['description'] = $description;
171
172        return $this->data['description'];
173    }
174
175    /**
176     * Get the feed generator entry
177     *
178     * @return null|string
179     */
180    public function getGenerator()
181    {
182        if (array_key_exists('generator', $this->data)) {
183            return $this->data['generator'];
184        }
185
186        $generator = $this->getExtension('Atom')->getGenerator();
187
188        $this->data['generator'] = $generator;
189
190        return $this->data['generator'];
191    }
192
193    /**
194     * Get the feed ID
195     *
196     * @return null|string
197     */
198    public function getId()
199    {
200        if (array_key_exists('id', $this->data)) {
201            return $this->data['id'];
202        }
203
204        $id = $this->getExtension('Atom')->getId();
205
206        $this->data['id'] = $id;
207
208        return $this->data['id'];
209    }
210
211    /**
212     * Get the feed language
213     *
214     * @return null|string
215     */
216    public function getLanguage()
217    {
218        if (array_key_exists('language', $this->data)) {
219            return $this->data['language'];
220        }
221
222        $language = $this->getExtension('Atom')->getLanguage();
223
224        if (! $language) {
225            $language = $this->xpath->evaluate('string(//@xml:lang[1])');
226        }
227
228        if (! $language) {
229            $language = null;
230        }
231
232        $this->data['language'] = $language;
233
234        return $this->data['language'];
235    }
236
237    /**
238     * Get a link to the source website
239     *
240     * @return null|string
241     */
242    public function getBaseUrl()
243    {
244        if (array_key_exists('baseUrl', $this->data)) {
245            return $this->data['baseUrl'];
246        }
247
248        $baseUrl = $this->getExtension('Atom')->getBaseUrl();
249
250        $this->data['baseUrl'] = $baseUrl;
251
252        return $this->data['baseUrl'];
253    }
254
255    /**
256     * Get a link to the source website
257     *
258     * @return null|string
259     */
260    public function getLink()
261    {
262        if (array_key_exists('link', $this->data)) {
263            return $this->data['link'];
264        }
265
266        $link = $this->getExtension('Atom')->getLink();
267
268        $this->data['link'] = $link;
269
270        return $this->data['link'];
271    }
272
273    /**
274     * Get feed image data
275     *
276     * @return null|array
277     */
278    public function getImage()
279    {
280        if (array_key_exists('image', $this->data)) {
281            return $this->data['image'];
282        }
283
284        $link = $this->getExtension('Atom')->getImage();
285
286        $this->data['image'] = $link;
287
288        return $this->data['image'];
289    }
290
291    /**
292     * Get a link to the feed's XML Url
293     *
294     * @return null|string
295     */
296    public function getFeedLink()
297    {
298        if (array_key_exists('feedlink', $this->data)) {
299            return $this->data['feedlink'];
300        }
301
302        $link = $this->getExtension('Atom')->getFeedLink();
303
304        if ($link === null || empty($link)) {
305            $link = $this->getOriginalSourceUri();
306        }
307
308        $this->data['feedlink'] = $link;
309
310        return $this->data['feedlink'];
311    }
312
313    /**
314     * Get the feed title
315     *
316     * @return null|string
317     */
318    public function getTitle()
319    {
320        if (array_key_exists('title', $this->data)) {
321            return $this->data['title'];
322        }
323
324        $title = $this->getExtension('Atom')->getTitle();
325
326        $this->data['title'] = $title;
327
328        return $this->data['title'];
329    }
330
331    /**
332     * Get an array of any supported Pusubhubbub endpoints
333     *
334     * @return null|array
335     */
336    public function getHubs()
337    {
338        if (array_key_exists('hubs', $this->data)) {
339            return $this->data['hubs'];
340        }
341
342        $hubs = $this->getExtension('Atom')->getHubs();
343
344        $this->data['hubs'] = $hubs;
345
346        return $this->data['hubs'];
347    }
348
349    /**
350     * Get all categories
351     *
352     * @return Reader\Collection\Category
353     */
354    public function getCategories()
355    {
356        if (array_key_exists('categories', $this->data)) {
357            return $this->data['categories'];
358        }
359
360        $categoryCollection = $this->getExtension('Atom')->getCategories();
361
362        if (count($categoryCollection) === 0) {
363            $categoryCollection = $this->getExtension('DublinCore')->getCategories();
364        }
365
366        $this->data['categories'] = $categoryCollection;
367
368        return $this->data['categories'];
369    }
370
371    /**
372     * Read all entries to the internal entries array
373     *
374     * @return void
375     */
376    protected function indexEntries()
377    {
378        if ($this->getType() === Reader\Reader::TYPE_ATOM_10
379            || $this->getType() === Reader\Reader::TYPE_ATOM_03
380        ) {
381            $entries = $this->xpath->evaluate('//atom:entry');
382
383            foreach ($entries as $index => $entry) {
384                $this->entries[$index] = $entry;
385            }
386        }
387    }
388
389    /**
390     * Register the default namespaces for the current feed format
391     */
392    protected function registerNamespaces()
393    {
394        switch ($this->data['type']) {
395            case Reader\Reader::TYPE_ATOM_03:
396                $this->xpath->registerNamespace('atom', Reader\Reader::NAMESPACE_ATOM_03);
397                break;
398            case Reader\Reader::TYPE_ATOM_10:
399            default:
400                $this->xpath->registerNamespace('atom', Reader\Reader::NAMESPACE_ATOM_10);
401        }
402    }
403}
404