Update copyright years
[dokuwiki.git] / inc / SimplePie.php
blob1c97e2384710de90bce8d456c8655f949a2b47c5
1 <?php
2 /**
3 * SimplePie
5 * A PHP-Based RSS and Atom Feed Framework.
6 * Takes the hard work out of managing a complete RSS/Atom solution.
8 * Copyright (c) 2004-2007, Ryan Parman and Geoffrey Sneddon
9 * All rights reserved.
11 * Redistribution and use in source and binary forms, with or without modification, are
12 * permitted provided that the following conditions are met:
14 * * Redistributions of source code must retain the above copyright notice, this list of
15 * conditions and the following disclaimer.
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.
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.
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.
35 * @package SimplePie
36 * @version "Razzleberry"
37 * @copyright 2004-2007 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
46 /**
47 * SimplePie Name
49 define('SIMPLEPIE_NAME', 'SimplePie');
51 /**
52 * SimplePie Version
54 define('SIMPLEPIE_VERSION', '1.0.1');
56 /**
57 * SimplePie Build
58 * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::parse_date() only every load of simplepie.inc)
60 define('SIMPLEPIE_BUILD', 20070719221955);
62 /**
63 * SimplePie Website URL
65 define('SIMPLEPIE_URL', 'http://simplepie.org/');
67 /**
68 * SimplePie Useragent
69 * @see SimplePie::set_useragent()
71 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
73 /**
74 * SimplePie Linkback
76 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
78 /**
79 * No Autodiscovery
80 * @see SimplePie::set_autodiscovery_level()
82 define('SIMPLEPIE_LOCATOR_NONE', 0);
84 /**
85 * Feed Link Element Autodiscovery
86 * @see SimplePie::set_autodiscovery_level()
88 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
90 /**
91 * Local Feed Extension Autodiscovery
92 * @see SimplePie::set_autodiscovery_level()
94 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
96 /**
97 * Local Feed Body Autodiscovery
98 * @see SimplePie::set_autodiscovery_level()
100 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
103 * Remote Feed Extension Autodiscovery
104 * @see SimplePie::set_autodiscovery_level()
106 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
109 * Remote Feed Body Autodiscovery
110 * @see SimplePie::set_autodiscovery_level()
112 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
115 * All Feed Autodiscovery
116 * @see SimplePie::set_autodiscovery_level()
118 define('SIMPLEPIE_LOCATOR_ALL', 31);
121 * No known feed type
123 define('SIMPLEPIE_TYPE_NONE', 0);
126 * RSS 0.90
128 define('SIMPLEPIE_TYPE_RSS_090', 1);
131 * RSS 0.91 (Netscape)
133 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
136 * RSS 0.91 (Userland)
138 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
141 * RSS 0.91 (both Netscape and Userland)
143 define('SIMPLEPIE_TYPE_RSS_091', 6);
146 * RSS 0.92
148 define('SIMPLEPIE_TYPE_RSS_092', 8);
151 * RSS 0.93
153 define('SIMPLEPIE_TYPE_RSS_093', 16);
156 * RSS 0.94
158 define('SIMPLEPIE_TYPE_RSS_094', 32);
161 * RSS 1.0
163 define('SIMPLEPIE_TYPE_RSS_10', 64);
166 * RSS 2.0
168 define('SIMPLEPIE_TYPE_RSS_20', 128);
171 * RDF-based RSS
173 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
176 * Non-RDF-based RSS (truly intended as syndication format)
178 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
181 * All RSS
183 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
186 * Atom 0.3
188 define('SIMPLEPIE_TYPE_ATOM_03', 256);
191 * Atom 1.0
193 define('SIMPLEPIE_TYPE_ATOM_10', 512);
196 * All Atom
198 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
201 * All feed types
203 define('SIMPLEPIE_TYPE_ALL', 1023);
206 * No construct
208 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
211 * Text construct
213 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
216 * HTML construct
218 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
221 * XHTML construct
223 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
226 * base64-encoded construct
228 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
231 * IRI construct
233 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
236 * A construct that might be HTML
238 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
241 * All constructs
243 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
246 * PCRE for HTML attributes
248 define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[a-z0-9\-._:]*)))?)*)\s*');
251 * PCRE for XML attributes
253 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
256 * XML Namespace
258 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
261 * Atom 1.0 Namespace
263 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
266 * Atom 0.3 Namespace
268 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
271 * RDF Namespace
273 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
276 * RSS 0.90 Namespace
278 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
281 * RSS 1.0 Namespace
283 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
286 * RSS 1.0 Content Module Namespace
288 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
291 * DC 1.0 Namespace
293 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
296 * DC 1.1 Namespace
298 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
301 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
303 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
306 * GeoRSS Namespace
308 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
311 * Media RSS Namespace
313 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
316 * iTunes RSS Namespace
318 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
321 * XHTML Namespace
323 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
326 * IANA Link Relations Registry
328 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
331 * Whether we're running on PHP5
333 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
336 * SimplePie
338 * @package SimplePie
339 * @version "Razzleberry"
340 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
341 * @author Ryan Parman
342 * @author Geoffrey Sneddon
343 * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
345 class SimplePie
348 * @var array Raw data
349 * @access private
351 var $data = array();
354 * @var mixed Error string
355 * @access private
357 var $error;
360 * @var object Instance of SimplePie_Sanitize (or other class)
361 * @see SimplePie::set_sanitize_class()
362 * @access private
364 var $sanitize;
367 * @var string SimplePie Useragent
368 * @see SimplePie::set_useragent()
369 * @access private
371 var $useragent = SIMPLEPIE_USERAGENT;
374 * @var string Feed URL
375 * @see SimplePie::set_feed_url()
376 * @access private
378 var $feed_url;
381 * @var object Instance of SimplePie_File to use as a feed
382 * @see SimplePie::set_file()
383 * @access private
385 var $file;
388 * @var string Raw feed data
389 * @see SimplePie::set_raw_data()
390 * @access private
392 var $raw_data;
395 * @var int Timeout for fetching remote files
396 * @see SimplePie::set_timeout()
397 * @access private
399 var $timeout = 10;
402 * @var bool Forces fsockopen() to be used for remote files instead
403 * of cURL, even if a new enough version is installed
404 * @see SimplePie::force_fsockopen()
405 * @access private
407 var $force_fsockopen = false;
410 * @var bool Enable/Disable XML dump
411 * @see SimplePie::enable_xml_dump()
412 * @access private
414 var $xml_dump = false;
417 * @var bool Enable/Disable Caching
418 * @see SimplePie::enable_cache()
419 * @access private
421 var $cache = true;
424 * @var int Cache duration (in seconds)
425 * @see SimplePie::set_cache_duration()
426 * @access private
428 var $cache_duration = 3600;
431 * @var int Auto-discovery cache duration (in seconds)
432 * @see SimplePie::set_autodiscovery_cache_duration()
433 * @access private
435 var $autodiscovery_cache_duration = 604800; // 7 Days.
438 * @var string Cache location (relative to executing script)
439 * @see SimplePie::set_cache_location()
440 * @access private
442 var $cache_location = './cache';
445 * @var string Function that creates the cache filename
446 * @see SimplePie::set_cache_name_function()
447 * @access private
449 var $cache_name_function = 'md5';
452 * @var bool Reorder feed by date descending
453 * @see SimplePie::enable_order_by_date()
454 * @access private
456 var $order_by_date = true;
459 * @var mixed Force input encoding to be set to the follow value
460 * (false, or anything type-cast to false, disables this feature)
461 * @see SimplePie::set_input_encoding()
462 * @access private
464 var $input_encoding = false;
467 * @var int Feed Autodiscovery Level
468 * @see SimplePie::set_autodiscovery_level()
469 * @access private
471 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
474 * @var string Class used for caching feeds
475 * @see SimplePie::set_cache_class()
476 * @access private
478 var $cache_class = 'SimplePie_Cache';
481 * @var string Class used for locating feeds
482 * @see SimplePie::set_locator_class()
483 * @access private
485 var $locator_class = 'SimplePie_Locator';
488 * @var string Class used for parsing feeds
489 * @see SimplePie::set_parser_class()
490 * @access private
492 var $parser_class = 'SimplePie_Parser';
495 * @var string Class used for fetching feeds
496 * @see SimplePie::set_file_class()
497 * @access private
499 var $file_class = 'SimplePie_File';
502 * @var string Class used for items
503 * @see SimplePie::set_item_class()
504 * @access private
506 var $item_class = 'SimplePie_Item';
509 * @var string Class used for authors
510 * @see SimplePie::set_author_class()
511 * @access private
513 var $author_class = 'SimplePie_Author';
516 * @var string Class used for categories
517 * @see SimplePie::set_category_class()
518 * @access private
520 var $category_class = 'SimplePie_Category';
523 * @var string Class used for enclosures
524 * @see SimplePie::set_enclosures_class()
525 * @access private
527 var $enclosure_class = 'SimplePie_Enclosure';
530 * @var string Class used for Media RSS <media:text> captions
531 * @see SimplePie::set_caption_class()
532 * @access private
534 var $caption_class = 'SimplePie_Caption';
537 * @var string Class used for Media RSS <media:copyright>
538 * @see SimplePie::set_copyright_class()
539 * @access private
541 var $copyright_class = 'SimplePie_Copyright';
544 * @var string Class used for Media RSS <media:credit>
545 * @see SimplePie::set_credit_class()
546 * @access private
548 var $credit_class = 'SimplePie_Credit';
551 * @var string Class used for Media RSS <media:rating>
552 * @see SimplePie::set_rating_class()
553 * @access private
555 var $rating_class = 'SimplePie_Rating';
558 * @var string Class used for Media RSS <media:restriction>
559 * @see SimplePie::set_restriction_class()
560 * @access private
562 var $restriction_class = 'SimplePie_Restriction';
565 * @var mixed Set javascript query string parameter (false, or
566 * anything type-cast to false, disables this feature)
567 * @see SimplePie::set_javascript()
568 * @access private
570 var $javascript = 'js';
573 * @var int Maximum number of feeds to check with autodiscovery
574 * @see SimplePie::set_max_checked_feeds()
575 * @access private
577 var $max_checked_feeds = 10;
580 * @var string Web-accessible path to the handler_favicon.php file.
581 * @see SimplePie::set_favicon_handler()
582 * @access private
584 var $favicon_handler = '';
587 * @var string Web-accessible path to the handler_image.php file.
588 * @see SimplePie::set_image_handler()
589 * @access private
591 var $image_handler = '';
594 * @var array Stores the URLs when multiple feeds are being initialized.
595 * @see SimplePie::set_feed_url()
596 * @access private
598 var $multifeed_url = array();
601 * @var array Stores SimplePie objects when multiple feeds initialized.
602 * @access private
604 var $multifeed_objects = array();
607 * @var array Stores the get_object_vars() array for use with multifeeds.
608 * @see SimplePie::set_feed_url()
609 * @access private
611 var $config_settings = null;
614 * @var array Stores the default attributes to be stripped by strip_attributes().
615 * @see SimplePie::strip_attributes()
616 * @access private
618 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
621 * @var array Stores the default tags to be stripped by strip_htmltags().
622 * @see SimplePie::strip_htmltags()
623 * @access private
625 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
628 * The SimplePie class contains feed level data and options
630 * There are two ways that you can create a new SimplePie object. The first
631 * is by passing a feed URL as a parameter to the SimplePie constructor
632 * (as well as optionally setting the cache location and cache expiry). This
633 * will initialise the whole feed with all of the default settings, and you
634 * can begin accessing methods and properties immediately.
636 * The second way is to create the SimplePie object with no parameters
637 * at all. This will enable you to set configuration options. After setting
638 * them, you must initialise the feed using $feed->init(). At that point the
639 * object's methods and properties will be available to you. This format is
640 * what is used throughout this documentation.
642 * @access public
643 * @since 1.0 Preview Release
644 * @param string $feed_url This is the URL you want to parse.
645 * @param string $cache_location This is where you want the cache to be stored.
646 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
648 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
650 // Other objects, instances created here so we can set options on them
651 $this->sanitize =& new SimplePie_Sanitize;
653 // Set options if they're passed to the constructor
654 if ($cache_location !== null)
656 $this->set_cache_location($cache_location);
659 if ($cache_duration !== null)
661 $this->set_cache_duration($cache_duration);
664 // Only init the script if we're passed a feed URL
665 if ($feed_url !== null)
667 $this->set_feed_url($feed_url);
668 $this->init();
673 * Used for converting object to a string
675 function __toString()
677 return md5(serialize($this->data));
681 * This is the URL of the feed you want to parse.
683 * This allows you to enter the URL of the feed you want to parse, or the
684 * website you want to try to use auto-discovery on. This takes priority
685 * over any set raw data.
687 * You can set multiple feeds to mash together by passing an array instead
688 * of a string for the $url. Remember that with each additional feed comes
689 * additional processing and resources.
691 * @access public
692 * @since 1.0 Preview Release
693 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
694 * @see SimplePie::set_raw_data()
696 function set_feed_url($url)
698 if (is_array($url))
700 $this->multifeed_url = array();
701 foreach ($url as $value)
703 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
706 else
708 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
713 * Provides an instance of SimplePie_File to use as a feed
715 * @access public
716 * @param object &$file Instance of SimplePie_File (or subclass)
717 * @return bool True on success, false on failure
719 function set_file(&$file)
721 if (SimplePie_Misc::is_a($file, 'SimplePie_File'))
723 $this->feed_url = $file->url;
724 $this->file =& $file;
725 return true;
727 return false;
731 * Allows you to use a string of RSS/Atom data instead of a remote feed.
733 * If you have a feed available as a string in PHP, you can tell SimplePie
734 * to parse that data string instead of a remote feed. Any set feed URL
735 * takes precedence.
737 * @access public
738 * @since 1.0 Beta 3
739 * @param string $data RSS or Atom data as a string.
740 * @see SimplePie::set_feed_url()
742 function set_raw_data($data)
744 $this->raw_data = trim($data);
748 * Allows you to override the default timeout for fetching remote feeds.
750 * This allows you to change the maximum time the feed's server to respond
751 * and send the feed back.
753 * @access public
754 * @since 1.0 Beta 3
755 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
757 function set_timeout($timeout = 10)
759 $this->timeout = (int) $timeout;
763 * Forces SimplePie to use fsockopen() instead of the preferred cURL
764 * functions.
766 * @access public
767 * @since 1.0 Beta 3
768 * @param bool $enable Force fsockopen() to be used
770 function force_fsockopen($enable = false)
772 $this->force_fsockopen = (bool) $enable;
776 * Outputs the raw XML content of the feed, after it has gone through
777 * SimplePie's filters.
779 * Used only for debugging, this function will output the XML content as
780 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
781 * before trying to parse it. Many parts of the feed are re-written in
782 * memory, and in the end, you have a parsable feed. XML dump shows you the
783 * actual XML that SimplePie tries to parse, which may or may not be very
784 * different from the original feed.
786 * @access public
787 * @since 1.0 Preview Release
788 * @param bool $enable Enable XML dump
790 function enable_xml_dump($enable = false)
792 $this->xml_dump = (bool) $enable;
796 * Enables/disables caching in SimplePie.
798 * This option allows you to disable caching all-together in SimplePie.
799 * However, disabling the cache can lead to longer load times.
801 * @access public
802 * @since 1.0 Preview Release
803 * @param bool $enable Enable caching
805 function enable_cache($enable = true)
807 $this->cache = (bool) $enable;
811 * Set the length of time (in seconds) that the contents of a feed
812 * will be cached.
814 * @access public
815 * @param int $seconds The feed content cache duration.
817 function set_cache_duration($seconds = 3600)
819 $this->cache_duration = (int) $seconds;
823 * Set the length of time (in seconds) that the autodiscovered feed
824 * URL will be cached.
826 * @access public
827 * @param int $seconds The autodiscovered feed URL cache duration.
829 function set_autodiscovery_cache_duration($seconds = 604800)
831 $this->autodiscovery_cache_duration = (int) $seconds;
835 * Set the file system location where the cached files should be stored.
837 * @access public
838 * @param string $location The file system location.
840 function set_cache_location($location = './cache')
842 $this->cache_location = (string) $location;
846 * Determines whether feed items should be sorted into reverse chronological order.
848 * @access public
849 * @param bool $enable Sort as reverse chronological order.
851 function enable_order_by_date($enable = true)
853 $this->order_by_date = (bool) $enable;
857 * Allows you to override the character encoding reported by the feed.
859 * @access public
860 * @param string $encoding Character encoding.
862 function set_input_encoding($encoding = false)
864 if ($encoding)
866 $this->input_encoding = (string) $encoding;
868 else
870 $this->input_encoding = false;
875 * Set how much feed autodiscovery to do
877 * @access public
878 * @see SIMPLEPIE_LOCATOR_NONE
879 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
880 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
881 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
882 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
883 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
884 * @see SIMPLEPIE_LOCATOR_ALL
885 * @param int $level Feed Autodiscovery Level (level can be a
886 * combination of the above constants, see bitwise OR operator)
888 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
890 $this->autodiscovery = (int) $level;
894 * Allows you to change which class SimplePie uses for caching.
895 * Useful when you are overloading or extending SimplePie's default classes.
897 * @access public
898 * @param string $class Name of custom class.
899 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
900 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
902 function set_cache_class($class = 'SimplePie_Cache')
904 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
906 $this->cache_class = $class;
907 return true;
909 return false;
913 * Allows you to change which class SimplePie uses for auto-discovery.
914 * Useful when you are overloading or extending SimplePie's default classes.
916 * @access public
917 * @param string $class Name of custom class.
918 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
919 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
921 function set_locator_class($class = 'SimplePie_Locator')
923 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
925 $this->locator_class = $class;
926 return true;
928 return false;
932 * Allows you to change which class SimplePie uses for XML parsing.
933 * Useful when you are overloading or extending SimplePie's default classes.
935 * @access public
936 * @param string $class Name of custom class.
937 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
938 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
940 function set_parser_class($class = 'SimplePie_Parser')
942 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
944 $this->parser_class = $class;
945 return true;
947 return false;
951 * Allows you to change which class SimplePie uses for remote file fetching.
952 * Useful when you are overloading or extending SimplePie's default classes.
954 * @access public
955 * @param string $class Name of custom class.
956 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
957 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
959 function set_file_class($class = 'SimplePie_File')
961 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
963 $this->file_class = $class;
964 return true;
966 return false;
970 * Allows you to change which class SimplePie uses for data sanitization.
971 * Useful when you are overloading or extending SimplePie's default classes.
973 * @access public
974 * @param string $class Name of custom class.
975 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
976 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
978 function set_sanitize_class($class = 'SimplePie_Sanitize')
980 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
982 $this->sanitize =& new $class;
983 return true;
985 return false;
989 * Allows you to change which class SimplePie uses for handling feed items.
990 * Useful when you are overloading or extending SimplePie's default classes.
992 * @access public
993 * @param string $class Name of custom class.
994 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
995 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
997 function set_item_class($class = 'SimplePie_Item')
999 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1001 $this->item_class = $class;
1002 return true;
1004 return false;
1008 * Allows you to change which class SimplePie uses for handling author data.
1009 * Useful when you are overloading or extending SimplePie's default classes.
1011 * @access public
1012 * @param string $class Name of custom class.
1013 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1014 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1016 function set_author_class($class = 'SimplePie_Author')
1018 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1020 $this->author_class = $class;
1021 return true;
1023 return false;
1027 * Allows you to change which class SimplePie uses for handling category data.
1028 * Useful when you are overloading or extending SimplePie's default classes.
1030 * @access public
1031 * @param string $class Name of custom class.
1032 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1033 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1035 function set_category_class($class = 'SimplePie_Category')
1037 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1039 $this->category_class = $class;
1040 return true;
1042 return false;
1046 * Allows you to change which class SimplePie uses for feed enclosures.
1047 * Useful when you are overloading or extending SimplePie's default classes.
1049 * @access public
1050 * @param string $class Name of custom class.
1051 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1052 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1054 function set_enclosure_class($class = 'SimplePie_Enclosure')
1056 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1058 $this->enclosure_class = $class;
1059 return true;
1061 return false;
1065 * Allows you to change which class SimplePie uses for <media:text> captions
1066 * Useful when you are overloading or extending SimplePie's default classes.
1068 * @access public
1069 * @param string $class Name of custom class.
1070 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1071 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1073 function set_caption_class($class = 'SimplePie_Caption')
1075 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1077 $this->caption_class = $class;
1078 return true;
1080 return false;
1084 * Allows you to change which class SimplePie uses for <media:copyright>
1085 * Useful when you are overloading or extending SimplePie's default classes.
1087 * @access public
1088 * @param string $class Name of custom class.
1089 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1090 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1092 function set_copyright_class($class = 'SimplePie_Copyright')
1094 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1096 $this->copyright_class = $class;
1097 return true;
1099 return false;
1103 * Allows you to change which class SimplePie uses for <media:credit>
1104 * Useful when you are overloading or extending SimplePie's default classes.
1106 * @access public
1107 * @param string $class Name of custom class.
1108 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1109 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1111 function set_credit_class($class = 'SimplePie_Credit')
1113 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1115 $this->credit_class = $class;
1116 return true;
1118 return false;
1122 * Allows you to change which class SimplePie uses for <media:rating>
1123 * Useful when you are overloading or extending SimplePie's default classes.
1125 * @access public
1126 * @param string $class Name of custom class.
1127 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1128 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1130 function set_rating_class($class = 'SimplePie_Rating')
1132 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1134 $this->rating_class = $class;
1135 return true;
1137 return false;
1141 * Allows you to change which class SimplePie uses for <media:restriction>
1142 * Useful when you are overloading or extending SimplePie's default classes.
1144 * @access public
1145 * @param string $class Name of custom class.
1146 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1147 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1149 function set_restriction_class($class = 'SimplePie_Restriction')
1151 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1153 $this->restriction_class = $class;
1154 return true;
1156 return false;
1160 * Allows you to override the default user agent string.
1162 * @access public
1163 * @param string $ua New user agent string.
1165 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1167 $this->useragent = (string) $ua;
1171 * Set callback function to create cache filename with
1173 * @access public
1174 * @param mixed $function Callback function
1176 function set_cache_name_function($function = 'md5')
1178 if (is_callable($function))
1180 $this->cache_name_function = $function;
1185 * Set javascript query string parameter
1187 * @access public
1188 * @param mixed $get Javascript query string parameter
1190 function set_javascript($get = 'js')
1192 if ($get)
1194 $this->javascript = (string) $get;
1196 else
1198 $this->javascript = false;
1203 * Set options to make SP as fast as possible. Forgoes a
1204 * substantial amount of data sanitization in favor of speed.
1206 * @access public
1207 * @param bool $set Whether to set them or not
1209 function set_stupidly_fast($set = false)
1211 if ($set)
1213 $this->enable_order_by_date(false);
1214 $this->remove_div(false);
1215 $this->strip_comments(false);
1216 $this->strip_htmltags(false);
1217 $this->strip_attributes(false);
1218 $this->set_image_handler(false);
1223 * Set maximum number of feeds to check with autodiscovery
1225 * @access public
1226 * @param int $max Maximum number of feeds to check
1228 function set_max_checked_feeds($max = 10)
1230 $this->max_checked_feeds = (int) $max;
1233 function remove_div($enable = true)
1235 $this->sanitize->remove_div($enable);
1238 function strip_htmltags($tags = '', $encode = null)
1240 if ($tags === '')
1242 $tags = $this->strip_htmltags;
1244 $this->sanitize->strip_htmltags($tags);
1245 if ($encode !== null)
1247 $this->sanitize->encode_instead_of_strip($tags);
1251 function encode_instead_of_strip($enable = true)
1253 $this->sanitize->encode_instead_of_strip($enable);
1256 function strip_attributes($attribs = '')
1258 if ($attribs === '')
1260 $attribs = $this->strip_attributes;
1262 $this->sanitize->strip_attributes($attribs);
1265 function set_output_encoding($encoding = 'UTF-8')
1267 $this->sanitize->set_output_encoding($encoding);
1270 function strip_comments($strip = false)
1272 $this->sanitize->strip_comments($strip);
1276 * Set element/attribute key/value pairs of HTML attributes
1277 * containing URLs that need to be resolved relative to the feed
1279 * @access public
1280 * @since 1.0
1281 * @param array $element_attribute Element/attribute key/value pairs
1283 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'))
1285 $this->sanitize->set_url_replacements($element_attribute);
1289 * Set the handler to enable the display of cached favicons.
1291 * @access public
1292 * @param str $page Web-accessible path to the handler_favicon.php file.
1293 * @param str $qs The query string that the value should be passed to.
1295 function set_favicon_handler($page = false, $qs = 'i')
1297 if ($page != false)
1299 $this->favicon_handler = $page . '?' . $qs . '=';
1301 else
1303 $this->favicon_handler = '';
1308 * Set the handler to enable the display of cached images.
1310 * @access public
1311 * @param str $page Web-accessible path to the handler_image.php file.
1312 * @param str $qs The query string that the value should be passed to.
1314 function set_image_handler($page = false, $qs = 'i')
1316 if ($page != false)
1318 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1320 else
1322 $this->image_handler = '';
1326 function init()
1328 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.1.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1330 return false;
1332 if (isset($_GET[$this->javascript]))
1334 if (function_exists('ob_gzhandler'))
1336 ob_start('ob_gzhandler');
1338 header('Content-type: text/javascript; charset: UTF-8');
1339 header('Cache-Control: must-revalidate');
1340 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1342 function embed_odeo(link) {
1343 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>');
1346 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1347 if (placeholder != '') {
1348 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>');
1350 else {
1351 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>');
1355 function embed_flash(bgcolor, width, height, link, loop, type) {
1356 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>');
1359 function embed_flv(width, height, link, placeholder, loop, player) {
1360 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>');
1363 function embed_wmedia(width, height, link) {
1364 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1366 <?php
1367 exit;
1370 // Pass whatever was set with config options over to the sanitizer.
1371 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1372 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1374 if ($this->feed_url !== null || $this->raw_data !== null)
1376 $this->data = array();
1377 $this->multifeed_objects = array();
1378 $cache = false;
1380 if ($this->feed_url !== null)
1382 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1383 // Decide whether to enable caching
1384 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1386 $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1388 // If it's enabled and we don't want an XML dump, use the cache
1389 if ($cache && !$this->xml_dump)
1391 // Load the Cache
1392 $this->data = $cache->load();
1393 if (!empty($this->data))
1395 // If the cache is for an outdated build of SimplePie
1396 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1398 $cache->unlink();
1399 $this->data = array();
1401 // If we've hit a collision just rerun it with caching disabled
1402 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1404 $cache = false;
1405 $this->data = array();
1407 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1408 elseif (isset($this->data['feed_url']))
1410 // If the autodiscovery cache is still valid use it.
1411 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1413 // Do not need to do feed autodiscovery yet.
1414 if ($this->data['feed_url'] == $this->data['url'])
1416 $cache->unlink();
1417 $this->data = array();
1419 else
1421 $this->set_feed_url($this->data['feed_url']);
1422 return $this->init();
1426 // Check if the cache has been updated
1427 elseif ($cache->mtime() + $this->cache_duration < time())
1429 // If we have last-modified and/or etag set
1430 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1432 $headers = array();
1433 if (isset($this->data['headers']['last-modified']))
1435 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1437 if (isset($this->data['headers']['etag']))
1439 $headers['if-none-match'] = $this->data['headers']['etag'];
1441 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1442 if ($file->success)
1444 if ($file->status_code == 304)
1446 $cache->touch();
1447 return true;
1449 else
1451 $headers = $file->headers;
1454 else
1456 unset($file);
1460 // If the cache is still valid, just return true
1461 else
1463 return true;
1466 // If the cache is empty, delete it
1467 else
1469 $cache->unlink();
1470 $this->data = array();
1473 // 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.
1474 if (!isset($file))
1476 if (SimplePie_Misc::is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1478 $file =& $this->file;
1480 else
1482 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1485 // If the file connection has an error, set SimplePie::error to that and quit
1486 if (!$file->success)
1488 $this->error = $file->error;
1489 if (!empty($this->data))
1491 return true;
1493 else
1495 return false;
1499 // Check if the supplied URL is a feed, if it isn't, look for it.
1500 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds);
1501 if (!$locate->is_feed($file))
1503 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1504 unset($file);
1505 if ($file = $locate->find($this->autodiscovery))
1507 if ($cache)
1509 if (!$cache->save(array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD)))
1511 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1513 $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1515 $this->feed_url = $file->url;
1517 else
1519 $this->error = "A feed could not be found at $this->feed_url";
1520 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1521 return false;
1524 $locate = null;
1526 $headers = $file->headers;
1527 $data = trim($file->body);
1528 unset($file);
1530 else
1532 $data = $this->raw_data;
1535 // First check to see if input has been overridden.
1536 if ($this->input_encoding !== false)
1538 $encoding = $this->input_encoding;
1540 // Second try HTTP headers
1541 elseif (isset($headers['content-type']) && preg_match('/;[\x09\x20]*charset=([^;]*)/i', $headers['content-type'], $charset))
1543 $encoding = $charset[1];
1545 // Then prolog, if at the very start of the document
1546 elseif (preg_match("/^<\?xml[\x20\x9\xD\xA]+version([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"1.0\"|'1.0'|\"1.1\"|'1.1')[\x20\x9\xD\xA]+encoding([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"[A-Za-z][A-Za-z0-9._\-]*\"|'[A-Za-z][A-Za-z0-9._\-]*')([\x20\x9\xD\xA]+standalone([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"(yes|no)\"|'(yes|no)'))?([\x20\x9\xD\xA]+)?\?>/", $data, $prolog))
1548 $encoding = substr($prolog[6], 1, -1);
1550 // UTF-32 Big Endian BOM
1551 elseif (strpos($data, "\x0\x0\xFE\xFF") === 0)
1553 $encoding = 'UTF-32be';
1555 // UTF-32 Little Endian BOM
1556 elseif (strpos($data, "\xFF\xFE\x0\x0") === 0)
1558 $encoding = 'UTF-32';
1560 // UTF-16 Big Endian BOM
1561 elseif (strpos($data, "\xFE\xFF") === 0)
1563 $encoding = 'UTF-16be';
1565 // UTF-16 Little Endian BOM
1566 elseif (strpos($data, "\xFF\xFE") === 0)
1568 $encoding = 'UTF-16le';
1570 // UTF-8 BOM
1571 elseif (strpos($data, "\xEF\xBB\xBF") === 0)
1573 $encoding = 'UTF-8';
1575 // Fallback to the default (US-ASCII for text/xml, ISO-8859-1 for text/* MIME types, UTF-8 otherwise)
1576 elseif (isset($headers['content-type']) && strtolower(SimplePie_Misc::parse_mime($headers['content-type'])) == 'text/xml')
1578 $encoding = 'US-ASCII';
1580 elseif (isset($headers['content-type']) && SimplePie_Misc::stripos(SimplePie_Misc::parse_mime($headers['content-type']), 'text/') === 0)
1582 $encoding = 'ISO-8859-1';
1584 else
1586 $encoding = 'UTF-8';
1589 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1590 if ($encoding != 'UTF-8')
1592 $data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8');
1595 // Strip illegal characters
1596 $data = SimplePie_Misc::utf8_bad_replace($data);
1598 $parser =& new $this->parser_class();
1599 $parser->pre_process($data, 'UTF-8');
1600 // If we want the XML, just output that and quit
1601 if ($this->xml_dump)
1603 header('Content-type: text/xml; charset=UTF-8');
1604 echo $data;
1605 exit;
1607 // If it's parsed fine
1608 elseif ($parser->parse($data))
1610 unset($data);
1611 $this->data = $parser->get_data();
1612 if (isset($this->data['child']))
1614 if (isset($headers))
1616 $this->data['headers'] = $headers;
1618 $this->data['build'] = SIMPLEPIE_BUILD;
1620 // Cache the file if caching is enabled
1621 if ($cache && !$cache->save($this->data))
1623 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1625 return true;
1627 else
1629 $this->error = "A feed could not be found at $this->feed_url";
1630 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1631 return false;
1634 // If we have an error, just set SimplePie::error to it and quit
1635 else
1637 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1638 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1639 return false;
1642 elseif (!empty($this->multifeed_url))
1644 $i = 0;
1645 $success = 0;
1646 $this->multifeed_objects = array();
1647 foreach ($this->multifeed_url as $url)
1649 if (SIMPLEPIE_PHP5)
1651 // This keyword needs to defy coding standards for PHP4 compatibility
1652 $this->multifeed_objects[$i] = clone($this);
1654 else
1656 $this->multifeed_objects[$i] = $this;
1658 $this->multifeed_objects[$i]->set_feed_url($url);
1659 $success |= $this->multifeed_objects[$i]->init();
1660 $i++;
1662 return (bool) $success;
1664 else
1666 return false;
1671 * Return the error message for the occured error
1673 * @access public
1674 * @return string Error message
1676 function error()
1678 return $this->error;
1681 function get_encoding()
1683 return $this->sanitize->output_encoding;
1686 function handle_content_type($mime = 'text/html')
1688 if (!headers_sent())
1690 $header = "Content-type: $mime;";
1691 if ($this->get_encoding())
1693 $header .= ' charset=' . $this->get_encoding();
1695 else
1697 $header .= ' charset=UTF-8';
1699 header($header);
1703 function get_type()
1705 if (!isset($this->data['type']))
1707 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1708 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1710 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1712 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1714 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1716 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1718 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1719 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1720 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1721 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1723 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1725 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1726 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1727 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1728 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1730 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1733 elseif (isset($this->data['child']['']['rss']))
1735 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1736 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1738 switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1740 case '0.91':
1741 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1742 if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1744 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1746 case '0':
1747 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1748 break;
1750 case '24':
1751 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1752 break;
1755 break;
1757 case '0.92':
1758 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1759 break;
1761 case '0.93':
1762 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1763 break;
1765 case '0.94':
1766 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1767 break;
1769 case '2.0':
1770 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1771 break;
1775 else
1777 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1780 return $this->data['type'];
1784 * Returns the URL for the favicon of the feed's website.
1786 * @access public
1787 * @since 1.0
1789 function get_favicon()
1791 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1793 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1795 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1797 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1799 if ($this->cache && $this->favicon_handler)
1801 $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $favicon), 'spi');
1803 if ($cache->load())
1805 return $this->sanitize($this->favicon_handler . rawurlencode($favicon), SIMPLEPIE_CONSTRUCT_IRI);
1807 else
1809 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1811 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1813 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1815 return $this->sanitize($this->favicon_handler . rawurlencode($favicon), SIMPLEPIE_CONSTRUCT_IRI);
1817 else
1819 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1820 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1825 else
1827 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1830 return false;
1834 * @todo If we have a perm redirect we should return the new URL
1835 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1836 * @todo Also, |atom:link|@rel=self
1838 function subscribe_url()
1840 if ($this->feed_url !== null)
1842 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1844 else
1846 return null;
1850 function subscribe_feed()
1852 if ($this->feed_url !== null)
1854 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
1856 else
1858 return null;
1862 function subscribe_outlook()
1864 if ($this->feed_url !== null)
1866 return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
1868 else
1870 return null;
1874 function subscribe_podcast()
1876 if ($this->feed_url !== null)
1878 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
1880 else
1882 return null;
1886 function subscribe_itunes()
1888 if ($this->feed_url !== null)
1890 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
1892 else
1894 return null;
1899 * Creates the subscribe_* methods' return data
1901 * @access private
1902 * @param string $feed_url String to prefix to the feed URL
1903 * @param string $site_url String to prefix to the site URL (and
1904 * suffix to the feed URL)
1905 * @return mixed URL if feed exists, false otherwise
1907 function subscribe_service($feed_url, $site_url = null)
1909 if ($this->subscribe_url())
1911 $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->subscribe_url());
1912 if ($site_url !== null && $this->get_link() !== null)
1914 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
1916 return $return;
1918 else
1920 return null;
1924 function subscribe_aol()
1926 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
1929 function subscribe_bloglines()
1931 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
1934 function subscribe_eskobo()
1936 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
1939 function subscribe_feedfeeds()
1941 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
1944 function subscribe_feedster()
1946 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
1949 function subscribe_google()
1951 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
1954 function subscribe_gritwire()
1956 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
1959 function subscribe_msn()
1961 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
1964 function subscribe_netvibes()
1966 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
1969 function subscribe_newsburst()
1971 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
1974 function subscribe_newsgator()
1976 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
1979 function subscribe_odeo()
1981 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
1984 function subscribe_podnova()
1986 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
1989 function subscribe_rojo()
1991 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
1994 function subscribe_yahoo()
1996 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
1999 function get_feed_tags($namespace, $tag)
2001 $type = $this->get_type();
2002 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2004 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2006 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2009 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2011 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2013 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2016 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2018 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2020 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2023 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2025 if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2027 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2030 return null;
2033 function get_channel_tags($namespace, $tag)
2035 $type = $this->get_type();
2036 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2038 if ($return = $this->get_feed_tags($namespace, $tag))
2040 return $return;
2043 if ($type & SIMPLEPIE_TYPE_RSS_10)
2045 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2047 if (isset($channel[0]['child'][$namespace][$tag]))
2049 return $channel[0]['child'][$namespace][$tag];
2053 if ($type & SIMPLEPIE_TYPE_RSS_090)
2055 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2057 if (isset($channel[0]['child'][$namespace][$tag]))
2059 return $channel[0]['child'][$namespace][$tag];
2063 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2065 if ($channel = $this->get_feed_tags('', 'channel'))
2067 if (isset($channel[0]['child'][$namespace][$tag]))
2069 return $channel[0]['child'][$namespace][$tag];
2073 return null;
2076 function get_image_tags($namespace, $tag)
2078 $type = $this->get_type();
2079 if ($type & SIMPLEPIE_TYPE_RSS_10)
2081 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2083 if (isset($image[0]['child'][$namespace][$tag]))
2085 return $image[0]['child'][$namespace][$tag];
2089 if ($type & SIMPLEPIE_TYPE_RSS_090)
2091 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2093 if (isset($image[0]['child'][$namespace][$tag]))
2095 return $image[0]['child'][$namespace][$tag];
2099 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2101 if ($image = $this->get_channel_tags('', 'image'))
2103 if (isset($image[0]['child'][$namespace][$tag]))
2105 return $image[0]['child'][$namespace][$tag];
2109 return null;
2112 function get_base($element = array())
2114 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2116 return $element['xml_base'];
2118 elseif ($this->get_link() !== null)
2120 return $this->get_link();
2122 elseif (isset($this->data['headers']['content-location']))
2124 return SimplePie_Misc::absolutize_url($this->data['headers']['content-location'], $this->subscribe_url());
2126 else
2128 return $this->subscribe_url();
2132 function sanitize($data, $type, $base = '')
2134 return $this->sanitize->sanitize($data, $type, $base);
2137 function get_title()
2139 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2141 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2143 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2145 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2147 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2149 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2151 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2153 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2155 elseif ($return = $this->get_channel_tags('', 'title'))
2157 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2159 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2161 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2163 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2165 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2167 else
2169 return null;
2173 function get_link($key = 0, $rel = 'alternate')
2175 $links = $this->get_links($rel);
2176 if (isset($links[$key]))
2178 return $links[$key];
2180 else
2182 return null;
2187 * Added for parity between the parent-level and the item/entry-level.
2189 function get_permalink()
2191 return $this->get_link(0);
2194 function get_links($rel = 'alternate')
2196 if (!isset($this->data['links']))
2198 $this->data['links'] = array();
2199 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2201 foreach ($links as $link)
2203 if (isset($link['attribs']['']['href']))
2205 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2206 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2210 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2212 foreach ($links as $link)
2214 if (isset($link['attribs']['']['href']))
2216 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2217 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2222 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2224 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2226 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2228 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2230 if ($links = $this->get_channel_tags('', 'link'))
2232 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2235 $keys = array_keys($this->data['links']);
2236 foreach ($keys as $key)
2238 if (SimplePie_Misc::is_isegment_nz_nc($key))
2240 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2242 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2243 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2245 else
2247 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2250 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2252 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2254 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2258 if (isset($this->data['links'][$rel]))
2260 return $this->data['links'][$rel];
2262 else
2264 return null;
2268 function get_description()
2270 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2272 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2274 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2276 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2278 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2280 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2282 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2284 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2286 elseif ($return = $this->get_channel_tags('', 'description'))
2288 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2290 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2292 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2294 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2296 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2298 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2300 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2302 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2304 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2306 else
2308 return null;
2312 function get_copyright()
2314 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2316 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2318 elseif ($return = $this->get_channel_tags('', 'copyright'))
2320 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2322 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2324 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2326 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2328 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2330 else
2332 return null;
2336 function get_language()
2338 if ($return = $this->get_channel_tags('', 'language'))
2340 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2342 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2344 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2346 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2348 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2350 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2352 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2354 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2356 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2358 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2360 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2362 elseif (isset($this->data['headers']['content-language']))
2364 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2366 else
2368 return null;
2372 function get_latitude()
2374 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2376 return (float) $return[0]['data'];
2378 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2380 return (float) $match[1];
2382 else
2384 return null;
2388 function get_longitude()
2390 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2392 return (float) $return[0]['data'];
2394 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2396 return (float) $return[0]['data'];
2398 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2400 return (float) $match[2];
2402 else
2404 return null;
2408 function get_image_title()
2410 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2412 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2414 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2416 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2418 elseif ($return = $this->get_image_tags('', 'title'))
2420 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2422 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2424 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2426 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2428 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2430 else
2432 return null;
2436 function get_image_url()
2438 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2440 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2442 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2444 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2446 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2448 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2450 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2452 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2454 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2456 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2458 elseif ($return = $this->get_image_tags('', 'url'))
2460 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2462 else
2464 return null;
2468 function get_image_link()
2470 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2472 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2474 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2476 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2478 elseif ($return = $this->get_image_tags('', 'link'))
2480 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2482 else
2484 return null;
2488 function get_image_width()
2490 if ($return = $this->get_image_tags('', 'width'))
2492 return round($return[0]['data']);
2494 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2496 return 88.0;
2498 else
2500 return null;
2504 function get_image_height()
2506 if ($return = $this->get_image_tags('', 'height'))
2508 return round($return[0]['data']);
2510 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2512 return 31.0;
2514 else
2516 return null;
2520 function get_item_quantity($max = 0)
2522 $qty = count($this->get_items());
2523 if ($max == 0)
2525 return $qty;
2527 else
2529 return ($qty > $max) ? $max : $qty;
2533 function get_item($key = 0)
2535 $items = $this->get_items();
2536 if (isset($items[$key]))
2538 return $items[$key];
2540 else
2542 return null;
2546 function get_items($start = 0, $end = 0)
2548 if (!empty($this->multifeed_objects))
2550 return SimplePie::merge_items($this->multifeed_objects, $start, $end);
2552 elseif (!isset($this->data['items']))
2554 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2556 $keys = array_keys($items);
2557 foreach ($keys as $key)
2559 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2562 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2564 $keys = array_keys($items);
2565 foreach ($keys as $key)
2567 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2570 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2572 $keys = array_keys($items);
2573 foreach ($keys as $key)
2575 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2578 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2580 $keys = array_keys($items);
2581 foreach ($keys as $key)
2583 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2586 if ($items = $this->get_channel_tags('', 'item'))
2588 $keys = array_keys($items);
2589 foreach ($keys as $key)
2591 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2596 if (!empty($this->data['items']))
2598 // If we want to order it by date, check if all items have a date, and then sort it
2599 if ($this->order_by_date)
2601 if (!isset($this->data['ordered_items']))
2603 $do_sort = true;
2604 foreach ($this->data['items'] as $item)
2606 if (!$item->get_date('U'))
2608 $do_sort = false;
2609 break;
2612 $item = null;
2613 $this->data['ordered_items'] = $this->data['items'];
2614 if ($do_sort)
2616 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2619 $items = $this->data['ordered_items'];
2621 else
2623 $items = $this->data['items'];
2626 // Slice the data as desired
2627 if ($end == 0)
2629 return array_slice($items, $start);
2631 else
2633 return array_slice($items, $start, $end);
2636 else
2638 return array();
2642 function sort_items($a, $b)
2644 return $a->get_date('U') <= $b->get_date('U');
2647 function merge_items($urls, $start = 0, $end = 0)
2649 if (is_array($urls) && sizeof($urls) > 0)
2651 $items = array();
2652 foreach ($urls as $arg)
2654 if (SimplePie_Misc::is_a($arg, 'SimplePie'))
2656 $items = array_merge($items, $arg->get_items());
2658 else
2660 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
2664 $do_sort = true;
2665 foreach ($items as $item)
2667 if (!$item->get_date('U'))
2669 $do_sort = false;
2670 break;
2673 $item = null;
2674 if ($do_sort)
2676 usort($items, array('SimplePie', 'sort_items'));
2679 if ($end == 0)
2681 return array_slice($items, $start);
2683 else
2685 return array_slice($items, $start, $end);
2688 else
2690 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
2691 return array();
2696 class SimplePie_Item
2698 var $feed;
2699 var $data = array();
2701 function SimplePie_Item($feed, $data)
2703 $this->feed = $feed;
2704 $this->data = $data;
2707 function __toString()
2709 return md5(serialize($this->data));
2712 function get_item_tags($namespace, $tag)
2714 if (isset($this->data['child'][$namespace][$tag]))
2716 return $this->data['child'][$namespace][$tag];
2718 else
2720 return null;
2724 function get_base($element = array())
2726 return $this->feed->get_base($element);
2729 function sanitize($data, $type, $base = '')
2731 return $this->feed->sanitize($data, $type, $base);
2734 function get_feed()
2736 return $this->feed;
2739 function get_id($hash = false)
2741 if ($hash)
2743 return $this->__toString();
2745 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
2747 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2749 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
2751 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2753 elseif ($return = $this->get_item_tags('', 'guid'))
2755 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2757 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
2759 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2761 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
2763 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2765 elseif (($return = $this->get_permalink()) !== null)
2767 return $return;
2769 elseif (($return = $this->get_title()) !== null)
2771 return $return;
2773 else
2775 return $this->__toString();
2779 function get_title()
2781 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2783 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2785 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2787 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2789 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2791 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2793 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2795 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2797 elseif ($return = $this->get_item_tags('', 'title'))
2799 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2801 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2803 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2805 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2807 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2809 else
2811 return null;
2815 function get_description($description_only = false)
2817 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
2819 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2821 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
2823 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2825 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2827 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2829 elseif ($return = $this->get_item_tags('', 'description'))
2831 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2833 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2835 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2837 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2839 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2841 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2843 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2845 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2847 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2849 elseif (!$description_only)
2851 return $this->get_content(true);
2853 else
2855 return null;
2859 function get_content($content_only = false)
2861 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
2863 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2865 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
2867 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2869 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
2871 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2873 elseif (!$content_only)
2875 return $this->get_description(true);
2877 else
2879 return null;
2883 function get_category($key = 0)
2885 $categories = $this->get_categories();
2886 if (isset($categories[$key]))
2888 return $categories[$key];
2890 else
2892 return null;
2896 function get_categories()
2898 $categories = array();
2900 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2902 $term = null;
2903 $scheme = null;
2904 $label = null;
2905 if (isset($category['attribs']['']['term']))
2907 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2909 if (isset($category['attribs']['']['scheme']))
2911 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2913 if (isset($category['attribs']['']['label']))
2915 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2917 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
2919 foreach ((array) $this->get_item_tags('', 'category') as $category)
2921 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2923 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2925 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2927 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2929 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2932 if (!empty($categories))
2934 return SimplePie_Misc::array_unique($categories);
2936 else
2938 return null;
2942 function get_author($key = 0)
2944 $authors = $this->get_authors();
2945 if (isset($authors[$key]))
2947 return $authors[$key];
2949 else
2951 return null;
2956 * @todo Atom inheritance (item author, source author, feed author)
2958 function get_authors()
2960 $authors = array();
2961 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2963 $name = null;
2964 $uri = null;
2965 $email = null;
2966 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2968 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2970 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2972 $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]));
2974 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2976 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2978 if ($name !== null || $email !== null || $uri !== null)
2980 $authors[] =& new $this->feed->author_class($name, $uri, $email);
2983 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2985 $name = null;
2986 $url = null;
2987 $email = null;
2988 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2990 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2992 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2994 $uri = $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]));
2996 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2998 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3000 if ($name !== null || $email !== null || $uri !== null)
3002 $authors[] =& new $this->feed->author_class($name, $url, $email);
3005 if ($author = $this->get_item_tags('', 'author'))
3007 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3009 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3011 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3013 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3015 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3017 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3019 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3022 if (!empty($authors))
3024 return SimplePie_Misc::array_unique($authors);
3026 else
3028 return null;
3032 function get_date($date_format = 'j F Y, g:i a')
3034 if (!isset($this->data['date']))
3036 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3038 $this->data['date']['raw'] = $return[0]['data'];
3040 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3042 $this->data['date']['raw'] = $return[0]['data'];
3044 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3046 $this->data['date']['raw'] = $return[0]['data'];
3048 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3050 $this->data['date']['raw'] = $return[0]['data'];
3052 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3054 $this->data['date']['raw'] = $return[0]['data'];
3056 elseif ($return = $this->get_item_tags('', 'pubDate'))
3058 $this->data['date']['raw'] = $return[0]['data'];
3060 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3062 $this->data['date']['raw'] = $return[0]['data'];
3064 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3066 $this->data['date']['raw'] = $return[0]['data'];
3069 if (!empty($this->data['date']['raw']))
3071 $this->data['date']['parsed'] = SimplePie_Misc::parse_date($this->data['date']['raw']);
3073 else
3075 $this->data['date'] = null;
3078 if ($this->data['date'])
3080 $date_format = (string) $date_format;
3081 switch ($date_format)
3083 case '':
3084 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3086 case 'U':
3087 return $this->data['date']['parsed'];
3089 default:
3090 return date($date_format, $this->data['date']['parsed']);
3093 else
3095 return null;
3099 function get_local_date($date_format = '%c')
3101 if (!$date_format)
3103 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3105 elseif (($date = $this->get_date('U')) !== null)
3107 return strftime($date_format, $date);
3109 else
3111 return null;
3115 function get_permalink()
3117 $link = $this->get_link();
3118 $enclosure = $this->get_enclosure(0);
3119 if ($link !== null)
3121 return $link;
3123 elseif ($enclosure !== null)
3125 return $enclosure->get_link();
3127 else
3129 return null;
3133 function get_link($key = 0, $rel = 'alternate')
3135 $links = $this->get_links($rel);
3136 if ($links[$key] !== null)
3138 return $links[$key];
3140 else
3142 return null;
3146 function get_links($rel = 'alternate')
3148 if (!isset($this->data['links']))
3150 $this->data['links'] = array();
3151 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3153 if (isset($link['attribs']['']['href']))
3155 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3156 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3160 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3162 if (isset($link['attribs']['']['href']))
3164 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3165 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3168 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3170 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3172 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3174 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3176 if ($links = $this->get_item_tags('', 'link'))
3178 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3180 if ($links = $this->get_item_tags('', 'guid'))
3182 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3184 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3188 $keys = array_keys($this->data['links']);
3189 foreach ($keys as $key)
3191 if (SimplePie_Misc::is_isegment_nz_nc($key))
3193 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3195 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3196 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3198 else
3200 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3203 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3205 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3207 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3210 if (isset($this->data['links'][$rel]))
3212 return $this->data['links'][$rel];
3214 else
3216 return null;
3221 * @todo Add ability to prefer one type of content over another (in a media group).
3223 function get_enclosure($key = 0, $prefer = null)
3225 $enclosures = $this->get_enclosures();
3226 if (isset($enclosures[$key]))
3228 return $enclosures[$key];
3230 else
3232 return null;
3237 * Grabs all available enclosures (podcasts, etc.)
3239 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3241 * 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.
3243 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3244 * @todo Add support for itunes: tags. These should be relatively simple compared to media:.
3245 * @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).
3247 function get_enclosures()
3249 if (!isset($this->data['enclosures']))
3251 $this->data['enclosures'] = array();
3253 // Elements
3254 $captions_parent = null;
3255 $categories_parent = null;
3256 $copyrights_parent = null;
3257 $credits_parent = null;
3258 $description_parent = null;
3259 $duration_parent = null;
3260 $hashes_parent = null;
3261 $keywords_parent = null;
3262 $player_parent = null;
3263 $ratings_parent = null;
3264 $restrictions_parent = null;
3265 $thumbnails_parent = null;
3266 $title_parent = null;
3268 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3269 $parent = $this->get_feed();
3271 // CAPTIONS
3272 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3274 foreach ($captions as $caption)
3276 $caption_type = null;
3277 $caption_lang = null;
3278 $caption_startTime = null;
3279 $caption_endTime = null;
3280 $caption_text = null;
3281 if (isset($caption['attribs']['']['type']))
3283 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3285 if (isset($caption['attribs']['']['lang']))
3287 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3289 if (isset($caption['attribs']['']['start']))
3291 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3293 if (isset($caption['attribs']['']['end']))
3295 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3297 if (isset($caption['data']))
3299 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3301 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3304 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3306 foreach ($captions as $caption)
3308 $caption_type = null;
3309 $caption_lang = null;
3310 $caption_startTime = null;
3311 $caption_endTime = null;
3312 $caption_text = null;
3313 if (isset($caption['attribs']['']['type']))
3315 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3317 if (isset($caption['attribs']['']['lang']))
3319 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3321 if (isset($caption['attribs']['']['start']))
3323 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3325 if (isset($caption['attribs']['']['end']))
3327 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3329 if (isset($caption['data']))
3331 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3333 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3336 if (is_array($captions_parent))
3338 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3341 // CATEGORIES
3342 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3344 $term = null;
3345 $scheme = null;
3346 $label = null;
3347 if (isset($category['data']))
3349 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3351 if (isset($category['attribs']['']['scheme']))
3353 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3355 else
3357 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3359 if (isset($category['attribs']['']['label']))
3361 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3363 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3365 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3367 $term = null;
3368 $scheme = null;
3369 $label = null;
3370 if (isset($category['data']))
3372 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3374 if (isset($category['attribs']['']['scheme']))
3376 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3378 else
3380 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3382 if (isset($category['attribs']['']['label']))
3384 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3386 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3388 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3390 $term = null;
3391 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3392 $label = null;
3393 if (isset($category['attribs']['']['text']))
3395 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3397 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3399 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3401 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3403 if (isset($subcategory['attribs']['']['text']))
3405 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3407 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3411 if (is_array($categories_parent))
3413 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3416 // COPYRIGHT
3417 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3419 $copyright_url = null;
3420 $copyright_label = null;
3421 if (isset($copyright[0]['attribs']['']['url']))
3423 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3425 if (isset($copyright[0]['data']))
3427 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3429 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3431 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3433 $copyright_url = null;
3434 $copyright_label = null;
3435 if (isset($copyright[0]['attribs']['']['url']))
3437 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3439 if (isset($copyright[0]['data']))
3441 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3443 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3446 // CREDITS
3447 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3449 foreach ($credits as $credit)
3451 $credit_role = null;
3452 $credit_scheme = null;
3453 $credit_name = null;
3454 if (isset($credit['attribs']['']['role']))
3456 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3458 if (isset($credit['attribs']['']['scheme']))
3460 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3462 else
3464 $credit_scheme = 'urn:ebu';
3466 if (isset($credit['data']))
3468 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3470 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3473 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3475 foreach ($credits as $credit)
3477 $credit_role = null;
3478 $credit_scheme = null;
3479 $credit_name = null;
3480 if (isset($credit['attribs']['']['role']))
3482 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3484 if (isset($credit['attribs']['']['scheme']))
3486 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3488 else
3490 $credit_scheme = 'urn:ebu';
3492 if (isset($credit['data']))
3494 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3496 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3499 if (is_array($credits_parent))
3501 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3504 // DESCRIPTION
3505 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3507 if (isset($description_parent[0]['data']))
3509 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3512 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3514 if (isset($description_parent[0]['data']))
3516 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3520 // DURATION
3521 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
3523 $seconds = null;
3524 $minutes = null;
3525 $hours = null;
3526 if (isset($duration_parent[0]['data']))
3528 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3529 if (sizeof($temp) > 0)
3531 (int) $seconds = array_pop($temp);
3533 if (sizeof($temp) > 0)
3535 (int) $minutes = array_pop($temp);
3536 $seconds += $minutes * 60;
3538 if (sizeof($temp) > 0)
3540 (int) $hours = array_pop($temp);
3541 $seconds += $hours * 3600;
3543 unset($temp);
3544 $duration_parent = $seconds;
3548 // HASHES
3549 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
3551 foreach ($hashes_iterator as $hash)
3553 $value = null;
3554 $algo = null;
3555 if (isset($hash['data']))
3557 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3559 if (isset($hash['attribs']['']['algo']))
3561 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
3563 else
3565 $algo = 'md5';
3567 $hashes_parent[] = $algo.':'.$value;
3570 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
3572 foreach ($hashes_iterator as $hash)
3574 $value = null;
3575 $algo = null;
3576 if (isset($hash['data']))
3578 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3580 if (isset($hash['attribs']['']['algo']))
3582 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
3584 else
3586 $algo = 'md5';
3588 $hashes_parent[] = $algo.':'.$value;
3591 if (is_array($hashes_parent))
3593 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
3596 // KEYWORDS
3597 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
3599 if (isset($keywords[0]['data']))
3601 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3602 foreach ($temp as $word)
3604 $keywords_parent[] = trim($word);
3607 unset($temp);
3609 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
3611 if (isset($keywords[0]['data']))
3613 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3614 foreach ($temp as $word)
3616 $keywords_parent[] = trim($word);
3619 unset($temp);
3621 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
3623 if (isset($keywords[0]['data']))
3625 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3626 foreach ($temp as $word)
3628 $keywords_parent[] = trim($word);
3631 unset($temp);
3633 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
3635 if (isset($keywords[0]['data']))
3637 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3638 foreach ($temp as $word)
3640 $keywords_parent[] = trim($word);
3643 unset($temp);
3645 if (is_array($keywords_parent))
3647 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
3650 // PLAYER
3651 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
3653 if (isset($player_parent[0]['attribs']['']['url']))
3655 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3658 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
3660 if (isset($player_parent[0]['attribs']['']['url']))
3662 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3666 // RATINGS
3667 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
3669 foreach ($ratings as $rating)
3671 $rating_scheme = null;
3672 $rating_value = null;
3673 if (isset($rating['attribs']['']['scheme']))
3675 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3677 else
3679 $rating_scheme = 'urn:simple';
3681 if (isset($rating['data']))
3683 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3685 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3688 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
3690 foreach ($ratings as $rating)
3692 $rating_scheme = 'urn:itunes';
3693 $rating_value = null;
3694 if (isset($rating['data']))
3696 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3698 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3701 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
3703 foreach ($ratings as $rating)
3705 $rating_scheme = null;
3706 $rating_value = null;
3707 if (isset($rating['attribs']['']['scheme']))
3709 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3711 else
3713 $rating_scheme = 'urn:simple';
3715 if (isset($rating['data']))
3717 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3719 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3722 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
3724 foreach ($ratings as $rating)
3726 $rating_scheme = 'urn:itunes';
3727 $rating_value = null;
3728 if (isset($rating['data']))
3730 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3732 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3735 if (is_array($ratings_parent))
3737 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
3740 // RESTRICTIONS
3741 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
3743 foreach ($restrictions as $restriction)
3745 $restriction_relationship = null;
3746 $restriction_type = null;
3747 $restriction_value = null;
3748 if (isset($restriction['attribs']['']['relationship']))
3750 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
3752 if (isset($restriction['attribs']['']['type']))
3754 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3756 if (isset($restriction['data']))
3758 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3760 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3763 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
3765 foreach ($restrictions as $restriction)
3767 $restriction_relationship = 'allow';
3768 $restriction_type = null;
3769 $restriction_value = 'itunes';
3770 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
3772 $restriction_relationship = 'deny';
3774 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3777 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
3779 foreach ($restrictions as $restriction)
3781 $restriction_relationship = null;
3782 $restriction_type = null;
3783 $restriction_value = null;
3784 if (isset($restriction['attribs']['']['relationship']))
3786 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
3788 if (isset($restriction['attribs']['']['type']))
3790 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3792 if (isset($restriction['data']))
3794 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3796 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3799 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
3801 foreach ($restrictions as $restriction)
3803 $restriction_relationship = 'allow';
3804 $restriction_type = null;
3805 $restriction_value = 'itunes';
3806 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
3808 $restriction_relationship = 'deny';
3810 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3813 if (is_array($restrictions_parent))
3815 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
3818 // THUMBNAILS
3819 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
3821 foreach ($thumbnails as $thumbnail)
3823 if (isset($thumbnail['attribs']['']['url']))
3825 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3829 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
3831 foreach ($thumbnails as $thumbnail)
3833 if (isset($thumbnail['attribs']['']['url']))
3835 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3840 // TITLES
3841 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
3843 if (isset($title_parent[0]['data']))
3845 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3848 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
3850 if (isset($title_parent[0]['data']))
3852 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3856 // Clear the memory
3857 unset($parent);
3859 // If we have media:group tags, loop through them.
3860 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
3862 // If we have media:content tags, loop through them.
3863 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
3865 if (isset($content['attribs']['']['url']))
3867 // Attributes
3868 $bitrate = null;
3869 $channels = null;
3870 $duration = null;
3871 $expression = null;
3872 $framerate = null;
3873 $height = null;
3874 $javascript = null;
3875 $lang = null;
3876 $length = null;
3877 $medium = null;
3878 $samplingrate = null;
3879 $type = null;
3880 $url = null;
3881 $width = null;
3883 // Elements
3884 $captions = null;
3885 $categories = null;
3886 $copyrights = null;
3887 $credits = null;
3888 $description = null;
3889 $hashes = null;
3890 $keywords = null;
3891 $player = null;
3892 $ratings = null;
3893 $restrictions = null;
3894 $thumbnails = null;
3895 $title = null;
3897 // Start checking the attributes of media:content
3898 if (isset($content['attribs']['']['bitrate']))
3900 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
3902 if (isset($content['attribs']['']['channels']))
3904 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
3906 if (isset($content['attribs']['']['duration']))
3908 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
3910 else
3912 $duration = $duration_parent;
3914 if (isset($content['attribs']['']['expression']))
3916 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
3918 if (isset($content['attribs']['']['framerate']))
3920 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
3922 if (isset($content['attribs']['']['height']))
3924 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
3926 if (isset($content['attribs']['']['lang']))
3928 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3930 if (isset($content['attribs']['']['fileSize']))
3932 $length = ceil($content['attribs']['']['fileSize']);
3934 if (isset($content['attribs']['']['medium']))
3936 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
3938 if (isset($content['attribs']['']['samplingrate']))
3940 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
3942 if (isset($content['attribs']['']['type']))
3944 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3946 if (isset($content['attribs']['']['width']))
3948 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
3950 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3952 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
3954 // CAPTIONS
3955 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
3957 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
3959 $caption_type = null;
3960 $caption_lang = null;
3961 $caption_startTime = null;
3962 $caption_endTime = null;
3963 $caption_text = null;
3964 if (isset($caption['attribs']['']['type']))
3966 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3968 if (isset($caption['attribs']['']['lang']))
3970 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3972 if (isset($caption['attribs']['']['start']))
3974 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3976 if (isset($caption['attribs']['']['end']))
3978 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3980 if (isset($caption['data']))
3982 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3984 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3986 if (is_array($captions))
3988 $captions = array_values(SimplePie_Misc::array_unique($captions));
3991 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
3993 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
3995 $caption_type = null;
3996 $caption_lang = null;
3997 $caption_startTime = null;
3998 $caption_endTime = null;
3999 $caption_text = null;
4000 if (isset($caption['attribs']['']['type']))
4002 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4004 if (isset($caption['attribs']['']['lang']))
4006 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4008 if (isset($caption['attribs']['']['start']))
4010 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4012 if (isset($caption['attribs']['']['end']))
4014 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4016 if (isset($caption['data']))
4018 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4020 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4022 if (is_array($captions))
4024 $captions = array_values(SimplePie_Misc::array_unique($captions));
4027 else
4029 $captions = $captions_parent;
4032 // CATEGORIES
4033 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4035 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4037 $term = null;
4038 $scheme = null;
4039 $label = null;
4040 if (isset($category['data']))
4042 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4044 if (isset($category['attribs']['']['scheme']))
4046 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4048 else
4050 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4052 if (isset($category['attribs']['']['label']))
4054 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4056 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4059 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4061 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4063 $term = null;
4064 $scheme = null;
4065 $label = null;
4066 if (isset($category['data']))
4068 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4070 if (isset($category['attribs']['']['scheme']))
4072 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4074 else
4076 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4078 if (isset($category['attribs']['']['label']))
4080 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4082 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4085 if (is_array($categories) && is_array($categories_parent))
4087 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4089 elseif (is_array($categories))
4091 $categories = array_values(SimplePie_Misc::array_unique($categories));
4093 elseif (is_array($categories_parent))
4095 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4098 // COPYRIGHTS
4099 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4101 $copyright_url = null;
4102 $copyright_label = null;
4103 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4105 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4107 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4109 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4111 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4113 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4115 $copyright_url = null;
4116 $copyright_label = null;
4117 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4119 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4121 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4123 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4125 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4127 else
4129 $copyrights = $copyrights_parent;
4132 // CREDITS
4133 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4135 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4137 $credit_role = null;
4138 $credit_scheme = null;
4139 $credit_name = null;
4140 if (isset($credit['attribs']['']['role']))
4142 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4144 if (isset($credit['attribs']['']['scheme']))
4146 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4148 else
4150 $credit_scheme = 'urn:ebu';
4152 if (isset($credit['data']))
4154 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4156 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4158 if (is_array($credits))
4160 $credits = array_values(SimplePie_Misc::array_unique($credits));
4163 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4165 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4167 $credit_role = null;
4168 $credit_scheme = null;
4169 $credit_name = null;
4170 if (isset($credit['attribs']['']['role']))
4172 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4174 if (isset($credit['attribs']['']['scheme']))
4176 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4178 else
4180 $credit_scheme = 'urn:ebu';
4182 if (isset($credit['data']))
4184 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4186 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4188 if (is_array($credits))
4190 $credits = array_values(SimplePie_Misc::array_unique($credits));
4193 else
4195 $credits = $credits_parent;
4198 // DESCRIPTION
4199 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4201 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4203 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4205 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4207 else
4209 $description = $description_parent;
4212 // HASHES
4213 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4215 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4217 $value = null;
4218 $algo = null;
4219 if (isset($hash['data']))
4221 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4223 if (isset($hash['attribs']['']['algo']))
4225 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4227 else
4229 $algo = 'md5';
4231 $hashes[] = $algo.':'.$value;
4233 if (is_array($hashes))
4235 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4238 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4240 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4242 $value = null;
4243 $algo = null;
4244 if (isset($hash['data']))
4246 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4248 if (isset($hash['attribs']['']['algo']))
4250 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4252 else
4254 $algo = 'md5';
4256 $hashes[] = $algo.':'.$value;
4258 if (is_array($hashes))
4260 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4263 else
4265 $hashes = $hashes_parent;
4268 // KEYWORDS
4269 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4271 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4273 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4274 foreach ($temp as $word)
4276 $keywords[] = trim($word);
4278 unset($temp);
4280 if (is_array($keywords))
4282 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4285 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4287 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4289 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4290 foreach ($temp as $word)
4292 $keywords[] = trim($word);
4294 unset($temp);
4296 if (is_array($keywords))
4298 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4301 else
4303 $keywords = $keywords_parent;
4306 // PLAYER
4307 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4309 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4311 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4313 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4315 else
4317 $player = $player_parent;
4320 // RATINGS
4321 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4323 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4325 $rating_scheme = null;
4326 $rating_value = null;
4327 if (isset($rating['attribs']['']['scheme']))
4329 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4331 else
4333 $rating_scheme = 'urn:simple';
4335 if (isset($rating['data']))
4337 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4339 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4341 if (is_array($ratings))
4343 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4346 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4348 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4350 $rating_scheme = null;
4351 $rating_value = null;
4352 if (isset($rating['attribs']['']['scheme']))
4354 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4356 else
4358 $rating_scheme = 'urn:simple';
4360 if (isset($rating['data']))
4362 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4364 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4366 if (is_array($ratings))
4368 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4371 else
4373 $ratings = $ratings_parent;
4376 // RESTRICTIONS
4377 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4379 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4381 $restriction_relationship = null;
4382 $restriction_type = null;
4383 $restriction_value = null;
4384 if (isset($restriction['attribs']['']['relationship']))
4386 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4388 if (isset($restriction['attribs']['']['type']))
4390 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4392 if (isset($restriction['data']))
4394 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4396 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4398 if (is_array($restrictions))
4400 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4403 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4405 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4407 $restriction_relationship = null;
4408 $restriction_type = null;
4409 $restriction_value = null;
4410 if (isset($restriction['attribs']['']['relationship']))
4412 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4414 if (isset($restriction['attribs']['']['type']))
4416 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4418 if (isset($restriction['data']))
4420 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4422 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4424 if (is_array($restrictions))
4426 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4429 else
4431 $restrictions = $restrictions_parent;
4434 // THUMBNAILS
4435 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4437 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4439 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4441 if (is_array($thumbnails))
4443 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4446 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4448 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4450 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4452 if (is_array($thumbnails))
4454 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4457 else
4459 $thumbnails = $thumbnails_parent;
4462 // TITLES
4463 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4465 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4467 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4469 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4471 else
4473 $title = $title_parent;
4476 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
4481 // If we have standalone media:content tags, loop through them.
4482 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4484 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4486 if (isset($content['attribs']['']['url']))
4488 // Attributes
4489 $bitrate = null;
4490 $channels = null;
4491 $duration = null;
4492 $expression = null;
4493 $framerate = null;
4494 $height = null;
4495 $javascript = null;
4496 $lang = null;
4497 $length = null;
4498 $medium = null;
4499 $samplingrate = null;
4500 $type = null;
4501 $url = null;
4502 $width = null;
4504 // Elements
4505 $captions = null;
4506 $categories = null;
4507 $copyrights = null;
4508 $credits = null;
4509 $description = null;
4510 $hashes = null;
4511 $keywords = null;
4512 $player = null;
4513 $ratings = null;
4514 $restrictions = null;
4515 $thumbnails = null;
4516 $title = null;
4518 // Start checking the attributes of media:content
4519 if (isset($content['attribs']['']['bitrate']))
4521 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4523 if (isset($content['attribs']['']['channels']))
4525 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4527 if (isset($content['attribs']['']['duration']))
4529 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4531 else
4533 $duration = $duration_parent;
4535 if (isset($content['attribs']['']['expression']))
4537 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4539 if (isset($content['attribs']['']['framerate']))
4541 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4543 if (isset($content['attribs']['']['height']))
4545 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4547 if (isset($content['attribs']['']['lang']))
4549 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4551 if (isset($content['attribs']['']['fileSize']))
4553 $length = ceil($content['attribs']['']['fileSize']);
4555 if (isset($content['attribs']['']['medium']))
4557 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4559 if (isset($content['attribs']['']['samplingrate']))
4561 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4563 if (isset($content['attribs']['']['type']))
4565 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4567 if (isset($content['attribs']['']['width']))
4569 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4571 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4573 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4575 // CAPTIONS
4576 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4578 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4580 $caption_type = null;
4581 $caption_lang = null;
4582 $caption_startTime = null;
4583 $caption_endTime = null;
4584 $caption_text = null;
4585 if (isset($caption['attribs']['']['type']))
4587 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4589 if (isset($caption['attribs']['']['lang']))
4591 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4593 if (isset($caption['attribs']['']['start']))
4595 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4597 if (isset($caption['attribs']['']['end']))
4599 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4601 if (isset($caption['data']))
4603 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4605 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4607 if (is_array($captions))
4609 $captions = array_values(SimplePie_Misc::array_unique($captions));
4612 else
4614 $captions = $captions_parent;
4617 // CATEGORIES
4618 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4620 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4622 $term = null;
4623 $scheme = null;
4624 $label = null;
4625 if (isset($category['data']))
4627 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4629 if (isset($category['attribs']['']['scheme']))
4631 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4633 else
4635 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4637 if (isset($category['attribs']['']['label']))
4639 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4641 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4644 if (is_array($categories) && is_array($categories_parent))
4646 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4648 elseif (is_array($categories))
4650 $categories = array_values(SimplePie_Misc::array_unique($categories));
4652 elseif (is_array($categories_parent))
4654 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4656 else
4658 $categories = null;
4661 // COPYRIGHTS
4662 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4664 $copyright_url = null;
4665 $copyright_label = null;
4666 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4668 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4670 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4672 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4674 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4676 else
4678 $copyrights = $copyrights_parent;
4681 // CREDITS
4682 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4684 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4686 $credit_role = null;
4687 $credit_scheme = null;
4688 $credit_name = null;
4689 if (isset($credit['attribs']['']['role']))
4691 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4693 if (isset($credit['attribs']['']['scheme']))
4695 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4697 else
4699 $credit_scheme = 'urn:ebu';
4701 if (isset($credit['data']))
4703 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4705 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4707 if (is_array($credits))
4709 $credits = array_values(SimplePie_Misc::array_unique($credits));
4712 else
4714 $credits = $credits_parent;
4717 // DESCRIPTION
4718 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4720 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4722 else
4724 $description = $description_parent;
4727 // HASHES
4728 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4730 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4732 $value = null;
4733 $algo = null;
4734 if (isset($hash['data']))
4736 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4738 if (isset($hash['attribs']['']['algo']))
4740 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4742 else
4744 $algo = 'md5';
4746 $hashes[] = $algo.':'.$value;
4748 if (is_array($hashes))
4750 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4753 else
4755 $hashes = $hashes_parent;
4758 // KEYWORDS
4759 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4761 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4763 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4764 foreach ($temp as $word)
4766 $keywords[] = trim($word);
4768 unset($temp);
4770 if (is_array($keywords))
4772 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4775 else
4777 $keywords = $keywords_parent;
4780 // PLAYER
4781 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4783 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4785 else
4787 $player = $player_parent;
4790 // RATINGS
4791 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4793 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4795 $rating_scheme = null;
4796 $rating_value = null;
4797 if (isset($rating['attribs']['']['scheme']))
4799 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4801 else
4803 $rating_scheme = 'urn:simple';
4805 if (isset($rating['data']))
4807 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4809 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4811 if (is_array($ratings))
4813 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4816 else
4818 $ratings = $ratings_parent;
4821 // RESTRICTIONS
4822 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4824 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4826 $restriction_relationship = null;
4827 $restriction_type = null;
4828 $restriction_value = null;
4829 if (isset($restriction['attribs']['']['relationship']))
4831 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4833 if (isset($restriction['attribs']['']['type']))
4835 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4837 if (isset($restriction['data']))
4839 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4841 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4843 if (is_array($restrictions))
4845 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4848 else
4850 $restrictions = $restrictions_parent;
4853 // THUMBNAILS
4854 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4856 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4858 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4860 if (is_array($thumbnails))
4862 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4865 else
4867 $thumbnails = $thumbnails_parent;
4870 // TITLES
4871 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4873 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4875 else
4877 $title = $title_parent;
4880 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
4885 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
4887 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
4889 // Attributes
4890 $bitrate = null;
4891 $channels = null;
4892 $duration = null;
4893 $expression = null;
4894 $framerate = null;
4895 $height = null;
4896 $javascript = null;
4897 $lang = null;
4898 $length = null;
4899 $medium = null;
4900 $samplingrate = null;
4901 $type = null;
4902 $url = null;
4903 $width = null;
4905 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
4906 if (isset($link['attribs']['']['type']))
4908 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4910 if (isset($link['attribs']['']['length']))
4912 $length = ceil($link['attribs']['']['length']);
4915 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
4916 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
4920 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
4922 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
4924 // Attributes
4925 $bitrate = null;
4926 $channels = null;
4927 $duration = null;
4928 $expression = null;
4929 $framerate = null;
4930 $height = null;
4931 $javascript = null;
4932 $lang = null;
4933 $length = null;
4934 $medium = null;
4935 $samplingrate = null;
4936 $type = null;
4937 $url = null;
4938 $width = null;
4940 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
4941 if (isset($link['attribs']['']['type']))
4943 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4945 if (isset($link['attribs']['']['length']))
4947 $length = ceil($link['attribs']['']['length']);
4950 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
4951 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
4955 if ($enclosure = $this->get_item_tags('', 'enclosure'))
4957 if (isset($enclosure[0]['attribs']['']['url']))
4959 // Attributes
4960 $bitrate = null;
4961 $channels = null;
4962 $duration = null;
4963 $expression = null;
4964 $framerate = null;
4965 $height = null;
4966 $javascript = null;
4967 $lang = null;
4968 $length = null;
4969 $medium = null;
4970 $samplingrate = null;
4971 $type = null;
4972 $url = null;
4973 $width = null;
4975 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
4976 if (isset($enclosure[0]['attribs']['']['type']))
4978 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4980 if (isset($enclosure[0]['attribs']['']['length']))
4982 $length = ceil($enclosure[0]['attribs']['']['length']);
4985 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
4986 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
4989 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
4991 if (!empty($this->data['enclosures']))
4993 return $this->data['enclosures'];
4995 else
4997 return null;
5001 function get_latitude()
5003 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5005 return (float) $return[0]['data'];
5007 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5009 return (float) $match[1];
5011 else
5013 return null;
5017 function get_longitude()
5019 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5021 return (float) $return[0]['data'];
5023 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5025 return (float) $return[0]['data'];
5027 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5029 return (float) $match[2];
5031 else
5033 return null;
5038 * Creates the add_to_* methods' return data
5040 * @access private
5041 * @param string $item_url String to prefix to the item permalink
5042 * @param string $title_url String to prefix to the item title
5043 * (and suffix to the item permalink)
5044 * @return mixed URL if feed exists, false otherwise
5046 function add_to_service($item_url, $title_url = null)
5048 if ($this->get_permalink() !== null)
5050 $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5051 if ($title_url !== null && $this->get_title() !== null)
5053 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5055 return $return;
5057 else
5059 return null;
5063 function add_to_blinklist()
5065 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5068 function add_to_blogmarks()
5070 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5073 function add_to_delicious()
5075 return $this->add_to_service('http://del.icio.us/post/?v=3&url=', '&title=');
5078 function add_to_digg()
5080 return $this->add_to_service('http://digg.com/submit?phase=2&URL=');
5083 function add_to_furl()
5085 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5088 function add_to_magnolia()
5090 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5093 function add_to_myweb20()
5095 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5098 function add_to_newsvine()
5100 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5103 function add_to_reddit()
5105 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5108 function add_to_segnalo()
5110 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5113 function add_to_simpy()
5115 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5118 function add_to_spurl()
5120 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5123 function add_to_wists()
5125 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5128 function search_technorati()
5130 return $this->add_to_service('http://www.technorati.com/search/');
5134 class SimplePie_Author
5136 var $name;
5137 var $link;
5138 var $email;
5140 // Constructor, used to input the data
5141 function SimplePie_Author($name = null, $link = null, $email = null)
5143 $this->name = $name;
5144 $this->link = $link;
5145 $this->email = $email;
5148 function __toString()
5150 // There is no $this->data here
5151 return md5(serialize($this));
5154 function get_name()
5156 if ($this->name !== null)
5158 return $this->name;
5160 else
5162 return null;
5166 function get_link()
5168 if ($this->link !== null)
5170 return $this->link;
5172 else
5174 return null;
5178 function get_email()
5180 if ($this->email !== null)
5182 return $this->email;
5184 else
5186 return null;
5191 class SimplePie_Category
5193 var $term;
5194 var $scheme;
5195 var $label;
5197 // Constructor, used to input the data
5198 function SimplePie_Category($term = null, $scheme = null, $label = null)
5200 $this->term = $term;
5201 $this->scheme = $scheme;
5202 $this->label = $label;
5205 function __toString()
5207 // There is no $this->data here
5208 return md5(serialize($this));
5211 function get_term()
5213 if ($this->term !== null)
5215 return $this->term;
5217 else
5219 return null;
5223 function get_scheme()
5225 if ($this->scheme !== null)
5227 return $this->scheme;
5229 else
5231 return null;
5235 function get_label()
5237 if ($this->label !== null)
5239 return $this->label;
5241 else
5243 return $this->get_term();
5248 class SimplePie_Enclosure
5250 var $bitrate;
5251 var $captions;
5252 var $categories;
5253 var $channels;
5254 var $copyright;
5255 var $credits;
5256 var $description;
5257 var $duration;
5258 var $expression;
5259 var $framerate;
5260 var $handler;
5261 var $hashes;
5262 var $height;
5263 var $javascript;
5264 var $keywords;
5265 var $lang;
5266 var $length;
5267 var $link;
5268 var $medium;
5269 var $player;
5270 var $ratings;
5271 var $restrictions;
5272 var $samplingrate;
5273 var $thumbnails;
5274 var $title;
5275 var $type;
5276 var $width;
5278 // Constructor, used to input the data
5279 function SimplePie_Enclosure($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)
5281 $this->bitrate = $bitrate;
5282 $this->captions = $captions;
5283 $this->categories = $categories;
5284 $this->channels = $channels;
5285 $this->copyright = $copyright;
5286 $this->credits = $credits;
5287 $this->description = $description;
5288 $this->duration = $duration;
5289 $this->expression = $expression;
5290 $this->framerate = $framerate;
5291 $this->hashes = $hashes;
5292 $this->height = $height;
5293 $this->javascript = $javascript;
5294 $this->keywords = $keywords;
5295 $this->lang = $lang;
5296 $this->length = $length;
5297 $this->link = $link;
5298 $this->medium = $medium;
5299 $this->player = $player;
5300 $this->ratings = $ratings;
5301 $this->restrictions = $restrictions;
5302 $this->samplingrate = $samplingrate;
5303 $this->thumbnails = $thumbnails;
5304 $this->title = $title;
5305 $this->type = $type;
5306 $this->width = $width;
5307 if (class_exists('idna_convert'))
5309 $idn =& new idna_convert;
5310 $parsed = SimplePie_Misc::parse_url($link);
5311 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
5313 $this->handler = $this->get_handler(); // Needs to load last
5316 function __toString()
5318 // There is no $this->data here
5319 return md5(serialize($this));
5322 function get_bitrate()
5324 if ($this->bitrate !== null)
5326 return $this->bitrate;
5328 else
5330 return null;
5334 function get_caption($key = 0)
5336 $captions = $this->get_captions();
5337 if (isset($captions[$key]))
5339 return $captions[$key];
5341 else
5343 return null;
5347 function get_captions()
5349 if ($this->captions !== null)
5351 return $this->captions;
5353 else
5355 return null;
5359 function get_category($key = 0)
5361 $categories = $this->get_categories();
5362 if (isset($categories[$key]))
5364 return $categories[$key];
5366 else
5368 return null;
5372 function get_categories()
5374 if ($this->categories !== null)
5376 return $this->categories;
5378 else
5380 return null;
5384 function get_channels()
5386 if ($this->channels !== null)
5388 return $this->channels;
5390 else
5392 return null;
5396 function get_copyright()
5398 if ($this->copyright !== null)
5400 return $this->copyright;
5402 else
5404 return null;
5408 function get_credit($key = 0)
5410 $credits = $this->get_credits();
5411 if (isset($credits[$key]))
5413 return $credits[$key];
5415 else
5417 return null;
5421 function get_credits()
5423 if ($this->credits !== null)
5425 return $this->credits;
5427 else
5429 return null;
5433 function get_description()
5435 if ($this->description !== null)
5437 return $this->description;
5439 else
5441 return null;
5445 function get_duration($convert = false)
5447 if ($this->duration !== null)
5449 if ($convert)
5451 $time = SimplePie_Misc::time_hms($this->duration);
5452 return $time;
5454 else
5456 return $this->duration;
5459 else
5461 return null;
5465 function get_expression()
5467 if ($this->expression !== null)
5469 return $this->expression;
5471 else
5473 return 'full';
5477 function get_extension()
5479 if ($this->link !== null)
5481 $url = SimplePie_Misc::parse_url($this->link);
5482 if ($url['path'] !== '')
5484 return pathinfo($url['path'], PATHINFO_EXTENSION);
5487 return null;
5490 function get_framerate()
5492 if ($this->framerate !== null)
5494 return $this->framerate;
5496 else
5498 return null;
5502 function get_handler()
5504 return $this->get_real_type(true);
5507 function get_hash($key = 0)
5509 $hashes = $this->get_hashes();
5510 if (isset($hashes[$key]))
5512 return $hashes[$key];
5514 else
5516 return null;
5520 function get_hashes()
5522 if ($this->hashes !== null)
5524 return $this->hashes;
5526 else
5528 return null;
5532 function get_height()
5534 if ($this->height !== null)
5536 return $this->height;
5538 else
5540 return null;
5544 function get_language()
5546 if ($this->lang !== null)
5548 return $this->lang;
5550 else
5552 return null;
5556 function get_keyword($key = 0)
5558 $keywords = $this->get_keywords();
5559 if (isset($keywords[$key]))
5561 return $keywords[$key];
5563 else
5565 return null;
5569 function get_keywords()
5571 if ($this->keywords !== null)
5573 return $this->keywords;
5575 else
5577 return null;
5581 function get_length()
5583 if ($this->length !== null)
5585 return $this->length;
5587 else
5589 return null;
5593 function get_link()
5595 if ($this->link !== null)
5597 return urldecode($this->link);
5599 else
5601 return null;
5605 function get_medium()
5607 if ($this->medium !== null)
5609 return $this->medium;
5611 else
5613 return null;
5617 function get_player()
5619 if ($this->player !== null)
5621 return $this->player;
5623 else
5625 return null;
5629 function get_rating($key = 0)
5631 $ratings = $this->get_ratings();
5632 if (isset($ratings[$key]))
5634 return $ratings[$key];
5636 else
5638 return null;
5642 function get_ratings()
5644 if ($this->ratings !== null)
5646 return $this->ratings;
5648 else
5650 return null;
5654 function get_restriction($key = 0)
5656 $restrictions = $this->get_restrictions();
5657 if (isset($restrictions[$key]))
5659 return $restrictions[$key];
5661 else
5663 return null;
5667 function get_restrictions()
5669 if ($this->restrictions !== null)
5671 return $this->restrictions;
5673 else
5675 return null;
5679 function get_sampling_rate()
5681 if ($this->samplingrate !== null)
5683 return $this->samplingrate;
5685 else
5687 return null;
5691 function get_size()
5693 $length = $this->get_length();
5694 if ($length !== null)
5696 return round($length/1048576, 2);
5698 else
5700 return null;
5704 function get_thumbnail($key = 0)
5706 $thumbnails = $this->get_thumbnails();
5707 if (isset($thumbnails[$key]))
5709 return $thumbnails[$key];
5711 else
5713 return null;
5717 function get_thumbnails()
5719 if ($this->thumbnails !== null)
5721 return $this->thumbnails;
5723 else
5725 return null;
5729 function get_title()
5731 if ($this->title !== null)
5733 return $this->title;
5735 else
5737 return null;
5741 function get_type()
5743 if ($this->type !== null)
5745 return $this->type;
5747 else
5749 return null;
5753 function get_width()
5755 if ($this->width !== null)
5757 return $this->width;
5759 else
5761 return null;
5765 function native_embed($options='')
5767 return $this->embed($options, true);
5771 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
5773 function embed($options = '', $native = false)
5775 // Set up defaults
5776 $audio = '';
5777 $video = '';
5778 $alt = '';
5779 $altclass = '';
5780 $loop = 'false';
5781 $width = 'auto';
5782 $height = 'auto';
5783 $bgcolor = '#ffffff';
5784 $mediaplayer = '';
5785 $widescreen = false;
5786 $handler = $this->get_handler();
5787 $type = $this->get_real_type();
5789 // Process options and reassign values as necessary
5790 if (is_array($options))
5792 extract($options);
5794 else
5796 $options = explode(',', $options);
5797 foreach($options as $option)
5799 $opt = explode(':', $option, 2);
5800 if (isset($opt[0], $opt[1]))
5802 $opt[0] = trim($opt[0]);
5803 $opt[1] = trim($opt[1]);
5804 switch ($opt[0])
5806 case 'audio':
5807 $audio = $opt[1];
5808 break;
5810 case 'video':
5811 $video = $opt[1];
5812 break;
5814 case 'alt':
5815 $alt = $opt[1];
5816 break;
5818 case 'altclass':
5819 $altclass = $opt[1];
5820 break;
5822 case 'loop':
5823 $loop = $opt[1];
5824 break;
5826 case 'width':
5827 $width = $opt[1];
5828 break;
5830 case 'height':
5831 $height = $opt[1];
5832 break;
5834 case 'bgcolor':
5835 $bgcolor = $opt[1];
5836 break;
5838 case 'mediaplayer':
5839 $mediaplayer = $opt[1];
5840 break;
5842 case 'widescreen':
5843 $widescreen = $opt[1];
5844 break;
5850 $mime = explode('/', $type, 2);
5851 $mime = $mime[0];
5853 // Process values for 'auto'
5854 if ($width == 'auto')
5856 if ($mime == 'video')
5858 if ($height == 'auto')
5860 $width = 480;
5862 elseif ($widescreen)
5864 $width = round((intval($height)/9)*16);
5866 else
5868 $width = round((intval($height)/3)*4);
5871 else
5873 $width = '100%';
5877 if ($height == 'auto')
5879 if ($mime == 'audio')
5881 $height = 0;
5883 elseif ($mime == 'video')
5885 if ($width == 'auto')
5887 if ($widescreen)
5889 $height = 270;
5891 else
5893 $height = 360;
5896 elseif ($widescreen)
5898 $height = round((intval($width)/16)*9);
5900 else
5902 $height = round((intval($width)/4)*3);
5905 else
5907 $height = 376;
5910 elseif ($mime == 'audio')
5912 $height = 0;
5915 // Set proper placeholder value
5916 if ($mime == 'audio')
5918 $placeholder = $audio;
5920 elseif ($mime == 'video')
5922 $placeholder = $video;
5925 $embed = '';
5927 // Make sure the JS library is included
5928 if (!$native)
5930 static $javascript_outputted = null;
5931 if (!$javascript_outputted && $this->javascript)
5933 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
5934 $javascript_outputted = true;
5938 // Odeo Feed MP3's
5939 if ($handler == 'odeo')
5941 if ($native)
5943 $embed .= '<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://adobe.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=' . $this->get_link() . '"></embed>';
5945 else
5947 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
5951 // Flash
5952 elseif ($handler == 'flash')
5954 if ($native)
5956 $embed .= "<embed src=\"" . $this->get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\"></embed>";
5958 else
5960 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
5964 // Flash Media Player file types.
5965 // Preferred handler for MP3 file types.
5966 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
5968 $height += 20;
5969 if ($native)
5971 $embed .= "<embed src=\"$mediaplayer\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" quality=\"high\" width=\"$width\" height=\"$height\" wmode=\"transparent\" flashvars=\"file=" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\"></embed>";
5973 else
5975 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
5979 // QuickTime 7 file types. Need to test with QuickTime 6.
5980 // Only handle MP3's if the Flash Media Player is not present.
5981 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
5983 $height += 16;
5984 if ($native)
5986 if ($placeholder != ""){
5987 $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" href=\"" . $this->get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
5989 else {
5990 $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" src=\"" . $this->get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
5993 else
5995 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
5999 // Windows Media
6000 elseif ($handler == 'wmedia')
6002 $height += 45;
6003 if ($native)
6005 $embed .= "<embed type=\"application/x-mplayer2\" src=\"" . $this->get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\"></embed>";
6007 else
6009 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
6013 // Everything else
6014 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
6016 return $embed;
6019 function get_real_type($find_handler = false)
6021 // If it's Odeo, let's get it out of the way.
6022 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
6024 return 'odeo';
6027 // Mime-types by handler.
6028 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
6029 $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
6030 $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime
6031 $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media
6032 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
6034 if ($this->get_type() !== null)
6036 $type = strtolower($this->type);
6038 else
6040 $type = null;
6043 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
6044 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
6046 switch (strtolower($this->get_extension()))
6048 // Audio mime-types
6049 case 'aac':
6050 case 'adts':
6051 $type = 'audio/acc';
6052 break;
6054 case 'aif':
6055 case 'aifc':
6056 case 'aiff':
6057 case 'cdda':
6058 $type = 'audio/aiff';
6059 break;
6061 case 'bwf':
6062 $type = 'audio/wav';
6063 break;
6065 case 'kar':
6066 case 'mid':
6067 case 'midi':
6068 case 'smf':
6069 $type = 'audio/midi';
6070 break;
6072 case 'm4a':
6073 $type = 'audio/x-m4a';
6074 break;
6076 case 'mp3':
6077 case 'swa':
6078 $type = 'audio/mp3';
6079 break;
6081 case 'wav':
6082 $type = 'audio/wav';
6083 break;
6085 case 'wax':
6086 $type = 'audio/x-ms-wax';
6087 break;
6089 case 'wma':
6090 $type = 'audio/x-ms-wma';
6091 break;
6093 // Video mime-types
6094 case '3gp':
6095 case '3gpp':
6096 $type = 'video/3gpp';
6097 break;
6099 case '3g2':
6100 case '3gp2':
6101 $type = 'video/3gpp2';
6102 break;
6104 case 'asf':
6105 $type = 'video/x-ms-asf';
6106 break;
6108 case 'flv':
6109 $type = 'video/x-flv';
6110 break;
6112 case 'm1a':
6113 case 'm1s':
6114 case 'm1v':
6115 case 'm15':
6116 case 'm75':
6117 case 'mp2':
6118 case 'mpa':
6119 case 'mpeg':
6120 case 'mpg':
6121 case 'mpm':
6122 case 'mpv':
6123 $type = 'video/mpeg';
6124 break;
6126 case 'm4v':
6127 $type = 'video/x-m4v';
6128 break;
6130 case 'mov':
6131 case 'qt':
6132 $type = 'video/quicktime';
6133 break;
6135 case 'mp4':
6136 case 'mpg4':
6137 $type = 'video/mp4';
6138 break;
6140 case 'sdv':
6141 $type = 'video/sd-video';
6142 break;
6144 case 'wm':
6145 $type = 'video/x-ms-wm';
6146 break;
6148 case 'wmv':
6149 $type = 'video/x-ms-wmv';
6150 break;
6152 case 'wvx':
6153 $type = 'video/x-ms-wvx';
6154 break;
6156 // Flash mime-types
6157 case 'spl':
6158 $type = 'application/futuresplash';
6159 break;
6161 case 'swf':
6162 $type = 'application/x-shockwave-flash';
6163 break;
6167 if ($find_handler)
6169 if (in_array($type, $types_flash))
6171 return 'flash';
6173 elseif (in_array($type, $types_fmedia))
6175 return 'fmedia';
6177 elseif (in_array($type, $types_quicktime))
6179 return 'quicktime';
6181 elseif (in_array($type, $types_wmedia))
6183 return 'wmedia';
6185 elseif (in_array($type, $types_mp3))
6187 return 'mp3';
6189 else
6191 return null;
6194 else
6196 return $type;
6201 class SimplePie_Caption
6203 var $type;
6204 var $lang;
6205 var $startTime;
6206 var $endTime;
6207 var $text;
6209 // Constructor, used to input the data
6210 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
6212 $this->type = $type;
6213 $this->lang = $lang;
6214 $this->startTime = $startTime;
6215 $this->endTime = $endTime;
6216 $this->text = $text;
6219 function __toString()
6221 // There is no $this->data here
6222 return md5(serialize($this));
6225 function get_endtime()
6227 if ($this->endTime !== null)
6229 return $this->endTime;
6231 else
6233 return null;
6237 function get_language()
6239 if ($this->language !== null)
6241 return $this->language;
6243 else
6245 return null;
6249 function get_starttime()
6251 if ($this->startTime !== null)
6253 return $this->startTime;
6255 else
6257 return null;
6261 function get_text()
6263 if ($this->text !== null)
6265 return $this->text;
6267 else
6269 return null;
6273 function get_type()
6275 if ($this->type !== null)
6277 return $this->type;
6279 else
6281 return null;
6286 class SimplePie_Credit
6288 var $role;
6289 var $scheme;
6290 var $name;
6292 // Constructor, used to input the data
6293 function SimplePie_Credit($role = null, $scheme = null, $name = null)
6295 $this->role = $role;
6296 $this->scheme = $scheme;
6297 $this->name = $name;
6300 function __toString()
6302 // There is no $this->data here
6303 return md5(serialize($this));
6306 function get_role()
6308 if ($this->role !== null)
6310 return $this->role;
6312 else
6314 return null;
6318 function get_scheme()
6320 if ($this->scheme !== null)
6322 return $this->scheme;
6324 else
6326 return null;
6330 function get_name()
6332 if ($this->name !== null)
6334 return $this->name;
6336 else
6338 return null;
6343 class SimplePie_Copyright
6345 var $url;
6346 var $label;
6348 // Constructor, used to input the data
6349 function SimplePie_Copyright($url = null, $label = null)
6351 $this->url = $url;
6352 $this->label = $label;
6355 function __toString()
6357 // There is no $this->data here
6358 return md5(serialize($this));
6361 function get_url()
6363 if ($this->url !== null)
6365 return $this->url;
6367 else
6369 return null;
6373 function get_attribution()
6375 if ($this->label !== null)
6377 return $this->label;
6379 else
6381 return null;
6386 class SimplePie_Rating
6388 var $scheme;
6389 var $value;
6391 // Constructor, used to input the data
6392 function SimplePie_Rating($scheme = null, $value = null)
6394 $this->scheme = $scheme;
6395 $this->value = $value;
6398 function __toString()
6400 // There is no $this->data here
6401 return md5(serialize($this));
6404 function get_scheme()
6406 if ($this->scheme !== null)
6408 return $this->scheme;
6410 else
6412 return null;
6416 function get_value()
6418 if ($this->value !== null)
6420 return $this->value;
6422 else
6424 return null;
6429 class SimplePie_Restriction
6431 var $relationship;
6432 var $type;
6433 var $value;
6435 // Constructor, used to input the data
6436 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
6438 $this->relationship = $relationship;
6439 $this->type = $type;
6440 $this->value = $value;
6443 function __toString()
6445 // There is no $this->data here
6446 return md5(serialize($this));
6449 function get_relationship()
6451 if ($this->relationship !== null)
6453 return $this->relationship;
6455 else
6457 return null;
6461 function get_type()
6463 if ($this->type !== null)
6465 return $this->type;
6467 else
6469 return null;
6473 function get_value()
6475 if ($this->value !== null)
6477 return $this->value;
6479 else
6481 return null;
6487 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
6489 class SimplePie_File
6491 var $url;
6492 var $useragent;
6493 var $success = true;
6494 var $headers = array();
6495 var $body;
6496 var $status_code;
6497 var $redirects = 0;
6498 var $error;
6499 var $method;
6501 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
6503 if (class_exists('idna_convert'))
6505 $idn =& new idna_convert;
6506 $parsed = SimplePie_Misc::parse_url($url);
6507 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6509 $this->url = $url;
6510 $this->useragent = $useragent;
6511 if (preg_match('/^http(s)?:\/\//i', $url))
6513 if ($useragent === null)
6515 $useragent = ini_get('user_agent');
6516 $this->useragent = $useragent;
6518 if (!is_array($headers))
6520 $headers = array();
6522 if (!$force_fsockopen && extension_loaded('curl'))
6524 $this->method = 'curl';
6525 $fp = curl_init();
6526 $headers2 = array();
6527 foreach ($headers as $key => $value)
6529 $headers2[] = "$key: $value";
6531 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
6533 curl_setopt($fp, CURLOPT_ENCODING, '');
6535 curl_setopt($fp, CURLOPT_URL, $url);
6536 curl_setopt($fp, CURLOPT_HEADER, 1);
6537 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
6538 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
6539 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
6540 curl_setopt($fp, CURLOPT_REFERER, $url);
6541 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
6542 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
6543 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
6545 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
6546 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
6549 $this->headers = curl_exec($fp);
6550 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
6552 curl_setopt($fp, CURLOPT_ENCODING, 'none');
6553 $this->headers = curl_exec($fp);
6555 if (curl_errno($fp))
6557 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
6558 $this->success = false;
6560 else
6562 $info = curl_getinfo($fp);
6563 curl_close($fp);
6564 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
6565 $this->headers = array_pop($this->headers);
6566 $parser =& new SimplePie_HTTP_Parser($this->headers);
6567 if ($parser->parse())
6569 $this->headers = $parser->headers;
6570 $this->body = $parser->body;
6571 $this->status_code = $parser->status_code;
6572 if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
6574 $this->redirects++;
6575 if (isset($this->headers['content-location']))
6577 $location = SimplePie_Misc::absolutize_url($this->headers['location'], SimplePie_Misc::absolutize_url($this->headers['content-location'], $url));
6579 else
6581 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
6583 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
6588 else
6590 $this->method = 'fsockopen';
6591 $url_parts = parse_url($url);
6592 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
6594 $url_parts['host'] = "ssl://$url_parts[host]";
6595 $url_parts['port'] = 443;
6597 if (!isset($url_parts['port']))
6599 $url_parts['port'] = 80;
6601 $fp = fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
6602 if (!$fp)
6604 $this->error = 'fsockopen error: ' . $errstr;
6605 $this->success = false;
6607 else
6609 if (function_exists('stream_set_timeout'))
6611 stream_set_timeout($fp, $timeout);
6613 else
6615 socket_set_timeout($fp, $timeout);
6617 if (isset($url_parts['path']))
6619 if (isset($url_parts['query']))
6621 $get = "$url_parts[path]?$url_parts[query]";
6623 else
6625 $get = $url_parts['path'];
6628 else
6630 $get = '/';
6632 $out = "GET $get HTTP/1.0\r\n";
6633 $out .= "Host: $url_parts[host]\r\n";
6634 $out .= "User-Agent: $useragent\r\n";
6635 if (function_exists('gzinflate'))
6637 $out .= "Accept-Encoding: gzip,deflate\r\n";
6640 if (isset($url_parts['user']) && isset($url_parts['pass']))
6642 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
6644 foreach ($headers as $key => $value)
6646 $out .= "$key: $value\r\n";
6648 $out .= "Connection: Close\r\n\r\n";
6649 fwrite($fp, $out);
6651 if (function_exists('stream_get_meta_data'))
6653 $info = stream_get_meta_data($fp);
6655 else
6657 $info = socket_get_status($fp);
6660 $this->headers = '';
6661 while (!$info['eof'] && !$info['timed_out'])
6663 $this->headers .= fread($fp, 1160);
6664 if (function_exists('stream_get_meta_data'))
6666 $info = stream_get_meta_data($fp);
6668 else
6670 $info = socket_get_status($fp);
6673 if (!$info['timed_out'])
6675 $parser =& new SimplePie_HTTP_Parser($this->headers);
6676 if ($parser->parse())
6678 $this->headers = $parser->headers;
6679 $this->body = $parser->body;
6680 $this->status_code = $parser->status_code;
6681 if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
6683 $this->redirects++;
6684 if (isset($this->headers['content-location']))
6686 $location = SimplePie_Misc::absolutize_url($this->headers['location'], SimplePie_Misc::absolutize_url($this->headers['content-location'], $url));
6688 else
6690 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
6692 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
6694 if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
6696 if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
6698 $this->body = substr($this->body, 10);
6700 $this->body = gzinflate($this->body);
6704 else
6706 $this->error = 'fsocket timed out';
6707 $this->success = false;
6709 fclose($fp);
6713 elseif (function_exists('file_get_contents'))
6715 $this->method = 'file_get_contents';
6716 if (!$this->body = file_get_contents($url))
6718 $this->error = 'file_get_contents could not read the file';
6719 $this->success = false;
6722 else
6724 $this->method = 'fopen';
6725 if (($fp = fopen($url, 'rb')) === false)
6727 $this->error = 'failed to open stream: No such file or directory';
6728 $this->success = false;
6730 else
6732 $this->body = '';
6733 while (!feof($fp))
6735 $this->body .= fread($fp, 8192);
6737 fclose($fp);
6744 * HTTP Response Parser
6746 * @package SimplePie
6747 * @todo Support HTTP Requests
6749 class SimplePie_HTTP_Parser
6752 * HTTP Version
6754 * @access public
6755 * @var string
6757 var $http_version = '';
6760 * Status code
6762 * @access public
6763 * @var string
6765 var $status_code = '';
6768 * Reason phrase
6770 * @access public
6771 * @var string
6773 var $reason = '';
6776 * Key/value pairs of the headers
6778 * @access public
6779 * @var array
6781 var $headers = array();
6784 * Body of the response
6786 * @access public
6787 * @var string
6789 var $body = '';
6792 * Current state of the state machine
6794 * @access private
6795 * @var string
6797 var $state = 'start';
6800 * Input data
6802 * @access private
6803 * @var string
6805 var $data = '';
6808 * Input data length (to avoid calling strlen() everytime this is needed)
6810 * @access private
6811 * @var int
6813 var $data_length = 0;
6816 * Current position of the pointer
6818 * @access private
6819 * @var int
6821 var $position = 0;
6824 * Name of the hedaer currently being parsed
6826 * @access private
6827 * @var string
6829 var $name = '';
6832 * Value of the hedaer currently being parsed
6834 * @access private
6835 * @var string
6837 var $value = '';
6840 * Create an instance of the class with the input data
6842 * @access public
6843 * @param string $data Input data
6845 function SimplePie_HTTP_Parser($data)
6847 $this->data = $data;
6848 $this->data_length = strlen($this->data);
6852 * Parse the input data
6854 * @access public
6855 * @return bool true on success, false on failure
6857 function parse()
6859 while ($this->state && $this->state != 'emit' && $this->has_data())
6861 $state = $this->state;
6862 $this->$state();
6864 $this->data = '';
6865 if ($this->state == 'emit')
6867 return true;
6869 else
6871 $this->http_version = '';
6872 $this->status_code = '';
6873 $this->headers = array();
6874 $this->body = '';
6875 return false;
6880 * Check whether there is data beyond the pointer
6882 * @access private
6883 * @return bool true if there is further data, false if not
6885 function has_data()
6887 return (bool) ($this->position < $this->data_length);
6891 * See if the next character is LWS
6893 * @access private
6894 * @return bool true if the next character is LWS, false if not
6896 function is_linear_whitespace()
6898 return (bool) (strspn($this->data, "\x09\x20", $this->position, 1)
6899 || (substr($this->data, $this->position, 2) == "\r\n" && strspn($this->data, "\x09\x20", $this->position + 2, 1))
6900 || (strspn($this->data, "\r\n", $this->position, 1) && strspn($this->data, "\x09\x20", $this->position + 1, 1)));
6904 * The starting state of the state machine, see if the data is a response or request
6906 * @access private
6908 function start()
6910 $this->state = 'http_version_response';
6914 * Parse an HTTP-version string
6916 * @access private
6918 function http_version()
6920 if (preg_match('/^HTTP\/([0-9]+\.[0-9]+)/i', substr($this->data, $this->position, strcspn($this->data, "\r\n", $this->position)), $match))
6922 $this->position += strlen($match[0]);
6923 $this->http_version = $match[1];
6924 return true;
6926 else
6928 return false;
6933 * Parse LWS, replacing consecutive characters with a single space
6935 * @access private
6937 function linear_whitespace()
6941 if (substr($this->data, $this->position, 2) == "\r\n")
6943 $this->position += 2;
6945 elseif (strspn($this->data, "\r\n", $this->position, 1))
6947 $this->position++;
6949 $this->position += strspn($this->data, "\x09\x20", $this->position);
6950 } while ($this->is_linear_whitespace());
6951 $this->value .= "\x20";
6955 * Parse an HTTP-version string within a response
6957 * @access private
6959 function http_version_response()
6961 if ($this->http_version() && $this->data[$this->position] == "\x20")
6963 $this->state = 'status_code';
6964 $this->position++;
6966 else
6968 $this->state = false;
6973 * Parse a status code
6975 * @access private
6977 function status_code()
6979 if (strspn($this->data, '1234567890', $this->position, 3) == 3)
6981 $this->status_code = substr($this->data, $this->position, 3);
6982 $this->state = 'reason_phrase';
6983 $this->position += 3;
6985 else
6987 $this->state = false;
6992 * Skip over the reason phrase (it has no normative value, and you can send absolutely anything here)
6994 * @access private
6996 function reason_phrase()
6998 $len = strcspn($this->data, "\r\n", $this->position);
6999 $this->reason = substr($this->data, $this->position, $len);
7000 $this->position += $len;
7001 if ($this->has_data())
7003 if (substr($this->data, $this->position, 2) == "\r\n")
7005 $this->position += 2;
7007 elseif (strspn($this->data, "\r\n", $this->position, 1))
7009 $this->position++;
7011 $this->state = 'name';
7016 * Parse a header name
7018 * @access private
7020 function name()
7022 $len = strcspn($this->data, ':', $this->position);
7023 $this->name = substr($this->data, $this->position, $len);
7024 $this->position += $len;
7026 if ($this->has_data() && $this->data[$this->position] == ':')
7028 $this->state = 'value_next';
7029 $this->position++;
7031 else
7033 $this->state = false;
7038 * See what state to move the state machine to while within non-quoted header values
7040 * @access private
7042 function value_next()
7044 if ($this->is_linear_whitespace())
7046 $this->state = 'value_linear_whitespace';
7048 elseif ($this->data[$this->position] == '"')
7050 $this->state = 'value_quote_next';
7051 $this->position++;
7053 elseif (substr($this->data, $this->position, 2) == "\r\n")
7055 $this->state = 'end_crlf';
7056 $this->position += 2;
7058 elseif (strspn($this->data, "\r\n", $this->position, 1))
7060 $this->state = 'end_crlf';
7061 $this->position++;
7063 else
7065 $this->state = 'value_no_quote';
7070 * Parse a header value while outside quotes
7072 * @access private
7074 function value_no_quote()
7076 $len = strcspn($this->data, "\x09\x20\r\n\"", $this->position);
7077 $this->value .= substr($this->data, $this->position, $len);
7078 $this->state = 'value_next';
7079 $this->position += $len;
7083 * Parse LWS outside quotes
7085 * @access private
7087 function value_linear_whitespace()
7089 $this->linear_whitespace();
7090 $this->state = 'value_next';
7094 * See what state to move the state machine to while within quoted header values
7096 * @access private
7098 function value_quote_next()
7100 if ($this->is_linear_whitespace())
7102 $this->state = 'value_linear_whitespace_quote';
7104 else
7106 switch ($this->data[$this->position])
7108 case '"':
7109 $this->state = 'value_next';
7110 $this->position++;
7111 break;
7113 case '\\':
7114 $this->state = 'value_quote_char';
7115 $this->position++;
7116 break;
7118 default:
7119 $this->state = 'value_quote';
7120 break;
7126 * Parse a header value while within quotes
7128 * @access private
7130 function value_quote()
7132 $len = strcspn($this->data, "\x09\x20\r\n\"\\", $this->position);
7133 $this->value .= substr($this->data, $this->position, $len);
7134 $this->position += $len;
7135 $this->state = 'value_quote_next';
7139 * Parse an escaped character within quotes
7141 * @access private
7143 function value_quote_char()
7145 $this->value .= $this->data[$this->position];
7146 $this->state = 'value_quote_next';
7147 $this->position++;
7151 * Parse LWS within quotes
7153 * @access private
7155 function value_linear_whitespace_quote()
7157 $this->linear_whitespace();
7158 $this->state = 'value_quote_next';
7162 * Parse a CRLF, and see whether we have a further header, or whether we are followed by the body
7164 * @access private
7166 function end_crlf()
7168 $this->name = strtolower($this->name);
7169 $this->value = trim($this->value, "\x20");
7170 if (isset($this->headers[$this->name]))
7172 $this->headers[$this->name] .= ', ' . $this->value;
7174 else
7176 $this->headers[$this->name] = $this->value;
7179 if (substr($this->data, $this->position, 2) == "\r\n")
7181 $this->body = substr($this->data, $this->position + 2);
7182 $this->state = 'emit';
7184 elseif (strspn($this->data, "\r\n", $this->position, 1))
7186 $this->body = substr($this->data, $this->position + 1);
7187 $this->state = 'emit';
7189 else
7191 $this->name = '';
7192 $this->value = '';
7193 $this->state = 'name';
7198 class SimplePie_Cache
7200 var $location;
7201 var $filename;
7202 var $extension;
7203 var $name;
7205 function SimplePie_Cache($location, $filename, $extension)
7207 $this->location = $location;
7208 $this->filename = rawurlencode($filename);
7209 $this->extension = rawurlencode($extension);
7210 $this->name = "$location/$this->filename.$this->extension";
7213 function save($data)
7215 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
7217 if (function_exists('file_put_contents'))
7219 return (bool) file_put_contents($this->name, serialize($data));
7221 else
7223 $fp = fopen($this->name, 'wb');
7224 if ($fp)
7226 fwrite($fp, serialize($data));
7227 fclose($fp);
7228 return true;
7232 return false;
7235 function load()
7237 if (file_exists($this->name) && is_readable($this->name))
7239 if (function_exists('file_get_contents'))
7241 return unserialize(file_get_contents($this->name));
7243 elseif (($fp = fopen($this->name, 'rb')) !== false)
7245 $data = '';
7246 while (!feof($fp))
7248 $data .= fread($fp, 8192);
7250 fclose($fp);
7251 return unserialize($data);
7254 return false;
7257 function mtime()
7259 if (file_exists($this->name))
7261 return filemtime($this->name);
7263 return false;
7266 function touch()
7268 if (file_exists($this->name))
7270 return touch($this->name);
7272 return false;
7275 function unlink()
7277 if (file_exists($this->name))
7279 return unlink($this->name);
7281 return false;
7285 class SimplePie_Misc
7287 function time_hms($seconds)
7289 $time = '';
7291 $hours = floor($seconds / 3600);
7292 $remainder = $seconds % 3600;
7293 if ($hours > 0)
7295 $time .= $hours.':';
7298 $minutes = floor($remainder / 60);
7299 $seconds = $remainder % 60;
7300 if ($minutes < 10 && $hours > 0)
7302 $minutes = '0' . $minutes;
7304 if ($seconds < 10)
7306 $seconds = '0' . $seconds;
7309 $time .= $minutes.':';
7310 $time .= $seconds;
7312 return $time;
7315 function absolutize_url($relative, $base)
7317 if ($relative !== '')
7319 $relative = SimplePie_Misc::parse_url($relative);
7320 if ($relative['scheme'] !== '')
7322 $target = $relative;
7324 elseif ($base !== '')
7326 $base = SimplePie_Misc::parse_url($base);
7327 $target = SimplePie_Misc::parse_url('');
7328 if ($relative['authority'] !== '')
7330 $target = $relative;
7331 $target['scheme'] = $base['scheme'];
7333 else
7335 $target['scheme'] = $base['scheme'];
7336 $target['authority'] = $base['authority'];
7337 if ($relative['path'] !== '')
7339 if (strpos($relative['path'], '/') === 0)
7341 $target['path'] = $relative['path'];
7343 elseif (($target['path'] = dirname("$base[path].")) == '/')
7345 $target['path'] .= $relative['path'];
7347 else
7349 $target['path'] .= '/' . $relative['path'];
7351 if ($relative['query'] !== '')
7353 $target['query'] = $relative['query'];
7356 else
7358 if ($base['path'] !== '')
7360 $target['path'] = $base['path'];
7362 else
7364 $target['path'] = '/';
7366 if ($relative['query'] !== '')
7368 $target['query'] = $relative['query'];
7370 elseif ($base['query'] !== '')
7372 $target['query'] = $base['query'];
7376 if ($relative['fragment'] !== '')
7378 $target['fragment'] = $relative['fragment'];
7381 else
7383 // No base URL, just return the relative URL
7384 $target = $relative;
7386 $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
7388 else
7390 $return = $base;
7392 $return = SimplePie_Misc::normalize_url($return);
7393 return $return;
7396 function remove_dot_segments($input)
7398 $output = '';
7399 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
7401 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
7402 if (strpos($input, '../') === 0)
7404 $input = substr($input, 3);
7406 elseif (strpos($input, './') === 0)
7408 $input = substr($input, 2);
7410 // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
7411 elseif (strpos($input, '/./') === 0)
7413 $input = substr_replace($input, '/', 0, 3);
7415 elseif ($input == '/.')
7417 $input = '/';
7419 // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
7420 elseif (strpos($input, '/../') === 0)
7422 $input = substr_replace($input, '/', 0, 4);
7423 $output = substr_replace($output, '', strrpos($output, '/'));
7425 elseif ($input == '/..')
7427 $input = '/';
7428 $output = substr_replace($output, '', strrpos($output, '/'));
7430 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
7431 elseif ($input == '.' || $input == '..')
7433 $input = '';
7435 // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
7436 elseif (($pos = strpos($input, '/', 1)) !== false)
7438 $output .= substr($input, 0, $pos);
7439 $input = substr_replace($input, '', 0, $pos);
7441 else
7443 $output .= $input;
7444 $input = '';
7447 return $output . $input;
7450 function get_element($realname, $string)
7452 $return = array();
7453 $name = preg_quote($realname, '/');
7454 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
7456 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
7458 $return[$i]['tag'] = $realname;
7459 $return[$i]['full'] = $matches[$i][0][0];
7460 $return[$i]['offset'] = $matches[$i][0][1];
7461 if (strlen($matches[$i][3][0]) <= 2)
7463 $return[$i]['self_closing'] = true;
7465 else
7467 $return[$i]['self_closing'] = false;
7468 $return[$i]['content'] = $matches[$i][4][0];
7470 $return[$i]['attribs'] = array();
7471 if (isset($matches[$i][2][0]) && preg_match_all('/((?:[^\s:]+:)?[^\s:]+)(?:\s*=\s*(?:"([^"]*)"|\'([^\']*)\'|([a-z0-9\-._:]*)))?\s/U', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
7473 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
7475 if (count($attribs[$j]) == 2)
7477 $attribs[$j][2] = $attribs[$j][1];
7479 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
7484 return $return;
7487 function element_implode($element)
7489 $full = "<$element[tag]";
7490 foreach ($element['attribs'] as $key => $value)
7492 $key = strtolower($key);
7493 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
7495 if ($element['self_closing'])
7497 $full .= ' />';
7499 else
7501 $full .= ">$element[content]</$element[tag]>";
7503 return $full;
7506 function error($message, $level, $file, $line)
7508 switch ($level)
7510 case E_USER_ERROR:
7511 $note = 'PHP Error';
7512 break;
7513 case E_USER_WARNING:
7514 $note = 'PHP Warning';
7515 break;
7516 case E_USER_NOTICE:
7517 $note = 'PHP Notice';
7518 break;
7519 default:
7520 $note = 'Unknown Error';
7521 break;
7523 error_log("$note: $message in $file on line $line", 0);
7524 return $message;
7528 * If a file has been cached, retrieve and display it.
7530 * This is most useful for caching images (get_favicon(), etc.),
7531 * however it works for all cached files. This WILL NOT display ANY
7532 * file/image/page/whatever, but rather only display what has already
7533 * been cached by SimplePie.
7535 * @access public
7536 * @see SimplePie::get_favicon()
7537 * @param str $identifier_url URL that is used to identify the content.
7538 * This may or may not be the actual URL of the live content.
7539 * @param str $cache_location Location of SimplePie's cache. Defaults
7540 * to './cache'.
7541 * @param str $cache_extension The file extension that the file was
7542 * cached with. Defaults to 'spc'.
7543 * @param str $cache_class Name of the cache-handling class being used
7544 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
7545 * as-is unless you've overloaded the class.
7546 * @param str $cache_name_function Function that converts the filename
7547 * for saving. Defaults to 'md5'.
7549 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
7551 $cache =& new $cache_class($cache_location, call_user_func($cache_name_function, $identifier_url), $cache_extension);
7553 if ($file = $cache->load())
7555 header('Content-type:' . $file['headers']['content-type']);
7556 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
7557 echo $file['body'];
7558 exit;
7561 die('Cached file for ' . $identifier_url . ' cannot be found.');
7564 function fix_protocol($url, $http = 1)
7566 $url = SimplePie_Misc::normalize_url($url);
7567 $parsed = SimplePie_Misc::parse_url($url);
7568 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
7570 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
7573 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
7575 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
7578 if ($http == 2 && $parsed['scheme'] !== '')
7580 return "feed:$url";
7582 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
7584 return substr_replace($url, 'podcast', 0, 4);
7586 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
7588 return substr_replace($url, 'itpc', 0, 4);
7590 else
7592 return $url;
7596 function parse_url($url)
7598 static $cache = array();
7599 if (isset($cache[$url]))
7601 return $cache[$url];
7603 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
7605 for ($i = count($match); $i <= 9; $i++)
7607 $match[$i] = '';
7609 return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
7611 else
7613 return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
7617 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
7619 $return = '';
7620 if ($scheme !== '')
7622 $return .= "$scheme:";
7624 if ($authority !== '')
7626 $return .= "//$authority";
7628 if ($path !== '')
7630 $return .= $path;
7632 if ($query !== '')
7634 $return .= "?$query";
7636 if ($fragment !== '')
7638 $return .= "#$fragment";
7640 return $return;
7643 function normalize_url($url)
7645 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
7646 $url = SimplePie_Misc::parse_url($url);
7647 $url['scheme'] = strtolower($url['scheme']);
7648 if ($url['authority'] !== '')
7650 $url['authority'] = strtolower($url['authority']);
7651 $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
7653 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
7656 function percent_encoding_normalization($match)
7658 $integer = hexdec($match[1]);
7659 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
7661 return chr($integer);
7663 else
7665 return strtoupper($match[0]);
7670 * Remove bad UTF-8 bytes
7672 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
7673 * FAQ: Multilingual Forms (modified to include full ASCII range)
7675 * @author Geoffrey Sneddon
7676 * @see http://www.w3.org/International/questions/qa-forms-utf-8
7677 * @param string $str String to remove bad UTF-8 bytes from
7678 * @return string UTF-8 string
7680 function utf8_bad_replace($str)
7682 if (function_exists('iconv'))
7684 $out = iconv('UTF-8', 'UTF-8//IGNORE', $str);
7685 if($out !== false) return $out;
7687 if (function_exists('mb_convert_encoding'))
7689 return mb_convert_encoding($str, 'UTF-8', 'UTF-8');
7691 elseif (preg_match_all('/([\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})/', $str, $matches))
7693 return implode("\xEF\xBF\xBD", $matches[0]);
7695 elseif ($str !== '')
7697 return "\xEF\xBF\xBD";
7699 else
7701 return '';
7705 function change_encoding($data, $input, $output)
7707 $input = SimplePie_Misc::encoding($input);
7708 $output = SimplePie_Misc::encoding($output);
7710 if (function_exists('iconv') && ($return = @iconv($input, "$output//IGNORE", $data)))
7712 return $return;
7714 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
7716 return $return;
7718 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
7720 return $return;
7722 elseif ($input == 'ISO-8859-1' && $output == 'UTF-8')
7724 return utf8_encode($data);
7726 elseif ($input == 'UTF-8' && $output == 'ISO-8859-1')
7728 return utf8_decode($data);
7730 return $data;
7733 function encoding($encoding)
7735 // Character sets are case-insensitive (though we'll return them in the form given in their registration)
7736 switch (strtoupper($encoding))
7738 case 'ANSI_X3.4-1968':
7739 case 'ISO-IR-6':
7740 case 'ANSI_X3.4-1986':
7741 case 'ISO_646.IRV:1991':
7742 case 'ASCII':
7743 case 'ISO646-US':
7744 case 'US-ASCII':
7745 case 'US':
7746 case 'IBM367':
7747 case 'CP367':
7748 case 'CSASCII':
7749 return 'US-ASCII';
7751 case 'ISO_8859-1:1987':
7752 case 'ISO-IR-100':
7753 case 'ISO_8859-1':
7754 case 'ISO-8859-1':
7755 case 'LATIN1':
7756 case 'L1':
7757 case 'IBM819':
7758 case 'CP819':
7759 case 'CSISOLATIN1':
7760 return 'ISO-8859-1';
7762 case 'ISO_8859-2:1987':
7763 case 'ISO-IR-101':
7764 case 'ISO_8859-2':
7765 case 'ISO-8859-2':
7766 case 'LATIN2':
7767 case 'L2':
7768 case 'CSISOLATIN2':
7769 return 'ISO-8859-2';
7771 case 'ISO_8859-3:1988':
7772 case 'ISO-IR-109':
7773 case 'ISO_8859-3':
7774 case 'ISO-8859-3':
7775 case 'LATIN3':
7776 case 'L3':
7777 case 'CSISOLATIN3':
7778 return 'ISO-8859-3';
7780 case 'ISO_8859-4:1988':
7781 case 'ISO-IR-110':
7782 case 'ISO_8859-4':
7783 case 'ISO-8859-4':
7784 case 'LATIN4':
7785 case 'L4':
7786 case 'CSISOLATIN4':
7787 return 'ISO-8859-4';
7789 case 'ISO_8859-5:1988':
7790 case 'ISO-IR-144':
7791 case 'ISO_8859-5':
7792 case 'ISO-8859-5':
7793 case 'CYRILLIC':
7794 case 'CSISOLATINCYRILLIC':
7795 return 'ISO-8859-5';
7797 case 'ISO_8859-6:1987':
7798 case 'ISO-IR-127':
7799 case 'ISO_8859-6':
7800 case 'ISO-8859-6':
7801 case 'ECMA-114':
7802 case 'ASMO-708':
7803 case 'ARABIC':
7804 case 'CSISOLATINARABIC':
7805 return 'ISO-8859-6';
7807 case 'ISO_8859-7:1987':
7808 case 'ISO-IR-126':
7809 case 'ISO_8859-7':
7810 case 'ISO-8859-7':
7811 case 'ELOT_928':
7812 case 'ECMA-118':
7813 case 'GREEK':
7814 case 'GREEK8':
7815 case 'CSISOLATINGREEK':
7816 return 'ISO-8859-7';
7818 case 'ISO_8859-8:1988':
7819 case 'ISO-IR-138':
7820 case 'ISO_8859-8':
7821 case 'ISO-8859-8':
7822 case 'HEBREW':
7823 case 'CSISOLATINHEBREW':
7824 return 'ISO-8859-8';
7826 case 'ISO_8859-9:1989':
7827 case 'ISO-IR-148':
7828 case 'ISO_8859-9':
7829 case 'ISO-8859-9':
7830 case 'LATIN5':
7831 case 'L5':
7832 case 'CSISOLATIN5':
7833 return 'ISO-8859-9';
7835 case 'ISO-8859-10':
7836 case 'ISO-IR-157':
7837 case 'L6':
7838 case 'ISO_8859-10:1992':
7839 case 'CSISOLATIN6':
7840 case 'LATIN6':
7841 return 'ISO-8859-10';
7843 case 'ISO_6937-2-ADD':
7844 case 'ISO-IR-142':
7845 case 'CSISOTEXTCOMM':
7846 return 'ISO_6937-2-add';
7848 case 'JIS_X0201':
7849 case 'X0201':
7850 case 'CSHALFWIDTHKATAKANA':
7851 return 'JIS_X0201';
7853 case 'JIS_ENCODING':
7854 case 'CSJISENCODING':
7855 return 'JIS_Encoding';
7857 case 'SHIFT_JIS':
7858 case 'MS_KANJI':
7859 case 'CSSHIFTJIS':
7860 return 'Shift_JIS';
7862 case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
7863 case 'CSEUCPKDFMTJAPANESE':
7864 case 'EUC-JP':
7865 return 'EUC-JP';
7867 case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
7868 case 'CSEUCFIXWIDJAPANESE':
7869 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
7871 case 'BS_4730':
7872 case 'ISO-IR-4':
7873 case 'ISO646-GB':
7874 case 'GB':
7875 case 'UK':
7876 case 'CSISO4UNITEDKINGDOM':
7877 return 'BS_4730';
7879 case 'SEN_850200_C':
7880 case 'ISO-IR-11':
7881 case 'ISO646-SE2':
7882 case 'SE2':
7883 case 'CSISO11SWEDISHFORNAMES':
7884 return 'SEN_850200_C';
7886 case 'IT':
7887 case 'ISO-IR-15':
7888 case 'ISO646-IT':
7889 case 'CSISO15ITALIAN':
7890 return 'IT';
7892 case 'ES':
7893 case 'ISO-IR-17':
7894 case 'ISO646-ES':
7895 case 'CSISO17SPANISH':
7896 return 'ES';
7898 case 'DIN_66003':
7899 case 'ISO-IR-21':
7900 case 'DE':
7901 case 'ISO646-DE':
7902 case 'CSISO21GERMAN':
7903 return 'DIN_66003';
7905 case 'NS_4551-1':
7906 case 'ISO-IR-60':
7907 case 'ISO646-NO':
7908 case 'NO':
7909 case 'CSISO60DANISHNORWEGIAN':
7910 case 'CSISO60NORWEGIAN1':
7911 return 'NS_4551-1';
7913 case 'NF_Z_62-010':
7914 case 'ISO-IR-69':
7915 case 'ISO646-FR':
7916 case 'FR':
7917 case 'CSISO69FRENCH':
7918 return 'NF_Z_62-010';
7920 case 'ISO-10646-UTF-1':
7921 case 'CSISO10646UTF1':
7922 return 'ISO-10646-UTF-1';
7924 case 'ISO_646.BASIC:1983':
7925 case 'REF':
7926 case 'CSISO646BASIC1983':
7927 return 'ISO_646.basic:1983';
7929 case 'INVARIANT':
7930 case 'CSINVARIANT':
7931 return 'INVARIANT';
7933 case 'ISO_646.IRV:1983':
7934 case 'ISO-IR-2':
7935 case 'IRV':
7936 case 'CSISO2INTLREFVERSION':
7937 return 'ISO_646.irv:1983';
7939 case 'NATS-SEFI':
7940 case 'ISO-IR-8-1':
7941 case 'CSNATSSEFI':
7942 return 'NATS-SEFI';
7944 case 'NATS-SEFI-ADD':
7945 case 'ISO-IR-8-2':
7946 case 'CSNATSSEFIADD':
7947 return 'NATS-SEFI-ADD';
7949 case 'NATS-DANO':
7950 case 'ISO-IR-9-1':
7951 case 'CSNATSDANO':
7952 return 'NATS-DANO';
7954 case 'NATS-DANO-ADD':
7955 case 'ISO-IR-9-2':
7956 case 'CSNATSDANOADD':
7957 return 'NATS-DANO-ADD';
7959 case 'SEN_850200_B':
7960 case 'ISO-IR-10':
7961 case 'FI':
7962 case 'ISO646-FI':
7963 case 'ISO646-SE':
7964 case 'SE':
7965 case 'CSISO10SWEDISH':
7966 return 'SEN_850200_B';
7968 case 'KS_C_5601-1987':
7969 case 'ISO-IR-149':
7970 case 'KS_C_5601-1989':
7971 case 'KSC_5601':
7972 case 'KOREAN':
7973 case 'CSKSC56011987':
7974 return 'KS_C_5601-1987';
7976 case 'ISO-2022-KR':
7977 case 'CSISO2022KR':
7978 return 'ISO-2022-KR';
7980 case 'EUC-KR':
7981 case 'CSEUCKR':
7982 return 'EUC-KR';
7984 case 'ISO-2022-JP':
7985 case 'CSISO2022JP':
7986 return 'ISO-2022-JP';
7988 case 'ISO-2022-JP-2':
7989 case 'CSISO2022JP2':
7990 return 'ISO-2022-JP-2';
7992 case 'JIS_C6220-1969-JP':
7993 case 'JIS_C6220-1969':
7994 case 'ISO-IR-13':
7995 case 'KATAKANA':
7996 case 'X0201-7':
7997 case 'CSISO13JISC6220JP':
7998 return 'JIS_C6220-1969-jp';
8000 case 'JIS_C6220-1969-RO':
8001 case 'ISO-IR-14':
8002 case 'JP':
8003 case 'ISO646-JP':
8004 case 'CSISO14JISC6220RO':
8005 return 'JIS_C6220-1969-ro';
8007 case 'PT':
8008 case 'ISO-IR-16':
8009 case 'ISO646-PT':
8010 case 'CSISO16PORTUGUESE':
8011 return 'PT';
8013 case 'GREEK7-OLD':
8014 case 'ISO-IR-18':
8015 case 'CSISO18GREEK7OLD':
8016 return 'greek7-old';
8018 case 'LATIN-GREEK':
8019 case 'ISO-IR-19':
8020 case 'CSISO19LATINGREEK':
8021 return 'latin-greek';
8023 case 'NF_Z_62-010_(1973)':
8024 case 'ISO-IR-25':
8025 case 'ISO646-FR1':
8026 case 'CSISO25FRENCH':
8027 return 'NF_Z_62-010_(1973)';
8029 case 'LATIN-GREEK-1':
8030 case 'ISO-IR-27':
8031 case 'CSISO27LATINGREEK1':
8032 return 'Latin-greek-1';
8034 case 'ISO_5427':
8035 case 'ISO-IR-37':
8036 case 'CSISO5427CYRILLIC':
8037 return 'ISO_5427';
8039 case 'JIS_C6226-1978':
8040 case 'ISO-IR-42':
8041 case 'CSISO42JISC62261978':
8042 return 'JIS_C6226-1978';
8044 case 'BS_VIEWDATA':
8045 case 'ISO-IR-47':
8046 case 'CSISO47BSVIEWDATA':
8047 return 'BS_viewdata';
8049 case 'INIS':
8050 case 'ISO-IR-49':
8051 case 'CSISO49INIS':
8052 return 'INIS';
8054 case 'INIS-8':
8055 case 'ISO-IR-50':
8056 case 'CSISO50INIS8':
8057 return 'INIS-8';
8059 case 'INIS-CYRILLIC':
8060 case 'ISO-IR-51':
8061 case 'CSISO51INISCYRILLIC':
8062 return 'INIS-cyrillic';
8064 case 'ISO_5427:1981':
8065 case 'ISO-IR-54':
8066 case 'ISO5427CYRILLIC1981':
8067 return 'ISO_5427:1981';
8069 case 'ISO_5428:1980':
8070 case 'ISO-IR-55':
8071 case 'CSISO5428GREEK':
8072 return 'ISO_5428:1980';
8074 case 'GB_1988-80':
8075 case 'ISO-IR-57':
8076 case 'CN':
8077 case 'ISO646-CN':
8078 case 'CSISO57GB1988':
8079 return 'GB_1988-80';
8081 case 'GB_2312-80':
8082 case 'ISO-IR-58':
8083 case 'CHINESE':
8084 case 'CSISO58GB231280':
8085 return 'GB_2312-80';
8087 case 'NS_4551-2':
8088 case 'ISO646-NO2':
8089 case 'ISO-IR-61':
8090 case 'NO2':
8091 case 'CSISO61NORWEGIAN2':
8092 return 'NS_4551-2';
8094 case 'VIDEOTEX-SUPPL':
8095 case 'ISO-IR-70':
8096 case 'CSISO70VIDEOTEXSUPP1':
8097 return 'videotex-suppl';
8099 case 'PT2':
8100 case 'ISO-IR-84':
8101 case 'ISO646-PT2':
8102 case 'CSISO84PORTUGUESE2':
8103 return 'PT2';
8105 case 'ES2':
8106 case 'ISO-IR-85':
8107 case 'ISO646-ES2':
8108 case 'CSISO85SPANISH2':
8109 return 'ES2';
8111 case 'MSZ_7795.3':
8112 case 'ISO-IR-86':
8113 case 'ISO646-HU':
8114 case 'HU':
8115 case 'CSISO86HUNGARIAN':
8116 return 'MSZ_7795.3';
8118 case 'JIS_C6226-1983':
8119 case 'ISO-IR-87':
8120 case 'X0208':
8121 case 'JIS_X0208-1983':
8122 case 'CSISO87JISX0208':
8123 return 'JIS_C6226-1983';
8125 case 'GREEK7':
8126 case 'ISO-IR-88':
8127 case 'CSISO88GREEK7':
8128 return 'greek7';
8130 case 'ASMO_449':
8131 case 'ISO_9036':
8132 case 'ARABIC7':
8133 case 'ISO-IR-89':
8134 case 'CSISO89ASMO449':
8135 return 'ASMO_449';
8137 case 'ISO-IR-90':
8138 case 'CSISO90':
8139 return 'iso-ir-90';
8141 case 'JIS_C6229-1984-A':
8142 case 'ISO-IR-91':
8143 case 'JP-OCR-A':
8144 case 'CSISO91JISC62291984A':
8145 return 'JIS_C6229-1984-a';
8147 case 'JIS_C6229-1984-B':
8148 case 'ISO-IR-92':
8149 case 'ISO646-JP-OCR-B':
8150 case 'JP-OCR-B':
8151 case 'CSISO92JISC62991984B':
8152 return 'JIS_C6229-1984-b';
8154 case 'JIS_C6229-1984-B-ADD':
8155 case 'ISO-IR-93':
8156 case 'JP-OCR-B-ADD':
8157 case 'CSISO93JIS62291984BADD':
8158 return 'JIS_C6229-1984-b-add';
8160 case 'JIS_C6229-1984-HAND':
8161 case 'ISO-IR-94':
8162 case 'JP-OCR-HAND':
8163 case 'CSISO94JIS62291984HAND':
8164 return 'JIS_C6229-1984-hand';
8166 case 'JIS_C6229-1984-HAND-ADD':
8167 case 'ISO-IR-95':
8168 case 'JP-OCR-HAND-ADD':
8169 case 'CSISO95JIS62291984HANDADD':
8170 return 'JIS_C6229-1984-hand-add';
8172 case 'JIS_C6229-1984-KANA':
8173 case 'ISO-IR-96':
8174 case 'CSISO96JISC62291984KANA':
8175 return 'JIS_C6229-1984-kana';
8177 case 'ISO_2033-1983':
8178 case 'ISO-IR-98':
8179 case 'E13B':
8180 case 'CSISO2033':
8181 return 'ISO_2033-1983';
8183 case 'ANSI_X3.110-1983':
8184 case 'ISO-IR-99':
8185 case 'CSA_T500-1983':
8186 case 'NAPLPS':
8187 case 'CSISO99NAPLPS':
8188 return 'ANSI_X3.110-1983';
8190 case 'T.61-7BIT':
8191 case 'ISO-IR-102':
8192 case 'CSISO102T617BIT':
8193 return 'T.61-7bit';
8195 case 'T.61-8BIT':
8196 case 'T.61':
8197 case 'ISO-IR-103':
8198 case 'CSISO103T618BIT':
8199 return 'T.61-8bit';
8201 case 'ECMA-CYRILLIC':
8202 case 'ISO-IR-111':
8203 case 'KOI8-E':
8204 case 'CSISO111ECMACYRILLIC':
8205 return 'ECMA-cyrillic';
8207 case 'CSA_Z243.4-1985-1':
8208 case 'ISO-IR-121':
8209 case 'ISO646-CA':
8210 case 'CSA7-1':
8211 case 'CA':
8212 case 'CSISO121CANADIAN1':
8213 return 'CSA_Z243.4-1985-1';
8215 case 'CSA_Z243.4-1985-2':
8216 case 'ISO-IR-122':
8217 case 'ISO646-CA2':
8218 case 'CSA7-2':
8219 case 'CSISO122CANADIAN2':
8220 return 'CSA_Z243.4-1985-2';
8222 case 'CSA_Z243.4-1985-GR':
8223 case 'ISO-IR-123':
8224 case 'CSISO123CSAZ24341985GR':
8225 return 'CSA_Z243.4-1985-gr';
8227 case 'ISO_8859-6-E':
8228 case 'CSISO88596E':
8229 case 'ISO-8859-6-E':
8230 return 'ISO-8859-6-E';
8232 case 'ISO_8859-6-I':
8233 case 'CSISO88596I':
8234 case 'ISO-8859-6-I':
8235 return 'ISO-8859-6-I';
8237 case 'T.101-G2':
8238 case 'ISO-IR-128':
8239 case 'CSISO128T101G2':
8240 return 'T.101-G2';
8242 case 'ISO_8859-8-E':
8243 case 'CSISO88598E':
8244 case 'ISO-8859-8-E':
8245 return 'ISO-8859-8-E';
8247 case 'ISO_8859-8-I':
8248 case 'CSISO88598I':
8249 case 'ISO-8859-8-I':
8250 return 'ISO-8859-8-I';
8252 case 'CSN_369103':
8253 case 'ISO-IR-139':
8254 case 'CSISO139CSN369103':
8255 return 'CSN_369103';
8257 case 'JUS_I.B1.002':
8258 case 'ISO-IR-141':
8259 case 'ISO646-YU':
8260 case 'JS':
8261 case 'YU':
8262 case 'CSISO141JUSIB1002':
8263 return 'JUS_I.B1.002';
8265 case 'IEC_P27-1':
8266 case 'ISO-IR-143':
8267 case 'CSISO143IECP271':
8268 return 'IEC_P27-1';
8270 case 'JUS_I.B1.003-SERB':
8271 case 'ISO-IR-146':
8272 case 'SERBIAN':
8273 case 'CSISO146SERBIAN':
8274 return 'JUS_I.B1.003-serb';
8276 case 'JUS_I.B1.003-MAC':
8277 case 'MACEDONIAN':
8278 case 'ISO-IR-147':
8279 case 'CSISO147MACEDONIAN':
8280 return 'JUS_I.B1.003-mac';
8282 case 'GREEK-CCITT':
8283 case 'ISO-IR-150':
8284 case 'CSISO150':
8285 case 'CSISO150GREEKCCITT':
8286 return 'greek-ccitt';
8288 case 'NC_NC00-10:81':
8289 case 'CUBA':
8290 case 'ISO-IR-151':
8291 case 'ISO646-CU':
8292 case 'CSISO151CUBA':
8293 return 'NC_NC00-10:81';
8295 case 'ISO_6937-2-25':
8296 case 'ISO-IR-152':
8297 case 'CSISO6937ADD':
8298 return 'ISO_6937-2-25';
8300 case 'GOST_19768-74':
8301 case 'ST_SEV_358-88':
8302 case 'ISO-IR-153':
8303 case 'CSISO153GOST1976874':
8304 return 'GOST_19768-74';
8306 case 'ISO_8859-SUPP':
8307 case 'ISO-IR-154':
8308 case 'LATIN1-2-5':
8309 case 'CSISO8859SUPP':
8310 return 'ISO_8859-supp';
8312 case 'ISO_10367-BOX':
8313 case 'ISO-IR-155':
8314 case 'CSISO10367BOX':
8315 return 'ISO_10367-box';
8317 case 'LATIN-LAP':
8318 case 'LAP':
8319 case 'ISO-IR-158':
8320 case 'CSISO158LAP':
8321 return 'latin-lap';
8323 case 'JIS_X0212-1990':
8324 case 'X0212':
8325 case 'ISO-IR-159':
8326 case 'CSISO159JISX02121990':
8327 return 'JIS_X0212-1990';
8329 case 'DS_2089':
8330 case 'DS2089':
8331 case 'ISO646-DK':
8332 case 'DK':
8333 case 'CSISO646DANISH':
8334 return 'DS_2089';
8336 case 'US-DK':
8337 case 'CSUSDK':
8338 return 'us-dk';
8340 case 'DK-US':
8341 case 'CSDKUS':
8342 return 'dk-us';
8344 case 'KSC5636':
8345 case 'ISO646-KR':
8346 case 'CSKSC5636':
8347 return 'KSC5636';
8349 case 'UNICODE-1-1-UTF-7':
8350 case 'CSUNICODE11UTF7':
8351 return 'UNICODE-1-1-UTF-7';
8353 case 'ISO-2022-CN':
8354 return 'ISO-2022-CN';
8356 case 'ISO-2022-CN-EXT':
8357 return 'ISO-2022-CN-EXT';
8359 case 'UTF-8':
8360 return 'UTF-8';
8362 case 'ISO-8859-13':
8363 return 'ISO-8859-13';
8365 case 'ISO-8859-14':
8366 case 'ISO-IR-199':
8367 case 'ISO_8859-14:1998':
8368 case 'ISO_8859-14':
8369 case 'LATIN8':
8370 case 'ISO-CELTIC':
8371 case 'L8':
8372 return 'ISO-8859-14';
8374 case 'ISO-8859-15':
8375 case 'ISO_8859-15':
8376 case 'LATIN-9':
8377 return 'ISO-8859-15';
8379 case 'ISO-8859-16':
8380 case 'ISO-IR-226':
8381 case 'ISO_8859-16:2001':
8382 case 'ISO_8859-16':
8383 case 'LATIN10':
8384 case 'L10':
8385 return 'ISO-8859-16';
8387 case 'GBK':
8388 case 'CP936':
8389 case 'MS936':
8390 case 'WINDOWS-936':
8391 return 'GBK';
8393 case 'GB18030':
8394 return 'GB18030';
8396 case 'OSD_EBCDIC_DF04_15':
8397 return 'OSD_EBCDIC_DF04_15';
8399 case 'OSD_EBCDIC_DF03_IRV':
8400 return 'OSD_EBCDIC_DF03_IRV';
8402 case 'OSD_EBCDIC_DF04_1':
8403 return 'OSD_EBCDIC_DF04_1';
8405 case 'ISO-11548-1':
8406 case 'ISO_11548-1':
8407 case 'ISO_TR_11548-1':
8408 case 'CSISO115481':
8409 return 'ISO-11548-1';
8411 case 'KZ-1048':
8412 case 'STRK1048-2002':
8413 case 'RK1048':
8414 case 'CSKZ1048':
8415 return 'KZ-1048';
8417 case 'ISO-10646-UCS-2':
8418 case 'CSUNICODE':
8419 return 'ISO-10646-UCS-2';
8421 case 'ISO-10646-UCS-4':
8422 case 'CSUCS4':
8423 return 'ISO-10646-UCS-4';
8425 case 'ISO-10646-UCS-BASIC':
8426 case 'CSUNICODEASCII':
8427 return 'ISO-10646-UCS-Basic';
8429 case 'ISO-10646-UNICODE-LATIN1':
8430 case 'CSUNICODELATIN1':
8431 case 'ISO-10646':
8432 return 'ISO-10646-Unicode-Latin1';
8434 case 'ISO-10646-J-1':
8435 return 'ISO-10646-J-1';
8437 case 'ISO-UNICODE-IBM-1261':
8438 case 'CSUNICODEIBM1261':
8439 return 'ISO-Unicode-IBM-1261';
8441 case 'ISO-UNICODE-IBM-1268':
8442 case 'CSUNICODEIBM1268':
8443 return 'ISO-Unicode-IBM-1268';
8445 case 'ISO-UNICODE-IBM-1276':
8446 case 'CSUNICODEIBM1276':
8447 return 'ISO-Unicode-IBM-1276';
8449 case 'ISO-UNICODE-IBM-1264':
8450 case 'CSUNICODEIBM1264':
8451 return 'ISO-Unicode-IBM-1264';
8453 case 'ISO-UNICODE-IBM-1265':
8454 case 'CSUNICODEIBM1265':
8455 return 'ISO-Unicode-IBM-1265';
8457 case 'UNICODE-1-1':
8458 case 'CSUNICODE11':
8459 return 'UNICODE-1-1';
8461 case 'SCSU':
8462 return 'SCSU';
8464 case 'UTF-7':
8465 return 'UTF-7';
8467 case 'UTF-16BE':
8468 return 'UTF-16BE';
8470 case 'UTF-16LE':
8471 return 'UTF-16LE';
8473 case 'UTF-16':
8474 return 'UTF-16';
8476 case 'CESU-8':
8477 case 'CSCESU-8':
8478 return 'CESU-8';
8480 case 'UTF-32':
8481 return 'UTF-32';
8483 case 'UTF-32BE':
8484 return 'UTF-32BE';
8486 case 'UTF-32LE':
8487 return 'UTF-32LE';
8489 case 'BOCU-1':
8490 case 'CSBOCU-1':
8491 return 'BOCU-1';
8493 case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
8494 case 'CSWINDOWS30LATIN1':
8495 return 'ISO-8859-1-Windows-3.0-Latin-1';
8497 case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
8498 case 'CSWINDOWS31LATIN1':
8499 return 'ISO-8859-1-Windows-3.1-Latin-1';
8501 case 'ISO-8859-2-WINDOWS-LATIN-2':
8502 case 'CSWINDOWS31LATIN2':
8503 return 'ISO-8859-2-Windows-Latin-2';
8505 case 'ISO-8859-9-WINDOWS-LATIN-5':
8506 case 'CSWINDOWS31LATIN5':
8507 return 'ISO-8859-9-Windows-Latin-5';
8509 case 'HP-ROMAN8':
8510 case 'ROMAN8':
8511 case 'R8':
8512 case 'CSHPROMAN8':
8513 return 'hp-roman8';
8515 case 'ADOBE-STANDARD-ENCODING':
8516 case 'CSADOBESTANDARDENCODING':
8517 return 'Adobe-Standard-Encoding';
8519 case 'VENTURA-US':
8520 case 'CSVENTURAUS':
8521 return 'Ventura-US';
8523 case 'VENTURA-INTERNATIONAL':
8524 case 'CSVENTURAINTERNATIONAL':
8525 return 'Ventura-International';
8527 case 'DEC-MCS':
8528 case 'DEC':
8529 case 'CSDECMCS':
8530 return 'DEC-MCS';
8532 case 'IBM850':
8533 case 'CP850':
8534 case '850':
8535 case 'CSPC850MULTILINGUAL':
8536 return 'IBM850';
8538 case 'PC8-DANISH-NORWEGIAN':
8539 case 'CSPC8DANISHNORWEGIAN':
8540 return 'PC8-Danish-Norwegian';
8542 case 'IBM862':
8543 case 'CP862':
8544 case '862':
8545 case 'CSPC862LATINHEBREW':
8546 return 'IBM862';
8548 case 'PC8-TURKISH':
8549 case 'CSPC8TURKISH':
8550 return 'PC8-Turkish';
8552 case 'IBM-SYMBOLS':
8553 case 'CSIBMSYMBOLS':
8554 return 'IBM-Symbols';
8556 case 'IBM-THAI':
8557 case 'CSIBMTHAI':
8558 return 'IBM-Thai';
8560 case 'HP-LEGAL':
8561 case 'CSHPLEGAL':
8562 return 'HP-Legal';
8564 case 'HP-PI-FONT':
8565 case 'CSHPPIFONT':
8566 return 'HP-Pi-font';
8568 case 'HP-MATH8':
8569 case 'CSHPMATH8':
8570 return 'HP-Math8';
8572 case 'ADOBE-SYMBOL-ENCODING':
8573 case 'CSHPPSMATH':
8574 return 'Adobe-Symbol-Encoding';
8576 case 'HP-DESKTOP':
8577 case 'CSHPDESKTOP':
8578 return 'HP-DeskTop';
8580 case 'VENTURA-MATH':
8581 case 'CSVENTURAMATH':
8582 return 'Ventura-Math';
8584 case 'MICROSOFT-PUBLISHING':
8585 case 'CSMICROSOFTPUBLISHING':
8586 return 'Microsoft-Publishing';
8588 case 'WINDOWS-31J':
8589 case 'CSWINDOWS31J':
8590 return 'Windows-31J';
8592 case 'GB2312':
8593 case 'CSGB2312':
8594 return 'GB2312';
8596 case 'BIG5':
8597 case 'CSBIG5':
8598 return 'Big5';
8600 case 'MACINTOSH':
8601 case 'MAC':
8602 case 'CSMACINTOSH':
8603 return 'macintosh';
8605 case 'IBM037':
8606 case 'CP037':
8607 case 'EBCDIC-CP-US':
8608 case 'EBCDIC-CP-CA':
8609 case 'EBCDIC-CP-WT':
8610 case 'EBCDIC-CP-NL':
8611 case 'CSIBM037':
8612 return 'IBM037';
8614 case 'IBM038':
8615 case 'EBCDIC-INT':
8616 case 'CP038':
8617 case 'CSIBM038':
8618 return 'IBM038';
8620 case 'IBM273':
8621 case 'CP273':
8622 case 'CSIBM273':
8623 return 'IBM273';
8625 case 'IBM274':
8626 case 'EBCDIC-BE':
8627 case 'CP274':
8628 case 'CSIBM274':
8629 return 'IBM274';
8631 case 'IBM275':
8632 case 'EBCDIC-BR':
8633 case 'CP275':
8634 case 'CSIBM275':
8635 return 'IBM275';
8637 case 'IBM277':
8638 case 'EBCDIC-CP-DK':
8639 case 'EBCDIC-CP-NO':
8640 case 'CSIBM277':
8641 return 'IBM277';
8643 case 'IBM278':
8644 case 'CP278':
8645 case 'EBCDIC-CP-FI':
8646 case 'EBCDIC-CP-SE':
8647 case 'CSIBM278':
8648 return 'IBM278';
8650 case 'IBM280':
8651 case 'CP280':
8652 case 'EBCDIC-CP-IT':
8653 case 'CSIBM280':
8654 return 'IBM280';
8656 case 'IBM281':
8657 case 'EBCDIC-JP-E':
8658 case 'CP281':
8659 case 'CSIBM281':
8660 return 'IBM281';
8662 case 'IBM284':
8663 case 'CP284':
8664 case 'EBCDIC-CP-ES':
8665 case 'CSIBM284':
8666 return 'IBM284';
8668 case 'IBM285':
8669 case 'CP285':
8670 case 'EBCDIC-CP-GB':
8671 case 'CSIBM285':
8672 return 'IBM285';
8674 case 'IBM290':
8675 case 'CP290':
8676 case 'EBCDIC-JP-KANA':
8677 case 'CSIBM290':
8678 return 'IBM290';
8680 case 'IBM297':
8681 case 'CP297':
8682 case 'EBCDIC-CP-FR':
8683 case 'CSIBM297':
8684 return 'IBM297';
8686 case 'IBM420':
8687 case 'CP420':
8688 case 'EBCDIC-CP-AR1':
8689 case 'CSIBM420':
8690 return 'IBM420';
8692 case 'IBM423':
8693 case 'CP423':
8694 case 'EBCDIC-CP-GR':
8695 case 'CSIBM423':
8696 return 'IBM423';
8698 case 'IBM424':
8699 case 'CP424':
8700 case 'EBCDIC-CP-HE':
8701 case 'CSIBM424':
8702 return 'IBM424';
8704 case 'IBM437':
8705 case 'CP437':
8706 case '437':
8707 case 'CSPC8CODEPAGE437':
8708 return 'IBM437';
8710 case 'IBM500':
8711 case 'CP500':
8712 case 'EBCDIC-CP-BE':
8713 case 'EBCDIC-CP-CH':
8714 case 'CSIBM500':
8715 return 'IBM500';
8717 case 'IBM851':
8718 case 'CP851':
8719 case '851':
8720 case 'CSIBM851':
8721 return 'IBM851';
8723 case 'IBM852':
8724 case 'CP852':
8725 case '852':
8726 case 'CSPCP852':
8727 return 'IBM852';
8729 case 'IBM855':
8730 case 'CP855':
8731 case '855':
8732 case 'CSIBM855':
8733 return 'IBM855';
8735 case 'IBM857':
8736 case 'CP857':
8737 case '857':
8738 case 'CSIBM857':
8739 return 'IBM857';
8741 case 'IBM860':
8742 case 'CP860':
8743 case '860':
8744 case 'CSIBM860':
8745 return 'IBM860';
8747 case 'IBM861':
8748 case 'CP861':
8749 case '861':
8750 case 'CP-IS':
8751 case 'CSIBM861':
8752 return 'IBM861';
8754 case 'IBM863':
8755 case 'CP863':
8756 case '863':
8757 case 'CSIBM863':
8758 return 'IBM863';
8760 case 'IBM864':
8761 case 'CP864':
8762 case 'CSIBM864':
8763 return 'IBM864';
8765 case 'IBM865':
8766 case 'CP865':
8767 case '865':
8768 case 'CSIBM865':
8769 return 'IBM865';
8771 case 'IBM868':
8772 case 'CP868':
8773 case 'CP-AR':
8774 case 'CSIBM868':
8775 return 'IBM868';
8777 case 'IBM869':
8778 case 'CP869':
8779 case '869':
8780 case 'CP-GR':
8781 case 'CSIBM869':
8782 return 'IBM869';
8784 case 'IBM870':
8785 case 'CP870':
8786 case 'EBCDIC-CP-ROECE':
8787 case 'EBCDIC-CP-YU':
8788 case 'CSIBM870':
8789 return 'IBM870';
8791 case 'IBM871':
8792 case 'CP871':
8793 case 'EBCDIC-CP-IS':
8794 case 'CSIBM871':
8795 return 'IBM871';
8797 case 'IBM880':
8798 case 'CP880':
8799 case 'EBCDIC-CYRILLIC':
8800 case 'CSIBM880':
8801 return 'IBM880';
8803 case 'IBM891':
8804 case 'CP891':
8805 case 'CSIBM891':
8806 return 'IBM891';
8808 case 'IBM903':
8809 case 'CP903':
8810 case 'CSIBM903':
8811 return 'IBM903';
8813 case 'IBM904':
8814 case 'CP904':
8815 case '904':
8816 case 'CSIBBM904':
8817 return 'IBM904';
8819 case 'IBM905':
8820 case 'CP905':
8821 case 'EBCDIC-CP-TR':
8822 case 'CSIBM905':
8823 return 'IBM905';
8825 case 'IBM918':
8826 case 'CP918':
8827 case 'EBCDIC-CP-AR2':
8828 case 'CSIBM918':
8829 return 'IBM918';
8831 case 'IBM1026':
8832 case 'CP1026':
8833 case 'CSIBM1026':
8834 return 'IBM1026';
8836 case 'EBCDIC-AT-DE':
8837 case 'CSIBMEBCDICATDE':
8838 return 'EBCDIC-AT-DE';
8840 case 'EBCDIC-AT-DE-A':
8841 case 'CSEBCDICATDEA':
8842 return 'EBCDIC-AT-DE-A';
8844 case 'EBCDIC-CA-FR':
8845 case 'CSEBCDICCAFR':
8846 return 'EBCDIC-CA-FR';
8848 case 'EBCDIC-DK-NO':
8849 case 'CSEBCDICDKNO':
8850 return 'EBCDIC-DK-NO';
8852 case 'EBCDIC-DK-NO-A':
8853 case 'CSEBCDICDKNOA':
8854 return 'EBCDIC-DK-NO-A';
8856 case 'EBCDIC-FI-SE':
8857 case 'CSEBCDICFISE':
8858 return 'EBCDIC-FI-SE';
8860 case 'EBCDIC-FI-SE-A':
8861 case 'CSEBCDICFISEA':
8862 return 'EBCDIC-FI-SE-A';
8864 case 'EBCDIC-FR':
8865 case 'CSEBCDICFR':
8866 return 'EBCDIC-FR';
8868 case 'EBCDIC-IT':
8869 case 'CSEBCDICIT':
8870 return 'EBCDIC-IT';
8872 case 'EBCDIC-PT':
8873 case 'CSEBCDICPT':
8874 return 'EBCDIC-PT';
8876 case 'EBCDIC-ES':
8877 case 'CSEBCDICES':
8878 return 'EBCDIC-ES';
8880 case 'EBCDIC-ES-A':
8881 case 'CSEBCDICESA':
8882 return 'EBCDIC-ES-A';
8884 case 'EBCDIC-ES-S':
8885 case 'CSEBCDICESS':
8886 return 'EBCDIC-ES-S';
8888 case 'EBCDIC-UK':
8889 case 'CSEBCDICUK':
8890 return 'EBCDIC-UK';
8892 case 'EBCDIC-US':
8893 case 'CSEBCDICUS':
8894 return 'EBCDIC-US';
8896 case 'UNKNOWN-8BIT':
8897 case 'CSUNKNOWN8BIT':
8898 return 'UNKNOWN-8BIT';
8900 case 'MNEMONIC':
8901 case 'CSMNEMONIC':
8902 return 'MNEMONIC';
8904 case 'MNEM':
8905 case 'CSMNEM':
8906 return 'MNEM';
8908 case 'VISCII':
8909 case 'CSVISCII':
8910 return 'VISCII';
8912 case 'VIQR':
8913 case 'CSVIQR':
8914 return 'VIQR';
8916 case 'KOI8-R':
8917 case 'CSKOI8R':
8918 return 'KOI8-R';
8920 case 'HZ-GB-2312':
8921 return 'HZ-GB-2312';
8923 case 'IBM866':
8924 case 'CP866':
8925 case '866':
8926 case 'CSIBM866':
8927 return 'IBM866';
8929 case 'IBM775':
8930 case 'CP775':
8931 case 'CSPC775BALTIC':
8932 return 'IBM775';
8934 case 'KOI8-U':
8935 return 'KOI8-U';
8937 case 'IBM00858':
8938 case 'CCSID00858':
8939 case 'CP00858':
8940 case 'PC-MULTILINGUAL-850+EURO':
8941 return 'IBM00858';
8943 case 'IBM00924':
8944 case 'CCSID00924':
8945 case 'CP00924':
8946 case 'EBCDIC-LATIN9--EURO':
8947 return 'IBM00924';
8949 case 'IBM01140':
8950 case 'CCSID01140':
8951 case 'CP01140':
8952 case 'EBCDIC-US-37+EURO':
8953 return 'IBM01140';
8955 case 'IBM01141':
8956 case 'CCSID01141':
8957 case 'CP01141':
8958 case 'EBCDIC-DE-273+EURO':
8959 return 'IBM01141';
8961 case 'IBM01142':
8962 case 'CCSID01142':
8963 case 'CP01142':
8964 case 'EBCDIC-DK-277+EURO':
8965 case 'EBCDIC-NO-277+EURO':
8966 return 'IBM01142';
8968 case 'IBM01143':
8969 case 'CCSID01143':
8970 case 'CP01143':
8971 case 'EBCDIC-FI-278+EURO':
8972 case 'EBCDIC-SE-278+EURO':
8973 return 'IBM01143';
8975 case 'IBM01144':
8976 case 'CCSID01144':
8977 case 'CP01144':
8978 case 'EBCDIC-IT-280+EURO':
8979 return 'IBM01144';
8981 case 'IBM01145':
8982 case 'CCSID01145':
8983 case 'CP01145':
8984 case 'EBCDIC-ES-284+EURO':
8985 return 'IBM01145';
8987 case 'IBM01146':
8988 case 'CCSID01146':
8989 case 'CP01146':
8990 case 'EBCDIC-GB-285+EURO':
8991 return 'IBM01146';
8993 case 'IBM01147':
8994 case 'CCSID01147':
8995 case 'CP01147':
8996 case 'EBCDIC-FR-297+EURO':
8997 return 'IBM01147';
8999 case 'IBM01148':
9000 case 'CCSID01148':
9001 case 'CP01148':
9002 case 'EBCDIC-INTERNATIONAL-500+EURO':
9003 return 'IBM01148';
9005 case 'IBM01149':
9006 case 'CCSID01149':
9007 case 'CP01149':
9008 case 'EBCDIC-IS-871+EURO':
9009 return 'IBM01149';
9011 case 'BIG5-HKSCS':
9012 return 'Big5-HKSCS';
9014 case 'IBM1047':
9015 case 'IBM-1047':
9016 return 'IBM1047';
9018 case 'PTCP154':
9019 case 'CSPTCP154':
9020 case 'PT154':
9021 case 'CP154':
9022 case 'CYRILLIC-ASIAN':
9023 return 'PTCP154';
9025 case 'AMIGA-1251':
9026 case 'AMI1251':
9027 case 'AMIGA1251':
9028 case 'AMI-1251':
9029 return 'Amiga-1251';
9031 case 'KOI7-SWITCHED':
9032 return 'KOI7-switched';
9034 case 'BRF':
9035 case 'CSBRF':
9036 return 'BRF';
9038 case 'TSCII':
9039 case 'CSTSCII':
9040 return 'TSCII';
9042 case 'WINDOWS-1250':
9043 return 'windows-1250';
9045 case 'WINDOWS-1251':
9046 return 'windows-1251';
9048 case 'WINDOWS-1252':
9049 return 'windows-1252';
9051 case 'WINDOWS-1253':
9052 return 'windows-1253';
9054 case 'WINDOWS-1254':
9055 return 'windows-1254';
9057 case 'WINDOWS-1255':
9058 return 'windows-1255';
9060 case 'WINDOWS-1256':
9061 return 'windows-1256';
9063 case 'WINDOWS-1257':
9064 return 'windows-1257';
9066 case 'WINDOWS-1258':
9067 return 'windows-1258';
9069 default:
9070 return (string) $encoding;
9074 function get_curl_version()
9076 if (is_array($curl = curl_version()))
9078 $curl = $curl['version'];
9080 elseif (substr($curl, 0, 5) == 'curl/')
9082 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
9084 elseif (substr($curl, 0, 8) == 'libcurl/')
9086 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
9088 else
9090 $curl = 0;
9092 return $curl;
9095 function is_subclass_of($class1, $class2)
9097 if (func_num_args() != 2)
9099 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
9101 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
9103 return is_subclass_of($class1, $class2);
9105 elseif (is_string($class1) && is_string($class2))
9107 if (class_exists($class1))
9109 if (class_exists($class2))
9111 $class2 = strtolower($class2);
9112 while ($class1 = strtolower(get_parent_class($class1)))
9114 if ($class1 == $class2)
9116 return true;
9121 else
9123 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
9126 return false;
9130 * Strip HTML comments
9132 * @access public
9133 * @param string $data Data to strip comments from
9134 * @return string Comment stripped string
9136 function strip_comments($data)
9138 $output = '';
9139 while (($start = strpos($data, '<!--')) !== false)
9141 $output .= substr($data, 0, $start);
9142 if (($end = strpos($data, '-->', $start)) !== false)
9144 $data = substr_replace($data, '', 0, $end + 3);
9146 else
9148 $data = '';
9151 return $output . $data;
9154 function parse_date($dt, $rfc822_tz = true)
9156 static $cache = array();
9157 if (!isset($cache[$dt][$rfc822_tz]))
9159 $dt = SimplePie_Misc::uncomment_rfc822($dt);
9161 Capturing subpatterns:
9162 1: RFC 822 date
9163 2: RFC 822 day
9164 3: RFC 822 month
9165 4: RFC 822 year
9166 5: ISO 8601 date
9167 6: ISO 8601 century
9168 7: ISO 8601 year
9169 8: ISO 8601 month
9170 9: ISO 8601 day
9171 10: ISO 8601 ordinal day
9172 11: ISO 8601 month
9173 12: ISO 8601 day
9174 13: ISO 8601 week
9175 14: ISO 8601 day of week
9176 15: Time
9177 16: Hour
9178 17: Hour Decimal
9179 18: Minute
9180 19: Minute Decimal
9181 20: Second
9182 21: Second Decimal
9183 22: Timezone
9184 23: Diff ±
9185 24: Hour
9186 25: Hour Decimal
9187 26: Minute
9188 27: Minute Decimal
9189 28: Alphabetic Timezone
9191 if (preg_match('/^(?:(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)[,\s]+)?(([0-9]{1,2})\s*(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s*([0-9]{4}|[0-9]{2}))|(([0-9]{2})(?:([0-9]{2})(?:(?:-|\s)*(?:([0-9]{2})([0-9]{2})|([0-9]{3})|([0-9]{2})(?:(?:-|\s)*([0-9]{2}))?|W([0-9]{2})(?:(?:-|\s)*([0-9]))?))?)?))((?:T|\s)+([0-9]{2})(?:(?:,|\.)([0-9]*)|(?:\:|\s)*([0-9]{2})(?:(?:,|\.)([0-9]*)|(?:\:|\s)*([0-9]{2})(?:(?:,|\.)([0-9]*))?)?)?(?:\s)*((?:(\+|-)([0-9]{2})(?:(?:,|\.)([0-9]*)|(?:\:|\s)*(?:([0-9]{2})(?:(?:,|\.)([0-9]*))?))?)|(UTC|GMT|EST|CST|MST|PST|EDT|CDT|MDT|PDT|UT|[A-IK-Z]))?)?$/i', $dt, $match))
9193 // Fill all matches
9194 for ($i = count($match); $i <= 28; $i++)
9196 $match[$i] = '';
9199 // Set blank vars
9200 $year = 1970;
9201 $month = 1;
9202 $day = 1;
9203 $hour = 0;
9204 $minute = 0;
9205 $second = 0;
9206 $timezone = false;
9208 // RFC 822
9209 if ($match[1] !== '')
9211 if (strlen($match[4]) == 2)
9213 $year = ($match[4] < 70) ? "20$match[4]" : "19$match[4]";
9215 else
9217 $year = $match[4];
9219 switch (strtolower($match[3]))
9221 case 'jan':
9222 $month = 1;
9223 break;
9225 case 'feb':
9226 $month = 2;
9227 break;
9229 case 'mar':
9230 $month = 3;
9231 break;
9233 case 'apr':
9234 $month = 4;
9235 break;
9237 case 'may':
9238 $month = 5;
9239 break;
9241 case 'jun':
9242 $month = 6;
9243 break;
9245 case 'jul':
9246 $month = 7;
9247 break;
9249 case 'aug':
9250 $month = 8;
9251 break;
9253 case 'sep':
9254 $month = 9;
9255 break;
9257 case 'oct':
9258 $month = 10;
9259 break;
9261 case 'nov':
9262 $month = 11;
9263 break;
9265 case 'dec':
9266 $month = 12;
9267 break;
9269 $day = $match[2];
9271 // ISO 8601
9272 else
9274 // Year
9275 if ($match[7] !== '')
9277 $year = "$match[6]$match[7]";
9279 // Two Digit Month/Day
9280 if ($match[11] !== '')
9282 $month = $match[11];
9283 if ($match[12] !== '')
9285 $day = $match[12];
9289 // Four Digit Month/Day
9290 elseif ($match[8] !== '')
9292 $month = $match[8];
9293 $day = $match[9];
9296 // Ordinal Day
9297 elseif ($match[10] !== '')
9299 $day = $match[10];
9302 // Week Date
9303 elseif ($match[13] !== '')
9305 // Week Day
9306 if ($match[14] !== '')
9308 $day = $match[14];
9311 $first_day_of_year = date('w', mktime(0, 0, 0, 1, 1, $year));
9312 if ($first_day_of_year == 0)
9314 $first_day_of_year = 7;
9317 $day = 7 * ($match[13] - 1) + $day - ($first_day_of_year - 1);
9320 else
9322 $year = "$match[6]00";
9325 // Time
9326 if ($match[15] !== '')
9328 $time = 0;
9329 $time += ($match[16] + ('.' . $match[17])) * 3600;
9330 $time += ($match[18] + ('.' . $match[19])) * 60;
9331 $time += $match[20] + ('.' . $match[21]);
9332 $hour = floor($time / 3600);
9333 $time -= $hour * 3600;
9334 $minute = floor($time / 60);
9335 $time -= $minute * 60;
9336 $second = round($time);
9338 // Timezone
9339 if ($match[22] !== '')
9341 // Alphabetic Timezone
9342 if ($match[28] !== '')
9344 // Military
9345 if (strlen($match[28]) == 1)
9347 if ($match[28] == 'Z' || $match[28] == 'z' || !$rfc822_tz)
9349 $timezone = 0;
9351 else
9353 $timezone = ord(strtoupper($match[28]));
9355 if ($timezone > 74)
9357 $timezone--;
9360 if ($timezone <= 76)
9362 $timezone = -($timezone - 64);
9364 else
9366 $timezone -= 76;
9369 $timezone *= 3600;
9372 // Code
9373 else
9375 switch (strtoupper($match[28]))
9377 case 'UT':
9378 case 'UTC':
9379 case 'GMT':
9380 $timezone = 0;
9381 break;
9383 case 'EST':
9384 $timezone = -18000;
9385 break;
9387 case 'CST':
9388 $timezone = -21600;
9389 break;
9391 case 'MST':
9392 $timezone = -25200;
9393 break;
9395 case 'PST':
9396 $timezone = -28800;
9397 break;
9399 case 'EDT':
9400 $timezone = -14400;
9401 break;
9403 case 'CDT':
9404 $timezone = -18000;
9405 break;
9407 case 'MDT':
9408 $timezone = -21600;
9409 break;
9411 case 'PDT':
9412 $timezone = -25200;
9413 break;
9417 // Timezone difference from UTC
9418 else
9420 $timezone = 0;
9421 $timezone += ($match[24] + ('.' . $match[25])) * 3600;
9422 $timezone += ($match[26] + ('.' . $match[27])) * 60;
9423 $timezone = (int) round($timezone);
9425 if ($match[23] == '-')
9427 $timezone = -$timezone;
9432 if ($timezone === false)
9434 $cache[$dt][$rfc822_tz] = mktime($hour, $minute, $second, $month, $day, $year);
9436 else
9438 $cache[$dt][$rfc822_tz] = gmmktime($hour, $minute, $second, $month, $day, $year) - $timezone;
9441 elseif (($time = strtotime($dt)) > 0)
9443 $cache[$dt][$rfc822_tz] = $time;
9445 else
9447 $cache[$dt][$rfc822_tz] = false;
9450 return $cache[$dt][$rfc822_tz];
9454 * Decode HTML entities
9456 * @static
9457 * @access public
9458 * @param string $data Input data
9459 * @return string Output data
9461 function entities_decode($data)
9463 $decoder = new SimplePie_Decode_HTML_Entities($data);
9464 return $decoder->parse();
9468 * Remove RFC822 comments
9470 * @author Tomas V.V.Cox <cox@idecnet.com>
9471 * @author Pierre-Alain Joye <pajoye@php.net>
9472 * @author Amir Mohammad Saied <amir@php.net>
9473 * @copyright 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox,Amir Mohammad Saied
9474 * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
9475 * @version CVS: $Id: Validate.php,v 1.104 2006/11/17 16:32:06 amir Exp $
9476 * @link http://pear.php.net/package/Validate
9477 * @access public
9478 * @param string $data Data to strip comments from
9479 * @return string Comment stripped string
9481 function uncomment_rfc822($data)
9483 if ((version_compare(PHP_VERSION, '4.4.6', '>=') && version_compare(PHP_VERSION, '5', '<')) || version_compare(PHP_VERSION, '5.2.2', '>='))
9485 return $data;
9487 else
9489 return preg_replace('/((?:(?:\\\\"|[^("])*(?:"(?:[^"\\\\\r]|\\\\.)*"\s*)?)*)((?<!\\\\)\((?:(?2)|.)*?(?<!\\\\)\))/', '$1', $data);
9493 function parse_mime($mime)
9495 if (($pos = strpos($mime, ';')) === false)
9497 return trim($mime);
9499 else
9501 return trim(substr($mime, 0, $pos));
9505 function htmlspecialchars_decode($string, $quote_style)
9507 if (function_exists('htmlspecialchars_decode'))
9509 return htmlspecialchars_decode($string, $quote_style);
9511 else
9513 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
9517 function atom_03_construct_type($attribs)
9519 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
9521 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
9523 else
9525 $mode = SIMPLEPIE_CONSTRUCT_NONE;
9527 if (isset($attribs['']['type']))
9529 switch (strtolower(trim($attribs['']['type'])))
9531 case 'text':
9532 case 'text/plain':
9533 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
9535 case 'html':
9536 case 'text/html':
9537 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
9539 case 'xhtml':
9540 case 'application/xhtml+xml':
9541 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
9543 default:
9544 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
9547 else
9549 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
9553 function atom_10_construct_type($attribs)
9555 if (isset($attribs['']['type']))
9557 switch (strtolower(trim($attribs['']['type'])))
9559 case 'text':
9560 return SIMPLEPIE_CONSTRUCT_TEXT;
9562 case 'html':
9563 return SIMPLEPIE_CONSTRUCT_HTML;
9565 case 'xhtml':
9566 return SIMPLEPIE_CONSTRUCT_XHTML;
9568 default:
9569 return SIMPLEPIE_CONSTRUCT_NONE;
9572 return SIMPLEPIE_CONSTRUCT_TEXT;
9575 function atom_10_content_construct_type($attribs)
9577 if (isset($attribs['']['type']))
9579 $type = strtolower(trim($attribs['']['type']));
9580 switch ($type)
9582 case 'text':
9583 return SIMPLEPIE_CONSTRUCT_TEXT;
9585 case 'html':
9586 return SIMPLEPIE_CONSTRUCT_HTML;
9588 case 'xhtml':
9589 return SIMPLEPIE_CONSTRUCT_XHTML;
9591 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
9593 return SIMPLEPIE_CONSTRUCT_NONE;
9595 else
9597 return SIMPLEPIE_CONSTRUCT_BASE64;
9600 else
9602 return SIMPLEPIE_CONSTRUCT_TEXT;
9606 function is_isegment_nz_nc($string)
9608 return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string);
9611 function space_seperated_tokens($string)
9613 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
9614 $string_length = strlen($string);
9616 $position = strspn($string, $space_characters);
9617 $tokens = array();
9619 while ($position < $string_length)
9621 $len = strcspn($string, $space_characters, $position);
9622 $tokens[] = substr($string, $position, $len);
9623 $position += $len;
9624 $position += strspn($string, $space_characters, $position);
9627 return $tokens;
9630 function array_unique($array)
9632 if (version_compare(PHP_VERSION, '5.2', '>='))
9634 return array_unique($array);
9636 else
9638 $array = (array) $array;
9639 $new_array = array();
9640 $new_array_strings = array();
9641 foreach ($array as $key => $value)
9643 if (is_object($value))
9645 if (method_exists($value, '__toString'))
9647 $cmp = $value->__toString();
9649 else
9651 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
9654 elseif (is_array($value))
9656 $cmp = (string) reset($value);
9658 else
9660 $cmp = (string) $value;
9662 if (!in_array($cmp, $new_array_strings))
9664 $new_array[$key] = $value;
9665 $new_array_strings[] = $cmp;
9668 return $new_array;
9673 * Converts a unicode codepoint to a UTF-8 character
9675 * @static
9676 * @access public
9677 * @param int $codepoint Unicode codepoint
9678 * @return string UTF-8 character
9680 function codepoint_to_utf8($codepoint)
9682 static $cache = array();
9683 $codepoint = (int) $codepoint;
9684 if (isset($cache[$codepoint]))
9686 return $cache[$codepoint];
9688 elseif ($codepoint < 0)
9690 return $cache[$codepoint] = false;
9692 else if ($codepoint <= 0x7f)
9694 return $cache[$codepoint] = chr($codepoint);
9696 else if ($codepoint <= 0x7ff)
9698 return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
9700 else if ($codepoint <= 0xffff)
9702 return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
9704 else if ($codepoint <= 0x10ffff)
9706 return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
9708 else
9710 // U+FFFD REPLACEMENT CHARACTER
9711 return $cache[$codepoint] = "\xEF\xBF\xBD";
9716 * Re-implementation of PHP 4.2.0's is_a()
9718 * @static
9719 * @access public
9720 * @param object $object The tested object
9721 * @param string $class_name The class name
9722 * @return bool Returns true if the object is of this class or has this class as one of its parents, false otherwise
9724 function is_a($object, $class_name)
9726 if (function_exists('is_a'))
9728 return is_a($object, $class_name);
9730 elseif (!is_object($object))
9732 return false;
9734 elseif (get_class($object) == strtolower($class_name))
9736 return true;
9738 else
9740 return is_subclass_of($object, $class_name);
9745 * Re-implementation of PHP 5's stripos()
9747 * Returns the numeric position of the first occurrence of needle in the
9748 * haystack string.
9750 * @static
9751 * @access string
9752 * @param object $haystack
9753 * @param string $needle Note that the needle may be a string of one or more
9754 * characters. If needle is not a string, it is converted to an integer
9755 * and applied as the ordinal value of a character.
9756 * @param int $offset The optional offset parameter allows you to specify which
9757 * character in haystack to start searching. The position returned is still
9758 * relative to the beginning of haystack.
9759 * @return bool If needle is not found, stripos() will return boolean false.
9761 function stripos($haystack, $needle, $offset = 0)
9763 if (function_exists('stripos'))
9765 return stripos($haystack, $needle, $offset);
9767 else
9769 if (is_string($needle))
9771 $needle = strtolower($needle);
9773 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
9775 $needle = strtolower(chr($needle));
9777 else
9779 trigger_error('needle is not a string or an integer', E_USER_WARNING);
9780 return false;
9783 return strpos(strtolower($haystack), $needle, $offset);
9789 * Decode HTML Entities
9791 * This implements HTML5 as of revision 967 (2007-06-28)
9793 * @package SimplePie
9795 class SimplePie_Decode_HTML_Entities
9798 * Data to be parsed
9800 * @access private
9801 * @var string
9803 var $data = '';
9806 * Currently consumed bytes
9808 * @access private
9809 * @var string
9811 var $consumed = '';
9814 * Position of the current byte being parsed
9816 * @access private
9817 * @var int
9819 var $position = 0;
9822 * Create an instance of the class with the input data
9824 * @access public
9825 * @param string $data Input data
9827 function SimplePie_Decode_HTML_Entities($data)
9829 $this->data = $data;
9833 * Parse the input data
9835 * @access public
9836 * @return string Output data
9838 function parse()
9840 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
9842 $this->consume();
9843 $this->entity();
9844 $this->consumed = '';
9846 return $this->data;
9850 * Consume the next byte
9852 * @access private
9853 * @return mixed The next byte, or false, if there is no more data
9855 function consume()
9857 if (isset($this->data[$this->position]))
9859 $this->consumed .= $this->data[$this->position];
9860 return $this->data[$this->position++];
9862 else
9864 $this->consumed = false;
9865 return false;
9870 * Consume a range of characters
9872 * @access private
9873 * @param string $chars Characters to consume
9874 * @return mixed A series of characters that match the range, or false
9876 function consume_range($chars)
9878 if ($len = strspn($this->data, $chars, $this->position))
9880 $data = substr($this->data, $this->position, $len);
9881 $this->consumed .= $data;
9882 $this->position += $len;
9883 return $data;
9885 else
9887 $this->consumed = false;
9888 return false;
9893 * Unconsume one byte
9895 * @access private
9897 function unconsume()
9899 $this->consumed = substr($this->consumed, 0, -1);
9900 $this->position--;
9904 * Decode an entity
9906 * @access private
9908 function entity()
9910 switch ($this->consume())
9912 case "\x09":
9913 case "\x0A":
9914 case "\x0B":
9915 case "\x0B":
9916 case "\x0C":
9917 case "\x20":
9918 case "\x3C":
9919 case "\x26":
9920 case false:
9921 break;
9923 case "\x23":
9924 switch ($this->consume())
9926 case "\x78":
9927 case "\x58":
9928 $range = '0123456789ABCDEFabcdef';
9929 $hex = true;
9930 break;
9932 default:
9933 $range = '0123456789';
9934 $hex = false;
9935 $this->unconsume();
9936 break;
9939 if ($codepoint = $this->consume_range($range))
9941 static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8");
9943 if ($hex)
9945 $codepoint = hexdec($codepoint);
9947 else
9949 $codepoint = intval($codepoint);
9952 if (isset($windows_1252_specials[$codepoint]))
9954 $replacement = $windows_1252_specials[$codepoint];
9956 else
9958 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
9961 if ($this->consume() != ';')
9963 $this->unconsume();
9966 $consumed_length = strlen($this->consumed);
9967 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
9968 $this->position += strlen($replacement) - $consumed_length;
9970 break;
9972 default:
9973 static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C");
9975 for ($i = 0, $match = null; $i < 9 && $this->consume(); $i++)
9977 $consumed = substr($this->consumed, 1);
9978 if (isset($entities[$consumed]))
9980 $match = $consumed;
9984 if ($match !== null)
9986 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
9987 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
9989 break;
9994 class SimplePie_Locator
9996 var $useragent;
9997 var $timeout;
9998 var $file;
9999 var $local = array();
10000 var $elsewhere = array();
10001 var $file_class = 'SimplePie_File';
10002 var $cached_entities = array();
10003 var $http_base;
10004 var $base;
10005 var $base_location = 0;
10006 var $checked_feeds = 0;
10007 var $max_checked_feeds = 10;
10009 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10)
10011 $this->file =& $file;
10012 $this->file_class = $file_class;
10013 $this->useragent = $useragent;
10014 $this->timeout = $timeout;
10015 $this->max_checked_feeds = $max_checked_feeds;
10018 function find($type = SIMPLEPIE_LOCATOR_ALL)
10020 if ($this->is_feed($this->file))
10022 return $this->file;
10025 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
10027 $this->get_base();
10030 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
10032 return $working;
10035 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
10037 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
10039 return $working;
10042 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
10044 return $working;
10047 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
10049 return $working;
10052 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
10054 return $working;
10057 return null;
10060 function is_feed(&$file)
10062 $body = SimplePie_Misc::strip_comments($file->body);
10063 if (preg_match('/<([^\s:]+:)?(rss|RDF|feed)' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/i', $body))
10065 return true;
10067 return false;
10070 function get_base()
10072 if (isset($this->file->headers['content-location']))
10074 $this->http_base = SimplePie_Misc::absolutize_url(trim($this->file->headers['content-location']), $this->file->url);
10076 else
10078 $this->http_base = $this->file->url;
10080 $this->base = $this->http_base;
10081 $elements = SimplePie_Misc::get_element('base', $this->file->body);
10082 foreach ($elements as $element)
10084 if ($element['attribs']['href']['data'] !== '')
10086 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
10087 $this->base_location = $element['offset'];
10088 break;
10093 function autodiscovery()
10095 $links = array_merge(SimplePie_Misc::get_element('link', $this->file->body), SimplePie_Misc::get_element('a', $this->file->body), SimplePie_Misc::get_element('area', $this->file->body));
10096 $done = array();
10097 foreach ($links as $link)
10099 if ($this->checked_feeds == $this->max_checked_feeds)
10101 break;
10103 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
10105 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
10107 if ($this->base_location < $link['offset'])
10109 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
10111 else
10113 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
10116 if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml'))))
10118 $this->checked_feeds++;
10119 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
10120 if ($this->is_feed($feed))
10122 return $feed;
10125 $done[] = $href;
10128 return null;
10131 function get_links()
10133 $links = SimplePie_Misc::get_element('a', $this->file->body);
10134 foreach ($links as $link)
10136 if (isset($link['attribs']['href']['data']))
10138 $href = trim($link['attribs']['href']['data']);
10139 $parsed = SimplePie_Misc::parse_url($href);
10140 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
10142 if ($this->base_location < $link['offset'])
10144 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
10146 else
10148 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
10151 $current = SimplePie_Misc::parse_url($this->file->url);
10153 if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
10155 $this->local[] = $href;
10157 else
10159 $this->elsewhere[] = $href;
10164 $this->local = array_unique($this->local);
10165 $this->elsewhere = array_unique($this->elsewhere);
10166 if (!empty($this->local) || !empty($this->elsewhere))
10168 return true;
10170 return null;
10173 function extension(&$array)
10175 foreach ($array as $key => $value)
10177 if ($this->checked_feeds == $this->max_checked_feeds)
10179 break;
10181 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
10183 $this->checked_feeds++;
10184 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
10185 if ($this->is_feed($feed))
10187 return $feed;
10189 else
10191 unset($array[$key]);
10195 return null;
10198 function body(&$array)
10200 foreach ($array as $key => $value)
10202 if ($this->checked_feeds == $this->max_checked_feeds)
10204 break;
10206 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
10208 $this->checked_feeds++;
10209 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
10210 if ($this->is_feed($feed))
10212 return $feed;
10214 else
10216 unset($array[$key]);
10220 return null;
10224 class SimplePie_Parser
10226 var $xml;
10227 var $error_code;
10228 var $error_string;
10229 var $current_line;
10230 var $current_column;
10231 var $current_byte;
10232 var $separator = ' ';
10233 var $feed = false;
10234 var $namespace = array('');
10235 var $element = array('');
10236 var $xml_base = array('');
10237 var $xml_base_explicit = array(false);
10238 var $xml_lang = array('');
10239 var $data = array();
10240 var $datas = array(array());
10241 var $current_xhtml_construct = -1;
10242 var $encoding;
10244 function pre_process(&$data, $encoding)
10246 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
10247 if (strtoupper($encoding) == 'US-ASCII')
10249 $this->encoding = 'UTF-8';
10251 else
10253 $this->encoding = $encoding;
10256 // Strip BOM:
10257 // UTF-32 Big Endian BOM
10258 if (strpos($data, "\x0\x0\xFE\xFF") === 0)
10260 $data = substr($data, 4);
10262 // UTF-32 Little Endian BOM
10263 elseif (strpos($data, "\xFF\xFE\x0\x0") === 0)
10265 $data = substr($data, 4);
10267 // UTF-16 Big Endian BOM
10268 elseif (strpos($data, "\xFE\xFF") === 0)
10270 $data = substr($data, 2);
10272 // UTF-16 Little Endian BOM
10273 elseif (strpos($data, "\xFF\xFE") === 0)
10275 $data = substr($data, 2);
10277 // UTF-8 BOM
10278 elseif (strpos($data, "\xEF\xBB\xBF") === 0)
10280 $data = substr($data, 3);
10283 // Make sure the XML prolog is sane and has the correct encoding
10284 $data = preg_replace("/^<\?xml[\x20\x9\xD\xA]+version([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"1.0\"|'1.0'|\"1.1\"|'1.1')([\x20\x9\xD\xA]+encoding([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"[A-Za-z][A-Za-z0-9._\-]*\"|'[A-Za-z][A-Za-z0-9._\-]*'))?([\x20\x9\xD\xA]+standalone([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"(yes|no)\"|'(yes|no)'))?([\x20\x9\xD\xA]+)?\?>/", '', $data);
10285 $data = "<?xml version='1.0' encoding='$encoding'?>\n" . $data;
10288 function parse(&$data)
10290 $return = true;
10292 // Create the parser
10293 $this->xml = xml_parser_create_ns($this->encoding, $this->separator);
10294 xml_parser_set_option($this->xml, XML_OPTION_SKIP_WHITE, 1);
10295 xml_parser_set_option($this->xml, XML_OPTION_CASE_FOLDING, 0);
10296 xml_set_object($this->xml, $this);
10297 xml_set_character_data_handler($this->xml, 'cdata');
10298 xml_set_element_handler($this->xml, 'tag_open', 'tag_close');
10300 // workound for a bug in PHP/libxml2 as described on http://bugs.simplepie.org/issues/show/101
10301 $data = str_replace('&lt;', '&#60;', $data);
10302 $data = str_replace('&gt;', '&#62;', $data);
10303 $data = str_replace('&amp;', '&#38;', $data);
10304 $data = str_replace('&apos;', '&#39;', $data);
10305 $data = str_replace('&quot;', '&#34;', $data);
10307 // Parse!
10308 if (!xml_parse($this->xml, $data, true))
10310 $this->data = null;
10311 $this->error_code = xml_get_error_code($this->xml);
10312 $this->error_string = xml_error_string($this->error_code);
10313 $return = false;
10315 $this->current_line = xml_get_current_line_number($this->xml);
10316 $this->current_column = xml_get_current_column_number($this->xml);
10317 $this->current_byte = xml_get_current_byte_index($this->xml);
10318 xml_parser_free($this->xml);
10319 return $return;
10322 function get_error_code()
10324 return $this->error_code;
10327 function get_error_string()
10329 return $this->error_string;
10332 function get_current_line()
10334 return $this->current_line;
10337 function get_current_column()
10339 return $this->current_column;
10342 function get_current_byte()
10344 return $this->current_byte;
10347 function get_data()
10349 return $this->data;
10352 function tag_open($parser, $tag, $attributes)
10354 if ($this->feed === 0)
10356 return;
10358 elseif ($this->feed == false)
10360 if (in_array($tag, array(
10361 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
10362 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
10363 'rss',
10364 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
10367 $this->feed = 1;
10370 else
10372 $this->feed++;
10375 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
10377 $attribs = array();
10378 foreach ($attributes as $name => $value)
10380 list($attrib_namespace, $attribute) = $this->split_ns($name);
10381 $attribs[$attrib_namespace][$attribute] = $value;
10384 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
10386 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
10387 $this->xml_base_explicit[] = true;
10389 else
10391 $this->xml_base[] = end($this->xml_base);
10392 $this->xml_base_explicit[] = end($this->xml_base_explicit);
10395 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
10397 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
10399 else
10401 $this->xml_lang[] = end($this->xml_lang);
10404 if ($this->current_xhtml_construct >= 0)
10406 $this->current_xhtml_construct++;
10407 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
10409 $this->data['data'] .= '<' . end($this->element);
10410 if (isset($attribs['']))
10412 foreach ($attribs[''] as $name => $value)
10414 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
10417 $this->data['data'] .= '>';
10420 else
10422 $this->datas[] =& $this->data;
10423 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
10424 $this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang));
10425 if ((end($this->namespace) == SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] == 'xml')
10426 || (end($this->namespace) == SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] == 'xhtml'))
10428 $this->current_xhtml_construct = 0;
10433 function cdata($parser, $cdata)
10435 if ($this->current_xhtml_construct >= 0)
10437 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
10439 elseif ($this->feed > 1)
10441 $this->data['data'] .= $cdata;
10445 function tag_close($parser, $tag)
10447 if (!$this->feed)
10449 return;
10452 if ($this->current_xhtml_construct >= 0)
10454 $this->current_xhtml_construct--;
10455 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param')))
10457 $this->data['data'] .= '</' . end($this->element) . '>';
10460 if ($this->current_xhtml_construct == -1)
10462 $this->data =& $this->datas[$this->feed];
10463 array_pop($this->datas);
10466 array_pop($this->element);
10467 array_pop($this->namespace);
10468 array_pop($this->xml_base);
10469 array_pop($this->xml_base_explicit);
10470 array_pop($this->xml_lang);
10471 $this->feed--;
10474 function split_ns($string)
10476 static $cache = array();
10477 if (!isset($cache[$string]))
10479 if ($pos = strpos($string, $this->separator))
10481 static $separator_length;
10482 if (!$separator_length)
10484 $separator_length = strlen($this->separator);
10486 $cache[$string] = array(substr($string, 0, $pos), substr($string, $pos + $separator_length));
10488 else
10490 $cache[$string] = array('', $string);
10493 return $cache[$string];
10498 * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shortern a string while preserving HTML tags
10500 class SimplePie_Sanitize
10502 // Private vars
10503 var $base;
10505 // Options
10506 var $remove_div = true;
10507 var $image_handler = '';
10508 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
10509 var $encode_instead_of_strip = false;
10510 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
10511 var $strip_comments = false;
10512 var $output_encoding = 'UTF-8';
10513 var $enable_cache = true;
10514 var $cache_location = './cache';
10515 var $cache_name_function = 'md5';
10516 var $cache_class = 'SimplePie_Cache';
10517 var $file_class = 'SimplePie_File';
10518 var $timeout = 10;
10519 var $useragent = '';
10520 var $force_fsockopen = false;
10522 var $replace_url_attributes = array(
10523 'a' => 'href',
10524 'area' => 'href',
10525 'blockquote' => 'cite',
10526 'del' => 'cite',
10527 'form' => 'action',
10528 'img' => array('longdesc', 'src'),
10529 'input' => 'src',
10530 'ins' => 'cite',
10531 'q' => 'cite'
10534 function remove_div($enable = true)
10536 $this->remove_div = (bool) $enable;
10539 function set_image_handler($page = false)
10541 if ($page)
10543 $this->image_handler = (string) $page;
10545 else
10547 $this->image_handler = false;
10551 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
10553 if (isset($enable_cache))
10555 $this->enable_cache = (bool) $enable_cache;
10558 if ($cache_location)
10560 $this->cache_location = (string) $cache_location;
10563 if ($cache_name_function)
10565 $this->cache_name_function = (string) $cache_name_function;
10568 if ($cache_class)
10570 $this->cache_class = (string) $cache_class;
10574 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
10576 if ($file_class)
10578 $this->file_class = (string) $file_class;
10581 if ($timeout)
10583 $this->timeout = (string) $timeout;
10586 if ($useragent)
10588 $this->useragent = (string) $useragent;
10591 if ($force_fsockopen)
10593 $this->force_fsockopen = (string) $force_fsockopen;
10597 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
10599 if ($tags)
10601 if (is_array($tags))
10603 $this->strip_htmltags = $tags;
10605 else
10607 $this->strip_htmltags = explode(',', $tags);
10610 else
10612 $this->strip_htmltags = false;
10616 function encode_instead_of_strip($encode = false)
10618 $this->encode_instead_of_strip = (bool) $encode;
10621 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
10623 if ($attribs)
10625 if (is_array($attribs))
10627 $this->strip_attributes = $attribs;
10629 else
10631 $this->strip_attributes = explode(',', $attribs);
10634 else
10636 $this->strip_attributes = false;
10640 function strip_comments($strip = false)
10642 $this->strip_comments = (bool) $strip;
10645 function set_output_encoding($encoding = 'UTF-8')
10647 $this->output_encoding = (string) $encoding;
10651 * Set element/attribute key/value pairs of HTML attributes
10652 * containing URLs that need to be resolved relative to the feed
10654 * @access public
10655 * @since 1.0
10656 * @param array $element_attribute Element/attribute key/value pairs
10658 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'))
10660 $this->replace_url_attributes = (array) $element_attribute;
10663 function sanitize($data, $type, $base = '')
10665 $data = trim($data);
10666 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
10668 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
10670 if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/(\w+)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
10672 $type |= SIMPLEPIE_CONSTRUCT_HTML;
10674 else
10676 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
10680 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
10682 $data = base64_decode($data);
10685 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
10687 if ($this->remove_div)
10689 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
10690 $data = preg_replace('/<\/div>$/', '', $data);
10692 else
10694 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
10698 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
10700 // Strip comments
10701 if ($this->strip_comments)
10703 $data = SimplePie_Misc::strip_comments($data);
10706 // Strip out HTML tags and attributes that might cause various security problems.
10707 // Based on recommendations by Mark Pilgrim at:
10708 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
10709 if ($this->strip_htmltags)
10711 foreach ($this->strip_htmltags as $tag)
10713 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
10714 while (preg_match($pcre, $data))
10716 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
10721 if ($this->strip_attributes)
10723 foreach ($this->strip_attributes as $attrib)
10725 $data = preg_replace('/ '. trim($attrib) .'=("|&quot;)(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|\'|&apos;|<|>|\+|{|})*("|&quot;)/i', '', $data);
10726 $data = preg_replace('/ '. trim($attrib) .'=(\'|&apos;)(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|"|&quot;|<|>|\+|{|})*(\'|&apos;)/i', '', $data);
10727 $data = preg_replace('/ '. trim($attrib) .'=(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|\+|{|})*/i', '', $data);
10731 // Replace relative URLs
10732 $this->base = $base;
10733 foreach ($this->replace_url_attributes as $element => $attributes)
10735 $data = $this->replace_urls($data, $element, $attributes);
10738 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
10739 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
10741 $images = SimplePie_Misc::get_element('img', $data);
10742 foreach ($images as $img)
10744 if (isset($img['attribs']['src']['data']))
10746 $image_url = $img['attribs']['src']['data'];
10747 $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $image_url), 'spi');
10749 if ($cache->load())
10751 $img['attribs']['src']['data'] = $this->image_handler . rawurlencode($img['attribs']['src']['data']);
10752 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
10754 else
10756 $file =& new $this->file_class($image_url, $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
10757 $headers = $file->headers;
10759 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
10761 if (!$cache->save(array('headers' => $file->headers, 'body' => $file->body)))
10763 trigger_error("$cache->name is not writeable", E_USER_WARNING);
10765 $img['attribs']['src']['data'] = $this->image_handler . rawurlencode($img['attribs']['src']['data']);
10766 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
10773 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
10774 $data = trim($data);
10777 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
10779 $data = SimplePie_Misc::absolutize_url($data, $base);
10782 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
10784 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
10787 if ($this->output_encoding != 'UTF-8')
10789 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
10792 return $data;
10795 function replace_urls($data, $tag, $attributes)
10797 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
10799 $elements = SimplePie_Misc::get_element($tag, $data);
10800 foreach ($elements as $element)
10802 if (is_array($attributes))
10804 foreach ($attributes as $attribute)
10806 if (isset($element['attribs'][$attribute]['data']))
10808 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
10809 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
10813 elseif (isset($element['attribs'][$attributes]['data']))
10815 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
10816 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
10820 return $data;
10823 function do_strip_htmltags($match)
10825 if ($this->encode_instead_of_strip)
10827 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
10829 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
10830 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
10831 return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
10833 else
10835 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
10838 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
10840 return $match[4];
10842 else
10844 return '';