Adding SimplePie feed parsing library MDL-7946, MDL-13932
[moodle.git] / lib / simplepie / simplepie.inc
CommitLineData
80d72d56 1<?php
2/**
3 * SimplePie
4 *
5 * A PHP-Based RSS and Atom Feed Framework.
6 * Takes the hard work out of managing a complete RSS/Atom solution.
7 *
8 * Copyright (c) 2004-2008, Ryan Parman and Geoffrey Sneddon
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without modification, are
12 * permitted provided that the following conditions are met:
13 *
14 * * Redistributions of source code must retain the above copyright notice, this list of
15 * conditions and the following disclaimer.
16 *
17 * * Redistributions in binary form must reproduce the above copyright notice, this list
18 * of conditions and the following disclaimer in the documentation and/or other materials
19 * provided with the distribution.
20 *
21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used
22 * to endorse or promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 * @package SimplePie
36 * @version 1.1.3
37 * @copyright 2004-2008 Ryan Parman, Geoffrey Sneddon
38 * @author Ryan Parman
39 * @author Geoffrey Sneddon
40 * @link http://simplepie.org/ SimplePie
41 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43 * @todo phpDoc comments
44 */
45
46/**
47 * SimplePie Name
48 */
49define('SIMPLEPIE_NAME', 'SimplePie');
50
51/**
52 * SimplePie Version
53 */
54define('SIMPLEPIE_VERSION', '1.1.3');
55
56/**
57 * SimplePie Build
58 */
59define('SIMPLEPIE_BUILD', 20081219);
60
61/**
62 * SimplePie Website URL
63 */
64define('SIMPLEPIE_URL', 'http://simplepie.org');
65
66/**
67 * SimplePie Useragent
68 * @see SimplePie::set_useragent()
69 */
70define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
71
72/**
73 * SimplePie Linkback
74 */
75define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
76
77/**
78 * No Autodiscovery
79 * @see SimplePie::set_autodiscovery_level()
80 */
81define('SIMPLEPIE_LOCATOR_NONE', 0);
82
83/**
84 * Feed Link Element Autodiscovery
85 * @see SimplePie::set_autodiscovery_level()
86 */
87define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
88
89/**
90 * Local Feed Extension Autodiscovery
91 * @see SimplePie::set_autodiscovery_level()
92 */
93define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
94
95/**
96 * Local Feed Body Autodiscovery
97 * @see SimplePie::set_autodiscovery_level()
98 */
99define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
100
101/**
102 * Remote Feed Extension Autodiscovery
103 * @see SimplePie::set_autodiscovery_level()
104 */
105define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
106
107/**
108 * Remote Feed Body Autodiscovery
109 * @see SimplePie::set_autodiscovery_level()
110 */
111define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
112
113/**
114 * All Feed Autodiscovery
115 * @see SimplePie::set_autodiscovery_level()
116 */
117define('SIMPLEPIE_LOCATOR_ALL', 31);
118
119/**
120 * No known feed type
121 */
122define('SIMPLEPIE_TYPE_NONE', 0);
123
124/**
125 * RSS 0.90
126 */
127define('SIMPLEPIE_TYPE_RSS_090', 1);
128
129/**
130 * RSS 0.91 (Netscape)
131 */
132define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
133
134/**
135 * RSS 0.91 (Userland)
136 */
137define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
138
139/**
140 * RSS 0.91 (both Netscape and Userland)
141 */
142define('SIMPLEPIE_TYPE_RSS_091', 6);
143
144/**
145 * RSS 0.92
146 */
147define('SIMPLEPIE_TYPE_RSS_092', 8);
148
149/**
150 * RSS 0.93
151 */
152define('SIMPLEPIE_TYPE_RSS_093', 16);
153
154/**
155 * RSS 0.94
156 */
157define('SIMPLEPIE_TYPE_RSS_094', 32);
158
159/**
160 * RSS 1.0
161 */
162define('SIMPLEPIE_TYPE_RSS_10', 64);
163
164/**
165 * RSS 2.0
166 */
167define('SIMPLEPIE_TYPE_RSS_20', 128);
168
169/**
170 * RDF-based RSS
171 */
172define('SIMPLEPIE_TYPE_RSS_RDF', 65);
173
174/**
175 * Non-RDF-based RSS (truly intended as syndication format)
176 */
177define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
178
179/**
180 * All RSS
181 */
182define('SIMPLEPIE_TYPE_RSS_ALL', 255);
183
184/**
185 * Atom 0.3
186 */
187define('SIMPLEPIE_TYPE_ATOM_03', 256);
188
189/**
190 * Atom 1.0
191 */
192define('SIMPLEPIE_TYPE_ATOM_10', 512);
193
194/**
195 * All Atom
196 */
197define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
198
199/**
200 * All feed types
201 */
202define('SIMPLEPIE_TYPE_ALL', 1023);
203
204/**
205 * No construct
206 */
207define('SIMPLEPIE_CONSTRUCT_NONE', 0);
208
209/**
210 * Text construct
211 */
212define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
213
214/**
215 * HTML construct
216 */
217define('SIMPLEPIE_CONSTRUCT_HTML', 2);
218
219/**
220 * XHTML construct
221 */
222define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
223
224/**
225 * base64-encoded construct
226 */
227define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
228
229/**
230 * IRI construct
231 */
232define('SIMPLEPIE_CONSTRUCT_IRI', 16);
233
234/**
235 * A construct that might be HTML
236 */
237define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
238
239/**
240 * All constructs
241 */
242define('SIMPLEPIE_CONSTRUCT_ALL', 63);
243
244/**
245 * PCRE for HTML attributes
246 */
247define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
248
249/**
250 * PCRE for XML attributes
251 */
252define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
253
254/**
255 * XML Namespace
256 */
257define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
258
259/**
260 * Atom 1.0 Namespace
261 */
262define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
263
264/**
265 * Atom 0.3 Namespace
266 */
267define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
268
269/**
270 * RDF Namespace
271 */
272define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
273
274/**
275 * RSS 0.90 Namespace
276 */
277define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
278
279/**
280 * RSS 1.0 Namespace
281 */
282define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
283
284/**
285 * RSS 1.0 Content Module Namespace
286 */
287define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
288
289/**
290 * RSS 2.0 Namespace
291 * (Stupid, I know, but I'm certain it will confuse people less with support.)
292 */
293define('SIMPLEPIE_NAMESPACE_RSS_20', '');
294
295/**
296 * DC 1.0 Namespace
297 */
298define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
299
300/**
301 * DC 1.1 Namespace
302 */
303define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
304
305/**
306 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
307 */
308define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
309
310/**
311 * GeoRSS Namespace
312 */
313define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
314
315/**
316 * Media RSS Namespace
317 */
318define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
319
320/**
321 * Wrong Media RSS Namespace
322 */
323define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
324
325/**
326 * iTunes RSS Namespace
327 */
328define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
329
330/**
331 * XHTML Namespace
332 */
333define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
334
335/**
336 * IANA Link Relations Registry
337 */
338define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
339
340/**
341 * Whether we're running on PHP5
342 */
343define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
344
345/**
346 * No file source
347 */
348define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
349
350/**
351 * Remote file source
352 */
353define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
354
355/**
356 * Local file source
357 */
358define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
359
360/**
361 * fsockopen() file source
362 */
363define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
364
365/**
366 * cURL file source
367 */
368define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
369
370/**
371 * file_get_contents() file source
372 */
373define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
374
375/**
376 * SimplePie
377 *
378 * @package SimplePie
379 * @version "Razzleberry"
380 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
381 * @author Ryan Parman
382 * @author Geoffrey Sneddon
383 * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
384 */
385class SimplePie
386{
387 /**
388 * @var array Raw data
389 * @access private
390 */
391 var $data = array();
392
393 /**
394 * @var mixed Error string
395 * @access private
396 */
397 var $error;
398
399 /**
400 * @var object Instance of SimplePie_Sanitize (or other class)
401 * @see SimplePie::set_sanitize_class()
402 * @access private
403 */
404 var $sanitize;
405
406 /**
407 * @var string SimplePie Useragent
408 * @see SimplePie::set_useragent()
409 * @access private
410 */
411 var $useragent = SIMPLEPIE_USERAGENT;
412
413 /**
414 * @var string Feed URL
415 * @see SimplePie::set_feed_url()
416 * @access private
417 */
418 var $feed_url;
419
420 /**
421 * @var object Instance of SimplePie_File to use as a feed
422 * @see SimplePie::set_file()
423 * @access private
424 */
425 var $file;
426
427 /**
428 * @var string Raw feed data
429 * @see SimplePie::set_raw_data()
430 * @access private
431 */
432 var $raw_data;
433
434 /**
435 * @var int Timeout for fetching remote files
436 * @see SimplePie::set_timeout()
437 * @access private
438 */
439 var $timeout = 10;
440
441 /**
442 * @var bool Forces fsockopen() to be used for remote files instead
443 * of cURL, even if a new enough version is installed
444 * @see SimplePie::force_fsockopen()
445 * @access private
446 */
447 var $force_fsockopen = false;
448
449 /**
450 * @var bool Force the given data/URL to be treated as a feed no matter what
451 * it appears like
452 * @see SimplePie::force_feed()
453 * @access private
454 */
455 var $force_feed = false;
456
457 /**
458 * @var bool Enable/Disable XML dump
459 * @see SimplePie::enable_xml_dump()
460 * @access private
461 */
462 var $xml_dump = false;
463
464 /**
465 * @var bool Enable/Disable Caching
466 * @see SimplePie::enable_cache()
467 * @access private
468 */
469 var $cache = true;
470
471 /**
472 * @var int Cache duration (in seconds)
473 * @see SimplePie::set_cache_duration()
474 * @access private
475 */
476 var $cache_duration = 3600;
477
478 /**
479 * @var int Auto-discovery cache duration (in seconds)
480 * @see SimplePie::set_autodiscovery_cache_duration()
481 * @access private
482 */
483 var $autodiscovery_cache_duration = 604800; // 7 Days.
484
485 /**
486 * @var string Cache location (relative to executing script)
487 * @see SimplePie::set_cache_location()
488 * @access private
489 */
490 var $cache_location = './cache';
491
492 /**
493 * @var string Function that creates the cache filename
494 * @see SimplePie::set_cache_name_function()
495 * @access private
496 */
497 var $cache_name_function = 'md5';
498
499 /**
500 * @var bool Reorder feed by date descending
501 * @see SimplePie::enable_order_by_date()
502 * @access private
503 */
504 var $order_by_date = true;
505
506 /**
507 * @var mixed Force input encoding to be set to the follow value
508 * (false, or anything type-cast to false, disables this feature)
509 * @see SimplePie::set_input_encoding()
510 * @access private
511 */
512 var $input_encoding = false;
513
514 /**
515 * @var int Feed Autodiscovery Level
516 * @see SimplePie::set_autodiscovery_level()
517 * @access private
518 */
519 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
520
521 /**
522 * @var string Class used for caching feeds
523 * @see SimplePie::set_cache_class()
524 * @access private
525 */
526 var $cache_class = 'SimplePie_Cache';
527
528 /**
529 * @var string Class used for locating feeds
530 * @see SimplePie::set_locator_class()
531 * @access private
532 */
533 var $locator_class = 'SimplePie_Locator';
534
535 /**
536 * @var string Class used for parsing feeds
537 * @see SimplePie::set_parser_class()
538 * @access private
539 */
540 var $parser_class = 'SimplePie_Parser';
541
542 /**
543 * @var string Class used for fetching feeds
544 * @see SimplePie::set_file_class()
545 * @access private
546 */
547 var $file_class = 'SimplePie_File';
548
549 /**
550 * @var string Class used for items
551 * @see SimplePie::set_item_class()
552 * @access private
553 */
554 var $item_class = 'SimplePie_Item';
555
556 /**
557 * @var string Class used for authors
558 * @see SimplePie::set_author_class()
559 * @access private
560 */
561 var $author_class = 'SimplePie_Author';
562
563 /**
564 * @var string Class used for categories
565 * @see SimplePie::set_category_class()
566 * @access private
567 */
568 var $category_class = 'SimplePie_Category';
569
570 /**
571 * @var string Class used for enclosures
572 * @see SimplePie::set_enclosures_class()
573 * @access private
574 */
575 var $enclosure_class = 'SimplePie_Enclosure';
576
577 /**
578 * @var string Class used for Media RSS <media:text> captions
579 * @see SimplePie::set_caption_class()
580 * @access private
581 */
582 var $caption_class = 'SimplePie_Caption';
583
584 /**
585 * @var string Class used for Media RSS <media:copyright>
586 * @see SimplePie::set_copyright_class()
587 * @access private
588 */
589 var $copyright_class = 'SimplePie_Copyright';
590
591 /**
592 * @var string Class used for Media RSS <media:credit>
593 * @see SimplePie::set_credit_class()
594 * @access private
595 */
596 var $credit_class = 'SimplePie_Credit';
597
598 /**
599 * @var string Class used for Media RSS <media:rating>
600 * @see SimplePie::set_rating_class()
601 * @access private
602 */
603 var $rating_class = 'SimplePie_Rating';
604
605 /**
606 * @var string Class used for Media RSS <media:restriction>
607 * @see SimplePie::set_restriction_class()
608 * @access private
609 */
610 var $restriction_class = 'SimplePie_Restriction';
611
612 /**
613 * @var string Class used for content-type sniffing
614 * @see SimplePie::set_content_type_sniffer_class()
615 * @access private
616 */
617 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
618
619 /**
620 * @var string Class used for item sources.
621 * @see SimplePie::set_source_class()
622 * @access private
623 */
624 var $source_class = 'SimplePie_Source';
625
626 /**
627 * @var mixed Set javascript query string parameter (false, or
628 * anything type-cast to false, disables this feature)
629 * @see SimplePie::set_javascript()
630 * @access private
631 */
632 var $javascript = 'js';
633
634 /**
635 * @var int Maximum number of feeds to check with autodiscovery
636 * @see SimplePie::set_max_checked_feeds()
637 * @access private
638 */
639 var $max_checked_feeds = 10;
640
641 /**
642 * @var string Web-accessible path to the handler_favicon.php file.
643 * @see SimplePie::set_favicon_handler()
644 * @access private
645 */
646 var $favicon_handler = '';
647
648 /**
649 * @var string Web-accessible path to the handler_image.php file.
650 * @see SimplePie::set_image_handler()
651 * @access private
652 */
653 var $image_handler = '';
654
655 /**
656 * @var array Stores the URLs when multiple feeds are being initialized.
657 * @see SimplePie::set_feed_url()
658 * @access private
659 */
660 var $multifeed_url = array();
661
662 /**
663 * @var array Stores SimplePie objects when multiple feeds initialized.
664 * @access private
665 */
666 var $multifeed_objects = array();
667
668 /**
669 * @var array Stores the get_object_vars() array for use with multifeeds.
670 * @see SimplePie::set_feed_url()
671 * @access private
672 */
673 var $config_settings = null;
674
675 /**
676 * @var integer Stores the number of items to return per-feed with multifeeds.
677 * @see SimplePie::set_item_limit()
678 * @access private
679 */
680 var $item_limit = 0;
681
682 /**
683 * @var array Stores the default attributes to be stripped by strip_attributes().
684 * @see SimplePie::strip_attributes()
685 * @access private
686 */
687 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
688
689 /**
690 * @var array Stores the default tags to be stripped by strip_htmltags().
691 * @see SimplePie::strip_htmltags()
692 * @access private
693 */
694 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
695
696 /**
697 * The SimplePie class contains feed level data and options
698 *
699 * There are two ways that you can create a new SimplePie object. The first
700 * is by passing a feed URL as a parameter to the SimplePie constructor
701 * (as well as optionally setting the cache location and cache expiry). This
702 * will initialise the whole feed with all of the default settings, and you
703 * can begin accessing methods and properties immediately.
704 *
705 * The second way is to create the SimplePie object with no parameters
706 * at all. This will enable you to set configuration options. After setting
707 * them, you must initialise the feed using $feed->init(). At that point the
708 * object's methods and properties will be available to you. This format is
709 * what is used throughout this documentation.
710 *
711 * @access public
712 * @since 1.0 Preview Release
713 * @param string $feed_url This is the URL you want to parse.
714 * @param string $cache_location This is where you want the cache to be stored.
715 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
716 */
717 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
718 {
719 // Other objects, instances created here so we can set options on them
720 $this->sanitize =& new SimplePie_Sanitize;
721
722 // Set options if they're passed to the constructor
723 if ($cache_location !== null)
724 {
725 $this->set_cache_location($cache_location);
726 }
727
728 if ($cache_duration !== null)
729 {
730 $this->set_cache_duration($cache_duration);
731 }
732
733 // Only init the script if we're passed a feed URL
734 if ($feed_url !== null)
735 {
736 $this->set_feed_url($feed_url);
737 $this->init();
738 }
739 }
740
741 /**
742 * Used for converting object to a string
743 */
744 function __toString()
745 {
746 return md5(serialize($this->data));
747 }
748
749 /**
750 * Remove items that link back to this before destroying this object
751 */
752 function __destruct()
753 {
754 if (!empty($this->data['items']))
755 {
756 foreach ($this->data['items'] as $item)
757 {
758 $item->__destruct();
759 }
760 unset($this->data['items']);
761 }
762 if (!empty($this->data['ordered_items']))
763 {
764 foreach ($this->data['ordered_items'] as $item)
765 {
766 $item->__destruct();
767 }
768 unset($this->data['ordered_items']);
769 }
770 }
771
772 /**
773 * Force the given data/URL to be treated as a feed no matter what it
774 * appears like
775 *
776 * @access public
777 * @since 1.1
778 * @param bool $enable Force the given data/URL to be treated as a feed
779 */
780 function force_feed($enable = false)
781 {
782 $this->force_feed = (bool) $enable;
783 }
784
785 /**
786 * This is the URL of the feed you want to parse.
787 *
788 * This allows you to enter the URL of the feed you want to parse, or the
789 * website you want to try to use auto-discovery on. This takes priority
790 * over any set raw data.
791 *
792 * You can set multiple feeds to mash together by passing an array instead
793 * of a string for the $url. Remember that with each additional feed comes
794 * additional processing and resources.
795 *
796 * @access public
797 * @since 1.0 Preview Release
798 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
799 * @see SimplePie::set_raw_data()
800 */
801 function set_feed_url($url)
802 {
803 if (is_array($url))
804 {
805 $this->multifeed_url = array();
806 foreach ($url as $value)
807 {
808 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
809 }
810 }
811 else
812 {
813 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
814 }
815 }
816
817 /**
818 * Provides an instance of SimplePie_File to use as a feed
819 *
820 * @access public
821 * @param object &$file Instance of SimplePie_File (or subclass)
822 * @return bool True on success, false on failure
823 */
824 function set_file(&$file)
825 {
826 if (is_a($file, 'SimplePie_File'))
827 {
828 $this->feed_url = $file->url;
829 $this->file =& $file;
830 return true;
831 }
832 return false;
833 }
834
835 /**
836 * Allows you to use a string of RSS/Atom data instead of a remote feed.
837 *
838 * If you have a feed available as a string in PHP, you can tell SimplePie
839 * to parse that data string instead of a remote feed. Any set feed URL
840 * takes precedence.
841 *
842 * @access public
843 * @since 1.0 Beta 3
844 * @param string $data RSS or Atom data as a string.
845 * @see SimplePie::set_feed_url()
846 */
847 function set_raw_data($data)
848 {
849 $this->raw_data = $data;
850 }
851
852 /**
853 * Allows you to override the default timeout for fetching remote feeds.
854 *
855 * This allows you to change the maximum time the feed's server to respond
856 * and send the feed back.
857 *
858 * @access public
859 * @since 1.0 Beta 3
860 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
861 */
862 function set_timeout($timeout = 10)
863 {
864 $this->timeout = (int) $timeout;
865 }
866
867 /**
868 * Forces SimplePie to use fsockopen() instead of the preferred cURL
869 * functions.
870 *
871 * @access public
872 * @since 1.0 Beta 3
873 * @param bool $enable Force fsockopen() to be used
874 */
875 function force_fsockopen($enable = false)
876 {
877 $this->force_fsockopen = (bool) $enable;
878 }
879
880 /**
881 * Outputs the raw XML content of the feed, after it has gone through
882 * SimplePie's filters.
883 *
884 * Used only for debugging, this function will output the XML content as
885 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
886 * before trying to parse it. Many parts of the feed are re-written in
887 * memory, and in the end, you have a parsable feed. XML dump shows you the
888 * actual XML that SimplePie tries to parse, which may or may not be very
889 * different from the original feed.
890 *
891 * @access public
892 * @since 1.0 Preview Release
893 * @param bool $enable Enable XML dump
894 */
895 function enable_xml_dump($enable = false)
896 {
897 $this->xml_dump = (bool) $enable;
898 }
899
900 /**
901 * Enables/disables caching in SimplePie.
902 *
903 * This option allows you to disable caching all-together in SimplePie.
904 * However, disabling the cache can lead to longer load times.
905 *
906 * @access public
907 * @since 1.0 Preview Release
908 * @param bool $enable Enable caching
909 */
910 function enable_cache($enable = true)
911 {
912 $this->cache = (bool) $enable;
913 }
914
915 /**
916 * Set the length of time (in seconds) that the contents of a feed
917 * will be cached.
918 *
919 * @access public
920 * @param int $seconds The feed content cache duration.
921 */
922 function set_cache_duration($seconds = 3600)
923 {
924 $this->cache_duration = (int) $seconds;
925 }
926
927 /**
928 * Set the length of time (in seconds) that the autodiscovered feed
929 * URL will be cached.
930 *
931 * @access public
932 * @param int $seconds The autodiscovered feed URL cache duration.
933 */
934 function set_autodiscovery_cache_duration($seconds = 604800)
935 {
936 $this->autodiscovery_cache_duration = (int) $seconds;
937 }
938
939 /**
940 * Set the file system location where the cached files should be stored.
941 *
942 * @access public
943 * @param string $location The file system location.
944 */
945 function set_cache_location($location = './cache')
946 {
947 $this->cache_location = (string) $location;
948 }
949
950 /**
951 * Determines whether feed items should be sorted into reverse chronological order.
952 *
953 * @access public
954 * @param bool $enable Sort as reverse chronological order.
955 */
956 function enable_order_by_date($enable = true)
957 {
958 $this->order_by_date = (bool) $enable;
959 }
960
961 /**
962 * Allows you to override the character encoding reported by the feed.
963 *
964 * @access public
965 * @param string $encoding Character encoding.
966 */
967 function set_input_encoding($encoding = false)
968 {
969 if ($encoding)
970 {
971 $this->input_encoding = (string) $encoding;
972 }
973 else
974 {
975 $this->input_encoding = false;
976 }
977 }
978
979 /**
980 * Set how much feed autodiscovery to do
981 *
982 * @access public
983 * @see SIMPLEPIE_LOCATOR_NONE
984 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
985 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
986 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
987 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
988 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
989 * @see SIMPLEPIE_LOCATOR_ALL
990 * @param int $level Feed Autodiscovery Level (level can be a
991 * combination of the above constants, see bitwise OR operator)
992 */
993 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
994 {
995 $this->autodiscovery = (int) $level;
996 }
997
998 /**
999 * Allows you to change which class SimplePie uses for caching.
1000 * Useful when you are overloading or extending SimplePie's default classes.
1001 *
1002 * @access public
1003 * @param string $class Name of custom class.
1004 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1005 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1006 */
1007 function set_cache_class($class = 'SimplePie_Cache')
1008 {
1009 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1010 {
1011 $this->cache_class = $class;
1012 return true;
1013 }
1014 return false;
1015 }
1016
1017 /**
1018 * Allows you to change which class SimplePie uses for auto-discovery.
1019 * Useful when you are overloading or extending SimplePie's default classes.
1020 *
1021 * @access public
1022 * @param string $class Name of custom class.
1023 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1024 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1025 */
1026 function set_locator_class($class = 'SimplePie_Locator')
1027 {
1028 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1029 {
1030 $this->locator_class = $class;
1031 return true;
1032 }
1033 return false;
1034 }
1035
1036 /**
1037 * Allows you to change which class SimplePie uses for XML parsing.
1038 * Useful when you are overloading or extending SimplePie's default classes.
1039 *
1040 * @access public
1041 * @param string $class Name of custom class.
1042 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1043 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1044 */
1045 function set_parser_class($class = 'SimplePie_Parser')
1046 {
1047 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1048 {
1049 $this->parser_class = $class;
1050 return true;
1051 }
1052 return false;
1053 }
1054
1055 /**
1056 * Allows you to change which class SimplePie uses for remote file fetching.
1057 * Useful when you are overloading or extending SimplePie's default classes.
1058 *
1059 * @access public
1060 * @param string $class Name of custom class.
1061 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1062 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1063 */
1064 function set_file_class($class = 'SimplePie_File')
1065 {
1066 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1067 {
1068 $this->file_class = $class;
1069 return true;
1070 }
1071 return false;
1072 }
1073
1074 /**
1075 * Allows you to change which class SimplePie uses for data sanitization.
1076 * Useful when you are overloading or extending SimplePie's default classes.
1077 *
1078 * @access public
1079 * @param string $class Name of custom class.
1080 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1081 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1082 */
1083 function set_sanitize_class($class = 'SimplePie_Sanitize')
1084 {
1085 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1086 {
1087 $this->sanitize =& new $class;
1088 return true;
1089 }
1090 return false;
1091 }
1092
1093 /**
1094 * Allows you to change which class SimplePie uses for handling feed items.
1095 * Useful when you are overloading or extending SimplePie's default classes.
1096 *
1097 * @access public
1098 * @param string $class Name of custom class.
1099 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1100 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1101 */
1102 function set_item_class($class = 'SimplePie_Item')
1103 {
1104 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1105 {
1106 $this->item_class = $class;
1107 return true;
1108 }
1109 return false;
1110 }
1111
1112 /**
1113 * Allows you to change which class SimplePie uses for handling author data.
1114 * Useful when you are overloading or extending SimplePie's default classes.
1115 *
1116 * @access public
1117 * @param string $class Name of custom class.
1118 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1119 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1120 */
1121 function set_author_class($class = 'SimplePie_Author')
1122 {
1123 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1124 {
1125 $this->author_class = $class;
1126 return true;
1127 }
1128 return false;
1129 }
1130
1131 /**
1132 * Allows you to change which class SimplePie uses for handling category data.
1133 * Useful when you are overloading or extending SimplePie's default classes.
1134 *
1135 * @access public
1136 * @param string $class Name of custom class.
1137 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1138 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1139 */
1140 function set_category_class($class = 'SimplePie_Category')
1141 {
1142 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1143 {
1144 $this->category_class = $class;
1145 return true;
1146 }
1147 return false;
1148 }
1149
1150 /**
1151 * Allows you to change which class SimplePie uses for feed enclosures.
1152 * Useful when you are overloading or extending SimplePie's default classes.
1153 *
1154 * @access public
1155 * @param string $class Name of custom class.
1156 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1157 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1158 */
1159 function set_enclosure_class($class = 'SimplePie_Enclosure')
1160 {
1161 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1162 {
1163 $this->enclosure_class = $class;
1164 return true;
1165 }
1166 return false;
1167 }
1168
1169 /**
1170 * Allows you to change which class SimplePie uses for <media:text> captions
1171 * Useful when you are overloading or extending SimplePie's default classes.
1172 *
1173 * @access public
1174 * @param string $class Name of custom class.
1175 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1176 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1177 */
1178 function set_caption_class($class = 'SimplePie_Caption')
1179 {
1180 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1181 {
1182 $this->caption_class = $class;
1183 return true;
1184 }
1185 return false;
1186 }
1187
1188 /**
1189 * Allows you to change which class SimplePie uses for <media:copyright>
1190 * Useful when you are overloading or extending SimplePie's default classes.
1191 *
1192 * @access public
1193 * @param string $class Name of custom class.
1194 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1195 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1196 */
1197 function set_copyright_class($class = 'SimplePie_Copyright')
1198 {
1199 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1200 {
1201 $this->copyright_class = $class;
1202 return true;
1203 }
1204 return false;
1205 }
1206
1207 /**
1208 * Allows you to change which class SimplePie uses for <media:credit>
1209 * Useful when you are overloading or extending SimplePie's default classes.
1210 *
1211 * @access public
1212 * @param string $class Name of custom class.
1213 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1214 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1215 */
1216 function set_credit_class($class = 'SimplePie_Credit')
1217 {
1218 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1219 {
1220 $this->credit_class = $class;
1221 return true;
1222 }
1223 return false;
1224 }
1225
1226 /**
1227 * Allows you to change which class SimplePie uses for <media:rating>
1228 * Useful when you are overloading or extending SimplePie's default classes.
1229 *
1230 * @access public
1231 * @param string $class Name of custom class.
1232 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1233 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1234 */
1235 function set_rating_class($class = 'SimplePie_Rating')
1236 {
1237 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1238 {
1239 $this->rating_class = $class;
1240 return true;
1241 }
1242 return false;
1243 }
1244
1245 /**
1246 * Allows you to change which class SimplePie uses for <media:restriction>
1247 * Useful when you are overloading or extending SimplePie's default classes.
1248 *
1249 * @access public
1250 * @param string $class Name of custom class.
1251 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1252 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1253 */
1254 function set_restriction_class($class = 'SimplePie_Restriction')
1255 {
1256 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1257 {
1258 $this->restriction_class = $class;
1259 return true;
1260 }
1261 return false;
1262 }
1263
1264 /**
1265 * Allows you to change which class SimplePie uses for content-type sniffing.
1266 * Useful when you are overloading or extending SimplePie's default classes.
1267 *
1268 * @access public
1269 * @param string $class Name of custom class.
1270 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1271 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1272 */
1273 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1274 {
1275 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1276 {
1277 $this->content_type_sniffer_class = $class;
1278 return true;
1279 }
1280 return false;
1281 }
1282
1283 /**
1284 * Allows you to change which class SimplePie uses item sources.
1285 * Useful when you are overloading or extending SimplePie's default classes.
1286 *
1287 * @access public
1288 * @param string $class Name of custom class.
1289 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1290 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1291 */
1292 function set_source_class($class = 'SimplePie_Source')
1293 {
1294 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1295 {
1296 $this->source_class = $class;
1297 return true;
1298 }
1299 return false;
1300 }
1301
1302 /**
1303 * Allows you to override the default user agent string.
1304 *
1305 * @access public
1306 * @param string $ua New user agent string.
1307 */
1308 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1309 {
1310 $this->useragent = (string) $ua;
1311 }
1312
1313 /**
1314 * Set callback function to create cache filename with
1315 *
1316 * @access public
1317 * @param mixed $function Callback function
1318 */
1319 function set_cache_name_function($function = 'md5')
1320 {
1321 if (is_callable($function))
1322 {
1323 $this->cache_name_function = $function;
1324 }
1325 }
1326
1327 /**
1328 * Set javascript query string parameter
1329 *
1330 * @access public
1331 * @param mixed $get Javascript query string parameter
1332 */
1333 function set_javascript($get = 'js')
1334 {
1335 if ($get)
1336 {
1337 $this->javascript = (string) $get;
1338 }
1339 else
1340 {
1341 $this->javascript = false;
1342 }
1343 }
1344
1345 /**
1346 * Set options to make SP as fast as possible. Forgoes a
1347 * substantial amount of data sanitization in favor of speed.
1348 *
1349 * @access public
1350 * @param bool $set Whether to set them or not
1351 */
1352 function set_stupidly_fast($set = false)
1353 {
1354 if ($set)
1355 {
1356 $this->enable_order_by_date(false);
1357 $this->remove_div(false);
1358 $this->strip_comments(false);
1359 $this->strip_htmltags(false);
1360 $this->strip_attributes(false);
1361 $this->set_image_handler(false);
1362 }
1363 }
1364
1365 /**
1366 * Set maximum number of feeds to check with autodiscovery
1367 *
1368 * @access public
1369 * @param int $max Maximum number of feeds to check
1370 */
1371 function set_max_checked_feeds($max = 10)
1372 {
1373 $this->max_checked_feeds = (int) $max;
1374 }
1375
1376 function remove_div($enable = true)
1377 {
1378 $this->sanitize->remove_div($enable);
1379 }
1380
1381 function strip_htmltags($tags = '', $encode = null)
1382 {
1383 if ($tags === '')
1384 {
1385 $tags = $this->strip_htmltags;
1386 }
1387 $this->sanitize->strip_htmltags($tags);
1388 if ($encode !== null)
1389 {
1390 $this->sanitize->encode_instead_of_strip($tags);
1391 }
1392 }
1393
1394 function encode_instead_of_strip($enable = true)
1395 {
1396 $this->sanitize->encode_instead_of_strip($enable);
1397 }
1398
1399 function strip_attributes($attribs = '')
1400 {
1401 if ($attribs === '')
1402 {
1403 $attribs = $this->strip_attributes;
1404 }
1405 $this->sanitize->strip_attributes($attribs);
1406 }
1407
1408 function set_output_encoding($encoding = 'UTF-8')
1409 {
1410 $this->sanitize->set_output_encoding($encoding);
1411 }
1412
1413 function strip_comments($strip = false)
1414 {
1415 $this->sanitize->strip_comments($strip);
1416 }
1417
1418 /**
1419 * Set element/attribute key/value pairs of HTML attributes
1420 * containing URLs that need to be resolved relative to the feed
1421 *
1422 * @access public
1423 * @since 1.0
1424 * @param array $element_attribute Element/attribute key/value pairs
1425 */
1426 function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
1427 {
1428 $this->sanitize->set_url_replacements($element_attribute);
1429 }
1430
1431 /**
1432 * Set the handler to enable the display of cached favicons.
1433 *
1434 * @access public
1435 * @param str $page Web-accessible path to the handler_favicon.php file.
1436 * @param str $qs The query string that the value should be passed to.
1437 */
1438 function set_favicon_handler($page = false, $qs = 'i')
1439 {
1440 if ($page != false)
1441 {
1442 $this->favicon_handler = $page . '?' . $qs . '=';
1443 }
1444 else
1445 {
1446 $this->favicon_handler = '';
1447 }
1448 }
1449
1450 /**
1451 * Set the handler to enable the display of cached images.
1452 *
1453 * @access public
1454 * @param str $page Web-accessible path to the handler_image.php file.
1455 * @param str $qs The query string that the value should be passed to.
1456 */
1457 function set_image_handler($page = false, $qs = 'i')
1458 {
1459 if ($page != false)
1460 {
1461 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1462 }
1463 else
1464 {
1465 $this->image_handler = '';
1466 }
1467 }
1468
1469 /**
1470 * Set the limit for items returned per-feed with multifeeds.
1471 *
1472 * @access public
1473 * @param integer $limit The maximum number of items to return.
1474 */
1475 function set_item_limit($limit = 0)
1476 {
1477 $this->item_limit = (int) $limit;
1478 }
1479
1480 function init()
1481 {
1482 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1483 {
1484 return false;
1485 }
1486 if (isset($_GET[$this->javascript]))
1487 {
1488 if (function_exists('ob_gzhandler'))
1489 {
1490 ob_start('ob_gzhandler');
1491 }
1492 header('Content-type: text/javascript; charset: UTF-8');
1493 header('Cache-Control: must-revalidate');
1494 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1495 ?>
1496function embed_odeo(link) {
1497 document.writeln('<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url='+link+'"></embed>');
1498}
1499
1500function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1501 if (placeholder != '') {
1502 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1503 }
1504 else {
1505 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1506 }
1507}
1508
1509function embed_flash(bgcolor, width, height, link, loop, type) {
1510 document.writeln('<embed src="'+link+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="'+type+'" quality="high" width="'+width+'" height="'+height+'" bgcolor="'+bgcolor+'" loop="'+loop+'"></embed>');
1511}
1512
1513function embed_flv(width, height, link, placeholder, loop, player) {
1514 document.writeln('<embed src="'+player+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="'+width+'" height="'+height+'" wmode="transparent" flashvars="file='+link+'&autostart=false&repeat='+loop+'&showdigits=true&showfsbutton=false"></embed>');
1515}
1516
1517function embed_wmedia(width, height, link) {
1518 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1519}
1520 <?php
1521 exit;
1522 }
1523
1524 // Pass whatever was set with config options over to the sanitizer.
1525 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1526 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1527
1528 if ($this->feed_url !== null || $this->raw_data !== null)
1529 {
1530 $this->data = array();
1531 $this->multifeed_objects = array();
1532 $cache = false;
1533
1534 if ($this->feed_url !== null)
1535 {
1536 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1537 // Decide whether to enable caching
1538 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1539 {
1540 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1541 }
1542 // If it's enabled and we don't want an XML dump, use the cache
1543 if ($cache && !$this->xml_dump)
1544 {
1545 // Load the Cache
1546 $this->data = $cache->load();
1547 if (!empty($this->data))
1548 {
1549 // If the cache is for an outdated build of SimplePie
1550 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1551 {
1552 $cache->unlink();
1553 $this->data = array();
1554 }
1555 // If we've hit a collision just rerun it with caching disabled
1556 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1557 {
1558 $cache = false;
1559 $this->data = array();
1560 }
1561 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1562 elseif (isset($this->data['feed_url']))
1563 {
1564 // If the autodiscovery cache is still valid use it.
1565 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1566 {
1567 // Do not need to do feed autodiscovery yet.
1568 if ($this->data['feed_url'] == $this->data['url'])
1569 {
1570 $cache->unlink();
1571 $this->data = array();
1572 }
1573 else
1574 {
1575 $this->set_feed_url($this->data['feed_url']);
1576 return $this->init();
1577 }
1578 }
1579 }
1580 // Check if the cache has been updated
1581 elseif ($cache->mtime() + $this->cache_duration < time())
1582 {
1583 // If we have last-modified and/or etag set
1584 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1585 {
1586 $headers = array();
1587 if (isset($this->data['headers']['last-modified']))
1588 {
1589 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1590 }
1591 if (isset($this->data['headers']['etag']))
1592 {
1593 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1594 }
1595 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1596 if ($file->success)
1597 {
1598 if ($file->status_code == 304)
1599 {
1600 $cache->touch();
1601 return true;
1602 }
1603 else
1604 {
1605 $headers = $file->headers;
1606 }
1607 }
1608 else
1609 {
1610 unset($file);
1611 }
1612 }
1613 }
1614 // If the cache is still valid, just return true
1615 else
1616 {
1617 return true;
1618 }
1619 }
1620 // If the cache is empty, delete it
1621 else
1622 {
1623 $cache->unlink();
1624 $this->data = array();
1625 }
1626 }
1627 // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
1628 if (!isset($file))
1629 {
1630 if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1631 {
1632 $file =& $this->file;
1633 }
1634 else
1635 {
1636 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1637 }
1638 }
1639 // If the file connection has an error, set SimplePie::error to that and quit
1640 if (!$file->success)
1641 {
1642 $this->error = $file->error;
1643 if (!empty($this->data))
1644 {
1645 return true;
1646 }
1647 else
1648 {
1649 return false;
1650 }
1651 }
1652
1653 if (!$this->force_feed)
1654 {
1655 // Check if the supplied URL is a feed, if it isn't, look for it.
1656 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1657 if (!$locate->is_feed($file))
1658 {
1659 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1660 unset($file);
1661 if ($file = $locate->find($this->autodiscovery))
1662 {
1663 if ($cache)
1664 {
1665 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1666 if (!$cache->save($this))
1667 {
1668 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1669 }
1670 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1671 }
1672 $this->feed_url = $file->url;
1673 }
1674 else
1675 {
1676 $this->error = "A feed could not be found at $this->feed_url";
1677 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1678 return false;
1679 }
1680 }
1681 $locate = null;
1682 }
1683
1684 $headers = $file->headers;
1685 $data = $file->body;
1686 $sniffer = new $this->content_type_sniffer_class($file);
1687 $sniffed = $sniffer->get_type();
1688 }
1689 else
1690 {
1691 $data = $this->raw_data;
1692 }
1693
1694 // Set up array of possible encodings
1695 $encodings = array();
1696
1697 // First check to see if input has been overridden.
1698 if ($this->input_encoding !== false)
1699 {
1700 $encodings[] = $this->input_encoding;
1701 }
1702
1703 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1704 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1705
1706 // RFC 3023 (only applies to sniffed content)
1707 if (isset($sniffed))
1708 {
1709 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1710 {
1711 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1712 {
1713 $encodings[] = strtoupper($charset[1]);
1714 }
1715 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1716 $encodings[] = 'UTF-8';
1717 }
1718 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1719 {
1720 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1721 {
1722 $encodings[] = $charset[1];
1723 }
1724 $encodings[] = 'US-ASCII';
1725 }
1726 // Text MIME-type default
1727 elseif (substr($sniffed, 0, 5) === 'text/')
1728 {
1729 $encodings[] = 'US-ASCII';
1730 }
1731 }
1732
1733 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1734 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1735 $encodings[] = 'UTF-8';
1736 $encodings[] = 'ISO-8859-1';
1737
1738 // There's no point in trying an encoding twice
1739 $encodings = array_unique($encodings);
1740
1741 // If we want the XML, just output that with the most likely encoding and quit
1742 if ($this->xml_dump)
1743 {
1744 header('Content-type: text/xml; charset=' . $encodings[0]);
1745 echo $data;
1746 exit;
1747 }
1748
1749 // Loop through each possible encoding, till we return something, or run out of possibilities
1750 foreach ($encodings as $encoding)
1751 {
1752 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1753 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1754 {
1755 // Create new parser
1756 $parser =& new $this->parser_class();
1757
1758 // If it's parsed fine
1759 if ($parser->parse($utf8_data, 'UTF-8'))
1760 {
1761 $this->data = $parser->get_data();
1762 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1763 {
1764 if (isset($headers))
1765 {
1766 $this->data['headers'] = $headers;
1767 }
1768 $this->data['build'] = SIMPLEPIE_BUILD;
1769
1770 // Cache the file if caching is enabled
1771 if ($cache && !$cache->save($this))
1772 {
1773 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1774 }
1775 return true;
1776 }
1777 else
1778 {
1779 $this->error = "A feed could not be found at $this->feed_url";
1780 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1781 return false;
1782 }
1783 }
1784 }
1785 }
1786 // We have an error, just set SimplePie::error to it and quit
1787 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1788 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1789 return false;
1790 }
1791 elseif (!empty($this->multifeed_url))
1792 {
1793 $i = 0;
1794 $success = 0;
1795 $this->multifeed_objects = array();
1796 foreach ($this->multifeed_url as $url)
1797 {
1798 if (SIMPLEPIE_PHP5)
1799 {
1800 // This keyword needs to defy coding standards for PHP4 compatibility
1801 $this->multifeed_objects[$i] = clone($this);
1802 }
1803 else
1804 {
1805 $this->multifeed_objects[$i] = $this;
1806 }
1807 $this->multifeed_objects[$i]->set_feed_url($url);
1808 $success |= $this->multifeed_objects[$i]->init();
1809 $i++;
1810 }
1811 return (bool) $success;
1812 }
1813 else
1814 {
1815 return false;
1816 }
1817 }
1818
1819 /**
1820 * Return the error message for the occured error
1821 *
1822 * @access public
1823 * @return string Error message
1824 */
1825 function error()
1826 {
1827 return $this->error;
1828 }
1829
1830 function get_encoding()
1831 {
1832 return $this->sanitize->output_encoding;
1833 }
1834
1835 function handle_content_type($mime = 'text/html')
1836 {
1837 if (!headers_sent())
1838 {
1839 $header = "Content-type: $mime;";
1840 if ($this->get_encoding())
1841 {
1842 $header .= ' charset=' . $this->get_encoding();
1843 }
1844 else
1845 {
1846 $header .= ' charset=UTF-8';
1847 }
1848 header($header);
1849 }
1850 }
1851
1852 function get_type()
1853 {
1854 if (!isset($this->data['type']))
1855 {
1856 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1857 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1858 {
1859 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1860 }
1861 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1862 {
1863 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1864 }
1865 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1866 {
1867 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1868 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1869 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1870 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1871 {
1872 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1873 }
1874 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1875 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1876 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1877 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1878 {
1879 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1880 }
1881 }
1882 elseif (isset($this->data['child']['']['rss']))
1883 {
1884 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1885 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1886 {
1887 switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1888 {
1889 case '0.91':
1890 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1891 if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1892 {
1893 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1894 {
1895 case '0':
1896 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1897 break;
1898
1899 case '24':
1900 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1901 break;
1902 }
1903 }
1904 break;
1905
1906 case '0.92':
1907 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1908 break;
1909
1910 case '0.93':
1911 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1912 break;
1913
1914 case '0.94':
1915 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1916 break;
1917
1918 case '2.0':
1919 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1920 break;
1921 }
1922 }
1923 }
1924 else
1925 {
1926 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1927 }
1928 }
1929 return $this->data['type'];
1930 }
1931
1932 /**
1933 * Returns the URL for the favicon of the feed's website.
1934 *
1935 * @todo Cache atom:icon
1936 * @access public
1937 * @since 1.0
1938 */
1939 function get_favicon()
1940 {
1941 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1942 {
1943 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1944 }
1945 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1946 {
1947 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1948
1949 if ($this->cache && $this->favicon_handler)
1950 {
1951 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1952 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1953
1954 if ($cache->load())
1955 {
1956 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1957 }
1958 else
1959 {
1960 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1961
1962 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1963 {
1964 $sniffer = new $this->content_type_sniffer_class($file);
1965 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1966 {
1967 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1968 {
1969 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1970 }
1971 else
1972 {
1973 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1974 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1975 }
1976 }
1977 }
1978 }
1979 }
1980 else
1981 {
1982 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1983 }
1984 }
1985 return false;
1986 }
1987
1988 /**
1989 * @todo If we have a perm redirect we should return the new URL
1990 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1991 * @todo Also, |atom:link|@rel=self
1992 */
1993 function subscribe_url()
1994 {
1995 if ($this->feed_url !== null)
1996 {
1997 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1998 }
1999 else
2000 {
2001 return null;
2002 }
2003 }
2004
2005 function subscribe_feed()
2006 {
2007 if ($this->feed_url !== null)
2008 {
2009 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2010 }
2011 else
2012 {
2013 return null;
2014 }
2015 }
2016
2017 function subscribe_outlook()
2018 {
2019 if ($this->feed_url !== null)
2020 {
2021 return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2022 }
2023 else
2024 {
2025 return null;
2026 }
2027 }
2028
2029 function subscribe_podcast()
2030 {
2031 if ($this->feed_url !== null)
2032 {
2033 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2034 }
2035 else
2036 {
2037 return null;
2038 }
2039 }
2040
2041 function subscribe_itunes()
2042 {
2043 if ($this->feed_url !== null)
2044 {
2045 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2046 }
2047 else
2048 {
2049 return null;
2050 }
2051 }
2052
2053 /**
2054 * Creates the subscribe_* methods' return data
2055 *
2056 * @access private
2057 * @param string $feed_url String to prefix to the feed URL
2058 * @param string $site_url String to prefix to the site URL (and
2059 * suffix to the feed URL)
2060 * @return mixed URL if feed exists, false otherwise
2061 */
2062 function subscribe_service($feed_url, $site_url = null)
2063 {
2064 if ($this->subscribe_url())
2065 {
2066 $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2067 if ($site_url !== null && $this->get_link() !== null)
2068 {
2069 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2070 }
2071 return $return;
2072 }
2073 else
2074 {
2075 return null;
2076 }
2077 }
2078
2079 function subscribe_aol()
2080 {
2081 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2082 }
2083
2084 function subscribe_bloglines()
2085 {
2086 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2087 }
2088
2089 function subscribe_eskobo()
2090 {
2091 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2092 }
2093
2094 function subscribe_feedfeeds()
2095 {
2096 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2097 }
2098
2099 function subscribe_feedster()
2100 {
2101 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2102 }
2103
2104 function subscribe_google()
2105 {
2106 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2107 }
2108
2109 function subscribe_gritwire()
2110 {
2111 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2112 }
2113
2114 function subscribe_msn()
2115 {
2116 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2117 }
2118
2119 function subscribe_netvibes()
2120 {
2121 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2122 }
2123
2124 function subscribe_newsburst()
2125 {
2126 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2127 }
2128
2129 function subscribe_newsgator()
2130 {
2131 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2132 }
2133
2134 function subscribe_odeo()
2135 {
2136 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2137 }
2138
2139 function subscribe_podnova()
2140 {
2141 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2142 }
2143
2144 function subscribe_rojo()
2145 {
2146 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2147 }
2148
2149 function subscribe_yahoo()
2150 {
2151 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2152 }
2153
2154 function get_feed_tags($namespace, $tag)
2155 {
2156 $type = $this->get_type();
2157 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2158 {
2159 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2160 {
2161 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2162 }
2163 }
2164 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2165 {
2166 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2167 {
2168 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2169 }
2170 }
2171 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2172 {
2173 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2174 {
2175 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2176 }
2177 }
2178 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2179 {
2180 if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2181 {
2182 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2183 }
2184 }
2185 return null;
2186 }
2187
2188 function get_channel_tags($namespace, $tag)
2189 {
2190 $type = $this->get_type();
2191 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2192 {
2193 if ($return = $this->get_feed_tags($namespace, $tag))
2194 {
2195 return $return;
2196 }
2197 }
2198 if ($type & SIMPLEPIE_TYPE_RSS_10)
2199 {
2200 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2201 {
2202 if (isset($channel[0]['child'][$namespace][$tag]))
2203 {
2204 return $channel[0]['child'][$namespace][$tag];
2205 }
2206 }
2207 }
2208 if ($type & SIMPLEPIE_TYPE_RSS_090)
2209 {
2210 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2211 {
2212 if (isset($channel[0]['child'][$namespace][$tag]))
2213 {
2214 return $channel[0]['child'][$namespace][$tag];
2215 }
2216 }
2217 }
2218 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2219 {
2220 if ($channel = $this->get_feed_tags('', 'channel'))
2221 {
2222 if (isset($channel[0]['child'][$namespace][$tag]))
2223 {
2224 return $channel[0]['child'][$namespace][$tag];
2225 }
2226 }
2227 }
2228 return null;
2229 }
2230
2231 function get_image_tags($namespace, $tag)
2232 {
2233 $type = $this->get_type();
2234 if ($type & SIMPLEPIE_TYPE_RSS_10)
2235 {
2236 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2237 {
2238 if (isset($image[0]['child'][$namespace][$tag]))
2239 {
2240 return $image[0]['child'][$namespace][$tag];
2241 }
2242 }
2243 }
2244 if ($type & SIMPLEPIE_TYPE_RSS_090)
2245 {
2246 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2247 {
2248 if (isset($image[0]['child'][$namespace][$tag]))
2249 {
2250 return $image[0]['child'][$namespace][$tag];
2251 }
2252 }
2253 }
2254 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2255 {
2256 if ($image = $this->get_channel_tags('', 'image'))
2257 {
2258 if (isset($image[0]['child'][$namespace][$tag]))
2259 {
2260 return $image[0]['child'][$namespace][$tag];
2261 }
2262 }
2263 }
2264 return null;
2265 }
2266
2267 function get_base($element = array())
2268 {
2269 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2270 {
2271 return $element['xml_base'];
2272 }
2273 elseif ($this->get_link() !== null)
2274 {
2275 return $this->get_link();
2276 }
2277 else
2278 {
2279 return $this->subscribe_url();
2280 }
2281 }
2282
2283 function sanitize($data, $type, $base = '')
2284 {
2285 return $this->sanitize->sanitize($data, $type, $base);
2286 }
2287
2288 function get_title()
2289 {
2290 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2291 {
2292 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2293 }
2294 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2295 {
2296 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2297 }
2298 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2299 {
2300 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2301 }
2302 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2303 {
2304 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2305 }
2306 elseif ($return = $this->get_channel_tags('', 'title'))
2307 {
2308 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2309 }
2310 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2311 {
2312 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2313 }
2314 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2315 {
2316 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2317 }
2318 else
2319 {
2320 return null;
2321 }
2322 }
2323
2324 function get_category($key = 0)
2325 {
2326 $categories = $this->get_categories();
2327 if (isset($categories[$key]))
2328 {
2329 return $categories[$key];
2330 }
2331 else
2332 {
2333 return null;
2334 }
2335 }
2336
2337 function get_categories()
2338 {
2339 $categories = array();
2340
2341 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2342 {
2343 $term = null;
2344 $scheme = null;
2345 $label = null;
2346 if (isset($category['attribs']['']['term']))
2347 {
2348 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2349 }
2350 if (isset($category['attribs']['']['scheme']))
2351 {
2352 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2353 }
2354 if (isset($category['attribs']['']['label']))
2355 {
2356 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2357 }
2358 $categories[] =& new $this->category_class($term, $scheme, $label);
2359 }
2360 foreach ((array) $this->get_channel_tags('', 'category') as $category)
2361 {
2362 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2363 }
2364 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2365 {
2366 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2367 }
2368 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2369 {
2370 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2371 }
2372
2373 if (!empty($categories))
2374 {
2375 return SimplePie_Misc::array_unique($categories);
2376 }
2377 else
2378 {
2379 return null;
2380 }
2381 }
2382
2383 function get_author($key = 0)
2384 {
2385 $authors = $this->get_authors();
2386 if (isset($authors[$key]))
2387 {
2388 return $authors[$key];
2389 }
2390 else
2391 {
2392 return null;
2393 }
2394 }
2395
2396 function get_authors()
2397 {
2398 $authors = array();
2399 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2400 {
2401 $name = null;
2402 $uri = null;
2403 $email = null;
2404 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2405 {
2406 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2407 }
2408 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2409 {
2410 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
2411 }
2412 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2413 {
2414 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2415 }
2416 if ($name !== null || $email !== null || $uri !== null)
2417 {
2418 $authors[] =& new $this->author_class($name, $uri, $email);
2419 }
2420 }
2421 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2422 {
2423 $name = null;
2424 $url = null;
2425 $email = null;
2426 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2427 {
2428 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2429 }
2430 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2431 {
2432 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2433 }
2434 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2435 {
2436 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2437 }
2438 if ($name !== null || $email !== null || $url !== null)
2439 {
2440 $authors[] =& new $this->author_class($name, $url, $email);
2441 }
2442 }
2443 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2444 {
2445 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2446 }
2447 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2448 {
2449 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2450 }
2451 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2452 {
2453 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2454 }
2455
2456 if (!empty($authors))
2457 {
2458 return SimplePie_Misc::array_unique($authors);
2459 }
2460 else
2461 {
2462 return null;
2463 }
2464 }
2465
2466 function get_contributor($key = 0)
2467 {
2468 $contributors = $this->get_contributors();
2469 if (isset($contributors[$key]))
2470 {
2471 return $contributors[$key];
2472 }
2473 else
2474 {
2475 return null;
2476 }
2477 }
2478
2479 function get_contributors()
2480 {
2481 $contributors = array();
2482 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2483 {
2484 $name = null;
2485 $uri = null;
2486 $email = null;
2487 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2488 {
2489 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2490 }
2491 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2492 {
2493 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
2494 }
2495 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2496 {
2497 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2498 }
2499 if ($name !== null || $email !== null || $uri !== null)
2500 {
2501 $contributors[] =& new $this->author_class($name, $uri, $email);
2502 }
2503 }
2504 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2505 {
2506 $name = null;
2507 $url = null;
2508 $email = null;
2509 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2510 {
2511 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2512 }
2513 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2514 {
2515 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2516 }
2517 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2518 {
2519 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2520 }
2521 if ($name !== null || $email !== null || $url !== null)
2522 {
2523 $contributors[] =& new $this->author_class($name, $url, $email);
2524 }
2525 }
2526
2527 if (!empty($contributors))
2528 {
2529 return SimplePie_Misc::array_unique($contributors);
2530 }
2531 else
2532 {
2533 return null;
2534 }
2535 }
2536
2537 function get_link($key = 0, $rel = 'alternate')
2538 {
2539 $links = $this->get_links($rel);
2540 if (isset($links[$key]))
2541 {
2542 return $links[$key];
2543 }
2544 else
2545 {
2546 return null;
2547 }
2548 }
2549
2550 /**
2551 * Added for parity between the parent-level and the item/entry-level.
2552 */
2553 function get_permalink()
2554 {
2555 return $this->get_link(0);
2556 }
2557
2558 function get_links($rel = 'alternate')
2559 {
2560 if (!isset($this->data['links']))
2561 {
2562 $this->data['links'] = array();
2563 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2564 {
2565 foreach ($links as $link)
2566 {
2567 if (isset($link['attribs']['']['href']))
2568 {
2569 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2570 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2571 }
2572 }
2573 }
2574 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2575 {
2576 foreach ($links as $link)
2577 {
2578 if (isset($link['attribs']['']['href']))
2579 {
2580 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2581 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2582
2583 }
2584 }
2585 }
2586 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2587 {
2588 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2589 }
2590 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2591 {
2592 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2593 }
2594 if ($links = $this->get_channel_tags('', 'link'))
2595 {
2596 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2597 }
2598
2599 $keys = array_keys($this->data['links']);
2600 foreach ($keys as $key)
2601 {
2602 if (SimplePie_Misc::is_isegment_nz_nc($key))
2603 {
2604 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2605 {
2606 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2607 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2608 }
2609 else
2610 {
2611 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2612 }
2613 }
2614 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2615 {
2616 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2617 }
2618 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2619 }
2620 }
2621
2622 if (isset($this->data['links'][$rel]))
2623 {
2624 return $this->data['links'][$rel];
2625 }
2626 else
2627 {
2628 return null;
2629 }
2630 }
2631
2632 function get_description()
2633 {
2634 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2635 {
2636 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2637 }
2638 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2639 {
2640 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2641 }
2642 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2643 {
2644 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2645 }
2646 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2647 {
2648 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2649 }
2650 elseif ($return = $this->get_channel_tags('', 'description'))
2651 {
2652 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2653 }
2654 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2655 {
2656 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2657 }
2658 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2659 {
2660 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2661 }
2662 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2663 {
2664 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2665 }
2666 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2667 {
2668 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2669 }
2670 else
2671 {
2672 return null;
2673 }
2674 }
2675
2676 function get_copyright()
2677 {
2678 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2679 {
2680 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2681 }
2682 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2683 {
2684 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2685 }
2686 elseif ($return = $this->get_channel_tags('', 'copyright'))
2687 {
2688 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2689 }
2690 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2691 {
2692 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2693 }
2694 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2695 {
2696 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2697 }
2698 else
2699 {
2700 return null;
2701 }
2702 }
2703
2704 function get_language()
2705 {
2706 if ($return = $this->get_channel_tags('', 'language'))
2707 {
2708 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2709 }
2710 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2711 {
2712 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2713 }
2714 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2715 {
2716 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2717 }
2718 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2719 {
2720 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2721 }
2722 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2723 {
2724 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2725 }
2726 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2727 {
2728 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2729 }
2730 elseif (isset($this->data['headers']['content-language']))
2731 {
2732 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2733 }
2734 else
2735 {
2736 return null;
2737 }
2738 }
2739
2740 function get_latitude()
2741 {
2742 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2743 {
2744 return (float) $return[0]['data'];
2745 }
2746 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2747 {
2748 return (float) $match[1];
2749 }
2750 else
2751 {
2752 return null;
2753 }
2754 }
2755
2756 function get_longitude()
2757 {
2758 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2759 {
2760 return (float) $return[0]['data'];
2761 }
2762 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2763 {
2764 return (float) $return[0]['data'];
2765 }
2766 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2767 {
2768 return (float) $match[2];
2769 }
2770 else
2771 {
2772 return null;
2773 }
2774 }
2775
2776 function get_image_title()
2777 {
2778 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2779 {
2780 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2781 }
2782 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2783 {
2784 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2785 }
2786 elseif ($return = $this->get_image_tags('', 'title'))
2787 {
2788 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2789 }
2790 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2791 {
2792 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2793 }
2794 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2795 {
2796 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2797 }
2798 else
2799 {
2800 return null;
2801 }
2802 }
2803
2804 function get_image_url()
2805 {
2806 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2807 {
2808 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2809 }
2810 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2811 {
2812 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2813 }
2814 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2815 {
2816 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2817 }
2818 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2819 {
2820 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2821 }
2822 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2823 {
2824 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2825 }
2826 elseif ($return = $this->get_image_tags('', 'url'))
2827 {
2828 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2829 }
2830 else
2831 {
2832 return null;
2833 }
2834 }
2835
2836 function get_image_link()
2837 {
2838 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2839 {
2840 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2841 }
2842 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2843 {
2844 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2845 }
2846 elseif ($return = $this->get_image_tags('', 'link'))
2847 {
2848 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2849 }
2850 else
2851 {
2852 return null;
2853 }
2854 }
2855
2856 function get_image_width()
2857 {
2858 if ($return = $this->get_image_tags('', 'width'))
2859 {
2860 return round($return[0]['data']);
2861 }
2862 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2863 {
2864 return 88.0;
2865 }
2866 else
2867 {
2868 return null;
2869 }
2870 }
2871
2872 function get_image_height()
2873 {
2874 if ($return = $this->get_image_tags('', 'height'))
2875 {
2876 return round($return[0]['data']);
2877 }
2878 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2879 {
2880 return 31.0;
2881 }
2882 else
2883 {
2884 return null;
2885 }
2886 }
2887
2888 function get_item_quantity($max = 0)
2889 {
2890 $qty = count($this->get_items());
2891 if ($max == 0)
2892 {
2893 return $qty;
2894 }
2895 else
2896 {
2897 return ($qty > $max) ? $max : $qty;
2898 }
2899 }
2900
2901 function get_item($key = 0)
2902 {
2903 $items = $this->get_items();
2904 if (isset($items[$key]))
2905 {
2906 return $items[$key];
2907 }
2908 else
2909 {
2910 return null;
2911 }
2912 }
2913
2914 function get_items($start = 0, $end = 0)
2915 {
2916 if (!empty($this->multifeed_objects))
2917 {
2918 return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2919 }
2920 elseif (!isset($this->data['items']))
2921 {
2922 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2923 {
2924 $keys = array_keys($items);
2925 foreach ($keys as $key)
2926 {
2927 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2928 }
2929 }
2930 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2931 {
2932 $keys = array_keys($items);
2933 foreach ($keys as $key)
2934 {
2935 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2936 }
2937 }
2938 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2939 {
2940 $keys = array_keys($items);
2941 foreach ($keys as $key)
2942 {
2943 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2944 }
2945 }
2946 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2947 {
2948 $keys = array_keys($items);
2949 foreach ($keys as $key)
2950 {
2951 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2952 }
2953 }
2954 if ($items = $this->get_channel_tags('', 'item'))
2955 {
2956 $keys = array_keys($items);
2957 foreach ($keys as $key)
2958 {
2959 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2960 }
2961 }
2962 }
2963
2964 if (!empty($this->data['items']))
2965 {
2966 // If we want to order it by date, check if all items have a date, and then sort it
2967 if ($this->order_by_date)
2968 {
2969 if (!isset($this->data['ordered_items']))
2970 {
2971 $do_sort = true;
2972 foreach ($this->data['items'] as $item)
2973 {
2974 if (!$item->get_date('U'))
2975 {
2976 $do_sort = false;
2977 break;
2978 }
2979 }
2980 $item = null;
2981 $this->data['ordered_items'] = $this->data['items'];
2982 if ($do_sort)
2983 {
2984 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2985 }
2986 }
2987 $items = $this->data['ordered_items'];
2988 }
2989 else
2990 {
2991 $items = $this->data['items'];
2992 }
2993
2994 // Slice the data as desired
2995 if ($end == 0)
2996 {
2997 return array_slice($items, $start);
2998 }
2999 else
3000 {
3001 return array_slice($items, $start, $end);
3002 }
3003 }
3004 else
3005 {
3006 return array();
3007 }
3008 }
3009
3010 function sort_items($a, $b)
3011 {
3012 return $a->get_date('U') <= $b->get_date('U');
3013 }
3014
3015 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3016 {
3017 if (is_array($urls) && sizeof($urls) > 0)
3018 {
3019 $items = array();
3020 foreach ($urls as $arg)
3021 {
3022 if (is_a($arg, 'SimplePie'))
3023 {
3024 $items = array_merge($items, $arg->get_items(0, $limit));
3025 }
3026 else
3027 {
3028 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3029 }
3030 }
3031
3032 $do_sort = true;
3033 foreach ($items as $item)
3034 {
3035 if (!$item->get_date('U'))
3036 {
3037 $do_sort = false;
3038 break;
3039 }
3040 }
3041 $item = null;
3042 if ($do_sort)
3043 {
3044 usort($items, array('SimplePie', 'sort_items'));
3045 }
3046
3047 if ($end == 0)
3048 {
3049 return array_slice($items, $start);
3050 }
3051 else
3052 {
3053 return array_slice($items, $start, $end);
3054 }
3055 }
3056 else
3057 {
3058 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3059 return array();
3060 }
3061 }
3062}
3063
3064class SimplePie_Item
3065{
3066 var $feed;
3067 var $data = array();
3068
3069 function SimplePie_Item($feed, $data)
3070 {
3071 $this->feed = $feed;
3072 $this->data = $data;
3073 }
3074
3075 function __toString()
3076 {
3077 return md5(serialize($this->data));
3078 }
3079
3080 /**
3081 * Remove items that link back to this before destroying this object
3082 */
3083 function __destruct()
3084 {
3085 unset($this->feed);
3086 }
3087
3088 function get_item_tags($namespace, $tag)
3089 {
3090 if (isset($this->data['child'][$namespace][$tag]))
3091 {
3092 return $this->data['child'][$namespace][$tag];
3093 }
3094 else
3095 {
3096 return null;
3097 }
3098 }
3099
3100 function get_base($element = array())
3101 {
3102 return $this->feed->get_base($element);
3103 }
3104
3105 function sanitize($data, $type, $base = '')
3106 {
3107 return $this->feed->sanitize($data, $type, $base);
3108 }
3109
3110 function get_feed()
3111 {
3112 return $this->feed;
3113 }
3114
3115 function get_id($hash = false)
3116 {
3117 if (!$hash)
3118 {
3119 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3120 {
3121 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3122 }
3123 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3124 {
3125 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3126 }
3127 elseif ($return = $this->get_item_tags('', 'guid'))
3128 {
3129 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3130 }
3131 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3132 {
3133 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3134 }
3135 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3136 {
3137 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3138 }
3139 elseif (($return = $this->get_permalink()) !== null)
3140 {
3141 return $return;
3142 }
3143 elseif (($return = $this->get_title()) !== null)
3144 {
3145 return $return;
3146 }
3147 }
3148 if ($this->get_permalink() !== null || $this->get_title() !== null)
3149 {
3150 return md5($this->get_permalink() . $this->get_title());
3151 }
3152 else
3153 {
3154 return md5(serialize($this->data));
3155 }
3156 }
3157
3158 function get_title()
3159 {
3160 if (!isset($this->data['title']))
3161 {
3162 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3163 {
3164 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3165 }
3166 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3167 {
3168 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3169 }
3170 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3171 {
3172 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3173 }
3174 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3175 {
3176 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3177 }
3178 elseif ($return = $this->get_item_tags('', 'title'))
3179 {
3180 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3181 }
3182 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3183 {
3184 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3185 }
3186 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3187 {
3188 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3189 }
3190 else
3191 {
3192 $this->data['title'] = null;
3193 }
3194 }
3195 return $this->data['title'];
3196 }
3197
3198 function get_description($description_only = false)
3199 {
3200 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3201 {
3202 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3203 }
3204 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3205 {
3206 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3207 }
3208 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3209 {
3210 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3211 }
3212 elseif ($return = $this->get_item_tags('', 'description'))
3213 {
3214 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3215 }
3216 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3217 {
3218 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3219 }
3220 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3221 {
3222 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3223 }
3224 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3225 {
3226 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3227 }
3228 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3229 {
3230 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3231 }
3232 elseif (!$description_only)
3233 {
3234 return $this->get_content(true);
3235 }
3236 else
3237 {
3238 return null;
3239 }
3240 }
3241
3242 function get_content($content_only = false)
3243 {
3244 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3245 {
3246 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3247 }
3248 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3249 {
3250 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3251 }
3252 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3253 {
3254 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3255 }
3256 elseif (!$content_only)
3257 {
3258 return $this->get_description(true);
3259 }
3260 else
3261 {
3262 return null;
3263 }
3264 }
3265
3266 function get_category($key = 0)
3267 {
3268 $categories = $this->get_categories();
3269 if (isset($categories[$key]))
3270 {
3271 return $categories[$key];
3272 }
3273 else
3274 {
3275 return null;
3276 }
3277 }
3278
3279 function get_categories()
3280 {
3281 $categories = array();
3282
3283 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3284 {
3285 $term = null;
3286 $scheme = null;
3287 $label = null;
3288 if (isset($category['attribs']['']['term']))
3289 {
3290 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3291 }
3292 if (isset($category['attribs']['']['scheme']))
3293 {
3294 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3295 }
3296 if (isset($category['attribs']['']['label']))
3297 {
3298 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3299 }
3300 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
3301 }
3302 foreach ((array) $this->get_item_tags('', 'category') as $category)
3303 {
3304 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3305 }
3306 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3307 {
3308 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3309 }
3310 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3311 {
3312 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3313 }
3314
3315 if (!empty($categories))
3316 {
3317 return SimplePie_Misc::array_unique($categories);
3318 }
3319 else
3320 {
3321 return null;
3322 }
3323 }
3324
3325 function get_author($key = 0)
3326 {
3327 $authors = $this->get_authors();
3328 if (isset($authors[$key]))
3329 {
3330 return $authors[$key];
3331 }
3332 else
3333 {
3334 return null;
3335 }
3336 }
3337
3338 function get_contributor($key = 0)
3339 {
3340 $contributors = $this->get_contributors();
3341 if (isset($contributors[$key]))
3342 {
3343 return $contributors[$key];
3344 }
3345 else
3346 {
3347 return null;
3348 }
3349 }
3350
3351 function get_contributors()
3352 {
3353 $contributors = array();
3354 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3355 {
3356 $name = null;
3357 $uri = null;
3358 $email = null;
3359 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3360 {
3361 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3362 }
3363 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3364 {
3365 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
3366 }
3367 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3368 {
3369 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3370 }
3371 if ($name !== null || $email !== null || $uri !== null)
3372 {
3373 $contributors[] =& new $this->feed->author_class($name, $uri, $email);
3374 }
3375 }
3376 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3377 {
3378 $name = null;
3379 $url = null;
3380 $email = null;
3381 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3382 {
3383 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3384 }
3385 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3386 {
3387 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
3388 }
3389 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3390 {
3391 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3392 }
3393 if ($name !== null || $email !== null || $url !== null)
3394 {
3395 $contributors[] =& new $this->feed->author_class($name, $url, $email);
3396 }
3397 }
3398
3399 if (!empty($contributors))
3400 {
3401 return SimplePie_Misc::array_unique($contributors);
3402 }
3403 else
3404 {
3405 return null;
3406 }
3407 }
3408
3409 /**
3410 * @todo Atom inheritance (item author, source author, feed author)
3411 */
3412 function get_authors()
3413 {
3414 $authors = array();
3415 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3416 {
3417 $name = null;
3418 $uri = null;
3419 $email = null;
3420 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3421 {
3422 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3423 }
3424 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3425 {
3426 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
3427 }
3428 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3429 {
3430 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3431 }
3432 if ($name !== null || $email !== null || $uri !== null)
3433 {
3434 $authors[] =& new $this->feed->author_class($name, $uri, $email);
3435 }
3436 }
3437 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3438 {
3439 $name = null;
3440 $url = null;
3441 $email = null;
3442 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3443 {
3444 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3445 }
3446 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3447 {
3448 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
3449 }
3450 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3451 {
3452 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3453 }
3454 if ($name !== null || $email !== null || $url !== null)
3455 {
3456 $authors[] =& new $this->feed->author_class($name, $url, $email);
3457 }
3458 }
3459 if ($author = $this->get_item_tags('', 'author'))
3460 {
3461 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3462 }
3463 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3464 {
3465 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3466 }
3467 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3468 {
3469 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3470 }
3471 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3472 {
3473 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3474 }
3475
3476 if (!empty($authors))
3477 {
3478 return SimplePie_Misc::array_unique($authors);
3479 }
3480 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3481 {
3482 return $authors;
3483 }
3484 elseif ($authors = $this->feed->get_authors())
3485 {
3486 return $authors;
3487 }
3488 else
3489 {
3490 return null;
3491 }
3492 }
3493
3494 function get_copyright()
3495 {
3496 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3497 {
3498 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3499 }
3500 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3501 {
3502 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3503 }
3504 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3505 {
3506 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3507 }
3508 else
3509 {
3510 return null;
3511 }
3512 }
3513
3514 function get_date($date_format = 'j F Y, g:i a')
3515 {
3516 if (!isset($this->data['date']))
3517 {
3518 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3519 {
3520 $this->data['date']['raw'] = $return[0]['data'];
3521 }
3522 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3523 {
3524 $this->data['date']['raw'] = $return[0]['data'];
3525 }
3526 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3527 {
3528 $this->data['date']['raw'] = $return[0]['data'];
3529 }
3530 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3531 {
3532 $this->data['date']['raw'] = $return[0]['data'];
3533 }
3534 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3535 {
3536 $this->data['date']['raw'] = $return[0]['data'];
3537 }
3538 elseif ($return = $this->get_item_tags('', 'pubDate'))
3539 {
3540 $this->data['date']['raw'] = $return[0]['data'];
3541 }
3542 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3543 {
3544 $this->data['date']['raw'] = $return[0]['data'];
3545 }
3546 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3547 {
3548 $this->data['date']['raw'] = $return[0]['data'];
3549 }
3550
3551 if (!empty($this->data['date']['raw']))
3552 {
3553 $parser = SimplePie_Parse_Date::get();
3554 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3555 }
3556 else
3557 {
3558 $this->data['date'] = null;
3559 }
3560 }
3561 if ($this->data['date'])
3562 {
3563 $date_format = (string) $date_format;
3564 switch ($date_format)
3565 {
3566 case '':
3567 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3568
3569 case 'U':
3570 return $this->data['date']['parsed'];
3571
3572 default:
3573 return date($date_format, $this->data['date']['parsed']);
3574 }
3575 }
3576 else
3577 {
3578 return null;
3579 }
3580 }
3581
3582 function get_local_date($date_format = '%c')
3583 {
3584 if (!$date_format)
3585 {
3586 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3587 }
3588 elseif (($date = $this->get_date('U')) !== null)
3589 {
3590 return strftime($date_format, $date);
3591 }
3592 else
3593 {
3594 return null;
3595 }
3596 }
3597
3598 function get_permalink()
3599 {
3600 $link = $this->get_link();
3601 $enclosure = $this->get_enclosure(0);
3602 if ($link !== null)
3603 {
3604 return $link;
3605 }
3606 elseif ($enclosure !== null)
3607 {
3608 return $enclosure->get_link();
3609 }
3610 else
3611 {
3612 return null;
3613 }
3614 }
3615
3616 function get_link($key = 0, $rel = 'alternate')
3617 {
3618 $links = $this->get_links($rel);
3619 if ($links[$key] !== null)
3620 {
3621 return $links[$key];
3622 }
3623 else
3624 {
3625 return null;
3626 }
3627 }
3628
3629 function get_links($rel = 'alternate')
3630 {
3631 if (!isset($this->data['links']))
3632 {
3633 $this->data['links'] = array();
3634 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3635 {
3636 if (isset($link['attribs']['']['href']))
3637 {
3638 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3639 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3640
3641 }
3642 }
3643 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3644 {
3645 if (isset($link['attribs']['']['href']))
3646 {
3647 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3648 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3649 }
3650 }
3651 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3652 {
3653 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3654 }
3655 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3656 {
3657 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3658 }
3659 if ($links = $this->get_item_tags('', 'link'))
3660 {
3661 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3662 }
3663 if ($links = $this->get_item_tags('', 'guid'))
3664 {
3665 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3666 {
3667 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3668 }
3669 }
3670
3671 $keys = array_keys($this->data['links']);
3672 foreach ($keys as $key)
3673 {
3674 if (SimplePie_Misc::is_isegment_nz_nc($key))
3675 {
3676 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3677 {
3678 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3679 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3680 }
3681 else
3682 {
3683 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3684 }
3685 }
3686 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3687 {
3688 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3689 }
3690 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3691 }
3692 }
3693 if (isset($this->data['links'][$rel]))
3694 {
3695 return $this->data['links'][$rel];
3696 }
3697 else
3698 {
3699 return null;
3700 }
3701 }
3702
3703 /**
3704 * @todo Add ability to prefer one type of content over another (in a media group).
3705 */
3706 function get_enclosure($key = 0, $prefer = null)
3707 {
3708 $enclosures = $this->get_enclosures();
3709 if (isset($enclosures[$key]))
3710 {
3711 return $enclosures[$key];
3712 }
3713 else
3714 {
3715 return null;
3716 }
3717 }
3718
3719 /**
3720 * Grabs all available enclosures (podcasts, etc.)
3721 *
3722 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3723 *
3724 * At this point, we're pretty much assuming that all enclosures for an item are the same content. Anything else is too complicated to properly support.
3725 *
3726 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3727 * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists).
3728 */
3729 function get_enclosures()
3730 {
3731 if (!isset($this->data['enclosures']))
3732 {
3733 $this->data['enclosures'] = array();
3734
3735 // Elements
3736 $captions_parent = null;
3737 $categories_parent = null;
3738 $copyrights_parent = null;
3739 $credits_parent = null;
3740 $description_parent = null;
3741 $duration_parent = null;
3742 $hashes_parent = null;
3743 $keywords_parent = null;
3744 $player_parent = null;
3745 $ratings_parent = null;
3746 $restrictions_parent = null;
3747 $thumbnails_parent = null;
3748 $title_parent = null;
3749
3750 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3751 $parent = $this->get_feed();
3752
3753 // CAPTIONS
3754 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3755 {
3756 foreach ($captions as $caption)
3757 {
3758 $caption_type = null;
3759 $caption_lang = null;
3760 $caption_startTime = null;
3761 $caption_endTime = null;
3762 $caption_text = null;
3763 if (isset($caption['attribs']['']['type']))
3764 {
3765 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3766 }
3767 if (isset($caption['attribs']['']['lang']))
3768 {
3769 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3770 }
3771 if (isset($caption['attribs']['']['start']))
3772 {
3773 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3774 }
3775 if (isset($caption['attribs']['']['end']))
3776 {
3777 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3778 }
3779 if (isset($caption['data']))
3780 {
3781 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3782 }
3783 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3784 }
3785 }
3786 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3787 {
3788 foreach ($captions as $caption)
3789 {
3790 $caption_type = null;
3791 $caption_lang = null;
3792 $caption_startTime = null;
3793 $caption_endTime = null;
3794 $caption_text = null;
3795 if (isset($caption['attribs']['']['type']))
3796 {
3797 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3798 }
3799 if (isset($caption['attribs']['']['lang']))
3800 {
3801 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3802 }
3803 if (isset($caption['attribs']['']['start']))
3804 {
3805 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3806 }
3807 if (isset($caption['attribs']['']['end']))
3808 {
3809 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3810 }
3811 if (isset($caption['data']))
3812 {
3813 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3814 }
3815 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3816 }
3817 }
3818 if (is_array($captions_parent))
3819 {
3820 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3821 }
3822
3823 // CATEGORIES
3824 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3825 {
3826 $term = null;
3827 $scheme = null;
3828 $label = null;
3829 if (isset($category['data']))
3830 {
3831 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3832 }
3833 if (isset($category['attribs']['']['scheme']))
3834 {
3835 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3836 }
3837 else
3838 {
3839 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3840 }
3841 if (isset($category['attribs']['']['label']))
3842 {
3843 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3844 }
3845 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3846 }
3847 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3848 {
3849 $term = null;
3850 $scheme = null;
3851 $label = null;
3852 if (isset($category['data']))
3853 {
3854 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3855 }
3856 if (isset($category['attribs']['']['scheme']))
3857 {
3858 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3859 }
3860 else
3861 {
3862 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3863 }
3864 if (isset($category['attribs']['']['label']))
3865 {
3866 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3867 }
3868 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3869 }
3870 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3871 {
3872 $term = null;
3873 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3874 $label = null;
3875 if (isset($category['attribs']['']['text']))
3876 {
3877 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3878 }
3879 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3880
3881 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3882 {
3883 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3884 {
3885 if (isset($subcategory['attribs']['']['text']))
3886 {
3887 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3888 }
3889 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3890 }
3891 }
3892 }
3893 if (is_array($categories_parent))
3894 {
3895 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3896 }
3897
3898 // COPYRIGHT
3899 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3900 {
3901 $copyright_url = null;
3902 $copyright_label = null;
3903 if (isset($copyright[0]['attribs']['']['url']))
3904 {
3905 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3906 }
3907 if (isset($copyright[0]['data']))
3908 {
3909 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3910 }
3911 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3912 }
3913 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3914 {
3915 $copyright_url = null;
3916 $copyright_label = null;
3917 if (isset($copyright[0]['attribs']['']['url']))
3918 {
3919 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3920 }
3921 if (isset($copyright[0]['data']))
3922 {
3923 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3924 }
3925 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3926 }
3927
3928 // CREDITS
3929 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3930 {
3931 foreach ($credits as $credit)
3932 {
3933 $credit_role = null;
3934 $credit_scheme = null;
3935 $credit_name = null;
3936 if (isset($credit['attribs']['']['role']))
3937 {
3938 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3939 }
3940 if (isset($credit['attribs']['']['scheme']))
3941 {
3942 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3943 }
3944 else
3945 {
3946 $credit_scheme = 'urn:ebu';
3947 }
3948 if (isset($credit['data']))
3949 {
3950 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3951 }
3952 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3953 }
3954 }
3955 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3956 {
3957 foreach ($credits as $credit)
3958 {
3959 $credit_role = null;
3960 $credit_scheme = null;
3961 $credit_name = null;
3962 if (isset($credit['attribs']['']['role']))
3963 {
3964 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3965 }
3966 if (isset($credit['attribs']['']['scheme']))
3967 {
3968 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3969 }
3970 else
3971 {
3972 $credit_scheme = 'urn:ebu';
3973 }
3974 if (isset($credit['data']))
3975 {
3976 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3977 }
3978 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3979 }