PageRenderTime 128ms CodeModel.GetById 60ms app.highlight 36ms RepoModel.GetById 25ms app.codeStats 0ms

/lib/Zend/Feed/Rss.php

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 529 lines | 334 code | 63 blank | 132 comment | 61 complexity | 444b6f6b39b2ac8446d398d12444a00b MD5 | raw file
  1<?php
  2
  3/**
  4 * Zend Framework
  5 *
  6 * LICENSE
  7 *
  8 * This source file is subject to the new BSD license that is bundled
  9 * with this package in the file LICENSE.txt.
 10 * It is also available through the world-wide-web at this URL:
 11 * http://framework.zend.com/license/new-bsd
 12 * If you did not receive a copy of the license and are unable to
 13 * obtain it through the world-wide-web, please send an email
 14 * to license@zend.com so we can send you a copy immediately.
 15 *
 16 * @category   Zend
 17 * @package    Zend_Feed
 18 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
 19 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 20 * @version    $Id: Rss.php 20096 2010-01-06 02:05:09Z bkarwin $
 21 */
 22
 23
 24/**
 25 * @see Zend_Feed_Abstract
 26 */
 27#require_once 'Zend/Feed/Abstract.php';
 28
 29/**
 30 * @see Zend_Feed_Entry_Rss
 31 */
 32#require_once 'Zend/Feed/Entry/Rss.php';
 33
 34
 35/**
 36 * RSS channel class
 37 *
 38 * The Zend_Feed_Rss class is a concrete subclass of
 39 * Zend_Feed_Abstract meant for representing RSS channels. It does not
 40 * add any methods to its parent, just provides a classname to check
 41 * against with the instanceof operator, and expects to be handling
 42 * RSS-formatted data instead of Atom.
 43 *
 44 * @category   Zend
 45 * @package    Zend_Feed
 46 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
 47 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 48 */
 49class Zend_Feed_Rss extends Zend_Feed_Abstract
 50{
 51    /**
 52     * The classname for individual channel elements.
 53     *
 54     * @var string
 55     */
 56    protected $_entryClassName = 'Zend_Feed_Entry_Rss';
 57
 58    /**
 59     * The element name for individual channel elements (RSS <item>s).
 60     *
 61     * @var string
 62     */
 63    protected $_entryElementName = 'item';
 64
 65    /**
 66     * The default namespace for RSS channels.
 67     *
 68     * @var string
 69     */
 70    protected $_defaultNamespace = 'rss';
 71
 72    /**
 73     * Override Zend_Feed_Abstract to set up the $_element and $_entries aliases.
 74     *
 75     * @return void
 76     * @throws Zend_Feed_Exception
 77     */
 78    public function __wakeup()
 79    {
 80        parent::__wakeup();
 81
 82        // Find the base channel element and create an alias to it.
 83        $rdfTags = $this->_element->getElementsByTagNameNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'RDF');
 84        if ($rdfTags->length != 0) {
 85            $this->_element = $rdfTags->item(0);
 86        } else  {
 87            $this->_element = $this->_element->getElementsByTagName('channel')->item(0);
 88        }
 89        if (!$this->_element) {
 90            /**
 91             * @see Zend_Feed_Exception
 92             */
 93            #require_once 'Zend/Feed/Exception.php';
 94            throw new Zend_Feed_Exception('No root <channel> element found, cannot parse channel.');
 95        }
 96
 97        // Find the entries and save a pointer to them for speed and
 98        // simplicity.
 99        $this->_buildEntryCache();
100    }
101
102
103    /**
104     * Make accessing some individual elements of the channel easier.
105     *
106     * Special accessors 'item' and 'items' are provided so that if
107     * you wish to iterate over an RSS channel's items, you can do so
108     * using foreach ($channel->items as $item) or foreach
109     * ($channel->item as $item).
110     *
111     * @param  string $var The property to access.
112     * @return mixed
113     */
114    public function __get($var)
115    {
116        switch ($var) {
117            case 'item':
118                // fall through to the next case
119            case 'items':
120                return $this;
121
122            default:
123                return parent::__get($var);
124        }
125    }
126
127    /**
128     * Generate the header of the feed when working in write mode
129     *
130     * @param  array $array the data to use
131     * @return DOMElement root node
132     */
133    protected function _mapFeedHeaders($array)
134    {
135        $channel = $this->_element->createElement('channel');
136
137        $title = $this->_element->createElement('title');
138        $title->appendChild($this->_element->createCDATASection($array->title));
139        $channel->appendChild($title);
140
141        $link = $this->_element->createElement('link', $array->link);
142        $channel->appendChild($link);
143
144        $desc = isset($array->description) ? $array->description : '';
145        $description = $this->_element->createElement('description');
146        $description->appendChild($this->_element->createCDATASection($desc));
147        $channel->appendChild($description);
148
149        $pubdate = isset($array->lastUpdate) ? $array->lastUpdate : time();
150        $pubdate = $this->_element->createElement('pubDate', date(DATE_RSS, $pubdate));
151        $channel->appendChild($pubdate);
152
153        if (isset($array->published)) {
154            $lastBuildDate = $this->_element->createElement('lastBuildDate', date(DATE_RSS, $array->published));
155            $channel->appendChild($lastBuildDate);
156        }
157
158        $editor = '';
159        if (!empty($array->email)) {
160            $editor .= $array->email;
161        }
162        if (!empty($array->author)) {
163            $editor .= ' (' . $array->author . ')';
164        }
165        if (!empty($editor)) {
166            $author = $this->_element->createElement('managingEditor', ltrim($editor));
167            $channel->appendChild($author);
168        }
169        if (isset($array->webmaster)) {
170            $channel->appendChild($this->_element->createElement('webMaster', $array->webmaster));
171        }
172
173        if (!empty($array->copyright)) {
174            $copyright = $this->_element->createElement('copyright', $array->copyright);
175            $channel->appendChild($copyright);
176        }
177
178        if (isset($array->category)) {
179            $category = $this->_element->createElement('category', $array->category);
180            $channel->appendChild($category);
181        }
182
183        if (!empty($array->image)) {
184            $image = $this->_element->createElement('image');
185            $url = $this->_element->createElement('url', $array->image);
186            $image->appendChild($url);
187            $imagetitle = $this->_element->createElement('title');
188            $imagetitle->appendChild($this->_element->createCDATASection($array->title));
189            $image->appendChild($imagetitle);
190            $imagelink = $this->_element->createElement('link', $array->link);
191            $image->appendChild($imagelink);
192
193            $channel->appendChild($image);
194        }
195
196        $generator = !empty($array->generator) ? $array->generator : 'Zend_Feed';
197        $generator = $this->_element->createElement('generator', $generator);
198        $channel->appendChild($generator);
199
200        if (!empty($array->language)) {
201            $language = $this->_element->createElement('language', $array->language);
202            $channel->appendChild($language);
203        }
204
205        $doc = $this->_element->createElement('docs', 'http://blogs.law.harvard.edu/tech/rss');
206        $channel->appendChild($doc);
207
208        if (isset($array->cloud)) {
209            $cloud = $this->_element->createElement('cloud');
210            $cloud->setAttribute('domain', $array->cloud['uri']->getHost());
211            $cloud->setAttribute('port', $array->cloud['uri']->getPort());
212            $cloud->setAttribute('path', $array->cloud['uri']->getPath());
213            $cloud->setAttribute('registerProcedure', $array->cloud['procedure']);
214            $cloud->setAttribute('protocol', $array->cloud['protocol']);
215            $channel->appendChild($cloud);
216        }
217
218        if (isset($array->ttl)) {
219            $ttl = $this->_element->createElement('ttl', $array->ttl);
220            $channel->appendChild($ttl);
221        }
222
223        if (isset($array->rating)) {
224            $rating = $this->_element->createElement('rating', $array->rating);
225            $channel->appendChild($rating);
226        }
227
228        if (isset($array->textInput)) {
229            $textinput = $this->_element->createElement('textInput');
230            $textinput->appendChild($this->_element->createElement('title', $array->textInput['title']));
231            $textinput->appendChild($this->_element->createElement('description', $array->textInput['description']));
232            $textinput->appendChild($this->_element->createElement('name', $array->textInput['name']));
233            $textinput->appendChild($this->_element->createElement('link', $array->textInput['link']));
234            $channel->appendChild($textinput);
235        }
236
237        if (isset($array->skipHours)) {
238            $skipHours = $this->_element->createElement('skipHours');
239            foreach ($array->skipHours as $hour) {
240                $skipHours->appendChild($this->_element->createElement('hour', $hour));
241            }
242            $channel->appendChild($skipHours);
243        }
244
245        if (isset($array->skipDays)) {
246            $skipDays = $this->_element->createElement('skipDays');
247            foreach ($array->skipDays as $day) {
248                $skipDays->appendChild($this->_element->createElement('day', $day));
249            }
250            $channel->appendChild($skipDays);
251        }
252
253        if (isset($array->itunes)) {
254            $this->_buildiTunes($channel, $array);
255        }
256
257        return $channel;
258    }
259
260    /**
261     * Adds the iTunes extensions to a root node
262     *
263     * @param  DOMElement $root
264     * @param  array $array
265     * @return void
266     */
267    private function _buildiTunes(DOMElement $root, $array)
268    {
269        /* author node */
270        $author = '';
271        if (isset($array->itunes->author)) {
272            $author = $array->itunes->author;
273        } elseif (isset($array->author)) {
274            $author = $array->author;
275        }
276        if (!empty($author)) {
277            $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:author', $author);
278            $root->appendChild($node);
279        }
280
281        /* owner node */
282        $author = '';
283        $email = '';
284        if (isset($array->itunes->owner)) {
285            if (isset($array->itunes->owner['name'])) {
286                $author = $array->itunes->owner['name'];
287            }
288            if (isset($array->itunes->owner['email'])) {
289                $email = $array->itunes->owner['email'];
290            }
291        }
292        if (empty($author) && isset($array->author)) {
293            $author = $array->author;
294        }
295        if (empty($email) && isset($array->email)) {
296            $email = $array->email;
297        }
298        if (!empty($author) || !empty($email)) {
299            $owner = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:owner');
300            if (!empty($author)) {
301                $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:name', $author);
302                $owner->appendChild($node);
303            }
304            if (!empty($email)) {
305                $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:email', $email);
306                $owner->appendChild($node);
307            }
308            $root->appendChild($owner);
309        }
310        $image = '';
311        if (isset($array->itunes->image)) {
312            $image = $array->itunes->image;
313        } elseif (isset($array->image)) {
314            $image = $array->image;
315        }
316        if (!empty($image)) {
317            $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:image');
318            $node->setAttribute('href', $image);
319            $root->appendChild($node);
320        }
321        $subtitle = '';
322        if (isset($array->itunes->subtitle)) {
323            $subtitle = $array->itunes->subtitle;
324        } elseif (isset($array->description)) {
325            $subtitle = $array->description;
326        }
327        if (!empty($subtitle)) {
328            $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:subtitle', $subtitle);
329            $root->appendChild($node);
330        }
331        $summary = '';
332        if (isset($array->itunes->summary)) {
333            $summary = $array->itunes->summary;
334        } elseif (isset($array->description)) {
335            $summary = $array->description;
336        }
337        if (!empty($summary)) {
338            $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:summary', $summary);
339            $root->appendChild($node);
340        }
341        if (isset($array->itunes->block)) {
342            $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:block', $array->itunes->block);
343            $root->appendChild($node);
344        }
345        if (isset($array->itunes->explicit)) {
346            $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:explicit', $array->itunes->explicit);
347            $root->appendChild($node);
348        }
349        if (isset($array->itunes->keywords)) {
350            $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:keywords', $array->itunes->keywords);
351            $root->appendChild($node);
352        }
353        if (isset($array->itunes->new_feed_url)) {
354            $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:new-feed-url', $array->itunes->new_feed_url);
355            $root->appendChild($node);
356        }
357        if (isset($array->itunes->category)) {
358            foreach ($array->itunes->category as $i => $category) {
359                $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:category');
360                $node->setAttribute('text', $category['main']);
361                $root->appendChild($node);
362                $add_end_category = false;
363                if (!empty($category['sub'])) {
364                    $add_end_category = true;
365                    $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:category');
366                    $node->setAttribute('text', $category['sub']);
367                    $root->appendChild($node);
368                }
369                if ($i > 0 || $add_end_category) {
370                    $node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:category');
371                    $root->appendChild($node);
372                }
373            }
374        }
375    }
376
377    /**
378     * Generate the entries of the feed when working in write mode
379     *
380     * The following nodes are constructed for each feed entry
381     * <item>
382     *    <title>entry title</title>
383     *    <link>url to feed entry</link>
384     *    <guid>url to feed entry</guid>
385     *    <description>short text</description>
386     *    <content:encoded>long version, can contain html</content:encoded>
387     * </item>
388     *
389     * @param  DOMElement $root the root node to use
390     * @param  array $array the data to use
391     * @return void
392     */
393    protected function _mapFeedEntries(DOMElement $root, $array)
394    {
395        Zend_Feed::registerNamespace('content', 'http://purl.org/rss/1.0/modules/content/');
396
397        foreach ($array as $dataentry) {
398            $item = $this->_element->createElement('item');
399
400            $title = $this->_element->createElement('title');
401            $title->appendChild($this->_element->createCDATASection($dataentry->title));
402            $item->appendChild($title);
403
404            if (isset($dataentry->author)) {
405                $author = $this->_element->createElement('author', $dataentry->author);
406                $item->appendChild($author);
407            }
408
409            $link = $this->_element->createElement('link', $dataentry->link);
410            $item->appendChild($link);
411
412            if (isset($dataentry->guid)) {
413                $guid = $this->_element->createElement('guid', $dataentry->guid);
414                if (!Zend_Uri::check($dataentry->guid)) {
415                    $guid->setAttribute('isPermaLink', 'false');
416                }
417                $item->appendChild($guid);
418            }
419
420            $description = $this->_element->createElement('description');
421            $description->appendChild($this->_element->createCDATASection($dataentry->description));
422            $item->appendChild($description);
423
424            if (isset($dataentry->content)) {
425                $content = $this->_element->createElement('content:encoded');
426                $content->appendChild($this->_element->createCDATASection($dataentry->content));
427                $item->appendChild($content);
428            }
429
430            $pubdate = isset($dataentry->lastUpdate) ? $dataentry->lastUpdate : time();
431            $pubdate = $this->_element->createElement('pubDate', date(DATE_RSS, $pubdate));
432            $item->appendChild($pubdate);
433
434            if (isset($dataentry->category)) {
435                foreach ($dataentry->category as $category) {
436                    $node = $this->_element->createElement('category', $category['term']);
437                    if (isset($category['scheme'])) {
438                        $node->setAttribute('domain', $category['scheme']);
439                    }
440                    $item->appendChild($node);
441                }
442            }
443
444            if (isset($dataentry->source)) {
445                $source = $this->_element->createElement('source', $dataentry->source['title']);
446                $source->setAttribute('url', $dataentry->source['url']);
447                $item->appendChild($source);
448            }
449
450            if (isset($dataentry->comments)) {
451                $comments = $this->_element->createElement('comments', $dataentry->comments);
452                $item->appendChild($comments);
453            }
454            if (isset($dataentry->commentRss)) {
455                $comments = $this->_element->createElementNS('http://wellformedweb.org/CommentAPI/',
456                                                             'wfw:commentRss',
457                                                             $dataentry->commentRss);
458                $item->appendChild($comments);
459            }
460
461
462            if (isset($dataentry->enclosure)) {
463                foreach ($dataentry->enclosure as $enclosure) {
464                    $node = $this->_element->createElement('enclosure');
465                    $node->setAttribute('url', $enclosure['url']);
466                    if (isset($enclosure['type'])) {
467                        $node->setAttribute('type', $enclosure['type']);
468                    }
469                    if (isset($enclosure['length'])) {
470                        $node->setAttribute('length', $enclosure['length']);
471                    }
472                    $item->appendChild($node);
473                }
474            }
475
476            $root->appendChild($item);
477        }
478    }
479
480    /**
481     * Override Zend_Feed_Element to include <rss> root node
482     *
483     * @return string
484     */
485    public function saveXml()
486    {
487        // Return a complete document including XML prologue.
488        $doc = new DOMDocument($this->_element->ownerDocument->version,
489                               $this->_element->ownerDocument->actualEncoding);
490        $root = $doc->createElement('rss');
491
492        // Use rss version 2.0
493        $root->setAttribute('version', '2.0');
494
495        // Content namespace
496        $root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:content', 'http://purl.org/rss/1.0/modules/content/');
497        $root->appendChild($doc->importNode($this->_element, true));
498
499        // Append root node
500        $doc->appendChild($root);
501
502        // Format output
503        $doc->formatOutput = true;
504
505        return $doc->saveXML();
506    }
507
508    /**
509     * Send feed to a http client with the correct header
510     *
511     * @return void
512     * @throws Zend_Feed_Exception if headers have already been sent
513     */
514    public function send()
515    {
516        if (headers_sent()) {
517            /**
518             * @see Zend_Feed_Exception
519             */
520            #require_once 'Zend/Feed/Exception.php';
521            throw new Zend_Feed_Exception('Cannot send RSS because headers have already been sent.');
522        }
523
524        header('Content-Type: application/rss+xml; charset=' . $this->_element->ownerDocument->actualEncoding);
525
526        echo $this->saveXml();
527    }
528
529}