Joomla Platform  13.1
Documentation des API du framework Joomla Platform
 Tout Classes Espaces de nommage Fichiers Fonctions Variables Pages
simplepie.php
Aller à la documentation de ce fichier.
1 <?php
2 /**
3  * This file will be removed in Joomla! CMS version 3.2. Developers should either supply their own copy
4  * in their installation packages or switch to JFeed.
5  */
6 /**
7  * SimplePie
8  *
9  * A PHP-Based RSS and Atom Feed Framework.
10  * Takes the hard work out of managing a complete RSS/Atom solution.
11  *
12  * Copyright (c) 2004-2009, Ryan Parman and Geoffrey Sneddon
13  * All rights reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without modification, are
16  * permitted provided that the following conditions are met:
17  *
18  * * Redistributions of source code must retain the above copyright notice, this list of
19  * conditions and the following disclaimer.
20  *
21  * * Redistributions in binary form must reproduce the above copyright notice, this list
22  * of conditions and the following disclaimer in the documentation and/or other materials
23  * provided with the distribution.
24  *
25  * * Neither the name of the SimplePie Team nor the names of its contributors may be used
26  * to endorse or promote products derived from this software without specific prior
27  * written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
30  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
31  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
32  * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
36  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  *
39  * @package SimplePie
40  * @version 1.2
41  * @copyright 2004-2009 Ryan Parman, Geoffrey Sneddon
42  * @author Ryan Parman
43  * @author Geoffrey Sneddon
44  * @link http://simplepie.org/ SimplePie
45  * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
46  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
47  * @todo phpDoc comments
48  */
49 
50 /**
51  * SimplePie Name
52  */
53 define('SIMPLEPIE_NAME', 'SimplePie');
54 
55 /**
56  * SimplePie Version
57  */
58 define('SIMPLEPIE_VERSION', '1.2');
59 
60 /**
61  * SimplePie Build
62  */
63 define('SIMPLEPIE_BUILD', '20090627192103');
64 
65 /**
66  * SimplePie Website URL
67  */
68 define('SIMPLEPIE_URL', 'http://simplepie.org');
69 
70 /**
71  * SimplePie Useragent
72  * @see SimplePie::set_useragent()
73  */
74 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
75 
76 /**
77  * SimplePie Linkback
78  */
79 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
80 
81 /**
82  * No Autodiscovery
83  * @see SimplePie::set_autodiscovery_level()
84  */
85 define('SIMPLEPIE_LOCATOR_NONE', 0);
86 
87 /**
88  * Feed Link Element Autodiscovery
89  * @see SimplePie::set_autodiscovery_level()
90  */
91 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
92 
93 /**
94  * Local Feed Extension Autodiscovery
95  * @see SimplePie::set_autodiscovery_level()
96  */
97 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
98 
99 /**
100  * Local Feed Body Autodiscovery
101  * @see SimplePie::set_autodiscovery_level()
102  */
103 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
104 
105 /**
106  * Remote Feed Extension Autodiscovery
107  * @see SimplePie::set_autodiscovery_level()
108  */
109 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
110 
111 /**
112  * Remote Feed Body Autodiscovery
113  * @see SimplePie::set_autodiscovery_level()
114  */
115 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
116 
117 /**
118  * All Feed Autodiscovery
119  * @see SimplePie::set_autodiscovery_level()
120  */
121 define('SIMPLEPIE_LOCATOR_ALL', 31);
122 
123 /**
124  * No known feed type
125  */
126 define('SIMPLEPIE_TYPE_NONE', 0);
127 
128 /**
129  * RSS 0.90
130  */
131 define('SIMPLEPIE_TYPE_RSS_090', 1);
132 
133 /**
134  * RSS 0.91 (Netscape)
135  */
136 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
137 
138 /**
139  * RSS 0.91 (Userland)
140  */
141 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
142 
143 /**
144  * RSS 0.91 (both Netscape and Userland)
145  */
146 define('SIMPLEPIE_TYPE_RSS_091', 6);
147 
148 /**
149  * RSS 0.92
150  */
151 define('SIMPLEPIE_TYPE_RSS_092', 8);
152 
153 /**
154  * RSS 0.93
155  */
156 define('SIMPLEPIE_TYPE_RSS_093', 16);
157 
158 /**
159  * RSS 0.94
160  */
161 define('SIMPLEPIE_TYPE_RSS_094', 32);
162 
163 /**
164  * RSS 1.0
165  */
166 define('SIMPLEPIE_TYPE_RSS_10', 64);
167 
168 /**
169  * RSS 2.0
170  */
171 define('SIMPLEPIE_TYPE_RSS_20', 128);
172 
173 /**
174  * RDF-based RSS
175  */
176 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
177 
178 /**
179  * Non-RDF-based RSS (truly intended as syndication format)
180  */
181 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
182 
183 /**
184  * All RSS
185  */
186 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
187 
188 /**
189  * Atom 0.3
190  */
191 define('SIMPLEPIE_TYPE_ATOM_03', 256);
192 
193 /**
194  * Atom 1.0
195  */
196 define('SIMPLEPIE_TYPE_ATOM_10', 512);
197 
198 /**
199  * All Atom
200  */
201 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
202 
203 /**
204  * All feed types
205  */
206 define('SIMPLEPIE_TYPE_ALL', 1023);
207 
208 /**
209  * No construct
210  */
211 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
212 
213 /**
214  * Text construct
215  */
216 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
217 
218 /**
219  * HTML construct
220  */
221 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
222 
223 /**
224  * XHTML construct
225  */
226 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
227 
228 /**
229  * base64-encoded construct
230  */
231 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
232 
233 /**
234  * IRI construct
235  */
236 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
237 
238 /**
239  * A construct that might be HTML
240  */
241 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
242 
243 /**
244  * All constructs
245  */
246 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
247 
248 /**
249  * Don't change case
250  */
251 define('SIMPLEPIE_SAME_CASE', 1);
252 
253 /**
254  * Change to lowercase
255  */
256 define('SIMPLEPIE_LOWERCASE', 2);
257 
258 /**
259  * Change to uppercase
260  */
261 define('SIMPLEPIE_UPPERCASE', 4);
262 
263 /**
264  * PCRE for HTML attributes
265  */
266 define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
267 
268 /**
269  * PCRE for XML attributes
270  */
271 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
272 
273 /**
274  * XML Namespace
275  */
276 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
277 
278 /**
279  * Atom 1.0 Namespace
280  */
281 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
282 
283 /**
284  * Atom 0.3 Namespace
285  */
286 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
287 
288 /**
289  * RDF Namespace
290  */
291 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
292 
293 /**
294  * RSS 0.90 Namespace
295  */
296 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
297 
298 /**
299  * RSS 1.0 Namespace
300  */
301 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
302 
303 /**
304  * RSS 1.0 Content Module Namespace
305  */
306 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
307 
308 /**
309  * RSS 2.0 Namespace
310  * (Stupid, I know, but I'm certain it will confuse people less with support.)
311  */
312 define('SIMPLEPIE_NAMESPACE_RSS_20', '');
313 
314 /**
315  * DC 1.0 Namespace
316  */
317 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
318 
319 /**
320  * DC 1.1 Namespace
321  */
322 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
323 
324 /**
325  * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
326  */
327 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
328 
329 /**
330  * GeoRSS Namespace
331  */
332 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
333 
334 /**
335  * Media RSS Namespace
336  */
337 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
338 
339 /**
340  * Wrong Media RSS Namespace
341  */
342 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
343 
344 /**
345  * iTunes RSS Namespace
346  */
347 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
348 
349 /**
350  * XHTML Namespace
351  */
352 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
353 
354 /**
355  * IANA Link Relations Registry
356  */
357 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
358 
359 /**
360  * Whether we're running on PHP5
361  */
362 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
363 
364 /**
365  * No file source
366  */
367 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
368 
369 /**
370  * Remote file source
371  */
372 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
373 
374 /**
375  * Local file source
376  */
377 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
378 
379 /**
380  * fsockopen() file source
381  */
382 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
383 
384 /**
385  * cURL file source
386  */
387 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
388 
389 /**
390  * file_get_contents() file source
391  */
392 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
393 
394 /**
395  * SimplePie
396  *
397  * @package SimplePie
398  */
400 {
401  /**
402  * @var array Raw data
403  * @access private
404  */
405  var $data = array();
406 
407  /**
408  * @var mixed Error string
409  * @access private
410  */
411  var $error;
412 
413  /**
414  * @var object Instance of SimplePie_Sanitize (or other class)
415  * @see SimplePie::set_sanitize_class()
416  * @access private
417  */
419 
420  /**
421  * @var string SimplePie Useragent
422  * @see SimplePie::set_useragent()
423  * @access private
424  */
426 
427  /**
428  * @var string Feed URL
429  * @see SimplePie::set_feed_url()
430  * @access private
431  */
433 
434  /**
435  * @var object Instance of SimplePie_File to use as a feed
436  * @see SimplePie::set_file()
437  * @access private
438  */
439  var $file;
440 
441  /**
442  * @var string Raw feed data
443  * @see SimplePie::set_raw_data()
444  * @access private
445  */
447 
448  /**
449  * @var int Timeout for fetching remote files
450  * @see SimplePie::set_timeout()
451  * @access private
452  */
453  var $timeout = 10;
454 
455  /**
456  * @var bool Forces fsockopen() to be used for remote files instead
457  * of cURL, even if a new enough version is installed
458  * @see SimplePie::force_fsockopen()
459  * @access private
460  */
461  var $force_fsockopen = false;
462 
463  /**
464  * @var bool Force the given data/URL to be treated as a feed no matter what
465  * it appears like
466  * @see SimplePie::force_feed()
467  * @access private
468  */
469  var $force_feed = false;
470 
471  /**
472  * @var bool Enable/Disable XML dump
473  * @see SimplePie::enable_xml_dump()
474  * @access private
475  */
476  var $xml_dump = false;
477 
478  /**
479  * @var bool Enable/Disable Caching
480  * @see SimplePie::enable_cache()
481  * @access private
482  */
483  var $cache = true;
484 
485  /**
486  * @var int Cache duration (in seconds)
487  * @see SimplePie::set_cache_duration()
488  * @access private
489  */
490  var $cache_duration = 3600;
491 
492  /**
493  * @var int Auto-discovery cache duration (in seconds)
494  * @see SimplePie::set_autodiscovery_cache_duration()
495  * @access private
496  */
497  var $autodiscovery_cache_duration = 604800; // 7 Days.
498 
499  /**
500  * @var string Cache location (relative to executing script)
501  * @see SimplePie::set_cache_location()
502  * @access private
503  */
504  var $cache_location = './cache';
505 
506  /**
507  * @var string Function that creates the cache filename
508  * @see SimplePie::set_cache_name_function()
509  * @access private
510  */
511  var $cache_name_function = 'md5';
512 
513  /**
514  * @var bool Reorder feed by date descending
515  * @see SimplePie::enable_order_by_date()
516  * @access private
517  */
518  var $order_by_date = true;
519 
520  /**
521  * @var mixed Force input encoding to be set to the follow value
522  * (false, or anything type-cast to false, disables this feature)
523  * @see SimplePie::set_input_encoding()
524  * @access private
525  */
526  var $input_encoding = false;
527 
528  /**
529  * @var int Feed Autodiscovery Level
530  * @see SimplePie::set_autodiscovery_level()
531  * @access private
532  */
534 
535  /**
536  * @var string Class used for caching feeds
537  * @see SimplePie::set_cache_class()
538  * @access private
539  */
540  var $cache_class = 'SimplePie_Cache';
541 
542  /**
543  * @var string Class used for locating feeds
544  * @see SimplePie::set_locator_class()
545  * @access private
546  */
547  var $locator_class = 'SimplePie_Locator';
548 
549  /**
550  * @var string Class used for parsing feeds
551  * @see SimplePie::set_parser_class()
552  * @access private
553  */
554  var $parser_class = 'SimplePie_Parser';
555 
556  /**
557  * @var string Class used for fetching feeds
558  * @see SimplePie::set_file_class()
559  * @access private
560  */
561  var $file_class = 'SimplePie_File';
562 
563  /**
564  * @var string Class used for items
565  * @see SimplePie::set_item_class()
566  * @access private
567  */
568  var $item_class = 'SimplePie_Item';
569 
570  /**
571  * @var string Class used for authors
572  * @see SimplePie::set_author_class()
573  * @access private
574  */
575  var $author_class = 'SimplePie_Author';
576 
577  /**
578  * @var string Class used for categories
579  * @see SimplePie::set_category_class()
580  * @access private
581  */
582  var $category_class = 'SimplePie_Category';
583 
584  /**
585  * @var string Class used for enclosures
586  * @see SimplePie::set_enclosures_class()
587  * @access private
588  */
589  var $enclosure_class = 'SimplePie_Enclosure';
590 
591  /**
592  * @var string Class used for Media RSS <media:text> captions
593  * @see SimplePie::set_caption_class()
594  * @access private
595  */
596  var $caption_class = 'SimplePie_Caption';
597 
598  /**
599  * @var string Class used for Media RSS <media:copyright>
600  * @see SimplePie::set_copyright_class()
601  * @access private
602  */
603  var $copyright_class = 'SimplePie_Copyright';
604 
605  /**
606  * @var string Class used for Media RSS <media:credit>
607  * @see SimplePie::set_credit_class()
608  * @access private
609  */
610  var $credit_class = 'SimplePie_Credit';
611 
612  /**
613  * @var string Class used for Media RSS <media:rating>
614  * @see SimplePie::set_rating_class()
615  * @access private
616  */
617  var $rating_class = 'SimplePie_Rating';
618 
619  /**
620  * @var string Class used for Media RSS <media:restriction>
621  * @see SimplePie::set_restriction_class()
622  * @access private
623  */
624  var $restriction_class = 'SimplePie_Restriction';
625 
626  /**
627  * @var string Class used for content-type sniffing
628  * @see SimplePie::set_content_type_sniffer_class()
629  * @access private
630  */
631  var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
632 
633  /**
634  * @var string Class used for item sources.
635  * @see SimplePie::set_source_class()
636  * @access private
637  */
638  var $source_class = 'SimplePie_Source';
639 
640  /**
641  * @var mixed Set javascript query string parameter (false, or
642  * anything type-cast to false, disables this feature)
643  * @see SimplePie::set_javascript()
644  * @access private
645  */
646  var $javascript = 'js';
647 
648  /**
649  * @var int Maximum number of feeds to check with autodiscovery
650  * @see SimplePie::set_max_checked_feeds()
651  * @access private
652  */
654 
655  /**
656  * @var array All the feeds found during the autodiscovery process
657  * @see SimplePie::get_all_discovered_feeds()
658  * @access private
659  */
660  var $all_discovered_feeds = array();
661 
662  /**
663  * @var string Web-accessible path to the handler_favicon.php file.
664  * @see SimplePie::set_favicon_handler()
665  * @access private
666  */
668 
669  /**
670  * @var string Web-accessible path to the handler_image.php file.
671  * @see SimplePie::set_image_handler()
672  * @access private
673  */
674  var $image_handler = '';
675 
676  /**
677  * @var array Stores the URLs when multiple feeds are being initialized.
678  * @see SimplePie::set_feed_url()
679  * @access private
680  */
681  var $multifeed_url = array();
682 
683  /**
684  * @var array Stores SimplePie objects when multiple feeds initialized.
685  * @access private
686  */
687  var $multifeed_objects = array();
688 
689  /**
690  * @var array Stores the get_object_vars() array for use with multifeeds.
691  * @see SimplePie::set_feed_url()
692  * @access private
693  */
694  var $config_settings = null;
695 
696  /**
697  * @var integer Stores the number of items to return per-feed with multifeeds.
698  * @see SimplePie::set_item_limit()
699  * @access private
700  */
701  var $item_limit = 0;
702 
703  /**
704  * @var array Stores the default attributes to be stripped by strip_attributes().
705  * @see SimplePie::strip_attributes()
706  * @access private
707  */
708  var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
709 
710  /**
711  * @var array Stores the default tags to be stripped by strip_htmltags().
712  * @see SimplePie::strip_htmltags()
713  * @access private
714  */
715  var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
716 
717  /**
718  * The SimplePie class contains feed level data and options
719  *
720  * There are two ways that you can create a new SimplePie object. The first
721  * is by passing a feed URL as a parameter to the SimplePie constructor
722  * (as well as optionally setting the cache location and cache expiry). This
723  * will initialise the whole feed with all of the default settings, and you
724  * can begin accessing methods and properties immediately.
725  *
726  * The second way is to create the SimplePie object with no parameters
727  * at all. This will enable you to set configuration options. After setting
728  * them, you must initialise the feed using $feed->init(). At that point the
729  * object's methods and properties will be available to you. This format is
730  * what is used throughout this documentation.
731  *
732  * @access public
733  * @since 1.0 Preview Release
734  * @param string $feed_url This is the URL you want to parse.
735  * @param string $cache_location This is where you want the cache to be stored.
736  * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
737  */
738  function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
739  {
740  // Other objects, instances created here so we can set options on them
741  $this->sanitize = new SimplePie_Sanitize;
742 
743  // Set options if they're passed to the constructor
744  if ($cache_location !== null)
745  {
747  }
748 
749  if ($cache_duration !== null)
750  {
752  }
753 
754  // Only init the script if we're passed a feed URL
755  if ($feed_url !== null)
756  {
757  $this->set_feed_url($feed_url);
758  $this->init();
759  }
760  }
761 
762  /**
763  * Used for converting object to a string
764  */
765  function __toString()
766  {
767  return md5(serialize($this->data));
768  }
769 
770  /**
771  * Remove items that link back to this before destroying this object
772  */
773  function __destruct()
774  {
775  if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
776  {
777  if (!empty($this->data['items']))
778  {
779  foreach ($this->data['items'] as $item)
780  {
781  $item->__destruct();
782  }
783  unset($item, $this->data['items']);
784  }
785  if (!empty($this->data['ordered_items']))
786  {
787  foreach ($this->data['ordered_items'] as $item)
788  {
789  $item->__destruct();
790  }
791  unset($item, $this->data['ordered_items']);
792  }
793  }
794  }
795 
796  /**
797  * Force the given data/URL to be treated as a feed no matter what it
798  * appears like
799  *
800  * @access public
801  * @since 1.1
802  * @param bool $enable Force the given data/URL to be treated as a feed
803  */
804  function force_feed($enable = false)
805  {
806  $this->force_feed = (bool) $enable;
807  }
808 
809  /**
810  * This is the URL of the feed you want to parse.
811  *
812  * This allows you to enter the URL of the feed you want to parse, or the
813  * website you want to try to use auto-discovery on. This takes priority
814  * over any set raw data.
815  *
816  * You can set multiple feeds to mash together by passing an array instead
817  * of a string for the $url. Remember that with each additional feed comes
818  * additional processing and resources.
819  *
820  * @access public
821  * @since 1.0 Preview Release
822  * @param mixed $url This is the URL (or array of URLs) that you want to parse.
823  * @see SimplePie::set_raw_data()
824  */
825  function set_feed_url($url)
826  {
827  if (is_array($url))
828  {
829  $this->multifeed_url = array();
830  foreach ($url as $value)
831  {
832  $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
833  }
834  }
835  else
836  {
837  $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
838  }
839  }
840 
841  /**
842  * Provides an instance of SimplePie_File to use as a feed
843  *
844  * @access public
845  * @param object &$file Instance of SimplePie_File (or subclass)
846  * @return bool True on success, false on failure
847  */
848  function set_file(&$file)
849  {
850  if (is_a($file, 'SimplePie_File'))
851  {
852  $this->feed_url = $file->url;
853  $this->file =& $file;
854  return true;
855  }
856  return false;
857  }
858 
859  /**
860  * Allows you to use a string of RSS/Atom data instead of a remote feed.
861  *
862  * If you have a feed available as a string in PHP, you can tell SimplePie
863  * to parse that data string instead of a remote feed. Any set feed URL
864  * takes precedence.
865  *
866  * @access public
867  * @since 1.0 Beta 3
868  * @param string $data RSS or Atom data as a string.
869  * @see SimplePie::set_feed_url()
870  */
871  function set_raw_data($data)
872  {
873  $this->raw_data = $data;
874  }
875 
876  /**
877  * Allows you to override the default timeout for fetching remote feeds.
878  *
879  * This allows you to change the maximum time the feed's server to respond
880  * and send the feed back.
881  *
882  * @access public
883  * @since 1.0 Beta 3
884  * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
885  */
886  function set_timeout($timeout = 10)
887  {
888  $this->timeout = (int) $timeout;
889  }
890 
891  /**
892  * Forces SimplePie to use fsockopen() instead of the preferred cURL
893  * functions.
894  *
895  * @access public
896  * @since 1.0 Beta 3
897  * @param bool $enable Force fsockopen() to be used
898  */
899  function force_fsockopen($enable = false)
900  {
901  $this->force_fsockopen = (bool) $enable;
902  }
903 
904  /**
905  * Outputs the raw XML content of the feed, after it has gone through
906  * SimplePie's filters.
907  *
908  * Used only for debugging, this function will output the XML content as
909  * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
910  * before trying to parse it. Many parts of the feed are re-written in
911  * memory, and in the end, you have a parsable feed. XML dump shows you the
912  * actual XML that SimplePie tries to parse, which may or may not be very
913  * different from the original feed.
914  *
915  * @access public
916  * @since 1.0 Preview Release
917  * @param bool $enable Enable XML dump
918  */
919  function enable_xml_dump($enable = false)
920  {
921  $this->xml_dump = (bool) $enable;
922  }
923 
924  /**
925  * Enables/disables caching in SimplePie.
926  *
927  * This option allows you to disable caching all-together in SimplePie.
928  * However, disabling the cache can lead to longer load times.
929  *
930  * @access public
931  * @since 1.0 Preview Release
932  * @param bool $enable Enable caching
933  */
934  function enable_cache($enable = true)
935  {
936  $this->cache = (bool) $enable;
937  }
938 
939  /**
940  * Set the length of time (in seconds) that the contents of a feed
941  * will be cached.
942  *
943  * @access public
944  * @param int $seconds The feed content cache duration.
945  */
946  function set_cache_duration($seconds = 3600)
947  {
948  $this->cache_duration = (int) $seconds;
949  }
950 
951  /**
952  * Set the length of time (in seconds) that the autodiscovered feed
953  * URL will be cached.
954  *
955  * @access public
956  * @param int $seconds The autodiscovered feed URL cache duration.
957  */
958  function set_autodiscovery_cache_duration($seconds = 604800)
959  {
960  $this->autodiscovery_cache_duration = (int) $seconds;
961  }
962 
963  /**
964  * Set the file system location where the cached files should be stored.
965  *
966  * @access public
967  * @param string $location The file system location.
968  */
969  function set_cache_location($location = './cache')
970  {
971  $this->cache_location = (string) $location;
972  }
973 
974  /**
975  * Determines whether feed items should be sorted into reverse chronological order.
976  *
977  * @access public
978  * @param bool $enable Sort as reverse chronological order.
979  */
980  function enable_order_by_date($enable = true)
981  {
982  $this->order_by_date = (bool) $enable;
983  }
984 
985  /**
986  * Allows you to override the character encoding reported by the feed.
987  *
988  * @access public
989  * @param string $encoding Character encoding.
990  */
991  function set_input_encoding($encoding = false)
992  {
993  if ($encoding)
994  {
995  $this->input_encoding = (string) $encoding;
996  }
997  else
998  {
999  $this->input_encoding = false;
1000  }
1001  }
1002 
1003  /**
1004  * Set how much feed autodiscovery to do
1005  *
1006  * @access public
1007  * @see SIMPLEPIE_LOCATOR_NONE
1008  * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
1009  * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
1010  * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
1011  * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
1012  * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
1013  * @see SIMPLEPIE_LOCATOR_ALL
1014  * @param int $level Feed Autodiscovery Level (level can be a
1015  * combination of the above constants, see bitwise OR operator)
1016  */
1018  {
1019  $this->autodiscovery = (int) $level;
1020  }
1021 
1022  /**
1023  * Allows you to change which class SimplePie uses for caching.
1024  * Useful when you are overloading or extending SimplePie's default classes.
1025  *
1026  * @access public
1027  * @param string $class Name of custom class.
1028  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1029  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1030  */
1031  function set_cache_class($class = 'SimplePie_Cache')
1032  {
1033  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1034  {
1035  $this->cache_class = $class;
1036  return true;
1037  }
1038  return false;
1039  }
1040 
1041  /**
1042  * Allows you to change which class SimplePie uses for auto-discovery.
1043  * Useful when you are overloading or extending SimplePie's default classes.
1044  *
1045  * @access public
1046  * @param string $class Name of custom class.
1047  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1048  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1049  */
1050  function set_locator_class($class = 'SimplePie_Locator')
1051  {
1052  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1053  {
1054  $this->locator_class = $class;
1055  return true;
1056  }
1057  return false;
1058  }
1059 
1060  /**
1061  * Allows you to change which class SimplePie uses for XML parsing.
1062  * Useful when you are overloading or extending SimplePie's default classes.
1063  *
1064  * @access public
1065  * @param string $class Name of custom class.
1066  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1067  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1068  */
1069  function set_parser_class($class = 'SimplePie_Parser')
1070  {
1071  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1072  {
1073  $this->parser_class = $class;
1074  return true;
1075  }
1076  return false;
1077  }
1078 
1079  /**
1080  * Allows you to change which class SimplePie uses for remote file fetching.
1081  * Useful when you are overloading or extending SimplePie's default classes.
1082  *
1083  * @access public
1084  * @param string $class Name of custom class.
1085  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1086  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1087  */
1088  function set_file_class($class = 'SimplePie_File')
1089  {
1090  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1091  {
1092  $this->file_class = $class;
1093  return true;
1094  }
1095  return false;
1096  }
1097 
1098  /**
1099  * Allows you to change which class SimplePie uses for data sanitization.
1100  * Useful when you are overloading or extending SimplePie's default classes.
1101  *
1102  * @access public
1103  * @param string $class Name of custom class.
1104  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1105  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1106  */
1107  function set_sanitize_class($class = 'SimplePie_Sanitize')
1108  {
1109  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1110  {
1111  $this->sanitize = new $class;
1112  return true;
1113  }
1114  return false;
1115  }
1116 
1117  /**
1118  * Allows you to change which class SimplePie uses for handling feed items.
1119  * Useful when you are overloading or extending SimplePie's default classes.
1120  *
1121  * @access public
1122  * @param string $class Name of custom class.
1123  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1124  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1125  */
1126  function set_item_class($class = 'SimplePie_Item')
1127  {
1128  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1129  {
1130  $this->item_class = $class;
1131  return true;
1132  }
1133  return false;
1134  }
1135 
1136  /**
1137  * Allows you to change which class SimplePie uses for handling author data.
1138  * Useful when you are overloading or extending SimplePie's default classes.
1139  *
1140  * @access public
1141  * @param string $class Name of custom class.
1142  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1143  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1144  */
1145  function set_author_class($class = 'SimplePie_Author')
1146  {
1147  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1148  {
1149  $this->author_class = $class;
1150  return true;
1151  }
1152  return false;
1153  }
1154 
1155  /**
1156  * Allows you to change which class SimplePie uses for handling category data.
1157  * Useful when you are overloading or extending SimplePie's default classes.
1158  *
1159  * @access public
1160  * @param string $class Name of custom class.
1161  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1162  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1163  */
1164  function set_category_class($class = 'SimplePie_Category')
1165  {
1166  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1167  {
1168  $this->category_class = $class;
1169  return true;
1170  }
1171  return false;
1172  }
1173 
1174  /**
1175  * Allows you to change which class SimplePie uses for feed enclosures.
1176  * Useful when you are overloading or extending SimplePie's default classes.
1177  *
1178  * @access public
1179  * @param string $class Name of custom class.
1180  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1181  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1182  */
1183  function set_enclosure_class($class = 'SimplePie_Enclosure')
1184  {
1185  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1186  {
1187  $this->enclosure_class = $class;
1188  return true;
1189  }
1190  return false;
1191  }
1192 
1193  /**
1194  * Allows you to change which class SimplePie uses for <media:text> captions
1195  * Useful when you are overloading or extending SimplePie's default classes.
1196  *
1197  * @access public
1198  * @param string $class Name of custom class.
1199  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1200  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1201  */
1202  function set_caption_class($class = 'SimplePie_Caption')
1203  {
1204  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1205  {
1206  $this->caption_class = $class;
1207  return true;
1208  }
1209  return false;
1210  }
1211 
1212  /**
1213  * Allows you to change which class SimplePie uses for <media:copyright>
1214  * Useful when you are overloading or extending SimplePie's default classes.
1215  *
1216  * @access public
1217  * @param string $class Name of custom class.
1218  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1219  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1220  */
1221  function set_copyright_class($class = 'SimplePie_Copyright')
1222  {
1223  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1224  {
1225  $this->copyright_class = $class;
1226  return true;
1227  }
1228  return false;
1229  }
1230 
1231  /**
1232  * Allows you to change which class SimplePie uses for <media:credit>
1233  * Useful when you are overloading or extending SimplePie's default classes.
1234  *
1235  * @access public
1236  * @param string $class Name of custom class.
1237  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1238  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1239  */
1240  function set_credit_class($class = 'SimplePie_Credit')
1241  {
1242  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1243  {
1244  $this->credit_class = $class;
1245  return true;
1246  }
1247  return false;
1248  }
1249 
1250  /**
1251  * Allows you to change which class SimplePie uses for <media:rating>
1252  * Useful when you are overloading or extending SimplePie's default classes.
1253  *
1254  * @access public
1255  * @param string $class Name of custom class.
1256  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1257  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1258  */
1259  function set_rating_class($class = 'SimplePie_Rating')
1260  {
1261  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1262  {
1263  $this->rating_class = $class;
1264  return true;
1265  }
1266  return false;
1267  }
1268 
1269  /**
1270  * Allows you to change which class SimplePie uses for <media:restriction>
1271  * Useful when you are overloading or extending SimplePie's default classes.
1272  *
1273  * @access public
1274  * @param string $class Name of custom class.
1275  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1276  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1277  */
1278  function set_restriction_class($class = 'SimplePie_Restriction')
1279  {
1280  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1281  {
1282  $this->restriction_class = $class;
1283  return true;
1284  }
1285  return false;
1286  }
1287 
1288  /**
1289  * Allows you to change which class SimplePie uses for content-type sniffing.
1290  * Useful when you are overloading or extending SimplePie's default classes.
1291  *
1292  * @access public
1293  * @param string $class Name of custom class.
1294  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1295  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1296  */
1297  function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1298  {
1299  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1300  {
1301  $this->content_type_sniffer_class = $class;
1302  return true;
1303  }
1304  return false;
1305  }
1306 
1307  /**
1308  * Allows you to change which class SimplePie uses item sources.
1309  * Useful when you are overloading or extending SimplePie's default classes.
1310  *
1311  * @access public
1312  * @param string $class Name of custom class.
1313  * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1314  * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1315  */
1316  function set_source_class($class = 'SimplePie_Source')
1317  {
1318  if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1319  {
1320  $this->source_class = $class;
1321  return true;
1322  }
1323  return false;
1324  }
1325 
1326  /**
1327  * Allows you to override the default user agent string.
1328  *
1329  * @access public
1330  * @param string $ua New user agent string.
1331  */
1333  {
1334  $this->useragent = (string) $ua;
1335  }
1336 
1337  /**
1338  * Set callback function to create cache filename with
1339  *
1340  * @access public
1341  * @param mixed $function Callback function
1342  */
1343  function set_cache_name_function($function = 'md5')
1344  {
1345  if (is_callable($function))
1346  {
1347  $this->cache_name_function = $function;
1348  }
1349  }
1350 
1351  /**
1352  * Set javascript query string parameter
1353  *
1354  * @access public
1355  * @param mixed $get Javascript query string parameter
1356  */
1357  function set_javascript($get = 'js')
1358  {
1359  if ($get)
1360  {
1361  $this->javascript = (string) $get;
1362  }
1363  else
1364  {
1365  $this->javascript = false;
1366  }
1367  }
1368 
1369  /**
1370  * Set options to make SP as fast as possible. Forgoes a
1371  * substantial amount of data sanitization in favor of speed.
1372  *
1373  * @access public
1374  * @param bool $set Whether to set them or not
1375  */
1376  function set_stupidly_fast($set = false)
1377  {
1378  if ($set)
1379  {
1380  $this->enable_order_by_date(false);
1381  $this->remove_div(false);
1382  $this->strip_comments(false);
1383  $this->strip_htmltags(false);
1384  $this->strip_attributes(false);
1385  $this->set_image_handler(false);
1386  }
1387  }
1388 
1389  /**
1390  * Set maximum number of feeds to check with autodiscovery
1391  *
1392  * @access public
1393  * @param int $max Maximum number of feeds to check
1394  */
1395  function set_max_checked_feeds($max = 10)
1396  {
1397  $this->max_checked_feeds = (int) $max;
1398  }
1399 
1400  function remove_div($enable = true)
1401  {
1402  $this->sanitize->remove_div($enable);
1403  }
1404 
1405  function strip_htmltags($tags = '', $encode = null)
1406  {
1407  if ($tags === '')
1408  {
1409  $tags = $this->strip_htmltags;
1410  }
1411  $this->sanitize->strip_htmltags($tags);
1412  if ($encode !== null)
1413  {
1414  $this->sanitize->encode_instead_of_strip($tags);
1415  }
1416  }
1417 
1418  function encode_instead_of_strip($enable = true)
1419  {
1420  $this->sanitize->encode_instead_of_strip($enable);
1421  }
1422 
1423  function strip_attributes($attribs = '')
1424  {
1425  if ($attribs === '')
1426  {
1427  $attribs = $this->strip_attributes;
1428  }
1429  $this->sanitize->strip_attributes($attribs);
1430  }
1431 
1432  function set_output_encoding($encoding = 'UTF-8')
1433  {
1434  $this->sanitize->set_output_encoding($encoding);
1435  }
1436 
1437  function strip_comments($strip = false)
1438  {
1439  $this->sanitize->strip_comments($strip);
1440  }
1441 
1442  /**
1443  * Set element/attribute key/value pairs of HTML attributes
1444  * containing URLs that need to be resolved relative to the feed
1445  *
1446  * @access public
1447  * @since 1.0
1448  * @param array $element_attribute Element/attribute key/value pairs
1449  */
1450  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'))
1451  {
1452  $this->sanitize->set_url_replacements($element_attribute);
1453  }
1454 
1455  /**
1456  * Set the handler to enable the display of cached favicons.
1457  *
1458  * @access public
1459  * @param str $page Web-accessible path to the handler_favicon.php file.
1460  * @param str $qs The query string that the value should be passed to.
1461  */
1462  function set_favicon_handler($page = false, $qs = 'i')
1463  {
1464  if ($page !== false)
1465  {
1466  $this->favicon_handler = $page . '?' . $qs . '=';
1467  }
1468  else
1469  {
1470  $this->favicon_handler = '';
1471  }
1472  }
1473 
1474  /**
1475  * Set the handler to enable the display of cached images.
1476  *
1477  * @access public
1478  * @param str $page Web-accessible path to the handler_image.php file.
1479  * @param str $qs The query string that the value should be passed to.
1480  */
1481  function set_image_handler($page = false, $qs = 'i')
1482  {
1483  if ($page !== false)
1484  {
1485  $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1486  }
1487  else
1488  {
1489  $this->image_handler = '';
1490  }
1491  }
1492 
1493  /**
1494  * Set the limit for items returned per-feed with multifeeds.
1495  *
1496  * @access public
1497  * @param integer $limit The maximum number of items to return.
1498  */
1499  function set_item_limit($limit = 0)
1500  {
1501  $this->item_limit = (int) $limit;
1502  }
1503 
1504  function init()
1505  {
1506  // Check absolute bare minimum requirements.
1507  if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1508  {
1509  return false;
1510  }
1511  // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader.
1512  elseif (!extension_loaded('xmlreader'))
1513  {
1514  static $xml_is_sane = null;
1515  if ($xml_is_sane === null)
1516  {
1517  $parser_check = xml_parser_create();
1518  xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
1519  xml_parser_free($parser_check);
1520  $xml_is_sane = isset($values[0]['value']);
1521  }
1522  if (!$xml_is_sane)
1523  {
1524  return false;
1525  }
1526  }
1527 
1528  if (isset($_GET[$this->javascript]))
1529  {
1531  exit;
1532  }
1533 
1534  // Pass whatever was set with config options over to the sanitizer.
1535  $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1536  $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1537 
1538  if ($this->feed_url !== null || $this->raw_data !== null)
1539  {
1540  $this->data = array();
1541  $this->multifeed_objects = array();
1542  $cache = false;
1543 
1544  if ($this->feed_url !== null)
1545  {
1546  $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1547  // Decide whether to enable caching
1548  if ($this->cache && $parsed_feed_url['scheme'] !== '')
1549  {
1550  $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1551  }
1552  // If it's enabled and we don't want an XML dump, use the cache
1553  if ($cache && !$this->xml_dump)
1554  {
1555  // Load the Cache
1556  $this->data = $cache->load();
1557  if (!empty($this->data))
1558  {
1559  // If the cache is for an outdated build of SimplePie
1560  if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
1561  {
1562  $cache->unlink();
1563  $this->data = array();
1564  }
1565  // If we've hit a collision just rerun it with caching disabled
1566  elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
1567  {
1568  $cache = false;
1569  $this->data = array();
1570  }
1571  // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1572  elseif (isset($this->data['feed_url']))
1573  {
1574  // If the autodiscovery cache is still valid use it.
1575  if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1576  {
1577  // Do not need to do feed autodiscovery yet.
1578  if ($this->data['feed_url'] === $this->data['url'])
1579  {
1580  $cache->unlink();
1581  $this->data = array();
1582  }
1583  else
1584  {
1585  $this->set_feed_url($this->data['feed_url']);
1586  return $this->init();
1587  }
1588  }
1589  }
1590  // Check if the cache has been updated
1591  elseif ($cache->mtime() + $this->cache_duration < time())
1592  {
1593  // If we have last-modified and/or etag set
1594  if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1595  {
1596  $headers = array();
1597  if (isset($this->data['headers']['last-modified']))
1598  {
1599  $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1600  }
1601  if (isset($this->data['headers']['etag']))
1602  {
1603  $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1604  }
1605  $file = new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1606  if ($file->success)
1607  {
1608  if ($file->status_code === 304)
1609  {
1610  $cache->touch();
1611  return true;
1612  }
1613  else
1614  {
1615  $headers = $file->headers;
1616  }
1617  }
1618  else
1619  {
1620  unset($file);
1621  }
1622  }
1623  }
1624  // If the cache is still valid, just return true
1625  else
1626  {
1627  return true;
1628  }
1629  }
1630  // If the cache is empty, delete it
1631  else
1632  {
1633  $cache->unlink();
1634  $this->data = array();
1635  }
1636  }
1637  // 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.
1638  if (!isset($file))
1639  {
1640  if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url)
1641  {
1642  $file =& $this->file;
1643  }
1644  else
1645  {
1646  $file = new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1647  }
1648  }
1649  // If the file connection has an error, set SimplePie::error to that and quit
1650  if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
1651  {
1652  $this->error = $file->error;
1653  if (!empty($this->data))
1654  {
1655  return true;
1656  }
1657  else
1658  {
1659  return false;
1660  }
1661  }
1662 
1663  if (!$this->force_feed)
1664  {
1665  // Check if the supplied URL is a feed, if it isn't, look for it.
1666  $locate = new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1667  if (!$locate->is_feed($file))
1668  {
1669  // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1670  unset($file);
1671  if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))
1672  {
1673  if ($cache)
1674  {
1675  $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1676  if (!$cache->save($this))
1677  {
1678  trigger_error("$this->cache_location is not writeable", E_USER_WARNING);
1679  }
1680  $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1681  }
1682  $this->feed_url = $file->url;
1683  }
1684  else
1685  {
1686  $this->error = "A feed could not be found at $this->feed_url";
1687  SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1688  return false;
1689  }
1690  }
1691  $locate = null;
1692  }
1693 
1694  $headers = $file->headers;
1695  $data = $file->body;
1696  $sniffer = new $this->content_type_sniffer_class($file);
1697  $sniffed = $sniffer->get_type();
1698  }
1699  else
1700  {
1702  }
1703 
1704  // Set up array of possible encodings
1705  $encodings = array();
1706 
1707  // First check to see if input has been overridden.
1708  if ($this->input_encoding !== false)
1709  {
1710  $encodings[] = $this->input_encoding;
1711  }
1712 
1713  $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1714  $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1715 
1716  // RFC 3023 (only applies to sniffed content)
1717  if (isset($sniffed))
1718  {
1719  if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1720  {
1721  if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1722  {
1723  $encodings[] = strtoupper($charset[1]);
1724  }
1725  $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1726  $encodings[] = 'UTF-8';
1727  }
1728  elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1729  {
1730  if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1731  {
1732  $encodings[] = $charset[1];
1733  }
1734  $encodings[] = 'US-ASCII';
1735  }
1736  // Text MIME-type default
1737  elseif (substr($sniffed, 0, 5) === 'text/')
1738  {
1739  $encodings[] = 'US-ASCII';
1740  }
1741  }
1742 
1743  // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1744  $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1745  $encodings[] = 'UTF-8';
1746  $encodings[] = 'ISO-8859-1';
1747 
1748  // There's no point in trying an encoding twice
1749  $encodings = array_unique($encodings);
1750 
1751  // If we want the XML, just output that with the most likely encoding and quit
1752  if ($this->xml_dump)
1753  {
1754  header('Content-type: text/xml; charset=' . $encodings[0]);
1755  echo $data;
1756  exit;
1757  }
1758 
1759  // Loop through each possible encoding, till we return something, or run out of possibilities
1760  foreach ($encodings as $encoding)
1761  {
1762  // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1763  if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1764  {
1765  // Create new parser
1766  $parser = new $this->parser_class();
1767 
1768  // If it's parsed fine
1769  if ($parser->parse($utf8_data, 'UTF-8'))
1770  {
1771  $this->data = $parser->get_data();
1772  if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1773  {
1774  if (isset($headers))
1775  {
1776  $this->data['headers'] = $headers;
1777  }
1778  $this->data['build'] = SIMPLEPIE_BUILD;
1779 
1780  // Cache the file if caching is enabled
1781  if ($cache && !$cache->save($this))
1782  {
1783  trigger_error("$cache->name is not writeable", E_USER_WARNING);
1784  }
1785  return true;
1786  }
1787  else
1788  {
1789  $this->error = "A feed could not be found at $this->feed_url";
1790  SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1791  return false;
1792  }
1793  }
1794  }
1795  }
1796  if(isset($parser))
1797  {
1798  // We have an error, just set SimplePie_Misc::error to it and quit
1799  $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1800  }
1801  else
1802  {
1803  $this->error = 'The data could not be converted to UTF-8';
1804  }
1805  SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1806  return false;
1807  }
1808  elseif (!empty($this->multifeed_url))
1809  {
1810  $i = 0;
1811  $success = 0;
1812  $this->multifeed_objects = array();
1813  foreach ($this->multifeed_url as $url)
1814  {
1815  if (SIMPLEPIE_PHP5)
1816  {
1817  // This keyword needs to defy coding standards for PHP4 compatibility
1818  $this->multifeed_objects[$i] = clone($this);
1819  }
1820  else
1821  {
1822  $this->multifeed_objects[$i] = $this;
1823  }
1824  $this->multifeed_objects[$i]->set_feed_url($url);
1825  $success |= $this->multifeed_objects[$i]->init();
1826  $i++;
1827  }
1828  return (bool) $success;
1829  }
1830  else
1831  {
1832  return false;
1833  }
1834  }
1835 
1836  /**
1837  * Return the error message for the occured error
1838  *
1839  * @access public
1840  * @return string Error message
1841  */
1842  function error()
1843  {
1844  return $this->error;
1845  }
1846 
1847  function get_encoding()
1848  {
1849  return $this->sanitize->output_encoding;
1850  }
1851 
1852  function handle_content_type($mime = 'text/html')
1853  {
1854  if (!headers_sent())
1855  {
1856  $header = "Content-type: $mime;";
1857  if ($this->get_encoding())
1858  {
1859  $header .= ' charset=' . $this->get_encoding();
1860  }
1861  else
1862  {
1863  $header .= ' charset=UTF-8';
1864  }
1865  header($header);
1866  }
1867  }
1868 
1869  function get_type()
1870  {
1871  if (!isset($this->data['type']))
1872  {
1873  $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1874  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1875  {
1876  $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1877  }
1878  elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1879  {
1880  $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1881  }
1882  elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1883  {
1884  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1885  || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1886  || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1887  || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1888  {
1889  $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1890  }
1891  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1892  || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1893  || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1894  || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1895  {
1896  $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1897  }
1898  }
1899  elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
1900  {
1901  $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1902  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1903  {
1904  switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1905  {
1906  case '0.91':
1907  $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1908  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1909  {
1910  switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1911  {
1912  case '0':
1913  $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1914  break;
1915 
1916  case '24':
1917  $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1918  break;
1919  }
1920  }
1921  break;
1922 
1923  case '0.92':
1924  $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1925  break;
1926 
1927  case '0.93':
1928  $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1929  break;
1930 
1931  case '0.94':
1932  $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1933  break;
1934 
1935  case '2.0':
1936  $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1937  break;
1938  }
1939  }
1940  }
1941  else
1942  {
1943  $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1944  }
1945  }
1946  return $this->data['type'];
1947  }
1948 
1949  /**
1950  * Returns the URL for the favicon of the feed's website.
1951  *
1952  * @todo Cache atom:icon
1953  * @access public
1954  * @since 1.0
1955  */
1956  function get_favicon()
1957  {
1958  if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1959  {
1960  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1961  }
1962  elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1963  {
1964  $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1965 
1966  if ($this->cache && $this->favicon_handler)
1967  {
1968  $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1969  $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1970 
1971  if ($cache->load())
1972  {
1973  return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1974  }
1975  else
1976  {
1977  $file = new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1978 
1979  if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1980  {
1981  $sniffer = new $this->content_type_sniffer_class($file);
1982  if (substr($sniffer->get_type(), 0, 6) === 'image/')
1983  {
1984  if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1985  {
1986  return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1987  }
1988  else
1989  {
1990  trigger_error("$cache->name is not writeable", E_USER_WARNING);
1991  return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1992  }
1993  }
1994  // not an image
1995  else
1996  {
1997  return false;
1998  }
1999  }
2000  }
2001  }
2002  else
2003  {
2004  return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2005  }
2006  }
2007  return false;
2008  }
2009 
2010  /**
2011  * @todo If we have a perm redirect we should return the new URL
2012  * @todo When we make the above change, let's support <itunes:new-feed-url> as well
2013  * @todo Also, |atom:link|@rel=self
2014  */
2015  function subscribe_url()
2016  {
2017  if ($this->feed_url !== null)
2018  {
2019  return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2020  }
2021  else
2022  {
2023  return null;
2024  }
2025  }
2026 
2027  function subscribe_feed()
2028  {
2029  if ($this->feed_url !== null)
2030  {
2031  return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2032  }
2033  else
2034  {
2035  return null;
2036  }
2037  }
2038 
2040  {
2041  if ($this->feed_url !== null)
2042  {
2043  return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2044  }
2045  else
2046  {
2047  return null;
2048  }
2049  }
2050 
2052  {
2053  if ($this->feed_url !== null)
2054  {
2055  return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2056  }
2057  else
2058  {
2059  return null;
2060  }
2061  }
2062 
2063  function subscribe_itunes()
2064  {
2065  if ($this->feed_url !== null)
2066  {
2067  return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2068  }
2069  else
2070  {
2071  return null;
2072  }
2073  }
2074 
2075  /**
2076  * Creates the subscribe_* methods' return data
2077  *
2078  * @access private
2079  * @param string $feed_url String to prefix to the feed URL
2080  * @param string $site_url String to prefix to the site URL (and
2081  * suffix to the feed URL)
2082  * @return mixed URL if feed exists, false otherwise
2083  */
2084  function subscribe_service($feed_url, $site_url = null)
2085  {
2086  if ($this->subscribe_url())
2087  {
2088  $return = $feed_url . rawurlencode($this->feed_url);
2089  if ($site_url !== null && $this->get_link() !== null)
2090  {
2091  $return .= $site_url . rawurlencode($this->get_link());
2092  }
2093  return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
2094  }
2095  else
2096  {
2097  return null;
2098  }
2099  }
2100 
2101  function subscribe_aol()
2102  {
2103  return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2104  }
2105 
2107  {
2108  return $this->subscribe_service('http://www.bloglines.com/sub/');
2109  }
2110 
2111  function subscribe_eskobo()
2112  {
2113  return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2114  }
2115 
2117  {
2118  return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2119  }
2120 
2122  {
2123  return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2124  }
2125 
2126  function subscribe_google()
2127  {
2128  return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2129  }
2130 
2132  {
2133  return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2134  }
2135 
2136  function subscribe_msn()
2137  {
2138  return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2139  }
2140 
2142  {
2143  return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2144  }
2145 
2147  {
2148  return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2149  }
2150 
2152  {
2153  return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2154  }
2155 
2156  function subscribe_odeo()
2157  {
2158  return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2159  }
2160 
2162  {
2163  return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2164  }
2165 
2166  function subscribe_rojo()
2167  {
2168  return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2169  }
2170 
2171  function subscribe_yahoo()
2172  {
2173  return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2174  }
2175 
2176  function get_feed_tags($namespace, $tag)
2177  {
2178  $type = $this->get_type();
2179  if ($type & SIMPLEPIE_TYPE_ATOM_10)
2180  {
2181  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2182  {
2183  return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2184  }
2185  }
2186  if ($type & SIMPLEPIE_TYPE_ATOM_03)
2187  {
2188  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2189  {
2190  return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2191  }
2192  }
2193  if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2194  {
2195  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2196  {
2197  return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2198  }
2199  }
2200  if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2201  {
2202  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
2203  {
2204  return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
2205  }
2206  }
2207  return null;
2208  }
2209 
2210  function get_channel_tags($namespace, $tag)
2211  {
2212  $type = $this->get_type();
2213  if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2214  {
2215  if ($return = $this->get_feed_tags($namespace, $tag))
2216  {
2217  return $return;
2218  }
2219  }
2220  if ($type & SIMPLEPIE_TYPE_RSS_10)
2221  {
2222  if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2223  {
2224  if (isset($channel[0]['child'][$namespace][$tag]))
2225  {
2226  return $channel[0]['child'][$namespace][$tag];
2227  }
2228  }
2229  }
2230  if ($type & SIMPLEPIE_TYPE_RSS_090)
2231  {
2232  if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2233  {
2234  if (isset($channel[0]['child'][$namespace][$tag]))
2235  {
2236  return $channel[0]['child'][$namespace][$tag];
2237  }
2238  }
2239  }
2240  if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2241  {
2242  if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
2243  {
2244  if (isset($channel[0]['child'][$namespace][$tag]))
2245  {
2246  return $channel[0]['child'][$namespace][$tag];
2247  }
2248  }
2249  }
2250  return null;
2251  }
2252 
2253  function get_image_tags($namespace, $tag)
2254  {
2255  $type = $this->get_type();
2256  if ($type & SIMPLEPIE_TYPE_RSS_10)
2257  {
2258  if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2259  {
2260  if (isset($image[0]['child'][$namespace][$tag]))
2261  {
2262  return $image[0]['child'][$namespace][$tag];
2263  }
2264  }
2265  }
2266  if ($type & SIMPLEPIE_TYPE_RSS_090)
2267  {
2268  if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2269  {
2270  if (isset($image[0]['child'][$namespace][$tag]))
2271  {
2272  return $image[0]['child'][$namespace][$tag];
2273  }
2274  }
2275  }
2276  if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2277  {
2278  if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
2279  {
2280  if (isset($image[0]['child'][$namespace][$tag]))
2281  {
2282  return $image[0]['child'][$namespace][$tag];
2283  }
2284  }
2285  }
2286  return null;
2287  }
2288 
2289  function get_base($element = array())
2290  {
2291  if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2292  {
2293  return $element['xml_base'];
2294  }
2295  elseif ($this->get_link() !== null)
2296  {
2297  return $this->get_link();
2298  }
2299  else
2300  {
2301  return $this->subscribe_url();
2302  }
2303  }
2304 
2305  function sanitize($data, $type, $base = '')
2306  {
2307  return $this->sanitize->sanitize($data, $type, $base);
2308  }
2309 
2310  function get_title()
2311  {
2312  if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2313  {
2314  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2315  }
2316  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2317  {
2318  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2319  }
2320  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2321  {
2322  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2323  }
2324  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2325  {
2326  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2327  }
2328  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2329  {
2330  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2331  }
2332  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2333  {
2334  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2335  }
2336  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2337  {
2338  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2339  }
2340  else
2341  {
2342  return null;
2343  }
2344  }
2345 
2346  function get_category($key = 0)
2347  {
2348  $categories = $this->get_categories();
2349  if (isset($categories[$key]))
2350  {
2351  return $categories[$key];
2352  }
2353  else
2354  {
2355  return null;
2356  }
2357  }
2358 
2359  function get_categories()
2360  {
2361  $categories = array();
2362 
2363  foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2364  {
2365  $term = null;
2366  $scheme = null;
2367  $label = null;
2368  if (isset($category['attribs']['']['term']))
2369  {
2370  $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2371  }
2372  if (isset($category['attribs']['']['scheme']))
2373  {
2374  $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2375  }
2376  if (isset($category['attribs']['']['label']))
2377  {
2378  $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2379  }
2380  $categories[] = new $this->category_class($term, $scheme, $label);
2381  }
2382  foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
2383  {
2384  // This is really the label, but keep this as the term also for BC.
2385  // Label will also work on retrieving because that falls back to term.
2386  $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2387  if (isset($category['attribs']['']['domain']))
2388  {
2389  $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
2390  }
2391  else
2392  {
2393  $scheme = null;
2394  }
2395  $categories[] = new $this->category_class($term, $scheme, null);
2396  }
2397  foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2398  {
2399  $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2400  }
2401  foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2402  {
2403  $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2404  }
2405 
2406  if (!empty($categories))
2407  {
2408  return SimplePie_Misc::array_unique($categories);
2409  }
2410  else
2411  {
2412  return null;
2413  }
2414  }
2415 
2416  function get_author($key = 0)
2417  {
2418  $authors = $this->get_authors();
2419  if (isset($authors[$key]))
2420  {
2421  return $authors[$key];
2422  }
2423  else
2424  {
2425  return null;
2426  }
2427  }
2428 
2429  function get_authors()
2430  {
2431  $authors = array();
2432  foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2433  {
2434  $name = null;
2435  $uri = null;
2436  $email = null;
2437  if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2438  {
2439  $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2440  }
2441  if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2442  {
2443  $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]));
2444  }
2445  if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2446  {
2447  $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2448  }
2449  if ($name !== null || $email !== null || $uri !== null)
2450  {
2451  $authors[] = new $this->author_class($name, $uri, $email);
2452  }
2453  }
2454  if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2455  {
2456  $name = null;
2457  $url = null;
2458  $email = null;
2459  if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2460  {
2461  $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2462  }
2463  if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2464  {
2465  $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2466  }
2467  if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2468  {
2469  $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2470  }
2471  if ($name !== null || $email !== null || $url !== null)
2472  {
2473  $authors[] = new $this->author_class($name, $url, $email);
2474  }
2475  }
2476  foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2477  {
2478  $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2479  }
2480  foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2481  {
2482  $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2483  }
2484  foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2485  {
2486  $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2487  }
2488 
2489  if (!empty($authors))
2490  {
2491  return SimplePie_Misc::array_unique($authors);
2492  }
2493  else
2494  {
2495  return null;
2496  }
2497  }
2498 
2499  function get_contributor($key = 0)
2500  {
2501  $contributors = $this->get_contributors();
2502  if (isset($contributors[$key]))
2503  {
2504  return $contributors[$key];
2505  }
2506  else
2507  {
2508  return null;
2509  }
2510  }
2511 
2512  function get_contributors()
2513  {
2514  $contributors = array();
2515  foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2516  {
2517  $name = null;
2518  $uri = null;
2519  $email = null;
2520  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2521  {
2522  $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2523  }
2524  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2525  {
2526  $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
2527  }
2528  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2529  {
2530  $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2531  }
2532  if ($name !== null || $email !== null || $uri !== null)
2533  {
2534  $contributors[] = new $this->author_class($name, $uri, $email);
2535  }
2536  }
2537  foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2538  {
2539  $name = null;
2540  $url = null;
2541  $email = null;
2542  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2543  {
2544  $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2545  }
2546  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2547  {
2548  $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2549  }
2550  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2551  {
2552  $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2553  }
2554  if ($name !== null || $email !== null || $url !== null)
2555  {
2556  $contributors[] = new $this->author_class($name, $url, $email);
2557  }
2558  }
2559 
2560  if (!empty($contributors))
2561  {
2562  return SimplePie_Misc::array_unique($contributors);
2563  }
2564  else
2565  {
2566  return null;
2567  }
2568  }
2569 
2570  function get_link($key = 0, $rel = 'alternate')
2571  {
2572  $links = $this->get_links($rel);
2573  if (isset($links[$key]))
2574  {
2575  return $links[$key];
2576  }
2577  else
2578  {
2579  return null;
2580  }
2581  }
2582 
2583  /**
2584  * Added for parity between the parent-level and the item/entry-level.
2585  */
2586  function get_permalink()
2587  {
2588  return $this->get_link(0);
2589  }
2590 
2591  function get_links($rel = 'alternate')
2592  {
2593  if (!isset($this->data['links']))
2594  {
2595  $this->data['links'] = array();
2596  if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2597  {
2598  foreach ($links as $link)
2599  {
2600  if (isset($link['attribs']['']['href']))
2601  {
2602  $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2603  $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2604  }
2605  }
2606  }
2607  if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2608  {
2609  foreach ($links as $link)
2610  {
2611  if (isset($link['attribs']['']['href']))
2612  {
2613  $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2614  $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2615 
2616  }
2617  }
2618  }
2619  if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2620  {
2621  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2622  }
2623  if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2624  {
2625  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2626  }
2627  if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2628  {
2629  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2630  }
2631 
2632  $keys = array_keys($this->data['links']);
2633  foreach ($keys as $key)
2634  {
2636  {
2637  if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2638  {
2639  $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2640  $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2641  }
2642  else
2643  {
2644  $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2645  }
2646  }
2647  elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2648  {
2649  $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2650  }
2651  $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2652  }
2653  }
2654 
2655  if (isset($this->data['links'][$rel]))
2656  {
2657  return $this->data['links'][$rel];
2658  }
2659  else
2660  {
2661  return null;
2662  }
2663  }
2664 
2666  {
2668  }
2669 
2670  function get_description()
2671  {
2672  if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2673  {
2674  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2675  }
2676  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2677  {
2678  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2679  }
2680  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2681  {
2682  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2683  }
2684  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2685  {
2686  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2687  }
2688  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
2689  {
2690  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2691  }
2692  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2693  {
2694  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2695  }
2696  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2697  {
2698  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2699  }
2700  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2701  {
2702  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2703  }
2704  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2705  {
2706  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2707  }
2708  else
2709  {
2710  return null;
2711  }
2712  }
2713 
2714  function get_copyright()
2715  {
2716  if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2717  {
2718  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2719  }
2720  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2721  {
2722  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2723  }
2724  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
2725  {
2726  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2727  }
2728  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2729  {
2730  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2731  }
2732  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2733  {
2734  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2735  }
2736  else
2737  {
2738  return null;
2739  }
2740  }
2741 
2742  function get_language()
2743  {
2744  if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
2745  {
2746  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2747  }
2748  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2749  {
2750  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2751  }
2752  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2753  {
2754  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2755  }
2756  elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2757  {
2758  return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2759  }
2760  elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2761  {
2762  return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2763  }
2764  elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2765  {
2766  return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2767  }
2768  elseif (isset($this->data['headers']['content-language']))
2769  {
2770  return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2771  }
2772  else
2773  {
2774  return null;
2775  }
2776  }
2777 
2778  function get_latitude()
2779  {
2780  if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2781  {
2782  return (float) $return[0]['data'];
2783  }
2784  elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2785  {
2786  return (float) $match[1];
2787  }
2788  else
2789  {
2790  return null;
2791  }
2792  }
2793 
2794  function get_longitude()
2795  {
2796  if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2797  {
2798  return (float) $return[0]['data'];
2799  }
2800  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2801  {
2802  return (float) $return[0]['data'];
2803  }
2804  elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2805  {
2806  return (float) $match[2];
2807  }
2808  else
2809  {
2810  return null;
2811  }
2812  }
2813 
2814  function get_image_title()
2815  {
2816  if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2817  {
2818  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2819  }
2820  elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2821  {
2822  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2823  }
2824  elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2825  {
2826  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2827  }
2828  elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2829  {
2830  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2831  }
2832  elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2833  {
2834  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2835  }
2836  else
2837  {
2838  return null;
2839  }
2840  }
2841 
2842  function get_image_url()
2843  {
2844  if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2845  {
2846  return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2847  }
2848  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2849  {
2850  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2851  }
2852  elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2853  {
2854  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2855  }
2856  elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2857  {
2858  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2859  }
2860  elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2861  {
2862  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2863  }
2864  elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2865  {
2866  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2867  }
2868  else
2869  {
2870  return null;
2871  }
2872  }
2873 
2874  function get_image_link()
2875  {
2876  if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2877  {
2878  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2879  }
2880  elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2881  {
2882  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2883  }
2884  elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2885  {
2886  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2887  }
2888  else
2889  {
2890  return null;
2891  }
2892  }
2893 
2894  function get_image_width()
2895  {
2896  if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
2897  {
2898  return round($return[0]['data']);
2899  }
2901  {
2902  return 88.0;
2903  }
2904  else
2905  {
2906  return null;
2907  }
2908  }
2909 
2910  function get_image_height()
2911  {
2912  if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
2913  {
2914  return round($return[0]['data']);
2915  }
2917  {
2918  return 31.0;
2919  }
2920  else
2921  {
2922  return null;
2923  }
2924  }
2925 
2926  function get_item_quantity($max = 0)
2927  {
2928  $max = (int) $max;
2929  $qty = count($this->get_items());
2930  if ($max === 0)
2931  {
2932  return $qty;
2933  }
2934  else
2935  {
2936  return ($qty > $max) ? $max : $qty;
2937  }
2938  }
2939 
2940  function get_item($key = 0)
2941  {
2942  $items = $this->get_items();
2943  if (isset($items[$key]))
2944  {
2945  return $items[$key];
2946  }
2947  else
2948  {
2949  return null;
2950  }
2951  }
2952 
2953  function get_items($start = 0, $end = 0)
2954  {
2955  if (!isset($this->data['items']))
2956  {
2957  if (!empty($this->multifeed_objects))
2958  {
2959  $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2960  }
2961  else
2962  {
2963  $this->data['items'] = array();
2964  if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2965  {
2966  $keys = array_keys($items);
2967  foreach ($keys as $key)
2968  {
2969  $this->data['items'][] = new $this->item_class($this, $items[$key]);
2970  }
2971  }
2972  if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2973  {
2974  $keys = array_keys($items);
2975  foreach ($keys as $key)
2976  {
2977  $this->data['items'][] = new $this->item_class($this, $items[$key]);
2978  }
2979  }
2980  if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2981  {
2982  $keys = array_keys($items);
2983  foreach ($keys as $key)
2984  {
2985  $this->data['items'][] = new $this->item_class($this, $items[$key]);
2986  }
2987  }
2988  if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2989  {
2990  $keys = array_keys($items);
2991  foreach ($keys as $key)
2992  {
2993  $this->data['items'][] = new $this->item_class($this, $items[$key]);
2994  }
2995  }
2996  if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
2997  {
2998  $keys = array_keys($items);
2999  foreach ($keys as $key)
3000  {
3001  $this->data['items'][] = new $this->item_class($this, $items[$key]);
3002  }
3003  }
3004  }
3005  }
3006 
3007  if (!empty($this->data['items']))
3008  {
3009  // If we want to order it by date, check if all items have a date, and then sort it
3010  if ($this->order_by_date && empty($this->multifeed_objects))
3011  {
3012  if (!isset($this->data['ordered_items']))
3013  {
3014  $do_sort = true;
3015  foreach ($this->data['items'] as $item)
3016  {
3017  if (!$item->get_date('U'))
3018  {
3019  $do_sort = false;
3020  break;
3021  }
3022  }
3023  $item = null;
3024  $this->data['ordered_items'] = $this->data['items'];
3025  if ($do_sort)
3026  {
3027  usort($this->data['ordered_items'], array(&$this, 'sort_items'));
3028  }
3029  }
3030  $items = $this->data['ordered_items'];
3031  }
3032  else
3033  {
3034  $items = $this->data['items'];
3035  }
3036 
3037  // Slice the data as desired
3038  if ($end === 0)
3039  {
3040  return array_slice($items, $start);
3041  }
3042  else
3043  {
3044  return array_slice($items, $start, $end);
3045  }
3046  }
3047  else
3048  {
3049  return array();
3050  }
3051  }
3052 
3053  /**
3054  * @static
3055  */
3056  function sort_items($a, $b)
3057  {
3058  return $a->get_date('U') <= $b->get_date('U');
3059  }
3060 
3061  /**
3062  * @static
3063  */
3064  function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3065  {
3066  if (is_array($urls) && sizeof($urls) > 0)
3067  {
3068  $items = array();
3069  foreach ($urls as $arg)
3070  {
3071  if (is_a($arg, 'SimplePie'))
3072  {
3073  $items = array_merge($items, $arg->get_items(0, $limit));
3074  }
3075  else
3076  {
3077  trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3078  }
3079  }
3080 
3081  $do_sort = true;
3082  foreach ($items as $item)
3083  {
3084  if (!$item->get_date('U'))
3085  {
3086  $do_sort = false;
3087  break;
3088  }
3089  }
3090  $item = null;
3091  if ($do_sort)
3092  {
3093  usort($items, array('SimplePie', 'sort_items'));
3094  }
3095 
3096  if ($end === 0)
3097  {
3098  return array_slice($items, $start);
3099  }
3100  else
3101  {
3102  return array_slice($items, $start, $end);
3103  }
3104  }
3105  else
3106  {
3107  trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3108  return array();
3109  }
3110  }
3111 }
3112 
3114 {
3115  var $feed;
3116  var $data = array();
3117 
3119  {
3120  $this->feed = $feed;
3121  $this->data = $data;
3122  }
3123 
3124  function __toString()
3125  {
3126  return md5(serialize($this->data));
3127  }
3128 
3129  /**
3130  * Remove items that link back to this before destroying this object
3131  */
3132  function __destruct()
3133  {
3134  if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
3135  {
3136  unset($this->feed);
3137  }
3138  }
3139 
3140  function get_item_tags($namespace, $tag)
3141  {
3142  if (isset($this->data['child'][$namespace][$tag]))
3143  {
3144  return $this->data['child'][$namespace][$tag];
3145  }
3146  else
3147  {
3148  return null;
3149  }
3150  }
3151 
3152  function get_base($element = array())
3153  {
3154  return $this->feed->get_base($element);
3155  }
3156 
3157  function sanitize($data, $type, $base = '')
3158  {
3159  return $this->feed->sanitize($data, $type, $base);
3160  }
3161 
3162  function get_feed()
3163  {
3164  return $this->feed;
3165  }
3166 
3167  function get_id($hash = false)
3168  {
3169  if (!$hash)
3170  {
3171  if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3172  {
3173  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3174  }
3175  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3176  {
3177  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3178  }
3179  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
3180  {
3181  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3182  }
3183  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3184  {
3185  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3186  }
3187  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3188  {
3189  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3190  }
3191  elseif (($return = $this->get_permalink()) !== null)
3192  {
3193  return $return;
3194  }
3195  elseif (($return = $this->get_title()) !== null)
3196  {
3197  return $return;
3198  }
3199  }
3200  if ($this->get_permalink() !== null || $this->get_title() !== null)
3201  {
3202  return md5($this->get_permalink() . $this->get_title());
3203  }
3204  else
3205  {
3206  return md5(serialize($this->data));
3207  }
3208  }
3209 
3210  function get_title()
3211  {
3212  if (!isset($this->data['title']))
3213  {
3214  if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3215  {
3216  $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3217  }
3218  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3219  {
3220  $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3221  }
3222  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3223  {
3224  $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3225  }
3226  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3227  {
3228  $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3229  }
3230  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
3231  {
3232  $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3233  }
3234  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3235  {
3236  $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3237  }
3238  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3239  {
3240  $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3241  }
3242  else
3243  {
3244  $this->data['title'] = null;
3245  }
3246  }
3247  return $this->data['title'];
3248  }
3249 
3250  function get_description($description_only = false)
3251  {
3252  if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3253  {
3254  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3255  }
3256  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3257  {
3258  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3259  }
3260  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3261  {
3262  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3263  }
3264  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
3265  {
3266  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3267  }
3268  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3269  {
3270  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3271  }
3272  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3273  {
3274  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3275  }
3276  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3277  {
3278  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3279  }
3280  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3281  {
3282  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3283  }
3284  elseif (!$description_only)
3285  {
3286  return $this->get_content(true);
3287  }
3288  else
3289  {
3290  return null;
3291  }
3292  }
3293 
3294  function get_content($content_only = false)
3295  {
3296  if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3297  {
3298  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3299  }
3300  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3301  {
3302  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3303  }
3304  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3305  {
3306  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3307  }
3308  elseif (!$content_only)
3309  {
3310  return $this->get_description(true);
3311  }
3312  else
3313  {
3314  return null;
3315  }
3316  }
3317 
3318  function get_category($key = 0)
3319  {
3320  $categories = $this->get_categories();
3321  if (isset($categories[$key]))
3322  {
3323  return $categories[$key];
3324  }
3325  else
3326  {
3327  return null;
3328  }
3329  }
3330 
3331  function get_categories()
3332  {
3333  $categories = array();
3334 
3335  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3336  {
3337  $term = null;
3338  $scheme = null;
3339  $label = null;
3340  if (isset($category['attribs']['']['term']))
3341  {
3342  $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3343  }
3344  if (isset($category['attribs']['']['scheme']))
3345  {
3346  $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3347  }
3348  if (isset($category['attribs']['']['label']))
3349  {
3350  $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3351  }
3352  $categories[] = new $this->feed->category_class($term, $scheme, $label);
3353  }
3354  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
3355  {
3356  // This is really the label, but keep this as the term also for BC.
3357  // Label will also work on retrieving because that falls back to term.
3358  $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3359  if (isset($category['attribs']['']['domain']))
3360  {
3361  $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
3362  }
3363  else
3364  {
3365  $scheme = null;
3366  }
3367  $categories[] = new $this->feed->category_class($term, $scheme, null);
3368  }
3369  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3370  {
3371  $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3372  }
3373  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3374  {
3375  $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3376  }
3377 
3378  if (!empty($categories))
3379  {
3380  return SimplePie_Misc::array_unique($categories);
3381  }
3382  else
3383  {
3384  return null;
3385  }
3386  }
3387 
3388  function get_author($key = 0)
3389  {
3390  $authors = $this->get_authors();
3391  if (isset($authors[$key]))
3392  {
3393  return $authors[$key];
3394  }
3395  else
3396  {
3397  return null;
3398  }
3399  }
3400 
3401  function get_contributor($key = 0)
3402  {
3403  $contributors = $this->get_contributors();
3404  if (isset($contributors[$key]))
3405  {
3406  return $contributors[$key];
3407  }
3408  else
3409  {
3410  return null;
3411  }
3412  }
3413 
3414  function get_contributors()
3415  {
3416  $contributors = array();
3417  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3418  {
3419  $name = null;
3420  $uri = null;
3421  $email = null;
3422  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3423  {
3424  $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3425  }
3426  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3427  {
3428  $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
3429  }
3430  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3431  {
3432  $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3433  }
3434  if ($name !== null || $email !== null || $uri !== null)
3435  {
3436  $contributors[] = new $this->feed->author_class($name, $uri, $email);
3437  }
3438  }
3439  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3440  {
3441  $name = null;
3442  $url = null;
3443  $email = null;
3444  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3445  {
3446  $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3447  }
3448  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3449  {
3450  $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
3451  }
3452  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3453  {
3454  $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3455  }
3456  if ($name !== null || $email !== null || $url !== null)
3457  {
3458  $contributors[] = new $this->feed->author_class($name, $url, $email);
3459  }
3460  }
3461 
3462  if (!empty($contributors))
3463  {
3464  return SimplePie_Misc::array_unique($contributors);
3465  }
3466  else
3467  {
3468  return null;
3469  }
3470  }
3471 
3472  function get_authors()
3473  {
3474  $authors = array();
3475  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3476  {
3477  $name = null;
3478  $uri = null;
3479  $email = null;
3480  if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3481  {
3482  $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3483  }
3484  if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3485  {
3486  $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]));
3487  }
3488  if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3489  {
3490  $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3491  }
3492  if ($name !== null || $email !== null || $uri !== null)
3493  {
3494  $authors[] = new $this->feed->author_class($name, $uri, $email);
3495  }
3496  }
3497  if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3498  {
3499  $name = null;
3500  $url = null;
3501  $email = null;
3502  if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3503  {
3504  $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3505  }
3506  if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3507  {
3508  $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
3509  }
3510  if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3511  {
3512  $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3513  }
3514  if ($name !== null || $email !== null || $url !== null)
3515  {
3516  $authors[] = new $this->feed->author_class($name, $url, $email);
3517  }
3518  }
3519  if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
3520  {
3521  $authors[] = new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3522  }
3523  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3524  {
3525  $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3526  }
3527  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3528  {
3529  $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3530  }
3531  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3532  {
3533  $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3534  }
3535 
3536  if (!empty($authors))
3537  {
3538  return SimplePie_Misc::array_unique($authors);
3539  }
3540  elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3541  {
3542  return $authors;
3543  }
3544  elseif ($authors = $this->feed->get_authors())
3545  {
3546  return $authors;
3547  }
3548  else
3549  {
3550  return null;
3551  }
3552  }
3553 
3554  function get_copyright()
3555  {
3556  if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3557  {
3558  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3559  }
3560  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3561  {
3562  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3563  }
3564  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3565  {
3566  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3567  }
3568  else
3569  {
3570  return null;
3571  }
3572  }
3573 
3574  function get_date($date_format = 'j F Y, g:i a')
3575  {
3576  if (!isset($this->data['date']))
3577  {
3578  if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3579  {
3580  $this->data['date']['raw'] = $return[0]['data'];
3581  }
3582  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3583  {
3584  $this->data['date']['raw'] = $return[0]['data'];
3585  }
3586  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3587  {
3588  $this->data['date']['raw'] = $return[0]['data'];
3589  }
3590  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3591  {
3592  $this->data['date']['raw'] = $return[0]['data'];
3593  }
3594  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3595  {
3596  $this->data['date']['raw'] = $return[0]['data'];
3597  }
3598  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
3599  {
3600  $this->data['date']['raw'] = $return[0]['data'];
3601  }
3602  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3603  {
3604  $this->data['date']['raw'] = $return[0]['data'];
3605  }
3606  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3607  {
3608  $this->data['date']['raw'] = $return[0]['data'];
3609  }
3610 
3611  if (!empty($this->data['date']['raw']))
3612  {
3613  $parser = SimplePie_Parse_Date::get();
3614  $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3615  }
3616  else
3617  {
3618  $this->data['date'] = null;
3619  }
3620  }
3621  if ($this->data['date'])
3622  {
3623  $date_format = (string) $date_format;
3624  switch ($date_format)
3625  {
3626  case '':
3627  return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3628 
3629  case 'U':
3630  return $this->data['date']['parsed'];
3631 
3632  default:
3633  return date($date_format, $this->data['date']['parsed']);
3634  }
3635  }
3636  else
3637  {
3638  return null;
3639  }
3640  }
3641 
3642  function get_local_date($date_format = '%c')
3643  {
3644  if (!$date_format)
3645  {
3646  return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3647  }
3648  elseif (($date = $this->get_date('U')) !== null)
3649  {
3650  return strftime($date_format, $date);
3651  }
3652  else
3653  {
3654  return null;
3655  }
3656  }
3657 
3658  function get_permalink()
3659  {
3660  $link = $this->get_link();
3661  $enclosure = $this->get_enclosure(0);
3662  if ($link !== null)
3663  {
3664  return $link;
3665  }
3666  elseif ($enclosure !== null)
3667  {
3668  return $enclosure->get_link();
3669  }
3670  else
3671  {
3672  return null;
3673  }
3674  }
3675 
3676  function get_link($key = 0, $rel = 'alternate')
3677  {
3678  $links = $this->get_links($rel);
3679  if ($links[$key] !== null)
3680  {
3681  return $links[$key];
3682  }
3683  else
3684  {
3685  return null;
3686  }
3687  }
3688 
3689  function get_links($rel = 'alternate')
3690  {
3691  if (!isset($this->data['links']))
3692  {
3693  $this->data['links'] = array();
3694  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3695  {
3696  if (isset($link['attribs']['']['href']))
3697  {
3698  $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3699  $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3700 
3701  }
3702  }
3703  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3704  {
3705  if (isset($link['attribs']['']['href']))
3706  {
3707  $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3708  $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3709  }
3710  }
3711  if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3712  {
3713  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3714  }
3715  if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3716  {
3717  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3718  }
3719  if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
3720  {
3721  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3722  }
3723  if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
3724  {
3725  if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')
3726  {
3727  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3728  }
3729  }
3730 
3731  $keys = array_keys($this->data['links']);
3732  foreach ($keys as $key)
3733  {
3735  {
3736  if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3737  {
3738  $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3739  $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3740  }
3741  else
3742  {
3743  $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3744  }
3745  }
3746  elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3747  {
3748  $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3749  }
3750  $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3751  }
3752  }
3753  if (isset($this->data['links'][$rel]))
3754  {
3755  return $this->data['links'][$rel];
3756  }
3757  else
3758  {
3759  return null;
3760  }
3761  }
3762 
3763  /**
3764  * @todo Add ability to prefer one type of content over another (in a media group).
3765  */
3766  function get_enclosure($key = 0, $prefer = null)
3767  {
3768  $enclosures = $this->get_enclosures();
3769  if (isset($enclosures[$key]))
3770  {
3771  return $enclosures[$key];
3772  }
3773  else
3774  {
3775  return null;
3776  }
3777  }
3778 
3779  /**
3780  * Grabs all available enclosures (podcasts, etc.)
3781  *
3782  * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3783  *
3784  * 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.
3785  *
3786  * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3787  * @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).
3788  */
3789  function get_enclosures()
3790  {
3791  if (!isset($this->data['enclosures']))
3792  {
3793  $this->data['enclosures'] = array();
3794 
3795  // Elements
3796  $captions_parent = null;
3797  $categories_parent = null;
3798  $copyrights_parent = null;
3799  $credits_parent = null;
3800  $description_parent = null;
3801  $duration_parent = null;
3802  $hashes_parent = null;
3803  $keywords_parent = null;
3804  $player_parent = null;
3805  $ratings_parent = null;
3806  $restrictions_parent = null;
3807  $thumbnails_parent = null;
3808  $title_parent = null;
3809 
3810  // Let's do the channel and item-level ones first, and just re-use them if we need to.
3811  $parent = $this->get_feed();
3812 
3813  // CAPTIONS
3814  if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3815  {
3816  foreach ($captions as $caption)
3817  {
3818  $caption_type = null;
3819  $caption_lang = null;
3820  $caption_startTime = null;
3821  $caption_endTime = null;
3822  $caption_text = null;
3823  if (isset($caption['attribs']['']['type']))
3824  {
3825  $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3826  }
3827  if (isset($caption['attribs']['']['lang']))
3828  {
3829  $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3830  }
3831  if (isset($caption['attribs']['']['start']))
3832  {
3833  $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3834  }
3835  if (isset($caption['attribs']['']['end']))
3836  {
3837  $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3838  }
3839  if (isset($caption['data']))
3840  {
3841  $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3842  }
3843  $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3844  }
3845  }
3846  elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3847  {
3848  foreach ($captions as $caption)
3849  {
3850  $caption_type = null;
3851  $caption_lang = null;
3852  $caption_startTime = null;
3853  $caption_endTime = null;
3854  $caption_text = null;
3855  if (isset($caption['attribs']['']['type']))
3856  {
3857  $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3858  }
3859  if (isset($caption['attribs']['']['lang']))
3860  {
3861  $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3862  }
3863  if (isset($caption['attribs']['']['start']))
3864  {
3865  $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3866  }
3867  if (isset($caption['attribs']['']['end']))
3868  {
3869  $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3870  }
3871  if (isset($caption['data']))
3872  {
3873  $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3874  }
3875  $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3876  }
3877  }
3878  if (is_array($captions_parent))
3879  {
3880  $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3881  }
3882 
3883  // CATEGORIES
3884  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3885  {
3886  $term = null;
3887  $scheme = null;
3888  $label = null;
3889  if (isset($category['data']))
3890  {
3891  $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3892  }
3893  if (isset($category['attribs']['']['scheme']))
3894  {
3895  $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3896  }
3897  else
3898  {
3899  $scheme = 'http://search.yahoo.com/mrss/category_schema';
3900  }
3901  if (isset($category['attribs']['']['label']))
3902  {
3903  $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3904  }
3905  $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3906  }
3907  foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3908  {
3909  $term = null;
3910  $scheme = null;
3911  $label = null;
3912  if (isset($category['data']))
3913  {
3914  $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3915  }
3916  if (isset($category['attribs']['']['scheme']))
3917  {
3918  $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3919  }
3920  else
3921  {
3922  $scheme = 'http://search.yahoo.com/mrss/category_schema';
3923  }
3924  if (isset($category['attribs']['']['label']))
3925  {
3926  $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3927  }
3928  $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3929  }
3930  foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3931  {
3932  $term = null;
3933  $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3934  $label = null;
3935  if (isset($category['attribs']['']['text']))
3936  {
3937  $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3938  }
3939  $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3940 
3941  if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3942  {
3943  foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3944  {
3945  if (isset($subcategory['attribs']['']['text']))
3946  {
3947  $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3948  }
3949  $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3950  }
3951  }
3952  }
3953  if (is_array($categories_parent))
3954  {
3955  $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3956  }
3957 
3958  // COPYRIGHT
3959  if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3960  {
3961  $copyright_url = null;
3962  $copyright_label = null;
3963  if (isset($copyright[0]['attribs']['']['url']))
3964  {
3965  $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3966  }
3967  if (isset($copyright[0]['data']))
3968  {
3969  $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3970  }
3971  $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label);
3972  }
3973  elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3974  {
3975  $copyright_url = null;
3976  $copyright_label = null;
3977  if (isset($copyright[0]['attribs']['']['url']))
3978  {
3979  $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3980  }
3981  if (isset($copyright[0]['data']))
3982  {
3983  $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3984  }
3985  $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label);
3986  }
3987 
3988  // CREDITS
3989  if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3990  {
3991  foreach ($credits as $credit)
3992  {
3993  $credit_role = null;
3994  $credit_scheme = null;
3995  $credit_name = null;
3996  if (isset($credit['attribs']['']['role']))
3997  {
3998  $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3999  }
4000  if (isset($credit['attribs']['']['scheme']))
4001  {
4002  $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4003  }
4004  else
4005  {
4006  $credit_scheme = 'urn:ebu';
4007  }
4008  if (isset($credit['data']))
4009  {
4010  $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4011  }
4012  $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4013  }
4014  }
4015  elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
4016  {
4017  foreach ($credits as $credit)
4018  {
4019  $credit_role = null;
4020  $credit_scheme = null;
4021  $credit_name = null;
4022  if (isset($credit['attribs']['']['role']))
4023  {
4024  $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4025  }
4026  if (isset($credit['attribs']['']['scheme']))
4027  {
4028  $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4029  }
4030  else
4031  {
4032  $credit_scheme = 'urn:ebu';
4033  }
4034  if (isset($credit['data']))
4035  {
4036  $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4037  }
4038  $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4039  }
4040  }
4041  if (is_array($credits_parent))
4042  {
4043  $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
4044  }
4045 
4046  // DESCRIPTION
4047  if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4048  {
4049  if (isset($description_parent[0]['data']))
4050  {
4051  $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4052  }
4053  }
4054  elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4055  {
4056  if (isset($description_parent[0]['data']))
4057  {
4058  $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4059  }
4060  }
4061 
4062  // DURATION
4063  if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
4064  {
4065  $seconds = null;
4066  $minutes = null;
4067  $hours = null;
4068  if (isset($duration_parent[0]['data']))
4069  {
4070  $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4071  if (sizeof($temp) > 0)
4072  {
4073  (int) $seconds = array_pop($temp);
4074  }
4075  if (sizeof($temp) > 0)
4076  {
4077  (int) $minutes = array_pop($temp);
4078  $seconds += $minutes * 60;
4079  }
4080  if (sizeof($temp) > 0)
4081  {
4082  (int) $hours = array_pop($temp);
4083  $seconds += $hours * 3600;
4084  }
4085  unset($temp);
4086  $duration_parent = $seconds;
4087  }
4088  }
4089 
4090  // HASHES
4091  if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4092  {
4093  foreach ($hashes_iterator as $hash)
4094  {
4095  $value = null;
4096  $algo = null;
4097  if (isset($hash['data']))
4098  {
4099  $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4100  }
4101  if (isset($hash['attribs']['']['algo']))
4102  {
4103  $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4104  }
4105  else
4106  {
4107  $algo = 'md5';
4108  }
4109  $hashes_parent[] = $algo.':'.$value;
4110  }
4111  }
4112  elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4113  {
4114  foreach ($hashes_iterator as $hash)
4115  {
4116  $value = null;
4117  $algo = null;
4118  if (isset($hash['data']))
4119  {
4120  $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4121  }
4122  if (isset($hash['attribs']['']['algo']))
4123  {
4124  $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4125  }
4126  else
4127  {
4128  $algo = 'md5';
4129  }
4130  $hashes_parent[] = $algo.':'.$value;
4131  }
4132  }
4133  if (is_array($hashes_parent))
4134  {
4135  $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4136  }
4137 
4138  // KEYWORDS
4139  if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4140  {
4141  if (isset($keywords[0]['data']))
4142  {
4143  $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4144  foreach ($temp as $word)
4145  {
4146  $keywords_parent[] = trim($word);
4147  }
4148  }
4149  unset($temp);
4150  }
4151  elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4152  {
4153  if (isset($keywords[0]['data']))
4154  {
4155  $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4156  foreach ($temp as $word)
4157  {
4158  $keywords_parent[] = trim($word);
4159  }
4160  }
4161  unset($temp);
4162  }
4163  elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4164  {
4165  if (isset($keywords[0]['data']))
4166  {
4167  $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4168  foreach ($temp as $word)
4169  {
4170  $keywords_parent[] = trim($word);
4171  }
4172  }
4173  unset($temp);
4174  }
4175  elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4176  {
4177  if (isset($keywords[0]['data']))
4178  {
4179  $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4180  foreach ($temp as $word)
4181  {
4182  $keywords_parent[] = trim($word);
4183  }
4184  }
4185  unset($temp);
4186  }
4187  if (is_array($keywords_parent))
4188  {
4189  $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4190  }
4191 
4192  // PLAYER
4193  if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4194  {
4195  if (isset($player_parent[0]['attribs']['']['url']))
4196  {
4197  $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4198  }
4199  }
4200  elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4201  {
4202  if (isset($player_parent[0]['attribs']['']['url']))
4203  {
4204  $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4205  }
4206  }
4207 
4208  // RATINGS
4209  if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4210  {
4211  foreach ($ratings as $rating)
4212  {
4213  $rating_scheme = null;
4214  $rating_value = null;
4215  if (isset($rating['attribs']['']['scheme']))
4216  {
4217  $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4218  }
4219  else
4220  {
4221  $rating_scheme = 'urn:simple';
4222  }
4223  if (isset($rating['data']))
4224  {
4225  $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4226  }
4227  $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4228  }
4229  }
4230  elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4231  {
4232  foreach ($ratings as $rating)
4233  {
4234  $rating_scheme = 'urn:itunes';
4235  $rating_value = null;
4236  if (isset($rating['data']))
4237  {
4238  $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4239  }
4240  $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4241  }
4242  }
4243  elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4244  {
4245  foreach ($ratings as $rating)
4246  {
4247  $rating_scheme = null;
4248  $rating_value = null;
4249  if (isset($rating['attribs']['']['scheme']))
4250  {
4251  $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4252  }
4253  else
4254  {
4255  $rating_scheme = 'urn:simple';
4256  }
4257  if (isset($rating['data']))
4258  {
4259  $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4260  }
4261  $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4262  }
4263  }
4264  elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4265  {
4266  foreach ($ratings as $rating)
4267  {
4268  $rating_scheme = 'urn:itunes';
4269  $rating_value = null;
4270  if (isset($rating['data']))
4271  {
4272  $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4273  }
4274  $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4275  }
4276  }
4277  if (is_array($ratings_parent))
4278  {
4279  $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4280  }
4281 
4282  // RESTRICTIONS
4283  if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4284  {
4285  foreach ($restrictions as $restriction)
4286  {
4287  $restriction_relationship = null;
4288  $restriction_type = null;
4289  $restriction_value = null;
4290  if (isset($restriction['attribs']['']['relationship']))
4291  {
4292  $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4293  }
4294  if (isset($restriction['attribs']['']['type']))
4295  {
4296  $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4297  }
4298  if (isset($restriction['data']))
4299  {
4300  $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4301  }
4302  $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4303  }
4304  }
4305  elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4306  {
4307  foreach ($restrictions as $restriction)
4308  {
4309  $restriction_relationship = 'allow';
4310  $restriction_type = null;
4311  $restriction_value = 'itunes';
4312  if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
4313  {
4314  $restriction_relationship = 'deny';
4315  }
4316  $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4317  }
4318  }
4319  elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4320  {
4321  foreach ($restrictions as $restriction)
4322  {
4323  $restriction_relationship = null;
4324  $restriction_type = null;
4325  $restriction_value = null;
4326  if (isset($restriction['attribs']['']['relationship']))
4327  {
4328  $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4329  }
4330  if (isset($restriction['attribs']['']['type']))
4331  {
4332  $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4333  }
4334  if (isset($restriction['data']))
4335  {
4336  $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4337  }
4338  $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4339  }
4340  }
4341  elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4342  {
4343  foreach ($restrictions as $restriction)
4344  {
4345  $restriction_relationship = 'allow';
4346  $restriction_type = null;
4347  $restriction_value = 'itunes';
4348  if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
4349  {
4350  $restriction_relationship = 'deny';
4351  }
4352  $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4353  }
4354  }
4355  if (is_array($restrictions_parent))
4356  {
4357  $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4358  }
4359 
4360  // THUMBNAILS
4361  if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4362  {
4363  foreach ($thumbnails as $thumbnail)
4364  {
4365  if (isset($thumbnail['attribs']['']['url']))
4366  {
4367  $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4368  }
4369  }
4370  }
4371  elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4372  {
4373  foreach ($thumbnails as $thumbnail)
4374  {
4375  if (isset($thumbnail['attribs']['']['url']))
4376  {
4377  $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4378  }
4379  }
4380  }
4381 
4382  // TITLES
4383  if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4384  {
4385  if (isset($title_parent[0]['data']))
4386  {
4387  $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4388  }
4389  }
4390  elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4391  {
4392  if (isset($title_parent[0]['data']))
4393  {
4394  $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4395  }
4396  }
4397 
4398  // Clear the memory
4399  unset($parent);
4400 
4401  // Attributes
4402  $bitrate = null;
4403  $channels = null;
4404  $duration = null;
4405  $expression = null;
4406  $framerate = null;
4407  $height = null;
4408  $javascript = null;
4409  $lang = null;
4410  $length = null;
4411  $medium = null;
4412  $samplingrate = null;
4413  $type = null;
4414  $url = null;
4415  $width = null;
4416 
4417  // Elements
4418  $captions = null;
4419  $categories = null;
4420  $copyrights = null;
4421  $credits = null;
4422  $description = null;
4423  $hashes = null;
4424  $keywords = null;
4425  $player = null;
4426  $ratings = null;
4427  $restrictions = null;
4428  $thumbnails = null;
4429  $title = null;
4430 
4431  // If we have media:group tags, loop through them.
4432  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4433  {
4434  // If we have media:content tags, loop through them.
4435  foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4436  {
4437  if (isset($content['attribs']['']['url']))
4438  {
4439  // Attributes
4440  $bitrate = null;
4441  $channels = null;
4442  $duration = null;
4443  $expression = null;
4444  $framerate = null;
4445  $height = null;
4446  $javascript = null;
4447  $lang = null;
4448  $length = null;
4449  $medium = null;
4450  $samplingrate = null;
4451  $type = null;
4452  $url = null;
4453  $width = null;
4454 
4455  // Elements
4456  $captions = null;
4457  $categories = null;
4458  $copyrights = null;
4459  $credits = null;
4460  $description = null;
4461  $hashes = null;
4462  $keywords = null;
4463  $player = null;
4464  $ratings = null;
4465  $restrictions = null;
4466  $thumbnails = null;
4467  $title = null;
4468 
4469  // Start checking the attributes of media:content
4470  if (isset($content['attribs']['']['bitrate']))
4471  {
4472  $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4473  }
4474  if (isset($content['attribs']['']['channels']))
4475  {
4476  $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4477  }
4478  if (isset($content['attribs']['']['duration']))
4479  {
4480  $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4481  }
4482  else
4483  {
4484  $duration = $duration_parent;
4485  }
4486  if (isset($content['attribs']['']['expression']))
4487  {
4488  $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4489  }
4490  if (isset($content['attribs']['']['framerate']))
4491  {
4492  $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4493  }
4494  if (isset($content['attribs']['']['height']))
4495  {
4496  $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4497  }
4498  if (isset($content['attribs']['']['lang']))
4499  {
4500  $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4501  }
4502  if (isset($content['attribs']['']['fileSize']))
4503  {
4504  $length = ceil($content['attribs']['']['fileSize']);
4505  }
4506  if (isset($content['attribs']['']['medium']))
4507  {
4508  $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4509  }
4510  if (isset($content['attribs']['']['samplingrate']))
4511  {
4512  $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4513  }
4514  if (isset($content['attribs']['']['type']))
4515  {
4516  $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4517  }
4518  if (isset($content['attribs']['']['width']))
4519  {
4520  $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4521  }
4522  $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4523 
4524  // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4525 
4526  // CAPTIONS
4527  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4528  {
4529  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4530  {
4531  $caption_type = null;
4532  $caption_lang = null;
4533  $caption_startTime = null;
4534  $caption_endTime = null;
4535  $caption_text = null;
4536  if (isset($caption['attribs']['']['type']))
4537  {
4538  $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4539  }
4540  if (isset($caption['attribs']['']['lang']))
4541  {
4542  $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4543  }
4544  if (isset($caption['attribs']['']['start']))
4545  {
4546  $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4547  }
4548  if (isset($caption['attribs']['']['end']))
4549  {
4550  $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4551  }
4552  if (isset($caption['data']))
4553  {
4554  $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4555  }
4556  $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4557  }
4558  if (is_array($captions))
4559  {
4560  $captions = array_values(SimplePie_Misc::array_unique($captions));
4561  }
4562  }
4563  elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4564  {
4565  foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4566  {
4567  $caption_type = null;
4568  $caption_lang = null;
4569  $caption_startTime = null;
4570  $caption_endTime = null;
4571  $caption_text = null;
4572  if (isset($caption['attribs']['']['type']))
4573  {
4574  $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4575  }
4576  if (isset($caption['attribs']['']['lang']))
4577  {
4578  $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4579  }
4580  if (isset($caption['attribs']['']['start']))
4581  {
4582  $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4583  }
4584  if (isset($caption['attribs']['']['end']))
4585  {
4586  $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4587  }
4588  if (isset($caption['data']))
4589  {
4590  $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4591  }
4592  $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4593  }
4594  if (is_array($captions))
4595  {
4596  $captions = array_values(SimplePie_Misc::array_unique($captions));
4597  }
4598  }
4599  else
4600  {
4601  $captions = $captions_parent;
4602  }
4603 
4604  // CATEGORIES
4605  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4606  {
4607  foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4608  {
4609  $term = null;
4610  $scheme = null;
4611  $label = null;
4612  if (isset($category['data']))
4613  {
4614  $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4615  }
4616  if (isset($category['attribs']['']['scheme']))
4617  {
4618  $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4619  }
4620  else
4621  {
4622  $scheme = 'http://search.yahoo.com/mrss/category_schema';
4623  }
4624  if (isset($category['attribs']['']['label']))
4625  {
4626  $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4627  }
4628  $categories[] = new $this->feed->category_class($term, $scheme, $label);
4629  }
4630  }
4631  if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4632  {
4633  foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4634  {
4635  $term = null;
4636  $scheme = null;
4637  $label = null;
4638  if (isset($category['data']))
4639  {
4640  $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4641  }
4642  if (isset($category['attribs']['']['scheme']))
4643  {
4644  $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4645  }
4646  else
4647  {
4648  $scheme = 'http://search.yahoo.com/mrss/category_schema';
4649  }
4650  if (isset($category['attribs']['']['label']))
4651  {
4652  $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4653  }
4654  $categories[] = new $this->feed->category_class($term, $scheme, $label);
4655  }
4656  }
4657  if (is_array($categories) && is_array($categories_parent))
4658  {
4659  $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4660  }
4661  elseif (is_array($categories))
4662  {
4663  $categories = array_values(SimplePie_Misc::array_unique($categories));
4664  }
4665  elseif (is_array($categories_parent))
4666  {
4667  $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4668  }
4669 
4670  // COPYRIGHTS
4671  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4672  {
4673  $copyright_url = null;
4674  $copyright_label = null;
4675  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4676  {
4677  $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4678  }
4679  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4680  {
4681  $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4682  }
4683  $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
4684  }
4685  elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4686  {
4687  $copyright_url = null;
4688  $copyright_label = null;
4689  if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4690  {
4691  $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4692  }
4693  if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4694  {
4695  $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4696  }
4697  $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
4698  }
4699  else
4700  {
4701  $copyrights = $copyrights_parent;
4702  }
4703 
4704  // CREDITS
4705  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4706  {
4707  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4708  {
4709  $credit_role = null;
4710  $credit_scheme = null;
4711  $credit_name = null;
4712  if (isset($credit['attribs']['']['role']))
4713  {
4714  $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4715  }
4716  if (isset($credit['attribs']['']['scheme']))
4717  {
4718  $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4719  }
4720  else
4721  {
4722  $credit_scheme = 'urn:ebu';
4723  }
4724  if (isset($credit['data']))
4725  {
4726  $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4727  }
4728  $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4729  }
4730  if (is_array($credits))
4731  {
4732  $credits = array_values(SimplePie_Misc::array_unique($credits));
4733  }
4734  }
4735  elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4736  {
4737  foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4738  {
4739  $credit_role = null;
4740  $credit_scheme = null;
4741  $credit_name = null;
4742  if (isset($credit['attribs']['']['role']))
4743  {
4744  $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4745  }
4746  if (isset($credit['attribs']['']['scheme']))
4747  {
4748  $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4749  }
4750  else
4751  {
4752  $credit_scheme = 'urn:ebu';
4753  }
4754  if (isset($credit['data']))
4755  {
4756  $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4757  }
4758  $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4759  }
4760  if (is_array($credits))
4761  {
4762  $credits = array_values(SimplePie_Misc::array_unique($credits));
4763  }
4764  }
4765  else
4766  {
4767  $credits = $credits_parent;
4768  }
4769 
4770  // DESCRIPTION
4771  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4772  {
4773  $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4774  }
4775  elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4776  {
4777  $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4778  }
4779  else
4780  {
4781  $description = $description_parent;
4782  }
4783 
4784  // HASHES
4785  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4786  {
4787  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4788  {
4789  $value = null;
4790  $algo = null;
4791  if (isset($hash['data']))
4792  {
4793  $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4794  }
4795  if (isset($hash['attribs']['']['algo']))
4796  {
4797  $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4798  }
4799  else
4800  {
4801  $algo = 'md5';
4802  }
4803  $hashes[] = $algo.':'.$value;
4804  }
4805  if (is_array($hashes))
4806  {
4807  $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4808  }
4809  }
4810  elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4811  {
4812  foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4813  {
4814  $value = null;
4815  $algo = null;
4816  if (isset($hash['data']))
4817  {
4818  $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4819  }
4820  if (isset($hash['attribs']['']['algo']))
4821  {
4822  $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4823  }
4824  else
4825  {
4826  $algo = 'md5';
4827  }
4828  $hashes[] = $algo.':'.$value;
4829  }
4830  if (is_array($hashes))
4831  {
4832  $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4833  }
4834  }
4835  else
4836  {
4837  $hashes = $hashes_parent;
4838  }
4839 
4840  // KEYWORDS
4841  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4842  {
4843  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4844  {
4845  $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4846  foreach ($temp as $word)
4847  {
4848  $keywords[] = trim($word);
4849  }
4850  unset($temp);
4851  }
4852  if (is_array($keywords))
4853  {
4854  $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4855  }
4856  }
4857  elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4858  {
4859  if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4860  {
4861  $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4862  foreach ($temp as $word)
4863  {
4864  $keywords[] = trim($word);
4865  }
4866  unset($temp);
4867  }
4868  if (is_array($keywords))
4869  {
4870  $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4871  }
4872  }
4873  else
4874  {
4875  $keywords = $keywords_parent;
4876  }
4877 
4878  // PLAYER
4879  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4880  {
4881  $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4882  }
4883  elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4884  {
4885  $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4886  }
4887  else
4888  {
4889  $player = $player_parent;
4890  }
4891 
4892  // RATINGS
4893  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4894  {
4895  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4896  {
4897  $rating_scheme = null;
4898  $rating_value = null;
4899  if (isset($rating['attribs']['']['scheme']))
4900  {
4901  $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4902  }
4903  else
4904  {
4905  $rating_scheme = 'urn:simple';
4906  }
4907  if (isset($rating['data']))
4908  {
4909  $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4910  }
4911  $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4912  }
4913  if (is_array($ratings))
4914  {
4915  $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4916  }
4917  }
4918  elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4919  {
4920  foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4921  {
4922  $rating_scheme = null;
4923  $rating_value = null;
4924  if (isset($rating['attribs']['']['scheme']))
4925  {
4926  $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4927  }
4928  else
4929  {
4930  $rating_scheme = 'urn:simple';
4931  }
4932  if (isset($rating['data']))
4933  {
4934  $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4935  }
4936  $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4937  }
4938  if (is_array($ratings))
4939  {
4940  $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4941  }
4942  }
4943  else
4944  {
4945  $ratings = $ratings_parent;
4946  }
4947 
4948  // RESTRICTIONS
4949  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4950  {
4951  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4952  {
4953  $restriction_relationship = null;
4954  $restriction_type = null;
4955  $restriction_value = null;
4956  if (isset($restriction['attribs']['']['relationship']))
4957  {
4958  $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4959  }
4960  if (isset($restriction['attribs']['']['type']))
4961  {
4962  $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4963  }
4964  if (isset($restriction['data']))
4965  {
4966  $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4967  }
4968  $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4969  }
4970  if (is_array($restrictions))
4971  {
4972  $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4973  }
4974  }
4975  elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4976  {
4977  foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4978  {
4979  $restriction_relationship = null;
4980  $restriction_type = null;
4981  $restriction_value = null;
4982  if (isset($restriction['attribs']['']['relationship']))
4983  {
4984  $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4985  }
4986  if (isset($restriction['attribs']['']['type']))
4987  {
4988  $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4989  }
4990  if (isset($restriction['data']))
4991  {
4992  $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4993  }
4994  $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4995  }
4996  if (is_array($restrictions))
4997  {
4998  $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4999  }
5000  }
5001  else
5002  {
5003  $restrictions = $restrictions_parent;
5004  }
5005 
5006  // THUMBNAILS
5007  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5008  {
5009  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5010  {
5011  $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5012  }
5013  if (is_array($thumbnails))
5014  {
5015  $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5016  }
5017  }
5018  elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5019  {
5020  foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5021  {
5022  $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5023  }
5024  if (is_array($thumbnails))
5025  {
5026  $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5027  }
5028  }
5029  else
5030  {
5031  $thumbnails = $thumbnails_parent;
5032  }
5033 
5034  // TITLES
5035  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5036  {
5037  $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5038  }
5039  elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5040  {
5041  $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5042  }
5043  else
5044  {
5045  $title = $title_parent;
5046  }
5047 
5048  $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);
5049  }
5050  }
5051  }
5052 
5053  // If we have standalone media:content tags, loop through them.
5054  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
5055  {
5056  foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
5057  {
5058  if (isset($content['attribs']['']['url']))
5059  {
5060  // Attributes
5061  $bitrate = null;
5062  $channels = null;
5063  $duration = null;
5064  $expression = null;
5065  $framerate = null;
5066  $height = null;
5067  $javascript = null;
5068  $lang = null;
5069  $length = null;
5070  $medium = null;
5071  $samplingrate = null;
5072  $type = null;
5073  $url = null;
5074  $width = null;
5075 
5076  // Elements
5077  $captions = null;
5078  $categories = null;
5079  $copyrights = null;
5080  $credits = null;
5081  $description = null;
5082  $hashes = null;
5083  $keywords = null;
5084  $player = null;
5085  $ratings = null;
5086  $restrictions = null;
5087  $thumbnails = null;
5088  $title = null;
5089 
5090  // Start checking the attributes of media:content
5091  if (isset($content['attribs']['']['bitrate']))
5092  {
5093  $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5094  }
5095  if (isset($content['attribs']['']['channels']))
5096  {
5097  $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5098  }
5099  if (isset($content['attribs']['']['duration']))
5100  {
5101  $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5102  }
5103  else
5104  {
5105  $duration = $duration_parent;
5106  }
5107  if (isset($content['attribs']['']['expression']))
5108  {
5109  $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5110  }
5111  if (isset($content['attribs']['']['framerate']))
5112  {
5113  $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5114  }
5115  if (isset($content['attribs']['']['height']))
5116  {
5117  $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5118  }
5119  if (isset($content['attribs']['']['lang']))
5120  {
5121  $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5122  }
5123  if (isset($content['attribs']['']['fileSize']))
5124  {
5125  $length = ceil($content['attribs']['']['fileSize']);
5126  }
5127  if (isset($content['attribs']['']['medium']))
5128  {
5129  $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5130  }
5131  if (isset($content['attribs']['']['samplingrate']))
5132  {
5133  $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5134  }
5135  if (isset($content['attribs']['']['type']))
5136  {
5137  $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5138  }
5139  if (isset($content['attribs']['']['width']))
5140  {
5141  $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5142  }
5143  $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5144 
5145  // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5146 
5147  // CAPTIONS
5148  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5149  {
5150  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5151  {
5152  $caption_type = null;
5153  $caption_lang = null;
5154  $caption_startTime = null;
5155  $caption_endTime = null;
5156  $caption_text = null;
5157  if (isset($caption['attribs']['']['type']))
5158  {
5159  $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5160  }
5161  if (isset($caption['attribs']['']['lang']))
5162  {
5163  $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5164  }
5165  if (isset($caption['attribs']['']['start']))
5166  {
5167  $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5168  }
5169  if (isset($caption['attribs']['']['end']))
5170  {
5171  $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5172  }
5173  if (isset($caption['data']))
5174  {
5175  $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5176  }
5177  $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5178  }
5179  if (is_array($captions))
5180  {
5181  $captions = array_values(SimplePie_Misc::array_unique($captions));
5182  }
5183  }
5184  else
5185  {
5186  $captions = $captions_parent;
5187  }
5188 
5189  // CATEGORIES
5190  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5191  {
5192  foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5193  {
5194  $term = null;
5195  $scheme = null;
5196  $label = null;
5197  if (isset($category['data']))
5198  {
5199  $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5200  }
5201  if (isset($category['attribs']['']['scheme']))
5202  {
5203  $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5204  }
5205  else
5206  {
5207  $scheme = 'http://search.yahoo.com/mrss/category_schema';
5208  }
5209  if (isset($category['attribs']['']['label']))
5210  {
5211  $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5212  }
5213  $categories[] = new $this->feed->category_class($term, $scheme, $label);
5214  }
5215  }
5216  if (is_array($categories) && is_array($categories_parent))
5217  {
5218  $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5219  }
5220  elseif (is_array($categories))
5221  {
5222  $categories = array_values(SimplePie_Misc::array_unique($categories));
5223  }
5224  elseif (is_array($categories_parent))
5225  {
5226  $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5227  }
5228  else
5229  {
5230  $categories = null;
5231  }
5232 
5233  // COPYRIGHTS
5234  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5235  {
5236  $copyright_url = null;
5237  $copyright_label = null;
5238  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5239  {
5240  $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5241  }
5242  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5243  {
5244  $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5245  }
5246  $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
5247  }
5248  else
5249  {
5250  $copyrights = $copyrights_parent;
5251  }
5252 
5253  // CREDITS
5254  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5255  {
5256  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5257  {
5258  $credit_role = null;
5259  $credit_scheme = null;
5260  $credit_name = null;
5261  if (isset($credit['attribs']['']['role']))
5262  {
5263  $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5264  }
5265  if (isset($credit['attribs']['']['scheme']))
5266  {
5267  $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5268  }
5269  else
5270  {
5271  $credit_scheme = 'urn:ebu';
5272  }
5273  if (isset($credit['data']))
5274  {
5275  $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5276  }
5277  $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5278  }
5279  if (is_array($credits))
5280  {
5281  $credits = array_values(SimplePie_Misc::array_unique($credits));
5282  }
5283  }
5284  else
5285  {
5286  $credits = $credits_parent;
5287  }
5288 
5289  // DESCRIPTION
5290  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5291  {
5292  $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5293  }
5294  else
5295  {
5296  $description = $description_parent;
5297  }
5298 
5299  // HASHES
5300  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5301  {
5302  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5303  {
5304  $value = null;
5305  $algo = null;
5306  if (isset($hash['data']))
5307  {
5308  $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5309  }
5310  if (isset($hash['attribs']['']['algo']))
5311  {
5312  $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5313  }
5314  else
5315  {
5316  $algo = 'md5';
5317  }
5318  $hashes[] = $algo.':'.$value;
5319  }
5320  if (is_array($hashes))
5321  {
5322  $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5323  }
5324  }
5325  else
5326  {
5327  $hashes = $hashes_parent;
5328  }
5329 
5330  // KEYWORDS
5331  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5332  {
5333  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5334  {
5335  $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5336  foreach ($temp as $word)
5337  {
5338  $keywords[] = trim($word);
5339  }
5340  unset($temp);
5341  }
5342  if (is_array($keywords))
5343  {
5344  $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5345  }
5346  }
5347  else
5348  {
5349  $keywords = $keywords_parent;
5350  }
5351 
5352  // PLAYER
5353  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5354  {
5355  $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5356  }
5357  else
5358  {
5359  $player = $player_parent;
5360  }
5361 
5362  // RATINGS
5363  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5364  {
5365  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5366  {
5367  $rating_scheme = null;
5368  $rating_value = null;
5369  if (isset($rating['attribs']['']['scheme']))
5370  {
5371  $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5372  }
5373  else
5374  {
5375  $rating_scheme = 'urn:simple';
5376  }
5377  if (isset($rating['data']))
5378  {
5379  $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5380  }
5381  $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
5382  }
5383  if (is_array($ratings))
5384  {
5385  $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5386  }
5387  }
5388  else
5389  {
5390  $ratings = $ratings_parent;
5391  }
5392 
5393  // RESTRICTIONS
5394  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5395  {
5396  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5397  {
5398  $restriction_relationship = null;
5399  $restriction_type = null;
5400  $restriction_value = null;
5401  if (isset($restriction['attribs']['']['relationship']))
5402  {
5403  $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5404  }
5405  if (isset($restriction['attribs']['']['type']))
5406  {
5407  $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5408  }
5409  if (isset($restriction['data']))
5410  {
5411  $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5412  }
5413  $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5414  }
5415  if (is_array($restrictions))
5416  {
5417  $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5418  }
5419  }
5420  else
5421  {
5422  $restrictions = $restrictions_parent;
5423  }
5424 
5425  // THUMBNAILS
5426  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5427  {
5428  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5429  {
5430  $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5431  }
5432  if (is_array($thumbnails))
5433  {
5434  $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5435  }
5436  }
5437  else
5438  {
5439  $thumbnails = $thumbnails_parent;
5440  }
5441 
5442  // TITLES
5443  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5444  {
5445  $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5446  }
5447  else
5448  {
5449  $title = $title_parent;
5450  }
5451 
5452  $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);
5453  }
5454  }
5455  }
5456 
5457  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5458  {
5459  if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
5460  {
5461  // Attributes
5462  $bitrate = null;
5463  $channels = null;
5464  $duration = null;
5465  $expression = null;
5466  $framerate = null;
5467  $height = null;
5468  $javascript = null;
5469  $lang = null;
5470  $length = null;
5471  $medium = null;
5472  $samplingrate = null;
5473  $type = null;
5474  $url = null;
5475  $width = null;
5476 
5477  $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5478  if (isset($link['attribs']['']['type']))
5479  {
5480  $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5481  }
5482  if (isset($link['attribs']['']['length']))
5483  {
5484  $length = ceil($link['attribs']['']['length']);
5485  }
5486 
5487  // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5488  $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);
5489  }
5490  }
5491 
5492  foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5493  {
5494  if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
5495  {
5496  // Attributes
5497  $bitrate = null;
5498  $channels = null;
5499  $duration = null;
5500  $expression = null;
5501  $framerate = null;
5502  $height = null;
5503  $javascript = null;
5504  $lang = null;
5505  $length = null;
5506  $medium = null;
5507  $samplingrate = null;
5508  $type = null;
5509  $url = null;
5510  $width = null;
5511 
5512  $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5513  if (isset($link['attribs']['']['type']))
5514  {
5515  $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5516  }
5517  if (isset($link['attribs']['']['length']))
5518  {
5519  $length = ceil($link['attribs']['']['length']);
5520  }
5521 
5522  // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5523  $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);
5524  }
5525  }
5526 
5527  if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure'))
5528  {
5529  if (isset($enclosure[0]['attribs']['']['url']))
5530  {
5531  // Attributes
5532  $bitrate = null;
5533  $channels = null;
5534  $duration = null;
5535  $expression = null;
5536  $framerate = null;
5537  $height = null;
5538  $javascript = null;
5539  $lang = null;
5540  $length = null;
5541  $medium = null;
5542  $samplingrate = null;
5543  $type = null;
5544  $url = null;
5545  $width = null;
5546 
5547  $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5548  if (isset($enclosure[0]['attribs']['']['type']))
5549  {
5550  $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5551  }
5552  if (isset($enclosure[0]['attribs']['']['length']))
5553  {
5554  $length = ceil($enclosure[0]['attribs']['']['length']);
5555  }
5556 
5557  // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5558  $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);
5559  }
5560  }
5561 
5562  if (sizeof($this->data['enclosures']) === 0 && ($url || $type || $length || $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))
5563  {
5564  // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5565  $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);
5566  }
5567 
5568  $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5569  }
5570  if (!empty($this->data['enclosures']))
5571  {
5572  return $this->data['enclosures'];
5573  }
5574  else
5575  {
5576  return null;
5577  }
5578  }
5579 
5580  function get_latitude()
5581  {
5582  if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5583  {
5584  return (float) $return[0]['data'];
5585  }
5586  elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5587  {
5588  return (float) $match[1];
5589  }
5590  else
5591  {
5592  return null;
5593  }
5594  }
5595 
5596  function get_longitude()
5597  {
5598  if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5599  {
5600  return (float) $return[0]['data'];
5601  }
5602  elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5603  {
5604  return (float) $return[0]['data'];
5605  }
5606  elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5607  {
5608  return (float) $match[2];
5609  }
5610  else
5611  {
5612  return null;
5613  }
5614  }
5615 
5616  function get_source()
5617  {
5618  if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5619  {
5620  return new $this->feed->source_class($this, $return[0]);
5621  }
5622  else
5623  {
5624  return null;
5625  }
5626  }
5627 
5628  /**
5629  * Creates the add_to_* methods' return data
5630  *
5631  * @access private
5632  * @param string $item_url String to prefix to the item permalink
5633  * @param string $title_url String to prefix to the item title
5634  * (and suffix to the item permalink)
5635  * @return mixed URL if feed exists, false otherwise
5636  */
5637  function add_to_service($item_url, $title_url = null, $summary_url = null)
5638  {
5639  if ($this->get_permalink() !== null)
5640  {
5641  $return = $item_url . rawurlencode($this->get_permalink());
5642  if ($title_url !== null && $this->get_title() !== null)
5643  {
5644  $return .= $title_url . rawurlencode($this->get_title());
5645  }
5646  if ($summary_url !== null && $this->get_description() !== null)
5647  {
5648  $return .= $summary_url . rawurlencode($this->get_description());
5649  }
5650  return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
5651  }
5652  else
5653  {
5654  return null;
5655  }
5656  }
5657 
5658  function add_to_blinklist()
5659  {
5660  return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5661  }
5662 
5663  function add_to_blogmarks()
5664  {
5665  return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5666  }
5667 
5668  function add_to_delicious()
5669  {
5670  return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5671  }
5672 
5673  function add_to_digg()
5674  {
5675  return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
5676  }
5677 
5678  function add_to_furl()
5679  {
5680  return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5681  }
5682 
5683  function add_to_magnolia()
5684  {
5685  return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5686  }
5687 
5688  function add_to_myweb20()
5689  {
5690  return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5691  }
5692 
5693  function add_to_newsvine()
5694  {
5695  return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5696  }
5697 
5698  function add_to_reddit()
5699  {
5700  return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5701  }
5702 
5703  function add_to_segnalo()
5704  {
5705  return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5706  }
5707 
5708  function add_to_simpy()
5709  {
5710  return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5711  }
5712 
5713  function add_to_spurl()
5714  {
5715  return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5716  }
5717 
5718  function add_to_wists()
5719  {
5720  return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5721  }
5722 
5724  {
5725  return $this->add_to_service('http://www.technorati.com/search/');
5726  }
5727 }
5728 
5730 {
5731  var $item;
5732  var $data = array();
5733 
5735  {
5736  $this->item = $item;
5737  $this->data = $data;
5738  }
5739 
5740  function __toString()
5741  {
5742  return md5(serialize($this->data));
5743  }
5744 
5745  function get_source_tags($namespace, $tag)
5746  {
5747  if (isset($this->data['child'][$namespace][$tag]))
5748  {
5749  return $this->data['child'][$namespace][$tag];
5750  }
5751  else
5752  {
5753  return null;
5754  }
5755  }
5756 
5757  function get_base($element = array())
5758  {
5759  return $this->item->get_base($element);
5760  }
5761 
5762  function sanitize($data, $type, $base = '')
5763  {
5764  return $this->item->sanitize($data, $type, $base);
5765  }
5766 
5767  function get_item()
5768  {
5769  return $this->item;
5770  }
5771 
5772  function get_title()
5773  {
5774  if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5775  {
5776  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5777  }
5778  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5779  {
5780  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5781  }
5782  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5783  {
5784  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5785  }
5786  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5787  {
5788  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5789  }
5790  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
5791  {
5792  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5793  }
5794  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5795  {
5796  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5797  }
5798  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5799  {
5800  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5801  }
5802  else
5803  {
5804  return null;
5805  }
5806  }
5807 
5808  function get_category($key = 0)
5809  {
5810  $categories = $this->get_categories();
5811  if (isset($categories[$key]))
5812  {
5813  return $categories[$key];
5814  }
5815  else
5816  {
5817  return null;
5818  }
5819  }
5820 
5821  function get_categories()
5822  {
5823  $categories = array();
5824 
5825  foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5826  {
5827  $term = null;
5828  $scheme = null;
5829  $label = null;
5830  if (isset($category['attribs']['']['term']))
5831  {
5832  $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5833  }
5834  if (isset($category['attribs']['']['scheme']))
5835  {
5836  $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5837  }
5838  if (isset($category['attribs']['']['label']))
5839  {
5840  $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5841  }
5842  $categories[] = new $this->item->feed->category_class($term, $scheme, $label);
5843  }
5844  foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
5845  {
5846  // This is really the label, but keep this as the term also for BC.
5847  // Label will also work on retrieving because that falls back to term.
5848  $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5849  if (isset($category['attribs']['']['domain']))
5850  {
5851  $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
5852  }
5853  else
5854  {
5855  $scheme = null;
5856  }
5857  $categories[] = new $this->item->feed->category_class($term, $scheme, null);
5858  }
5859  foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5860  {
5861  $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5862  }
5863  foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5864  {
5865  $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5866  }
5867 
5868  if (!empty($categories))
5869  {
5870  return SimplePie_Misc::array_unique($categories);
5871  }
5872  else
5873  {
5874  return null;
5875  }
5876  }
5877 
5878  function get_author($key = 0)
5879  {
5880  $authors = $this->get_authors();
5881  if (isset($authors[$key]))
5882  {
5883  return $authors[$key];
5884  }
5885  else
5886  {
5887  return null;
5888  }
5889  }
5890 
5891  function get_authors()
5892  {
5893  $authors = array();
5894  foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5895  {
5896  $name = null;
5897  $uri = null;
5898  $email = null;
5899  if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5900  {
5901  $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5902  }
5903  if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5904  {
5905  $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]));
5906  }
5907  if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5908  {
5909  $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5910  }
5911  if ($name !== null || $email !== null || $uri !== null)
5912  {
5913  $authors[] = new $this->item->feed->author_class($name, $uri, $email);
5914  }
5915  }
5916  if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5917  {
5918  $name = null;
5919  $url = null;
5920  $email = null;
5921  if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5922  {
5923  $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5924  }
5925  if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5926  {
5927  $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
5928  }
5929  if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5930  {
5931  $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5932  }
5933  if ($name !== null || $email !== null || $url !== null)
5934  {
5935  $authors[] = new $this->item->feed->author_class($name, $url, $email);
5936  }
5937  }
5938  foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5939  {
5940  $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5941  }
5942  foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5943  {
5944  $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5945  }
5946  foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5947  {
5948  $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5949  }
5950 
5951  if (!empty($authors))
5952  {
5953  return SimplePie_Misc::array_unique($authors);
5954  }
5955  else
5956  {
5957  return null;
5958  }
5959  }
5960 
5961  function get_contributor($key = 0)
5962  {
5963  $contributors = $this->get_contributors();
5964  if (isset($contributors[$key]))
5965  {
5966  return $contributors[$key];
5967  }
5968  else
5969  {
5970  return null;
5971  }
5972  }
5973 
5974  function get_contributors()
5975  {
5976  $contributors = array();
5977  foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5978  {
5979  $name = null;
5980  $uri = null;
5981  $email = null;
5982  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5983  {
5984  $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5985  }
5986  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5987  {
5988  $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
5989  }
5990  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5991  {
5992  $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5993  }
5994  if ($name !== null || $email !== null || $uri !== null)
5995  {
5996  $contributors[] = new $this->item->feed->author_class($name, $uri, $email);
5997  }
5998  }
5999  foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
6000  {
6001  $name = null;
6002  $url = null;
6003  $email = null;
6004  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
6005  {
6006  $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6007  }
6008  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
6009  {
6010  $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
6011  }
6012  if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
6013  {
6014  $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6015  }
6016  if ($name !== null || $email !== null || $url !== null)
6017  {
6018  $contributors[] = new $this->item->feed->author_class($name, $url, $email);
6019  }
6020  }
6021 
6022  if (!empty($contributors))
6023  {
6024  return SimplePie_Misc::array_unique($contributors);
6025  }
6026  else
6027  {
6028  return null;
6029  }
6030  }
6031 
6032  function get_link($key = 0, $rel = 'alternate')
6033  {
6034  $links = $this->get_links($rel);
6035  if (isset($links[$key]))
6036  {
6037  return $links[$key];
6038  }
6039  else
6040  {
6041  return null;
6042  }
6043  }
6044 
6045  /**
6046  * Added for parity between the parent-level and the item/entry-level.
6047  */
6048  function get_permalink()
6049  {
6050  return $this->get_link(0);
6051  }
6052 
6053  function get_links($rel = 'alternate')
6054  {
6055  if (!isset($this->data['links']))
6056  {
6057  $this->data['links'] = array();
6058  if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
6059  {
6060  foreach ($links as $link)
6061  {
6062  if (isset($link['attribs']['']['href']))
6063  {
6064  $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6065  $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6066  }
6067  }
6068  }
6069  if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
6070  {
6071  foreach ($links as $link)
6072  {
6073  if (isset($link['attribs']['']['href']))
6074  {
6075  $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6076  $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6077 
6078  }
6079  }
6080  }
6081  if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
6082  {
6083  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6084  }
6085  if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6086  {
6087  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6088  }
6089  if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
6090  {
6091  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6092  }
6093 
6094  $keys = array_keys($this->data['links']);
6095  foreach ($keys as $key)
6096  {
6098  {
6099  if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6100  {
6101  $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6102  $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6103  }
6104  else
6105  {
6106  $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6107  }
6108  }
6109  elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6110  {
6111  $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6112  }
6113  $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6114  }
6115  }
6116 
6117  if (isset($this->data['links'][$rel]))
6118  {
6119  return $this->data['links'][$rel];
6120  }
6121  else
6122  {
6123  return null;
6124  }
6125  }
6126 
6127  function get_description()
6128  {
6129  if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6130  {
6131  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6132  }
6133  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6134  {
6135  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6136  }
6137  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6138  {
6139  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6140  }
6141  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6142  {
6143  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6144  }
6145  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
6146  {
6147  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6148  }
6149  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6150  {
6151  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6152  }
6153  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6154  {
6155  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6156  }
6157  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6158  {
6159  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6160  }
6161  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6162  {
6163  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6164  }
6165  else
6166  {
6167  return null;
6168  }
6169  }
6170 
6171  function get_copyright()
6172  {
6173  if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6174  {
6175  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6176  }
6177  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6178  {
6179  return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6180  }
6181  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
6182  {
6183  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6184  }
6185  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6186  {
6187  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6188  }
6189  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6190  {
6191  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6192  }
6193  else
6194  {
6195  return null;
6196  }
6197  }
6198 
6199  function get_language()
6200  {
6201  if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
6202  {
6203  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6204  }
6205  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6206  {
6207  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6208  }
6209  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6210  {
6211  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6212  }
6213  elseif (isset($this->data['xml_lang']))
6214  {
6215  return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6216  }
6217  else
6218  {
6219  return null;
6220  }
6221  }
6222 
6223  function get_latitude()
6224  {
6225  if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6226  {
6227  return (float) $return[0]['data'];
6228  }
6229  elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6230  {
6231  return (float) $match[1];
6232  }
6233  else
6234  {
6235  return null;
6236  }
6237  }
6238 
6239  function get_longitude()
6240  {
6241  if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6242  {
6243  return (float) $return[0]['data'];
6244  }
6245  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6246  {
6247  return (float) $return[0]['data'];
6248  }
6249  elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6250  {
6251  return (float) $match[2];
6252  }
6253  else
6254  {
6255  return null;
6256  }
6257  }
6258 
6259  function get_image_url()
6260  {
6261  if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6262  {
6263  return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6264  }
6265  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6266  {
6267  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6268  }
6269  elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6270  {
6271  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6272  }
6273  else
6274  {
6275  return null;
6276  }
6277  }
6278 }
6279 
6281 {
6282  var $name;
6283  var $link;
6284  var $email;
6285 
6286  // Constructor, used to input the data
6287  function SimplePie_Author($name = null, $link = null, $email = null)
6288  {
6289  $this->name = $name;
6290  $this->link = $link;
6291  $this->email = $email;
6292  }
6293 
6294  function __toString()
6295  {
6296  // There is no $this->data here
6297  return md5(serialize($this));
6298  }
6299 
6300  function get_name()
6301  {
6302  if ($this->name !== null)
6303  {
6304  return $this->name;
6305  }
6306  else
6307  {
6308  return null;
6309  }
6310  }
6311 
6312  function get_link()
6313  {
6314  if ($this->link !== null)
6315  {
6316  return $this->link;
6317  }
6318  else
6319  {
6320  return null;
6321  }
6322  }
6323 
6324  function get_email()
6325  {
6326  if ($this->email !== null)
6327  {
6328  return $this->email;
6329  }
6330  else
6331  {
6332  return null;
6333  }
6334  }
6335 }
6336 
6338 {
6339  var $term;
6340  var $scheme;
6341  var $label;
6342 
6343  // Constructor, used to input the data
6344  function SimplePie_Category($term = null, $scheme = null, $label = null)
6345  {
6346  $this->term = $term;
6347  $this->scheme = $scheme;
6348  $this->label = $label;
6349  }
6350 
6351  function __toString()
6352  {
6353  // There is no $this->data here
6354  return md5(serialize($this));
6355  }
6356 
6357  function get_term()
6358  {
6359  if ($this->term !== null)
6360  {
6361  return $this->term;
6362  }
6363  else
6364  {
6365  return null;
6366  }
6367  }
6368 
6369  function get_scheme()
6370  {
6371  if ($this->scheme !== null)
6372  {
6373  return $this->scheme;
6374  }
6375  else
6376  {
6377  return null;
6378  }
6379  }
6380 
6381  function get_label()
6382  {
6383  if ($this->label !== null)
6384  {
6385  return $this->label;
6386  }
6387  else
6388  {
6389  return $this->get_term();
6390  }
6391  }
6392 }
6393 
6395 {
6407  var $hashes;
6408  var $height;
6411  var $lang;
6412  var $length;
6413  var $link;
6414  var $medium;
6415  var $player;
6420  var $title;
6421  var $type;
6422  var $width;
6423 
6424  // Constructor, used to input the data
6425  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)
6426  {
6427  $this->bitrate = $bitrate;
6428  $this->captions = $captions;
6429  $this->categories = $categories;
6430  $this->channels = $channels;
6431  $this->copyright = $copyright;
6432  $this->credits = $credits;
6433  $this->description = $description;
6434  $this->duration = $duration;
6435  $this->expression = $expression;
6436  $this->framerate = $framerate;
6437  $this->hashes = $hashes;
6438  $this->height = $height;
6439  $this->javascript = $javascript;
6440  $this->keywords = $keywords;
6441  $this->lang = $lang;
6442  $this->length = $length;
6443  $this->link = $link;
6444  $this->medium = $medium;
6445  $this->player = $player;
6446  $this->ratings = $ratings;
6447  $this->restrictions = $restrictions;
6448  $this->samplingrate = $samplingrate;
6449  $this->thumbnails = $thumbnails;
6450  $this->title = $title;
6451  $this->type = $type;
6452  $this->width = $width;
6453  if (class_exists('idna_convert'))
6454  {
6455  $idn = new idna_convert;
6456  $parsed = SimplePie_Misc::parse_url($link);
6457  $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6458  }
6459  $this->handler = $this->get_handler(); // Needs to load last
6460  }
6461 
6462  function __toString()
6463  {
6464  // There is no $this->data here
6465  return md5(serialize($this));
6466  }
6467 
6468  function get_bitrate()
6469  {
6470  if ($this->bitrate !== null)
6471  {
6472  return $this->bitrate;
6473  }
6474  else
6475  {
6476  return null;
6477  }
6478  }
6479 
6480  function get_caption($key = 0)
6481  {
6482  $captions = $this->get_captions();
6483  if (isset($captions[$key]))
6484  {
6485  return $captions[$key];
6486  }
6487  else
6488  {
6489  return null;
6490  }
6491  }
6492 
6493  function get_captions()
6494  {
6495  if ($this->captions !== null)
6496  {
6497  return $this->captions;
6498  }
6499  else
6500  {
6501  return null;
6502  }
6503  }
6504 
6505  function get_category($key = 0)
6506  {
6507  $categories = $this->get_categories();
6508  if (isset($categories[$key]))
6509  {
6510  return $categories[$key];
6511  }
6512  else
6513  {
6514  return null;
6515  }
6516  }
6517 
6518  function get_categories()
6519  {
6520  if ($this->categories !== null)
6521  {
6522  return $this->categories;
6523  }
6524  else
6525  {
6526  return null;
6527  }
6528  }
6529 
6530  function get_channels()
6531  {
6532  if ($this->channels !== null)
6533  {
6534  return $this->channels;
6535  }
6536  else
6537  {
6538  return null;
6539  }
6540  }
6541 
6542  function get_copyright()
6543  {
6544  if ($this->copyright !== null)
6545  {
6546  return $this->copyright;
6547  }
6548  else
6549  {
6550  return null;
6551  }
6552  }
6553 
6554  function get_credit($key = 0)
6555  {
6556  $credits = $this->get_credits();
6557  if (isset($credits[$key]))
6558  {
6559  return $credits[$key];
6560  }
6561  else
6562  {
6563  return null;
6564  }
6565  }
6566 
6567  function get_credits()
6568  {
6569  if ($this->credits !== null)
6570  {
6571  return $this->credits;
6572  }
6573  else
6574  {
6575  return null;
6576  }
6577  }
6578 
6579  function get_description()
6580  {
6581  if ($this->description !== null)
6582  {
6583  return $this->description;
6584  }
6585  else
6586  {
6587  return null;
6588  }
6589  }
6590 
6591  function get_duration($convert = false)
6592  {
6593  if ($this->duration !== null)
6594  {
6595  if ($convert)
6596  {
6597  $time = SimplePie_Misc::time_hms($this->duration);
6598  return $time;
6599  }
6600  else
6601  {
6602  return $this->duration;
6603  }
6604  }
6605  else
6606  {
6607  return null;
6608  }
6609  }
6610 
6611  function get_expression()
6612  {
6613  if ($this->expression !== null)
6614  {
6615  return $this->expression;
6616  }
6617  else
6618  {
6619  return 'full';
6620  }
6621  }
6622 
6623  function get_extension()
6624  {
6625  if ($this->link !== null)
6626  {
6627  $url = SimplePie_Misc::parse_url($this->link);
6628  if ($url['path'] !== '')
6629  {
6630  return pathinfo($url['path'], PATHINFO_EXTENSION);
6631  }
6632  }
6633  return null;
6634  }
6635 
6636  function get_framerate()
6637  {
6638  if ($this->framerate !== null)
6639  {
6640  return $this->framerate;
6641  }
6642  else
6643  {
6644  return null;
6645  }
6646  }
6647 
6648  function get_handler()
6649  {
6650  return $this->get_real_type(true);
6651  }
6652 
6653  function get_hash($key = 0)
6654  {
6655  $hashes = $this->get_hashes();
6656  if (isset($hashes[$key]))
6657  {
6658  return $hashes[$key];
6659  }
6660  else
6661  {
6662  return null;
6663  }
6664  }
6665 
6666  function get_hashes()
6667  {
6668  if ($this->hashes !== null)
6669  {
6670  return $this->hashes;
6671  }
6672  else
6673  {
6674  return null;
6675  }
6676  }
6677 
6678  function get_height()
6679  {
6680  if ($this->height !== null)
6681  {
6682  return $this->height;
6683  }
6684  else
6685  {
6686  return null;
6687  }
6688  }
6689 
6690  function get_language()
6691  {
6692  if ($this->lang !== null)
6693  {
6694  return $this->lang;
6695  }
6696  else
6697  {
6698  return null;
6699  }
6700  }
6701 
6702  function get_keyword($key = 0)
6703  {
6704  $keywords = $this->get_keywords();
6705  if (isset($keywords[$key]))
6706  {
6707  return $keywords[$key];
6708  }
6709  else
6710  {
6711  return null;
6712  }
6713  }
6714 
6715  function get_keywords()
6716  {
6717  if ($this->keywords !== null)
6718  {
6719  return $this->keywords;
6720  }
6721  else
6722  {
6723  return null;
6724  }
6725  }
6726 
6727  function get_length()
6728  {
6729  if ($this->length !== null)
6730  {
6731  return $this->length;
6732  }
6733  else
6734  {
6735  return null;
6736  }
6737  }
6738 
6739  function get_link()
6740  {
6741  if ($this->link !== null)
6742  {
6743  return urldecode($this->link);
6744  }
6745  else
6746  {
6747  return null;
6748  }
6749  }
6750 
6751  function get_medium()
6752  {
6753  if ($this->medium !== null)
6754  {
6755  return $this->medium;
6756  }
6757  else
6758  {
6759  return null;
6760  }
6761  }
6762 
6763  function get_player()
6764  {
6765  if ($this->player !== null)
6766  {
6767  return $this->player;
6768  }
6769  else
6770  {
6771  return null;
6772  }
6773  }
6774 
6775  function get_rating($key = 0)
6776  {
6777  $ratings = $this->get_ratings();
6778  if (isset($ratings[$key]))
6779  {
6780  return $ratings[$key];
6781  }
6782  else
6783  {
6784  return null;
6785  }
6786  }
6787 
6788  function get_ratings()
6789  {
6790  if ($this->ratings !== null)
6791  {
6792  return $this->ratings;
6793  }
6794  else
6795  {
6796  return null;
6797  }
6798  }
6799 
6800  function get_restriction($key = 0)
6801  {
6802  $restrictions = $this->get_restrictions();
6803  if (isset($restrictions[$key]))
6804  {
6805  return $restrictions[$key];
6806  }
6807  else
6808  {
6809  return null;
6810  }
6811  }
6812 
6813  function get_restrictions()
6814  {
6815  if ($this->restrictions !== null)
6816  {
6817  return $this->restrictions;
6818  }
6819  else
6820  {
6821  return null;
6822  }
6823  }
6824 
6826  {
6827  if ($this->samplingrate !== null)
6828  {
6829  return $this->samplingrate;
6830  }
6831  else
6832  {
6833  return null;
6834  }
6835  }
6836 
6837  function get_size()
6838  {
6839  $length = $this->get_length();
6840  if ($length !== null)
6841  {
6842  return round($length/1048576, 2);
6843  }
6844  else
6845  {
6846  return null;
6847  }
6848  }
6849 
6850  function get_thumbnail($key = 0)
6851  {
6852  $thumbnails = $this->get_thumbnails();
6853  if (isset($thumbnails[$key]))
6854  {
6855  return $thumbnails[$key];
6856  }
6857  else
6858  {
6859  return null;
6860  }
6861  }
6862 
6863  function get_thumbnails()
6864  {
6865  if ($this->thumbnails !== null)
6866  {
6867  return $this->thumbnails;
6868  }
6869  else
6870  {
6871  return null;
6872  }
6873  }
6874 
6875  function get_title()
6876  {
6877  if ($this->title !== null)
6878  {
6879  return $this->title;
6880  }
6881  else
6882  {
6883  return null;
6884  }
6885  }
6886 
6887  function get_type()
6888  {
6889  if ($this->type !== null)
6890  {
6891  return $this->type;
6892  }
6893  else
6894  {
6895  return null;
6896  }
6897  }
6898 
6899  function get_width()
6900  {
6901  if ($this->width !== null)
6902  {
6903  return $this->width;
6904  }
6905  else
6906  {
6907  return null;
6908  }
6909  }
6910 
6911  function native_embed($options='')
6912  {
6913  return $this->embed($options, true);
6914  }
6915 
6916  /**
6917  * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6918  */
6919  function embed($options = '', $native = false)
6920  {
6921  // Set up defaults
6922  $audio = '';
6923  $video = '';
6924  $alt = '';
6925  $altclass = '';
6926  $loop = 'false';
6927  $width = 'auto';
6928  $height = 'auto';
6929  $bgcolor = '#ffffff';
6930  $mediaplayer = '';
6931  $widescreen = false;
6932  $handler = $this->get_handler();
6933  $type = $this->get_real_type();
6934 
6935  // Process options and reassign values as necessary
6936  if (is_array($options))
6937  {
6938  extract($options);
6939  }
6940  else
6941  {
6942  $options = explode(',', $options);
6943  foreach($options as $option)
6944  {
6945  $opt = explode(':', $option, 2);
6946  if (isset($opt[0], $opt[1]))
6947  {
6948  $opt[0] = trim($opt[0]);
6949  $opt[1] = trim($opt[1]);
6950  switch ($opt[0])
6951  {
6952  case 'audio':
6953  $audio = $opt[1];
6954  break;
6955 
6956  case 'video':
6957  $video = $opt[1];
6958  break;
6959 
6960  case 'alt':
6961  $alt = $opt[1];
6962  break;
6963 
6964  case 'altclass':
6965  $altclass = $opt[1];
6966  break;
6967 
6968  case 'loop':
6969  $loop = $opt[1];
6970  break;
6971 
6972  case 'width':
6973  $width = $opt[1];
6974  break;
6975 
6976  case 'height':
6977  $height = $opt[1];
6978  break;
6979 
6980  case 'bgcolor':
6981  $bgcolor = $opt[1];
6982  break;
6983 
6984  case 'mediaplayer':
6985  $mediaplayer = $opt[1];
6986  break;
6987 
6988  case 'widescreen':
6989  $widescreen = $opt[1];
6990  break;
6991  }
6992  }
6993  }
6994  }
6995 
6996  $mime = explode('/', $type, 2);
6997  $mime = $mime[0];
6998 
6999  // Process values for 'auto'
7000  if ($width === 'auto')
7001  {
7002  if ($mime === 'video')
7003  {
7004  if ($height === 'auto')
7005  {
7006  $width = 480;
7007  }
7008  elseif ($widescreen)
7009  {
7010  $width = round((intval($height)/9)*16);
7011  }
7012  else
7013  {
7014  $width = round((intval($height)/3)*4);
7015  }
7016  }
7017  else
7018  {
7019  $width = '100%';
7020  }
7021  }
7022 
7023  if ($height === 'auto')
7024  {
7025  if ($mime === 'audio')
7026  {
7027  $height = 0;
7028  }
7029  elseif ($mime === 'video')
7030  {
7031  if ($width === 'auto')
7032  {
7033  if ($widescreen)
7034  {
7035  $height = 270;
7036  }
7037  else
7038  {
7039  $height = 360;
7040  }
7041  }
7042  elseif ($widescreen)
7043  {
7044  $height = round((intval($width)/16)*9);
7045  }
7046  else
7047  {
7048  $height = round((intval($width)/4)*3);
7049  }
7050  }
7051  else
7052  {
7053  $height = 376;
7054  }
7055  }
7056  elseif ($mime === 'audio')
7057  {
7058  $height = 0;
7059  }
7060 
7061  // Set proper placeholder value
7062  if ($mime === 'audio')
7063  {
7064  $placeholder = $audio;
7065  }
7066  elseif ($mime === 'video')
7067  {
7068  $placeholder = $video;
7069  }
7070 
7071  $embed = '';
7072 
7073  // Make sure the JS library is included
7074  if (!$native)
7075  {
7076  static $javascript_outputted = null;
7077  if (!$javascript_outputted && $this->javascript)
7078  {
7079  $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7080  $javascript_outputted = true;
7081  }
7082  }
7083 
7084  // Odeo Feed MP3's
7085  if ($handler === 'odeo')
7086  {
7087  if ($native)
7088  {
7089  $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>';
7090  }
7091  else
7092  {
7093  $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
7094  }
7095  }
7096 
7097  // Flash
7098  elseif ($handler === 'flash')
7099  {
7100  if ($native)
7101  {
7102  $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>";
7103  }
7104  else
7105  {
7106  $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
7107  }
7108  }
7109 
7110  // Flash Media Player file types.
7111  // Preferred handler for MP3 file types.
7112  elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
7113  {
7114  $height += 20;
7115  if ($native)
7116  {
7117  $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>";
7118  }
7119  else
7120  {
7121  $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7122  }
7123  }
7124 
7125  // QuickTime 7 file types. Need to test with QuickTime 6.
7126  // Only handle MP3's if the Flash Media Player is not present.
7127  elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
7128  {
7129  $height += 16;
7130  if ($native)
7131  {
7132  if ($placeholder !== '')
7133  {
7134  $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>";
7135  }
7136  else
7137  {
7138  $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>";
7139  }
7140  }
7141  else
7142  {
7143  $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7144  }
7145  }
7146 
7147  // Windows Media
7148  elseif ($handler === 'wmedia')
7149  {
7150  $height += 45;
7151  if ($native)
7152  {
7153  $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>";
7154  }
7155  else
7156  {
7157  $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7158  }
7159  }
7160 
7161  // Everything else
7162  else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7163 
7164  return $embed;
7165  }
7166 
7167  function get_real_type($find_handler = false)
7168  {
7169  // If it's Odeo, let's get it out of the way.
7170  if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')
7171  {
7172  return 'odeo';
7173  }
7174 
7175  // Mime-types by handler.
7176  $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7177  $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
7178  $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
7179  $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
7180  $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7181 
7182  if ($this->get_type() !== null)
7183  {
7184  $type = strtolower($this->type);
7185  }
7186  else
7187  {
7188  $type = null;
7189  }
7190 
7191  // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7192  if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7193  {
7194  switch (strtolower($this->get_extension()))
7195  {
7196  // Audio mime-types
7197  case 'aac':
7198  case 'adts':
7199  $type = 'audio/acc';
7200  break;
7201 
7202  case 'aif':
7203  case 'aifc':
7204  case 'aiff':
7205  case 'cdda':
7206  $type = 'audio/aiff';
7207  break;
7208 
7209  case 'bwf':
7210  $type = 'audio/wav';
7211  break;
7212 
7213  case 'kar':
7214  case 'mid':
7215  case 'midi':
7216  case 'smf':
7217  $type = 'audio/midi';
7218  break;
7219 
7220  case 'm4a':
7221  $type = 'audio/x-m4a';
7222  break;
7223 
7224  case 'mp3':
7225  case 'swa':
7226  $type = 'audio/mp3';
7227  break;
7228 
7229  case 'wav':
7230  $type = 'audio/wav';
7231  break;
7232 
7233  case 'wax':
7234  $type = 'audio/x-ms-wax';
7235  break;
7236 
7237  case 'wma':
7238  $type = 'audio/x-ms-wma';
7239  break;
7240 
7241  // Video mime-types
7242  case '3gp':
7243  case '3gpp':
7244  $type = 'video/3gpp';
7245  break;
7246 
7247  case '3g2':
7248  case '3gp2':
7249  $type = 'video/3gpp2';
7250  break;
7251 
7252  case 'asf':
7253  $type = 'video/x-ms-asf';
7254  break;
7255 
7256  case 'flv':
7257  $type = 'video/x-flv';
7258  break;
7259 
7260  case 'm1a':
7261  case 'm1s':
7262  case 'm1v':
7263  case 'm15':
7264  case 'm75':
7265  case 'mp2':
7266  case 'mpa':
7267  case 'mpeg':
7268  case 'mpg':
7269  case 'mpm':
7270  case 'mpv':
7271  $type = 'video/mpeg';
7272  break;
7273 
7274  case 'm4v':
7275  $type = 'video/x-m4v';
7276  break;
7277 
7278  case 'mov':
7279  case 'qt':
7280  $type = 'video/quicktime';
7281  break;
7282 
7283  case 'mp4':
7284  case 'mpg4':
7285  $type = 'video/mp4';
7286  break;
7287 
7288  case 'sdv':
7289  $type = 'video/sd-video';
7290  break;
7291 
7292  case 'wm':
7293  $type = 'video/x-ms-wm';
7294  break;
7295 
7296  case 'wmv':
7297  $type = 'video/x-ms-wmv';
7298  break;
7299 
7300  case 'wvx':
7301  $type = 'video/x-ms-wvx';
7302  break;
7303 
7304  // Flash mime-types
7305  case 'spl':
7306  $type = 'application/futuresplash';
7307  break;
7308 
7309  case 'swf':
7310  $type = 'application/x-shockwave-flash';
7311  break;
7312  }
7313  }
7314 
7315  if ($find_handler)
7316  {
7317  if (in_array($type, $types_flash))
7318  {
7319  return 'flash';
7320  }
7321  elseif (in_array($type, $types_fmedia))
7322  {
7323  return 'fmedia';
7324  }
7325  elseif (in_array($type, $types_quicktime))
7326  {
7327  return 'quicktime';
7328  }
7329  elseif (in_array($type, $types_wmedia))
7330  {
7331  return 'wmedia';
7332  }
7333  elseif (in_array($type, $types_mp3))
7334  {
7335  return 'mp3';
7336  }
7337  else
7338  {
7339  return null;
7340  }
7341  }
7342  else
7343  {
7344  return $type;
7345  }
7346  }
7347 }
7348 
7350 {
7351  var $type;
7352  var $lang;
7355  var $text;
7356 
7357  // Constructor, used to input the data
7358  function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7359  {
7360  $this->type = $type;
7361  $this->lang = $lang;
7362  $this->startTime = $startTime;
7363  $this->endTime = $endTime;
7364  $this->text = $text;
7365  }
7366 
7367  function __toString()
7368  {
7369  // There is no $this->data here
7370  return md5(serialize($this));
7371  }
7372 
7373  function get_endtime()
7374  {
7375  if ($this->endTime !== null)
7376  {
7377  return $this->endTime;
7378  }
7379  else
7380  {
7381  return null;
7382  }
7383  }
7384 
7385  function get_language()
7386  {
7387  if ($this->lang !== null)
7388  {
7389  return $this->lang;
7390  }
7391  else
7392  {
7393  return null;
7394  }
7395  }
7396 
7397  function get_starttime()
7398  {
7399  if ($this->startTime !== null)
7400  {
7401  return $this->startTime;
7402  }
7403  else
7404  {
7405  return null;
7406  }
7407  }
7408 
7409  function get_text()
7410  {
7411  if ($this->text !== null)
7412  {
7413  return $this->text;
7414  }
7415  else
7416  {
7417  return null;
7418  }
7419  }
7420 
7421  function get_type()
7422  {
7423  if ($this->type !== null)
7424  {
7425  return $this->type;
7426  }
7427  else
7428  {
7429  return null;
7430  }
7431  }
7432 }
7433 
7435 {
7436  var $role;
7437  var $scheme;
7438  var $name;
7439 
7440  // Constructor, used to input the data
7441  function SimplePie_Credit($role = null, $scheme = null, $name = null)
7442  {
7443  $this->role = $role;
7444  $this->scheme = $scheme;
7445  $this->name = $name;
7446  }
7447 
7448  function __toString()
7449  {
7450  // There is no $this->data here
7451  return md5(serialize($this));
7452  }
7453 
7454  function get_role()
7455  {
7456  if ($this->role !== null)
7457  {
7458  return $this->role;
7459  }
7460  else
7461  {
7462  return null;
7463  }
7464  }
7465 
7466  function get_scheme()
7467  {
7468  if ($this->scheme !== null)
7469  {
7470  return $this->scheme;
7471  }
7472  else
7473  {
7474  return null;
7475  }
7476  }
7477 
7478  function get_name()
7479  {
7480  if ($this->name !== null)
7481  {
7482  return $this->name;
7483  }
7484  else
7485  {
7486  return null;
7487  }
7488  }
7489 }
7490 
7492 {
7493  var $url;
7494  var $label;
7495 
7496  // Constructor, used to input the data
7497  function SimplePie_Copyright($url = null, $label = null)
7498  {
7499  $this->url = $url;
7500  $this->label = $label;
7501  }
7502 
7503  function __toString()
7504  {
7505  // There is no $this->data here
7506  return md5(serialize($this));
7507  }
7508 
7509  function get_url()
7510  {
7511  if ($this->url !== null)
7512  {
7513  return $this->url;
7514  }
7515  else
7516  {
7517  return null;
7518  }
7519  }
7520 
7521  function get_attribution()
7522  {
7523  if ($this->label !== null)
7524  {
7525  return $this->label;
7526  }
7527  else
7528  {
7529  return null;
7530  }
7531  }
7532 }
7533 
7535 {
7536  var $scheme;
7537  var $value;
7538 
7539  // Constructor, used to input the data
7540  function SimplePie_Rating($scheme = null, $value = null)
7541  {
7542  $this->scheme = $scheme;
7543  $this->value = $value;
7544  }
7545 
7546  function __toString()
7547  {
7548  // There is no $this->data here
7549  return md5(serialize($this));
7550  }
7551 
7552  function get_scheme()
7553  {
7554  if ($this->scheme !== null)
7555  {
7556  return $this->scheme;
7557  }
7558  else
7559  {
7560  return null;
7561  }
7562  }
7563 
7564  function get_value()
7565  {
7566  if ($this->value !== null)
7567  {
7568  return $this->value;
7569  }
7570  else
7571  {
7572  return null;
7573  }
7574  }
7575 }
7576 
7578 {
7580  var $type;
7581  var $value;
7582 
7583  // Constructor, used to input the data
7584  function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7585  {
7586  $this->relationship = $relationship;
7587  $this->type = $type;
7588  $this->value = $value;
7589  }
7590 
7591  function __toString()
7592  {
7593  // There is no $this->data here
7594  return md5(serialize($this));
7595  }
7596 
7597  function get_relationship()
7598  {
7599  if ($this->relationship !== null)
7600  {
7601  return $this->relationship;
7602  }
7603  else
7604  {
7605  return null;
7606  }
7607  }
7608 
7609  function get_type()
7610  {
7611  if ($this->type !== null)
7612  {
7613  return $this->type;
7614  }
7615  else
7616  {
7617  return null;
7618  }
7619  }
7620 
7621  function get_value()
7622  {
7623  if ($this->value !== null)
7624  {
7625  return $this->value;
7626  }
7627  else
7628  {
7629  return null;
7630  }
7631  }
7632 }
7633 
7634 /**
7635  * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7636  */
7638 {
7639  var $url;
7641  var $success = true;
7642  var $headers = array();
7643  var $body;
7645  var $redirects = 0;
7646  var $error;
7648 
7649  function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7650  {
7651  if (class_exists('idna_convert'))
7652  {
7653  $idn = new idna_convert;
7654  $parsed = SimplePie_Misc::parse_url($url);
7655  $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7656  }
7657  $this->url = $url;
7658  $this->useragent = $useragent;
7659  if (preg_match('/^http(s)?:\/\//i', $url))
7660  {
7661  if ($useragent === null)
7662  {
7663  $useragent = ini_get('user_agent');
7664  $this->useragent = $useragent;
7665  }
7666  if (!is_array($headers))
7667  {
7668  $headers = array();
7669  }
7670  if (!$force_fsockopen && function_exists('curl_exec'))
7671  {
7673  $fp = curl_init();
7674  $headers2 = array();
7675  foreach ($headers as $key => $value)
7676  {
7677  $headers2[] = "$key: $value";
7678  }
7679  if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7680  {
7681  curl_setopt($fp, CURLOPT_ENCODING, '');
7682  }
7683  curl_setopt($fp, CURLOPT_URL, $url);
7684  curl_setopt($fp, CURLOPT_HEADER, 1);
7685  curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7686  curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7687  curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7688  curl_setopt($fp, CURLOPT_REFERER, $url);
7689  curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7690  curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7691  if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7692  {
7693  curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7694  curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7695  }
7696 
7697  $this->headers = curl_exec($fp);
7698  if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
7699  {
7700  curl_setopt($fp, CURLOPT_ENCODING, 'none');
7701  $this->headers = curl_exec($fp);
7702  }
7703  if (curl_errno($fp))
7704  {
7705  $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7706  $this->success = false;
7707  }
7708  else
7709  {
7710  $info = curl_getinfo($fp);
7711  curl_close($fp);
7712  $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7713  $this->headers = array_pop($this->headers);
7714  $parser = new SimplePie_HTTP_Parser($this->headers);
7715  if ($parser->parse())
7716  {
7717  $this->headers = $parser->headers;
7718  $this->body = $parser->body;
7719  $this->status_code = $parser->status_code;
7720  if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7721  {
7722  $this->redirects++;
7723  $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7724  return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7725  }
7726  }
7727  }
7728  }
7729  else
7730  {
7732  $url_parts = parse_url($url);
7733  if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
7734  {
7735  $url_parts['host'] = "ssl://$url_parts[host]";
7736  $url_parts['port'] = 443;
7737  }
7738  if (!isset($url_parts['port']))
7739  {
7740  $url_parts['port'] = 80;
7741  }
7742  $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7743  if (!$fp)
7744  {
7745  $this->error = 'fsockopen error: ' . $errstr;
7746  $this->success = false;
7747  }
7748  else
7749  {
7750  stream_set_timeout($fp, $timeout);
7751  if (isset($url_parts['path']))
7752  {
7753  if (isset($url_parts['query']))
7754  {
7755  $get = "$url_parts[path]?$url_parts[query]";
7756  }
7757  else
7758  {
7759  $get = $url_parts['path'];
7760  }
7761  }
7762  else
7763  {
7764  $get = '/';
7765  }
7766  $out = "GET $get HTTP/1.0\r\n";
7767  $out .= "Host: $url_parts[host]\r\n";
7768  $out .= "User-Agent: $useragent\r\n";
7769  if (extension_loaded('zlib'))
7770  {
7771  $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7772  }
7773 
7774  if (isset($url_parts['user']) && isset($url_parts['pass']))
7775  {
7776  $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7777  }
7778  foreach ($headers as $key => $value)
7779  {
7780  $out .= "$key: $value\r\n";
7781  }
7782  $out .= "Connection: Close\r\n\r\n";
7783  fwrite($fp, $out);
7784 
7785  $info = stream_get_meta_data($fp);
7786 
7787  $this->headers = '';
7788  while (!$info['eof'] && !$info['timed_out'])
7789  {
7790  $this->headers .= fread($fp, 1160);
7791  $info = stream_get_meta_data($fp);
7792  }
7793  if (!$info['timed_out'])
7794  {
7795  $parser = new SimplePie_HTTP_Parser($this->headers);
7796  if ($parser->parse())
7797  {
7798  $this->headers = $parser->headers;
7799  $this->body = $parser->body;
7800  $this->status_code = $parser->status_code;
7801  if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7802  {
7803  $this->redirects++;
7804  $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7805  return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7806  }
7807  if (isset($this->headers['content-encoding']))
7808  {
7809  // Hey, we act dumb elsewhere, so let's do that here too
7810  switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
7811  {
7812  case 'gzip':
7813  case 'x-gzip':
7814  $decoder = new SimplePie_gzdecode($this->body);
7815  if (!$decoder->parse())
7816  {
7817  $this->error = 'Unable to decode HTTP "gzip" stream';
7818  $this->success = false;
7819  }
7820  else
7821  {
7822  $this->body = $decoder->data;
7823  }
7824  break;
7825 
7826  case 'deflate':
7827  if (($body = gzuncompress($this->body)) === false)
7828  {
7829  if (($body = gzinflate($this->body)) === false)
7830  {
7831  $this->error = 'Unable to decode HTTP "deflate" stream';
7832  $this->success = false;
7833  }
7834  }
7835  $this->body = $body;
7836  break;
7837 
7838  default:
7839  $this->error = 'Unknown content coding';
7840  $this->success = false;
7841  }
7842  }
7843  }
7844  }
7845  else
7846  {
7847  $this->error = 'fsocket timed out';
7848  $this->success = false;
7849  }
7850  fclose($fp);
7851  }
7852  }
7853  }
7854  else
7855  {
7857  if (!$this->body = file_get_contents($url))
7858  {
7859  $this->error = 'file_get_contents could not read the file';
7860  $this->success = false;
7861  }
7862  }
7863  }
7864 }
7865 
7866 /**
7867  * HTTP Response Parser
7868  *
7869  * @package SimplePie
7870  */
7872 {
7873  /**
7874  * HTTP Version
7875  *
7876  * @access public
7877  * @var float
7878  */
7879  var $http_version = 0.0;
7880 
7881  /**
7882  * Status code
7883  *
7884  * @access public
7885  * @var int
7886  */
7887  var $status_code = 0;
7888 
7889  /**
7890  * Reason phrase
7891  *
7892  * @access public
7893  * @var string
7894  */
7895  var $reason = '';
7896 
7897  /**
7898  * Key/value pairs of the headers
7899  *
7900  * @access public
7901  * @var array
7902  */
7903  var $headers = array();
7904 
7905  /**
7906  * Body of the response
7907  *
7908  * @access public
7909  * @var string
7910  */
7911  var $body = '';
7912 
7913  /**
7914  * Current state of the state machine
7915  *
7916  * @access private
7917  * @var string
7918  */
7919  var $state = 'http_version';
7920 
7921  /**
7922  * Input data
7923  *
7924  * @access private
7925  * @var string
7926  */
7927  var $data = '';
7928 
7929  /**
7930  * Input data length (to avoid calling strlen() everytime this is needed)
7931  *
7932  * @access private
7933  * @var int
7934  */
7935  var $data_length = 0;
7936 
7937  /**
7938  * Current position of the pointer
7939  *
7940  * @var int
7941  * @access private
7942  */
7943  var $position = 0;
7944 
7945  /**
7946  * Name of the hedaer currently being parsed
7947  *
7948  * @access private
7949  * @var string
7950  */
7951  var $name = '';
7952 
7953  /**
7954  * Value of the hedaer currently being parsed
7955  *
7956  * @access private
7957  * @var string
7958  */
7959  var $value = '';
7960 
7961  /**
7962  * Create an instance of the class with the input data
7963  *
7964  * @access public
7965  * @param string $data Input data
7966  */
7968  {
7969  $this->data = $data;
7970  $this->data_length = strlen($this->data);
7971  }
7972 
7973  /**
7974  * Parse the input data
7975  *
7976  * @access public
7977  * @return bool true on success, false on failure
7978  */
7979  function parse()
7980  {
7981  while ($this->state && $this->state !== 'emit' && $this->has_data())
7982  {
7983  $state = $this->state;
7984  $this->$state();
7985  }
7986  $this->data = '';
7987  if ($this->state === 'emit' || $this->state === 'body')
7988  {
7989  return true;
7990  }
7991  else
7992  {
7993  $this->http_version = '';
7994  $this->status_code = '';
7995  $this->reason = '';
7996  $this->headers = array();
7997  $this->body = '';
7998  return false;
7999  }
8000  }
8001 
8002  /**
8003  * Check whether there is data beyond the pointer
8004  *
8005  * @access private
8006  * @return bool true if there is further data, false if not
8007  */
8008  function has_data()
8009  {
8010  return (bool) ($this->position < $this->data_length);
8011  }
8012 
8013  /**
8014  * See if the next character is LWS
8015  *
8016  * @access private
8017  * @return bool true if the next character is LWS, false if not
8018  */
8020  {
8021  return (bool) ($this->data[$this->position] === "\x09"
8022  || $this->data[$this->position] === "\x20"
8023  || ($this->data[$this->position] === "\x0A"
8024  && isset($this->data[$this->position + 1])
8025  && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
8026  }
8027 
8028  /**
8029  * Parse the HTTP version
8030  *
8031  * @access private
8032  */
8033  function http_version()
8034  {
8035  if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
8036  {
8037  $len = strspn($this->data, '0123456789.', 5);
8038  $this->http_version = substr($this->data, 5, $len);
8039  $this->position += 5 + $len;
8040  if (substr_count($this->http_version, '.') <= 1)
8041  {
8042  $this->http_version = (float) $this->http_version;
8043  $this->position += strspn($this->data, "\x09\x20", $this->position);
8044  $this->state = 'status';
8045  }
8046  else
8047  {
8048  $this->state = false;
8049  }
8050  }
8051  else
8052  {
8053  $this->state = false;
8054  }
8055  }
8056 
8057  /**
8058  * Parse the status code
8059  *
8060  * @access private
8061  */
8062  function status()
8063  {
8064  if ($len = strspn($this->data, '0123456789', $this->position))
8065  {
8066  $this->status_code = (int) substr($this->data, $this->position, $len);
8067  $this->position += $len;
8068  $this->state = 'reason';
8069  }
8070  else
8071  {
8072  $this->state = false;
8073  }
8074  }
8075 
8076  /**
8077  * Parse the reason phrase
8078  *
8079  * @access private
8080  */
8081  function reason()
8082  {
8083  $len = strcspn($this->data, "\x0A", $this->position);
8084  $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
8085  $this->position += $len + 1;
8086  $this->state = 'new_line';
8087  }
8088 
8089  /**
8090  * Deal with a new line, shifting data around as needed
8091  *
8092  * @access private
8093  */
8094  function new_line()
8095  {
8096  $this->value = trim($this->value, "\x0D\x20");
8097  if ($this->name !== '' && $this->value !== '')
8098  {
8099  $this->name = strtolower($this->name);
8100  if (isset($this->headers[$this->name]))
8101  {
8102  $this->headers[$this->name] .= ', ' . $this->value;
8103  }
8104  else
8105  {
8106  $this->headers[$this->name] = $this->value;
8107  }
8108  }
8109  $this->name = '';
8110  $this->value = '';
8111  if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8112  {
8113  $this->position += 2;
8114  $this->state = 'body';
8115  }
8116  elseif ($this->data[$this->position] === "\x0A")
8117  {
8118  $this->position++;
8119  $this->state = 'body';
8120  }
8121  else
8122  {
8123  $this->state = 'name';
8124  }
8125  }
8126 
8127  /**
8128  * Parse a header name
8129  *
8130  * @access private
8131  */
8132  function name()
8133  {
8134  $len = strcspn($this->data, "\x0A:", $this->position);
8135  if (isset($this->data[$this->position + $len]))
8136  {
8137  if ($this->data[$this->position + $len] === "\x0A")
8138  {
8139  $this->position += $len;
8140  $this->state = 'new_line';
8141  }
8142  else
8143  {
8144  $this->name = substr($this->data, $this->position, $len);
8145  $this->position += $len + 1;
8146  $this->state = 'value';
8147  }
8148  }
8149  else
8150  {
8151  $this->state = false;
8152  }
8153  }
8154 
8155  /**
8156  * Parse LWS, replacing consecutive LWS characters with a single space
8157  *
8158  * @access private
8159  */
8161  {
8162  do
8163  {
8164  if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8165  {
8166  $this->position += 2;
8167  }
8168  elseif ($this->data[$this->position] === "\x0A")
8169  {
8170  $this->position++;
8171  }
8172  $this->position += strspn($this->data, "\x09\x20", $this->position);
8173  } while ($this->has_data() && $this->is_linear_whitespace());
8174  $this->value .= "\x20";
8175  }
8176 
8177  /**
8178  * See what state to move to while within non-quoted header values
8179  *
8180  * @access private
8181  */
8182  function value()
8183  {
8184  if ($this->is_linear_whitespace())
8185  {
8186  $this->linear_whitespace();
8187  }
8188  else
8189  {
8190  switch ($this->data[$this->position])
8191  {
8192  case '"':
8193  $this->position++;
8194  $this->state = 'quote';
8195  break;
8196 
8197  case "\x0A":
8198  $this->position++;
8199  $this->state = 'new_line';
8200  break;
8201 
8202  default:
8203  $this->state = 'value_char';
8204  break;
8205  }
8206  }
8207  }
8208 
8209  /**
8210  * Parse a header value while outside quotes
8211  *
8212  * @access private
8213  */
8214  function value_char()
8215  {
8216  $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8217  $this->value .= substr($this->data, $this->position, $len);
8218  $this->position += $len;
8219  $this->state = 'value';
8220  }
8221 
8222  /**
8223  * See what state to move to while within quoted header values
8224  *
8225  * @access private
8226  */
8227  function quote()
8228  {
8229  if ($this->is_linear_whitespace())
8230  {
8231  $this->linear_whitespace();
8232  }
8233  else
8234  {
8235  switch ($this->data[$this->position])
8236  {
8237  case '"':
8238  $this->position++;
8239  $this->state = 'value';
8240  break;
8241 
8242  case "\x0A":
8243  $this->position++;
8244  $this->state = 'new_line';
8245  break;
8246 
8247  case '\\':
8248  $this->position++;
8249  $this->state = 'quote_escaped';
8250  break;
8251 
8252  default:
8253  $this->state = 'quote_char';
8254  break;
8255  }
8256  }
8257  }
8258 
8259  /**
8260  * Parse a header value while within quotes
8261  *
8262  * @access private
8263  */
8264  function quote_char()
8265  {
8266  $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8267  $this->value .= substr($this->data, $this->position, $len);
8268  $this->position += $len;
8269  $this->state = 'value';
8270  }
8271 
8272  /**
8273  * Parse an escaped character within quotes
8274  *
8275  * @access private
8276  */
8277  function quote_escaped()
8278  {
8279  $this->value .= $this->data[$this->position];
8280  $this->position++;
8281  $this->state = 'quote';
8282  }
8283 
8284  /**
8285  * Parse the body
8286  *
8287  * @access private
8288  */
8289  function body()
8290  {
8291  $this->body = substr($this->data, $this->position);
8292  $this->state = 'emit';
8293  }
8294 }
8295 
8296 /**
8297  * gzdecode
8298  *
8299  * @package SimplePie
8300  */
8302 {
8303  /**
8304  * Compressed data
8305  *
8306  * @access private
8307  * @see gzdecode::$data
8308  */
8310 
8311  /**
8312  * Size of compressed data
8313  *
8314  * @access private
8315  */
8317 
8318  /**
8319  * Minimum size of a valid gzip string
8320  *
8321  * @access private
8322  */
8324 
8325  /**
8326  * Current position of pointer
8327  *
8328  * @access private
8329  */
8330  var $position = 0;
8331 
8332  /**
8333  * Flags (FLG)
8334  *
8335  * @access private
8336  */
8337  var $flags;
8338 
8339  /**
8340  * Uncompressed data
8341  *
8342  * @access public
8343  * @see gzdecode::$compressed_data
8344  */
8345  var $data;
8346 
8347  /**
8348  * Modified time
8349  *
8350  * @access public
8351  */
8352  var $MTIME;
8353 
8354  /**
8355  * Extra Flags
8356  *
8357  * @access public
8358  */
8359  var $XFL;
8360 
8361  /**
8362  * Operating System
8363  *
8364  * @access public
8365  */
8366  var $OS;
8367 
8368  /**
8369  * Subfield ID 1
8370  *
8371  * @access public
8372  * @see gzdecode::$extra_field
8373  * @see gzdecode::$SI2
8374  */
8375  var $SI1;
8376 
8377  /**
8378  * Subfield ID 2
8379  *
8380  * @access public
8381  * @see gzdecode::$extra_field
8382  * @see gzdecode::$SI1
8383  */
8384  var $SI2;
8385 
8386  /**
8387  * Extra field content
8388  *
8389  * @access public
8390  * @see gzdecode::$SI1
8391  * @see gzdecode::$SI2
8392  */
8394 
8395  /**
8396  * Original filename
8397  *
8398  * @access public
8399  */
8401 
8402  /**
8403  * Human readable comment
8404  *
8405  * @access public
8406  */
8408 
8409  /**
8410  * Don't allow anything to be set
8411  *
8412  * @access public
8413  */
8414  function __set($name, $value)
8415  {
8416  trigger_error("Cannot write property $name", E_USER_ERROR);
8417  }
8418 
8419  /**
8420  * Set the compressed string and related properties
8421  *
8422  * @access public
8423  */
8425  {
8426  $this->compressed_data = $data;
8427  $this->compressed_size = strlen($data);
8428  }
8429 
8430  /**
8431  * Decode the GZIP stream
8432  *
8433  * @access public
8434  */
8435  function parse()
8436  {
8437  if ($this->compressed_size >= $this->min_compressed_size)
8438  {
8439  // Check ID1, ID2, and CM
8440  if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
8441  {
8442  return false;
8443  }
8444 
8445  // Get the FLG (FLaGs)
8446  $this->flags = ord($this->compressed_data[3]);
8447 
8448  // FLG bits above (1 << 4) are reserved
8449  if ($this->flags > 0x1F)
8450  {
8451  return false;
8452  }
8453 
8454  // Advance the pointer after the above
8455  $this->position += 4;
8456 
8457  // MTIME
8458  $mtime = substr($this->compressed_data, $this->position, 4);
8459  // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8460  if (current(unpack('S', "\x00\x01")) === 1)
8461  {
8462  $mtime = strrev($mtime);
8463  }
8464  $this->MTIME = current(unpack('l', $mtime));
8465  $this->position += 4;
8466 
8467  // Get the XFL (eXtra FLags)
8468  $this->XFL = ord($this->compressed_data[$this->position++]);
8469 
8470  // Get the OS (Operating System)
8471  $this->OS = ord($this->compressed_data[$this->position++]);
8472 
8473  // Parse the FEXTRA
8474  if ($this->flags & 4)
8475  {
8476  // Read subfield IDs
8477  $this->SI1 = $this->compressed_data[$this->position++];
8478  $this->SI2 = $this->compressed_data[$this->position++];
8479 
8480  // SI2 set to zero is reserved for future use
8481  if ($this->SI2 === "\x00")
8482  {
8483  return false;
8484  }
8485 
8486  // Get the length of the extra field
8487  $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8488  $position += 2;
8489 
8490  // Check the length of the string is still valid
8491  $this->min_compressed_size += $len + 4;
8492  if ($this->compressed_size >= $this->min_compressed_size)
8493  {
8494  // Set the extra field to the given data
8495  $this->extra_field = substr($this->compressed_data, $this->position, $len);
8496  $this->position += $len;
8497  }
8498  else
8499  {
8500  return false;
8501  }
8502  }
8503 
8504  // Parse the FNAME
8505  if ($this->flags & 8)
8506  {
8507  // Get the length of the filename
8508  $len = strcspn($this->compressed_data, "\x00", $this->position);
8509 
8510  // Check the length of the string is still valid
8511  $this->min_compressed_size += $len + 1;
8512  if ($this->compressed_size >= $this->min_compressed_size)
8513  {
8514  // Set the original filename to the given string
8515  $this->filename = substr($this->compressed_data, $this->position, $len);
8516  $this->position += $len + 1;
8517  }
8518  else
8519  {
8520  return false;
8521  }
8522  }
8523 
8524  // Parse the FCOMMENT
8525  if ($this->flags & 16)
8526  {
8527  // Get the length of the comment
8528  $len = strcspn($this->compressed_data, "\x00", $this->position);
8529 
8530  // Check the length of the string is still valid
8531  $this->min_compressed_size += $len + 1;
8532  if ($this->compressed_size >= $this->min_compressed_size)
8533  {
8534  // Set the original comment to the given string
8535  $this->comment = substr($this->compressed_data, $this->position, $len);
8536  $this->position += $len + 1;
8537  }
8538  else
8539  {
8540  return false;
8541  }
8542  }
8543 
8544  // Parse the FHCRC
8545  if ($this->flags & 2)
8546  {
8547  // Check the length of the string is still valid
8548  $this->min_compressed_size += $len + 2;
8549  if ($this->compressed_size >= $this->min_compressed_size)
8550  {
8551  // Read the CRC
8552  $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8553 
8554  // Check the CRC matches
8555  if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
8556  {
8557  $this->position += 2;
8558  }
8559  else
8560  {
8561  return false;
8562  }
8563  }
8564  else
8565  {
8566  return false;
8567  }
8568  }
8569 
8570  // Decompress the actual data
8571  if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
8572  {
8573  return false;
8574  }
8575  else
8576  {
8577  $this->position = $this->compressed_size - 8;
8578  }
8579 
8580  // Check CRC of data
8581  $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8582  $this->position += 4;
8583  /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8584  {
8585  return false;
8586  }*/
8587 
8588  // Check ISIZE of data
8589  $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8590  $this->position += 4;
8591  if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8592  {
8593  return false;
8594  }
8595 
8596  // Wow, against all odds, we've actually got a valid gzip string
8597  return true;
8598  }
8599  else
8600  {
8601  return false;
8602  }
8603  }
8604 }
8605 
8607 {
8608  /**
8609  * Don't call the constructor. Please.
8610  *
8611  * @access private
8612  */
8613  function SimplePie_Cache()
8614  {
8615  trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8616  }
8617 
8618  /**
8619  * Create a new SimplePie_Cache object
8620  *
8621  * @static
8622  * @access public
8623  */
8624  function create($location, $filename, $extension)
8625  {
8626  $location_iri = new SimplePie_IRI($location);
8627  switch ($location_iri->get_scheme())
8628  {
8629  case 'mysql':
8630  if (extension_loaded('mysql'))
8631  {
8632  return new SimplePie_Cache_MySQL($location_iri, $filename, $extension);
8633  }
8634  break;
8635 
8636  default:
8637  return new SimplePie_Cache_File($location, $filename, $extension);
8638  }
8639  }
8640 }
8641 
8643 {
8647  var $name;
8648 
8650  {
8651  $this->location = $location;
8652  $this->filename = $filename;
8653  $this->extension = $extension;
8654  $this->name = "$this->location/$this->filename.$this->extension";
8655  }
8656 
8657  function save($data)
8658  {
8659  if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8660  {
8661  if (is_a($data, 'SimplePie'))
8662  {
8663  $data = $data->data;
8664  }
8665 
8666  $data = serialize($data);
8667 
8668  if (function_exists('file_put_contents'))
8669  {
8670  return (bool) file_put_contents($this->name, $data);
8671  }
8672  else
8673  {
8674  $fp = fopen($this->name, 'wb');
8675  if ($fp)
8676  {
8677  fwrite($fp, $data);
8678  fclose($fp);
8679  return true;
8680  }
8681  }
8682  }
8683  return false;
8684  }
8685 
8686  function load()
8687  {
8688  if (file_exists($this->name) && is_readable($this->name))
8689  {
8690  return unserialize(file_get_contents($this->name));
8691  }
8692  return false;
8693  }
8694 
8695  function mtime()
8696  {
8697  if (file_exists($this->name))
8698  {
8699  return filemtime($this->name);
8700  }
8701  return false;
8702  }
8703 
8704  function touch()
8705  {
8706  if (file_exists($this->name))
8707  {
8708  return touch($this->name);
8709  }
8710  return false;
8711  }
8712 
8713  function unlink()
8714  {
8715  if (file_exists($this->name))
8716  {
8717  return unlink($this->name);
8718  }
8719  return false;
8720  }
8721 }
8722 
8724 {
8726  {
8727  $items = $data->get_items();
8728  $items_by_id = array();
8729 
8730  if (!empty($items))
8731  {
8732  foreach ($items as $item)
8733  {
8734  $items_by_id[$item->get_id()] = $item;
8735  }
8736 
8737  if (count($items_by_id) !== count($items))
8738  {
8739  $items_by_id = array();
8740  foreach ($items as $item)
8741  {
8742  $items_by_id[$item->get_id(true)] = $item;
8743  }
8744  }
8745 
8746  if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
8747  {
8748  $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
8749  }
8750  elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
8751  {
8752  $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
8753  }
8754  elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
8755  {
8756  $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
8757  }
8758  elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
8759  {
8760  $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
8761  }
8762  else
8763  {
8764  $channel = null;
8765  }
8766 
8767  if ($channel !== null)
8768  {
8769  if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
8770  {
8771  unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
8772  }
8773  if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
8774  {
8775  unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
8776  }
8777  if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
8778  {
8779  unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
8780  }
8781  if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
8782  {
8783  unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
8784  }
8785  if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
8786  {
8787  unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
8788  }
8789  }
8790  if (isset($data->data['items']))
8791  {
8792  unset($data->data['items']);
8793  }
8794  if (isset($data->data['ordered_items']))
8795  {
8796  unset($data->data['ordered_items']);
8797  }
8798  }
8799  return array(serialize($data->data), $items_by_id);
8800  }
8801 }
8802 
8804 {
8805  var $mysql;
8807  var $id;
8808 
8809  function SimplePie_Cache_MySQL($mysql_location, $name, $extension)
8810  {
8811  $host = $mysql_location->get_host();
8812  if (SimplePie_Misc::stripos($host, 'unix(') === 0 && substr($host, -1) === ')')
8813  {
8814  $server = ':' . substr($host, 5, -1);
8815  }
8816  else
8817  {
8818  $server = $host;
8819  if ($mysql_location->get_port() !== null)
8820  {
8821  $server .= ':' . $mysql_location->get_port();
8822  }
8823  }
8824 
8825  if (strpos($mysql_location->get_userinfo(), ':') !== false)
8826  {
8827  list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2);
8828  }
8829  else
8830  {
8831  $username = $mysql_location->get_userinfo();
8832  $password = null;
8833  }
8834 
8835  if ($this->mysql = mysql_connect($server, $username, $password))
8836  {
8837  $this->id = $name . $extension;
8838  $this->options = SimplePie_Misc::parse_str($mysql_location->get_query());
8839  if (!isset($this->options['prefix'][0]))
8840  {
8841  $this->options['prefix'][0] = '';
8842  }
8843 
8844  if (mysql_select_db(ltrim($mysql_location->get_path(), '/'))
8845  && mysql_query('SET NAMES utf8')
8846  && ($query = mysql_unbuffered_query('SHOW TABLES')))
8847  {
8848  $db = array();
8849  while ($row = mysql_fetch_row($query))
8850  {
8851  $db[] = $row[0];
8852  }
8853 
8854  if (!in_array($this->options['prefix'][0] . 'cache_data', $db))
8855  {
8856  if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))'))
8857  {
8858  $this->mysql = null;
8859  }
8860  }
8861 
8862  if (!in_array($this->options['prefix'][0] . 'items', $db))
8863  {
8864  if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))'))
8865  {
8866  $this->mysql = null;
8867  }
8868  }
8869  }
8870  else
8871  {
8872  $this->mysql = null;
8873  }
8874  }
8875  }
8876 
8877  function save($data)
8878  {
8879  if ($this->mysql)
8880  {
8881  $feed_id = "'" . mysql_real_escape_string($this->id) . "'";
8882 
8883  if (is_a($data, 'SimplePie'))
8884  {
8885  if (SIMPLEPIE_PHP5)
8886  {
8887  // This keyword needs to defy coding standards for PHP4 compatibility
8888  $data = clone($data);
8889  }
8890 
8891  $prepared = $this->prepare_simplepie_object_for_cache($data);
8892 
8893  if ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
8894  {
8895  if (mysql_num_rows($query))
8896  {
8897  $items = count($prepared[1]);
8898  if ($items)
8899  {
8900  $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
8901  }
8902  else
8903  {
8904  $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
8905  }
8906 
8907  if (!mysql_query($sql, $this->mysql))
8908  {
8909  return false;
8910  }
8911  }
8912  elseif (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(' . $feed_id . ', ' . count($prepared[1]) . ', \'' . mysql_real_escape_string($prepared[0]) . '\', ' . time() . ')', $this->mysql))
8913  {
8914  return false;
8915  }
8916 
8917  $ids = array_keys($prepared[1]);
8918  if (!empty($ids))
8919  {
8920  foreach ($ids as $id)
8921  {
8922  $database_ids[] = mysql_real_escape_string($id);
8923  }
8924 
8925  if ($query = mysql_unbuffered_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'items` WHERE `id` = \'' . implode('\' OR `id` = \'', $database_ids) . '\' AND `feed_id` = ' . $feed_id, $this->mysql))
8926  {
8927  $existing_ids = array();
8928  while ($row = mysql_fetch_row($query))
8929  {
8930  $existing_ids[] = $row[0];
8931  }
8932 
8933  $new_ids = array_diff($ids, $existing_ids);
8934 
8935  foreach ($new_ids as $new_id)
8936  {
8937  if (!($date = $prepared[1][$new_id]->get_date('U')))
8938  {
8939  $date = time();
8940  }
8941 
8942  if (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(' . $feed_id . ', \'' . mysql_real_escape_string($new_id) . '\', \'' . mysql_real_escape_string(serialize($prepared[1][$new_id]->data)) . '\', ' . $date . ')', $this->mysql))
8943  {
8944  return false;
8945  }
8946  }
8947  return true;
8948  }
8949  }
8950  else
8951  {
8952  return true;
8953  }
8954  }
8955  }
8956  elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
8957  {
8958  if (mysql_num_rows($query))
8959  {
8960  if (mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = 0, `data` = \'' . mysql_real_escape_string(serialize($data)) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id, $this->mysql))
8961  {
8962  return true;
8963  }
8964  }
8965  elseif (mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(\'' . mysql_real_escape_string($this->id) . '\', 0, \'' . mysql_real_escape_string(serialize($data)) . '\', ' . time() . ')', $this->mysql))
8966  {
8967  return true;
8968  }
8969  }
8970  }
8971  return false;
8972  }
8973 
8974  function load()
8975  {
8976  if ($this->mysql && ($query = mysql_query('SELECT `items`, `data` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
8977  {
8978  $data = unserialize($row[1]);
8979 
8980  if (isset($this->options['items'][0]))
8981  {
8982  $items = (int) $this->options['items'][0];
8983  }
8984  else
8985  {
8986  $items = (int) $row[0];
8987  }
8988 
8989  if ($items !== 0)
8990  {
8991  if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
8992  {
8993  $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
8994  }
8995  elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
8996  {
8997  $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
8998  }
8999  elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
9000  {
9001  $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
9002  }
9003  elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
9004  {
9005  $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
9006  }
9007  else
9008  {
9009  $feed = null;
9010  }
9011 
9012  if ($feed !== null)
9013  {
9014  $sql = 'SELECT `data` FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . '\' ORDER BY `posted` DESC';
9015  if ($items > 0)
9016  {
9017  $sql .= ' LIMIT ' . $items;
9018  }
9019 
9020  if ($query = mysql_unbuffered_query($sql, $this->mysql))
9021  {
9022  while ($row = mysql_fetch_row($query))
9023  {
9024  $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row[0]);
9025  }
9026  }
9027  else
9028  {
9029  return false;
9030  }
9031  }
9032  }
9033  return $data;
9034  }
9035  return false;
9036  }
9037 
9038  function mtime()
9039  {
9040  if ($this->mysql && ($query = mysql_query('SELECT `mtime` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
9041  {
9042  return $row[0];
9043  }
9044  else
9045  {
9046  return false;
9047  }
9048  }
9049 
9050  function touch()
9051  {
9052  if ($this->mysql && ($query = mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `mtime` = ' . time() . ' WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && mysql_affected_rows($this->mysql))
9053  {
9054  return true;
9055  }
9056  else
9057  {
9058  return false;
9059  }
9060  }
9061 
9062  function unlink()
9063  {
9064  if ($this->mysql && ($query = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($query2 = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)))
9065  {
9066  return true;
9067  }
9068  else
9069  {
9070  return false;
9071  }
9072  }
9073 }
9074 
9076 {
9077  function time_hms($seconds)
9078  {
9079  $time = '';
9080 
9081  $hours = floor($seconds / 3600);
9082  $remainder = $seconds % 3600;
9083  if ($hours > 0)
9084  {
9085  $time .= $hours.':';
9086  }
9087 
9088  $minutes = floor($remainder / 60);
9089  $seconds = $remainder % 60;
9090  if ($minutes < 10 && $hours > 0)
9091  {
9092  $minutes = '0' . $minutes;
9093  }
9094  if ($seconds < 10)
9095  {
9096  $seconds = '0' . $seconds;
9097  }
9098 
9099  $time .= $minutes.':';
9100  $time .= $seconds;
9101 
9102  return $time;
9103  }
9104 
9105  function absolutize_url($relative, $base)
9106  {
9107  $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);
9108  return $iri->get_iri();
9109  }
9110 
9111  function remove_dot_segments($input)
9112  {
9113  $output = '';
9114  while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
9115  {
9116  // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
9117  if (strpos($input, '../') === 0)
9118  {
9119  $input = substr($input, 3);
9120  }
9121  elseif (strpos($input, './') === 0)
9122  {
9123  $input = substr($input, 2);
9124  }
9125  // 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,
9126  elseif (strpos($input, '/./') === 0)
9127  {
9128  $input = substr_replace($input, '/', 0, 3);
9129  }
9130  elseif ($input === '/.')
9131  {
9132  $input = '/';
9133  }
9134  // 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,
9135  elseif (strpos($input, '/../') === 0)
9136  {
9137  $input = substr_replace($input, '/', 0, 4);
9138  $output = substr_replace($output, '', strrpos($output, '/'));
9139  }
9140  elseif ($input === '/..')
9141  {
9142  $input = '/';
9143  $output = substr_replace($output, '', strrpos($output, '/'));
9144  }
9145  // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
9146  elseif ($input === '.' || $input === '..')
9147  {
9148  $input = '';
9149  }
9150  // 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
9151  elseif (($pos = strpos($input, '/', 1)) !== false)
9152  {
9153  $output .= substr($input, 0, $pos);
9154  $input = substr_replace($input, '', 0, $pos);
9155  }
9156  else
9157  {
9158  $output .= $input;
9159  $input = '';
9160  }
9161  }
9162  return $output . $input;
9163  }
9164 
9165  function get_element($realname, $string)
9166  {
9167  $return = array();
9168  $name = preg_quote($realname, '/');
9169  if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
9170  {
9171  for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
9172  {
9173  $return[$i]['tag'] = $realname;
9174  $return[$i]['full'] = $matches[$i][0][0];
9175  $return[$i]['offset'] = $matches[$i][0][1];
9176  if (strlen($matches[$i][3][0]) <= 2)
9177  {
9178  $return[$i]['self_closing'] = true;
9179  }
9180  else
9181  {
9182  $return[$i]['self_closing'] = false;
9183  $return[$i]['content'] = $matches[$i][4][0];
9184  }
9185  $return[$i]['attribs'] = array();
9186  if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
9187  {
9188  for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
9189  {
9190  if (count($attribs[$j]) === 2)
9191  {
9192  $attribs[$j][2] = $attribs[$j][1];
9193  }
9194  $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
9195  }
9196  }
9197  }
9198  }
9199  return $return;
9200  }
9201 
9202  function element_implode($element)
9203  {
9204  $full = "<$element[tag]";
9205  foreach ($element['attribs'] as $key => $value)
9206  {
9207  $key = strtolower($key);
9208  $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
9209  }
9210  if ($element['self_closing'])
9211  {
9212  $full .= ' />';
9213  }
9214  else
9215  {
9216  $full .= ">$element[content]</$element[tag]>";
9217  }
9218  return $full;
9219  }
9220 
9221  function error($message, $level, $file, $line)
9222  {
9223  if ((ini_get('error_reporting') & $level) > 0)
9224  {
9225  switch ($level)
9226  {
9227  case E_USER_ERROR:
9228  $note = 'PHP Error';
9229  break;
9230  case E_USER_WARNING:
9231  $note = 'PHP Warning';
9232  break;
9233  case E_USER_NOTICE:
9234  $note = 'PHP Notice';
9235  break;
9236  default:
9237  $note = 'Unknown Error';
9238  break;
9239  }
9240  error_log("$note: $message in $file on line $line", 0);
9241  }
9242  return $message;
9243  }
9244 
9245  /**
9246  * If a file has been cached, retrieve and display it.
9247  *
9248  * This is most useful for caching images (get_favicon(), etc.),
9249  * however it works for all cached files. This WILL NOT display ANY
9250  * file/image/page/whatever, but rather only display what has already
9251  * been cached by SimplePie.
9252  *
9253  * @access public
9254  * @see SimplePie::get_favicon()
9255  * @param str $identifier_url URL that is used to identify the content.
9256  * This may or may not be the actual URL of the live content.
9257  * @param str $cache_location Location of SimplePie's cache. Defaults
9258  * to './cache'.
9259  * @param str $cache_extension The file extension that the file was
9260  * cached with. Defaults to 'spc'.
9261  * @param str $cache_class Name of the cache-handling class being used
9262  * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
9263  * as-is unless you've overloaded the class.
9264  * @param str $cache_name_function Obsolete. Exists for backwards
9265  * compatibility reasons only.
9266  */
9267  function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
9268  {
9269  $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
9270 
9271  if ($file = $cache->load())
9272  {
9273  if (isset($file['headers']['content-type']))
9274  {
9275  header('Content-type:' . $file['headers']['content-type']);
9276  }
9277  else
9278  {
9279  header('Content-type: application/octet-stream');
9280  }
9281  header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
9282  echo $file['body'];
9283  exit;
9284  }
9285 
9286  die('Cached file for ' . $identifier_url . ' cannot be found.');
9287  }
9288 
9289  function fix_protocol($url, $http = 1)
9290  {
9291  $url = SimplePie_Misc::normalize_url($url);
9292  $parsed = SimplePie_Misc::parse_url($url);
9293  if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
9294  {
9295  return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
9296  }
9297 
9298  if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
9299  {
9300  return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
9301  }
9302 
9303  if ($http === 2 && $parsed['scheme'] !== '')
9304  {
9305  return "feed:$url";
9306  }
9307  elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
9308  {
9309  return substr_replace($url, 'podcast', 0, 4);
9310  }
9311  elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
9312  {
9313  return substr_replace($url, 'itpc', 0, 4);
9314  }
9315  else
9316  {
9317  return $url;
9318  }
9319  }
9320 
9321  function parse_url($url)
9322  {
9323  $iri = new SimplePie_IRI($url);
9324  return array(
9325  'scheme' => (string) $iri->get_scheme(),
9326  'authority' => (string) $iri->get_authority(),
9327  'path' => (string) $iri->get_path(),
9328  'query' => (string) $iri->get_query(),
9329  'fragment' => (string) $iri->get_fragment()
9330  );
9331  }
9332 
9333  function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
9334  {
9335  $iri = new SimplePie_IRI('');
9336  $iri->set_scheme($scheme);
9337  $iri->set_authority($authority);
9338  $iri->set_path($path);
9339  $iri->set_query($query);
9340  $iri->set_fragment($fragment);
9341  return $iri->get_iri();
9342  }
9343 
9344  function normalize_url($url)
9345  {
9346  $iri = new SimplePie_IRI($url);
9347  return $iri->get_iri();
9348  }
9349 
9350  function percent_encoding_normalization($match)
9351  {
9352  $integer = hexdec($match[1]);
9353  if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
9354  {
9355  return chr($integer);
9356  }
9357  else
9358  {
9359  return strtoupper($match[0]);
9360  }
9361  }
9362 
9363  /**
9364  * Remove bad UTF-8 bytes
9365  *
9366  * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9367  * FAQ: Multilingual Forms (modified to include full ASCII range)
9368  *
9369  * @author Geoffrey Sneddon
9370  * @see http://www.w3.org/International/questions/qa-forms-utf-8
9371  * @param string $str String to remove bad UTF-8 bytes from
9372  * @return string UTF-8 string
9373  */
9374  function utf8_bad_replace($str)
9375  {
9376  if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9377  {
9378  return $return;
9379  }
9380  elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9381  {
9382  return $return;
9383  }
9384  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))
9385  {
9386  return implode("\xEF\xBF\xBD", $matches[0]);
9387  }
9388  elseif ($str !== '')
9389  {
9390  return "\xEF\xBF\xBD";
9391  }
9392  else
9393  {
9394  return '';
9395  }
9396  }
9397 
9398  /**
9399  * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9400  *
9401  * @static
9402  * @access public
9403  * @param string $string Windows-1252 encoded string
9404  * @return string UTF-8 encoded string
9405  */
9406  function windows_1252_to_utf8($string)
9407  {
9408  static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF");
9409 
9410  return strtr($string, $convert_table);
9411  }
9412 
9413  function change_encoding($data, $input, $output)
9414  {
9415  $input = SimplePie_Misc::encoding($input);
9416  $output = SimplePie_Misc::encoding($output);
9417 
9418  // We fail to fail on non US-ASCII bytes
9419  if ($input === 'US-ASCII')
9420  {
9421  static $non_ascii_octects = '';
9422  if (!$non_ascii_octects)
9423  {
9424  for ($i = 0x80; $i <= 0xFF; $i++)
9425  {
9426  $non_ascii_octects .= chr($i);
9427  }
9428  }
9429  $data = substr($data, 0, strcspn($data, $non_ascii_octects));
9430  }
9431 
9432  // This is first, as behaviour of this is completely predictable
9433  if ($input === 'Windows-1252' && $output === 'UTF-8')
9434  {
9436  }
9437  // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
9438  elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && ($return = @mb_convert_encoding($data, $output, $input)))
9439  {
9440  return $return;
9441  }
9442  // This is last, as behaviour of this varies with OS userland and PHP version
9443  elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9444  {
9445  return $return;
9446  }
9447  // If we can't do anything, just fail
9448  else
9449  {
9450  return false;
9451  }
9452  }
9453 
9454  function encoding($charset)
9455  {
9456  // Normalization from UTS #22
9457  switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
9458  {
9459  case 'adobestandardencoding':
9460  case 'csadobestandardencoding':
9461  return 'Adobe-Standard-Encoding';
9462 
9463  case 'adobesymbolencoding':
9464  case 'cshppsmath':
9465  return 'Adobe-Symbol-Encoding';
9466 
9467  case 'ami1251':
9468  case 'amiga1251':
9469  return 'Amiga-1251';
9470 
9471  case 'ansix31101983':
9472  case 'csat5001983':
9473  case 'csiso99naplps':
9474  case 'isoir99':
9475  case 'naplps':
9476  return 'ANSI_X3.110-1983';
9477 
9478  case 'arabic7':
9479  case 'asmo449':
9480  case 'csiso89asmo449':
9481  case 'iso9036':
9482  case 'isoir89':
9483  return 'ASMO_449';
9484 
9485  case 'big5':
9486  case 'csbig5':
9487  case 'xxbig5':
9488  return 'Big5';
9489 
9490  case 'big5hkscs':
9491  return 'Big5-HKSCS';
9492 
9493  case 'bocu1':
9494  case 'csbocu1':
9495  return 'BOCU-1';
9496 
9497  case 'brf':
9498  case 'csbrf':
9499  return 'BRF';
9500 
9501  case 'bs4730':
9502  case 'csiso4unitedkingdom':
9503  case 'gb':
9504  case 'iso646gb':
9505  case 'isoir4':
9506  case 'uk':
9507  return 'BS_4730';
9508 
9509  case 'bsviewdata':
9510  case 'csiso47bsviewdata':
9511  case 'isoir47':
9512  return 'BS_viewdata';
9513 
9514  case 'cesu8':
9515  case 'cscesu8':
9516  return 'CESU-8';
9517 
9518  case 'ca':
9519  case 'csa71':
9520  case 'csaz243419851':
9521  case 'csiso121canadian1':
9522  case 'iso646ca':
9523  case 'isoir121':
9524  return 'CSA_Z243.4-1985-1';
9525 
9526  case 'csa72':
9527  case 'csaz243419852':
9528  case 'csiso122canadian2':
9529  case 'iso646ca2':
9530  case 'isoir122':
9531  return 'CSA_Z243.4-1985-2';
9532 
9533  case 'csaz24341985gr':
9534  case 'csiso123csaz24341985gr':
9535  case 'isoir123':
9536  return 'CSA_Z243.4-1985-gr';
9537 
9538  case 'csiso139csn369103':
9539  case 'csn369103':
9540  case 'isoir139':
9541  return 'CSN_369103';
9542 
9543  case 'csdecmcs':
9544  case 'dec':
9545  case 'decmcs':
9546  return 'DEC-MCS';
9547 
9548  case 'csiso21german':
9549  case 'de':
9550  case 'din66003':
9551  case 'iso646de':
9552  case 'isoir21':
9553  return 'DIN_66003';
9554 
9555  case 'csdkus':
9556  case 'dkus':
9557  return 'dk-us';
9558 
9559  case 'csiso646danish':
9560  case 'dk':
9561  case 'ds2089':
9562  case 'iso646dk':
9563  return 'DS_2089';
9564 
9565  case 'csibmebcdicatde':
9566  case 'ebcdicatde':
9567  return 'EBCDIC-AT-DE';
9568 
9569  case 'csebcdicatdea':
9570  case 'ebcdicatdea':
9571  return 'EBCDIC-AT-DE-A';
9572 
9573  case 'csebcdiccafr':
9574  case 'ebcdiccafr':
9575  return 'EBCDIC-CA-FR';
9576 
9577  case 'csebcdicdkno':
9578  case 'ebcdicdkno':
9579  return 'EBCDIC-DK-NO';
9580 
9581  case 'csebcdicdknoa':
9582  case 'ebcdicdknoa':
9583  return 'EBCDIC-DK-NO-A';
9584 
9585  case 'csebcdices':
9586  case 'ebcdices':
9587  return 'EBCDIC-ES';
9588 
9589  case 'csebcdicesa':
9590  case 'ebcdicesa':
9591  return 'EBCDIC-ES-A';
9592 
9593  case 'csebcdicess':
9594  case 'ebcdicess':
9595  return 'EBCDIC-ES-S';
9596 
9597  case 'csebcdicfise':
9598  case 'ebcdicfise':
9599  return 'EBCDIC-FI-SE';
9600 
9601  case 'csebcdicfisea':
9602  case 'ebcdicfisea':
9603  return 'EBCDIC-FI-SE-A';
9604 
9605  case 'csebcdicfr':
9606  case 'ebcdicfr':
9607  return 'EBCDIC-FR';
9608 
9609  case 'csebcdicit':
9610  case 'ebcdicit':
9611  return 'EBCDIC-IT';
9612 
9613  case 'csebcdicpt':
9614  case 'ebcdicpt':
9615  return 'EBCDIC-PT';
9616 
9617  case 'csebcdicuk':
9618  case 'ebcdicuk':
9619  return 'EBCDIC-UK';
9620 
9621  case 'csebcdicus':
9622  case 'ebcdicus':
9623  return 'EBCDIC-US';
9624 
9625  case 'csiso111ecmacyrillic':
9626  case 'ecmacyrillic':
9627  case 'isoir111':
9628  case 'koi8e':
9629  return 'ECMA-cyrillic';
9630 
9631  case 'csiso17spanish':
9632  case 'es':
9633  case 'iso646es':
9634  case 'isoir17':
9635  return 'ES';
9636 
9637  case 'csiso85spanish2':
9638  case 'es2':
9639  case 'iso646es2':
9640  case 'isoir85':
9641  return 'ES2';
9642 
9643  case 'cseucfixwidjapanese':
9644  case 'extendedunixcodefixedwidthforjapanese':
9645  return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9646 
9647  case 'cseucpkdfmtjapanese':
9648  case 'eucjp':
9649  case 'extendedunixcodepackedformatforjapanese':
9650  return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
9651 
9652  case 'gb18030':
9653  return 'GB18030';
9654 
9655  case 'chinese':
9656  case 'cp936':
9657  case 'csgb2312':
9658  case 'csiso58gb231280':
9659  case 'gb2312':
9660  case 'gb231280':
9661  case 'gbk':
9662  case 'isoir58':
9663  case 'ms936':
9664  case 'windows936':
9665  return 'GBK';
9666 
9667  case 'cn':
9668  case 'csiso57gb1988':
9669  case 'gb198880':
9670  case 'iso646cn':
9671  case 'isoir57':
9672  return 'GB_1988-80';
9673 
9674  case 'csiso153gost1976874':
9675  case 'gost1976874':
9676  case 'isoir153':
9677  case 'stsev35888':
9678  return 'GOST_19768-74';
9679 
9680  case 'csiso150':
9681  case 'csiso150greekccitt':
9682  case 'greekccitt':
9683  case 'isoir150':
9684  return 'greek-ccitt';
9685 
9686  case 'csiso88greek7':
9687  case 'greek7':
9688  case 'isoir88':
9689  return 'greek7';
9690 
9691  case 'csiso18greek7old':
9692  case 'greek7old':
9693  case 'isoir18':
9694  return 'greek7-old';
9695 
9696  case 'cshpdesktop':
9697  case 'hpdesktop':
9698  return 'HP-DeskTop';
9699 
9700  case 'cshplegal':
9701  case 'hplegal':
9702  return 'HP-Legal';
9703 
9704  case 'cshpmath8':
9705  case 'hpmath8':
9706  return 'HP-Math8';
9707 
9708  case 'cshppifont':
9709  case 'hppifont':
9710  return 'HP-Pi-font';
9711 
9712  case 'cshproman8':
9713  case 'hproman8':
9714  case 'r8':
9715  case 'roman8':
9716  return 'hp-roman8';
9717 
9718  case 'hzgb2312':
9719  return 'HZ-GB-2312';
9720 
9721  case 'csibmsymbols':
9722  case 'ibmsymbols':
9723  return 'IBM-Symbols';
9724 
9725  case 'csibmthai':
9726  case 'ibmthai':
9727  return 'IBM-Thai';
9728 
9729  case 'ccsid858':
9730  case 'cp858':
9731  case 'ibm858':
9732  case 'pcmultilingual850euro':
9733  return 'IBM00858';
9734 
9735  case 'ccsid924':
9736  case 'cp924':
9737  case 'ebcdiclatin9euro':
9738  case 'ibm924':
9739  return 'IBM00924';
9740 
9741  case 'ccsid1140':
9742  case 'cp1140':
9743  case 'ebcdicus37euro':
9744  case 'ibm1140':
9745  return 'IBM01140';
9746 
9747  case 'ccsid1141':
9748  case 'cp1141':
9749  case 'ebcdicde273euro':
9750  case 'ibm1141':
9751  return 'IBM01141';
9752 
9753  case 'ccsid1142':
9754  case 'cp1142':
9755  case 'ebcdicdk277euro':
9756  case 'ebcdicno277euro':
9757  case 'ibm1142':
9758  return 'IBM01142';
9759 
9760  case 'ccsid1143':
9761  case 'cp1143':
9762  case 'ebcdicfi278euro':
9763  case 'ebcdicse278euro':
9764  case 'ibm1143':
9765  return 'IBM01143';
9766 
9767  case 'ccsid1144':
9768  case 'cp1144':
9769  case 'ebcdicit280euro':
9770  case 'ibm1144':
9771  return 'IBM01144';
9772 
9773  case 'ccsid1145':
9774  case 'cp1145':
9775  case 'ebcdices284euro':
9776  case 'ibm1145':
9777  return 'IBM01145';
9778 
9779  case 'ccsid1146':
9780  case 'cp1146':
9781  case 'ebcdicgb285euro':
9782  case 'ibm1146':
9783  return 'IBM01146';
9784 
9785  case 'ccsid1147':
9786  case 'cp1147':
9787  case 'ebcdicfr297euro':
9788  case 'ibm1147':
9789  return 'IBM01147';
9790 
9791  case 'ccsid1148':
9792  case 'cp1148':
9793  case 'ebcdicinternational500euro':
9794  case 'ibm1148':
9795  return 'IBM01148';
9796 
9797  case 'ccsid1149':
9798  case 'cp1149':
9799  case 'ebcdicis871euro':
9800  case 'ibm1149':
9801  return 'IBM01149';
9802 
9803  case 'cp37':
9804  case 'csibm37':
9805  case 'ebcdiccpca':
9806  case 'ebcdiccpnl':
9807  case 'ebcdiccpus':
9808  case 'ebcdiccpwt':
9809  case 'ibm37':
9810  return 'IBM037';
9811 
9812  case 'cp38':
9813  case 'csibm38':
9814  case 'ebcdicint':
9815  case 'ibm38':
9816  return 'IBM038';
9817 
9818  case 'cp273':
9819  case 'csibm273':
9820  case 'ibm273':
9821  return 'IBM273';
9822 
9823  case 'cp274':
9824  case 'csibm274':
9825  case 'ebcdicbe':
9826  case 'ibm274':
9827  return 'IBM274';
9828 
9829  case 'cp275':
9830  case 'csibm275':
9831  case 'ebcdicbr':
9832  case 'ibm275':
9833  return 'IBM275';
9834 
9835  case 'csibm277':
9836  case 'ebcdiccpdk':
9837  case 'ebcdiccpno':
9838  case 'ibm277':
9839  return 'IBM277';
9840 
9841  case 'cp278':
9842  case 'csibm278':
9843  case 'ebcdiccpfi':
9844  case 'ebcdiccpse':
9845  case 'ibm278':
9846  return 'IBM278';
9847 
9848  case 'cp280':
9849  case 'csibm280':
9850  case 'ebcdiccpit':
9851  case 'ibm280':
9852  return 'IBM280';
9853 
9854  case 'cp281':
9855  case 'csibm281':
9856  case 'ebcdicjpe':
9857  case 'ibm281':
9858  return 'IBM281';
9859 
9860  case 'cp284':
9861  case 'csibm284':
9862  case 'ebcdiccpes':
9863  case 'ibm284':
9864  return 'IBM284';
9865 
9866  case 'cp285':
9867  case 'csibm285':
9868  case 'ebcdiccpgb':
9869  case 'ibm285':
9870  return 'IBM285';
9871 
9872  case 'cp290':
9873  case 'csibm290':
9874  case 'ebcdicjpkana':
9875  case 'ibm290':
9876  return 'IBM290';
9877 
9878  case 'cp297':
9879  case 'csibm297':
9880  case 'ebcdiccpfr':
9881  case 'ibm297':
9882  return 'IBM297';
9883 
9884  case 'cp420':
9885  case 'csibm420':
9886  case 'ebcdiccpar1':
9887  case 'ibm420':
9888  return 'IBM420';
9889 
9890  case 'cp423':
9891  case 'csibm423':
9892  case 'ebcdiccpgr':
9893  case 'ibm423':
9894  return 'IBM423';
9895 
9896  case 'cp424':
9897  case 'csibm424':
9898  case 'ebcdiccphe':
9899  case 'ibm424':
9900  return 'IBM424';
9901 
9902  case '437':
9903  case 'cp437':
9904  case 'cspc8codepage437':
9905  case 'ibm437':
9906  return 'IBM437';
9907 
9908  case 'cp500':
9909  case 'csibm500':
9910  case 'ebcdiccpbe':
9911  case 'ebcdiccpch':
9912  case 'ibm500':
9913  return 'IBM500';
9914 
9915  case 'cp775':
9916  case 'cspc775baltic':
9917  case 'ibm775':
9918  return 'IBM775';
9919 
9920  case '850':
9921  case 'cp850':
9922  case 'cspc850multilingual':
9923  case 'ibm850':
9924  return 'IBM850';
9925 
9926  case '851':
9927  case 'cp851':
9928  case 'csibm851':
9929  case 'ibm851':
9930  return 'IBM851';
9931 
9932  case '852':
9933  case 'cp852':
9934  case 'cspcp852':
9935  case 'ibm852':
9936  return 'IBM852';
9937 
9938  case '855':
9939  case 'cp855':
9940  case 'csibm855':
9941  case 'ibm855':
9942  return 'IBM855';
9943 
9944  case '857':
9945  case 'cp857':
9946  case 'csibm857':
9947  case 'ibm857':
9948  return 'IBM857';
9949 
9950  case '860':
9951  case 'cp860':
9952  case 'csibm860':
9953  case 'ibm860':
9954  return 'IBM860';
9955 
9956  case '861':
9957  case 'cp861':
9958  case 'cpis':
9959  case 'csibm861':
9960  case 'ibm861':
9961  return 'IBM861';
9962 
9963  case '862':
9964  case 'cp862':
9965  case 'cspc862latinhebrew':
9966  case 'ibm862':
9967  return 'IBM862';
9968 
9969  case '863':
9970  case 'cp863':
9971  case 'csibm863':
9972  case 'ibm863':
9973  return 'IBM863';
9974 
9975  case 'cp864':
9976  case 'csibm864':
9977  case 'ibm864':
9978  return 'IBM864';
9979 
9980  case '865':
9981  case 'cp865':
9982  case 'csibm865':
9983  case 'ibm865':
9984  return 'IBM865';
9985 
9986  case '866':
9987  case 'cp866':
9988  case 'csibm866':
9989  case 'ibm866':
9990  return 'IBM866';
9991 
9992  case 'cp868':
9993  case 'cpar':
9994  case 'csibm868':
9995  case 'ibm868':
9996  return 'IBM868';
9997 
9998  case '869':
9999  case 'cp869':
10000  case 'cpgr':
10001  case 'csibm869':
10002  case 'ibm869':
10003  return 'IBM869';
10004 
10005  case 'cp870':
10006  case 'csibm870':
10007  case 'ebcdiccproece':
10008  case 'ebcdiccpyu':
10009  case 'ibm870':
10010  return 'IBM870';
10011 
10012  case 'cp871':
10013  case 'csibm871':
10014  case 'ebcdiccpis':
10015  case 'ibm871':
10016  return 'IBM871';
10017 
10018  case 'cp880':
10019  case 'csibm880':
10020  case 'ebcdiccyrillic':
10021  case 'ibm880':
10022  return 'IBM880';
10023 
10024  case 'cp891':
10025  case 'csibm891':
10026  case 'ibm891':
10027  return 'IBM891';
10028 
10029  case 'cp903':
10030  case 'csibm903':
10031  case 'ibm903':
10032  return 'IBM903';
10033 
10034  case '904':
10035  case 'cp904':
10036  case 'csibbm904':
10037  case 'ibm904':
10038  return 'IBM904';
10039 
10040  case 'cp905':
10041  case 'csibm905':
10042  case 'ebcdiccptr':
10043  case 'ibm905':
10044  return 'IBM905';
10045 
10046  case 'cp918':
10047  case 'csibm918':
10048  case 'ebcdiccpar2':
10049  case 'ibm918':
10050  return 'IBM918';
10051 
10052  case 'cp1026':
10053  case 'csibm1026':
10054  case 'ibm1026':
10055  return 'IBM1026';
10056 
10057  case 'ibm1047':
10058  return 'IBM1047';
10059 
10060  case 'csiso143iecp271':
10061  case 'iecp271':
10062  case 'isoir143':
10063  return 'IEC_P27-1';
10064 
10065  case 'csiso49inis':
10066  case 'inis':
10067  case 'isoir49':
10068  return 'INIS';
10069 
10070  case 'csiso50inis8':
10071  case 'inis8':
10072  case 'isoir50':
10073  return 'INIS-8';
10074 
10075  case 'csiso51iniscyrillic':
10076  case 'iniscyrillic':
10077  case 'isoir51':
10078  return 'INIS-cyrillic';
10079 
10080  case 'csinvariant':
10081  case 'invariant':
10082  return 'INVARIANT';
10083 
10084  case 'iso2022cn':
10085  return 'ISO-2022-CN';
10086 
10087  case 'iso2022cnext':
10088  return 'ISO-2022-CN-EXT';
10089 
10090  case 'csiso2022jp':
10091  case 'iso2022jp':
10092  return 'ISO-2022-JP';
10093 
10094  case 'csiso2022jp2':
10095  case 'iso2022jp2':
10096  return 'ISO-2022-JP-2';
10097 
10098  case 'csiso2022kr':
10099  case 'iso2022kr':
10100  return 'ISO-2022-KR';
10101 
10102  case 'cswindows30latin1':
10103  case 'iso88591windows30latin1':
10104  return 'ISO-8859-1-Windows-3.0-Latin-1';
10105 
10106  case 'cswindows31latin1':
10107  case 'iso88591windows31latin1':
10108  return 'ISO-8859-1-Windows-3.1-Latin-1';
10109 
10110  case 'csisolatin2':
10111  case 'iso88592':
10112  case 'iso885921987':
10113  case 'isoir101':
10114  case 'l2':
10115  case 'latin2':
10116  return 'ISO-8859-2';
10117 
10118  case 'cswindows31latin2':
10119  case 'iso88592windowslatin2':
10120  return 'ISO-8859-2-Windows-Latin-2';
10121 
10122  case 'csisolatin3':
10123  case 'iso88593':
10124  case 'iso885931988':
10125  case 'isoir109':
10126  case 'l3':
10127  case 'latin3':
10128  return 'ISO-8859-3';
10129 
10130  case 'csisolatin4':
10131  case 'iso88594':
10132  case 'iso885941988':
10133  case 'isoir110':
10134  case 'l4':
10135  case 'latin4':
10136  return 'ISO-8859-4';
10137 
10138  case 'csisolatincyrillic':
10139  case 'cyrillic':
10140  case 'iso88595':
10141  case 'iso885951988':
10142  case 'isoir144':
10143  return 'ISO-8859-5';
10144 
10145  case 'arabic':
10146  case 'asmo708':
10147  case 'csisolatinarabic':
10148  case 'ecma114':
10149  case 'iso88596':
10150  case 'iso885961987':
10151  case 'isoir127':
10152  return 'ISO-8859-6';
10153 
10154  case 'csiso88596e':
10155  case 'iso88596e':
10156  return 'ISO-8859-6-E';
10157 
10158  case 'csiso88596i':
10159  case 'iso88596i':
10160  return 'ISO-8859-6-I';
10161 
10162  case 'csisolatingreek':
10163  case 'ecma118':
10164  case 'elot928':
10165  case 'greek':
10166  case 'greek8':
10167  case 'iso88597':
10168  case 'iso885971987':
10169  case 'isoir126':
10170  return 'ISO-8859-7';
10171 
10172  case 'csisolatinhebrew':
10173  case 'hebrew':
10174  case 'iso88598':
10175  case 'iso885981988':
10176  case 'isoir138':
10177  return 'ISO-8859-8';
10178 
10179  case 'csiso88598e':
10180  case 'iso88598e':
10181  return 'ISO-8859-8-E';
10182 
10183  case 'csiso88598i':
10184  case 'iso88598i':
10185  return 'ISO-8859-8-I';
10186 
10187  case 'cswindows31latin5':
10188  case 'iso88599windowslatin5':
10189  return 'ISO-8859-9-Windows-Latin-5';
10190 
10191  case 'csisolatin6':
10192  case 'iso885910':
10193  case 'iso8859101992':
10194  case 'isoir157':
10195  case 'l6':
10196  case 'latin6':
10197  return 'ISO-8859-10';
10198 
10199  case 'iso885913':
10200  return 'ISO-8859-13';
10201 
10202  case 'iso885914':
10203  case 'iso8859141998':
10204  case 'isoceltic':
10205  case 'isoir199':
10206  case 'l8':
10207  case 'latin8':
10208  return 'ISO-8859-14';
10209 
10210  case 'iso885915':
10211  case 'latin9':
10212  return 'ISO-8859-15';
10213 
10214  case 'iso885916':
10215  case 'iso8859162001':
10216  case 'isoir226':
10217  case 'l10':
10218  case 'latin10':
10219  return 'ISO-8859-16';
10220 
10221  case 'iso10646j1':
10222  return 'ISO-10646-J-1';
10223 
10224  case 'csunicode':
10225  case 'iso10646ucs2':
10226  return 'ISO-10646-UCS-2';
10227 
10228  case 'csucs4':
10229  case 'iso10646ucs4':
10230  return 'ISO-10646-UCS-4';
10231 
10232  case 'csunicodeascii':
10233  case 'iso10646ucsbasic':
10234  return 'ISO-10646-UCS-Basic';
10235 
10236  case 'csunicodelatin1':
10237  case 'iso10646':
10238  case 'iso10646unicodelatin1':
10239  return 'ISO-10646-Unicode-Latin1';
10240 
10241  case 'csiso10646utf1':
10242  case 'iso10646utf1':
10243  return 'ISO-10646-UTF-1';
10244 
10245  case 'csiso115481':
10246  case 'iso115481':
10247  case 'isotr115481':
10248  return 'ISO-11548-1';
10249 
10250  case 'csiso90':
10251  case 'isoir90':
10252  return 'iso-ir-90';
10253 
10254  case 'csunicodeibm1261':
10255  case 'isounicodeibm1261':
10256  return 'ISO-Unicode-IBM-1261';
10257 
10258  case 'csunicodeibm1264':
10259  case 'isounicodeibm1264':
10260  return 'ISO-Unicode-IBM-1264';
10261 
10262  case 'csunicodeibm1265':
10263  case 'isounicodeibm1265':
10264  return 'ISO-Unicode-IBM-1265';
10265 
10266  case 'csunicodeibm1268':
10267  case 'isounicodeibm1268':
10268  return 'ISO-Unicode-IBM-1268';
10269 
10270  case 'csunicodeibm1276':
10271  case 'isounicodeibm1276':
10272  return 'ISO-Unicode-IBM-1276';
10273 
10274  case 'csiso646basic1983':
10275  case 'iso646basic1983':
10276  case 'ref':
10277  return 'ISO_646.basic:1983';
10278 
10279  case 'csiso2intlrefversion':
10280  case 'irv':
10281  case 'iso646irv1983':
10282  case 'isoir2':
10283  return 'ISO_646.irv:1983';
10284 
10285  case 'csiso2033':
10286  case 'e13b':
10287  case 'iso20331983':
10288  case 'isoir98':
10289  return 'ISO_2033-1983';
10290 
10291  case 'csiso5427cyrillic':
10292  case 'iso5427':
10293  case 'isoir37':
10294  return 'ISO_5427';
10295 
10296  case 'iso5427cyrillic1981':
10297  case 'iso54271981':
10298  case 'isoir54':
10299  return 'ISO_5427:1981';
10300 
10301  case 'csiso5428greek':
10302  case 'iso54281980':
10303  case 'isoir55':
10304  return 'ISO_5428:1980';
10305 
10306  case 'csiso6937add':
10307  case 'iso6937225':
10308  case 'isoir152':
10309  return 'ISO_6937-2-25';
10310 
10311  case 'csisotextcomm':
10312  case 'iso69372add':
10313  case 'isoir142':
10314  return 'ISO_6937-2-add';
10315 
10316  case 'csiso8859supp':
10317  case 'iso8859supp':
10318  case 'isoir154':
10319  case 'latin125':
10320  return 'ISO_8859-supp';
10321 
10322  case 'csiso10367box':
10323  case 'iso10367box':
10324  case 'isoir155':
10325  return 'ISO_10367-box';
10326 
10327  case 'csiso15italian':
10328  case 'iso646it':
10329  case 'isoir15':
10330  case 'it':
10331  return 'IT';
10332 
10333  case 'csiso13jisc6220jp':
10334  case 'isoir13':
10335  case 'jisc62201969':
10336  case 'jisc62201969jp':
10337  case 'katakana':
10338  case 'x2017':
10339  return 'JIS_C6220-1969-jp';
10340 
10341  case 'csiso14jisc6220ro':
10342  case 'iso646jp':
10343  case 'isoir14':
10344  case 'jisc62201969ro':
10345  case 'jp':
10346  return 'JIS_C6220-1969-ro';
10347 
10348  case 'csiso42jisc62261978':
10349  case 'isoir42':
10350  case 'jisc62261978':
10351  return 'JIS_C6226-1978';
10352 
10353  case 'csiso87jisx208':
10354  case 'isoir87':
10355  case 'jisc62261983':
10356  case 'jisx2081983':
10357  case 'x208':
10358  return 'JIS_C6226-1983';
10359 
10360  case 'csiso91jisc62291984a':
10361  case 'isoir91':
10362  case 'jisc62291984a':
10363  case 'jpocra':
10364  return 'JIS_C6229-1984-a';
10365 
10366  case 'csiso92jisc62991984b':
10367  case 'iso646jpocrb':
10368  case 'isoir92':
10369  case 'jisc62291984b':
10370  case 'jpocrb':
10371  return 'JIS_C6229-1984-b';
10372 
10373  case 'csiso93jis62291984badd':
10374  case 'isoir93':
10375  case 'jisc62291984badd':
10376  case 'jpocrbadd':
10377  return 'JIS_C6229-1984-b-add';
10378 
10379  case 'csiso94jis62291984hand':
10380  case 'isoir94':
10381  case 'jisc62291984hand':
10382  case 'jpocrhand':
10383  return 'JIS_C6229-1984-hand';
10384 
10385  case 'csiso95jis62291984handadd':
10386  case 'isoir95':
10387  case 'jisc62291984handadd':
10388  case 'jpocrhandadd':
10389  return 'JIS_C6229-1984-hand-add';
10390 
10391  case 'csiso96jisc62291984kana':
10392  case 'isoir96':
10393  case 'jisc62291984kana':
10394  return 'JIS_C6229-1984-kana';
10395 
10396  case 'csjisencoding':
10397  case 'jisencoding':
10398  return 'JIS_Encoding';
10399 
10400  case 'cshalfwidthkatakana':
10401  case 'jisx201':
10402  case 'x201':
10403  return 'JIS_X0201';
10404 
10405  case 'csiso159jisx2121990':
10406  case 'isoir159':
10407  case 'jisx2121990':
10408  case 'x212':
10409  return 'JIS_X0212-1990';
10410 
10411  case 'csiso141jusib1002':
10412  case 'iso646yu':
10413  case 'isoir141':
10414  case 'js':
10415  case 'jusib1002':
10416  case 'yu':
10417  return 'JUS_I.B1.002';
10418 
10419  case 'csiso147macedonian':
10420  case 'isoir147':
10421  case 'jusib1003mac':
10422  case 'macedonian':
10423  return 'JUS_I.B1.003-mac';
10424 
10425  case 'csiso146serbian':
10426  case 'isoir146':
10427  case 'jusib1003serb':
10428  case 'serbian':
10429  return 'JUS_I.B1.003-serb';
10430 
10431  case 'koi7switched':
10432  return 'KOI7-switched';
10433 
10434  case 'cskoi8r':
10435  case 'koi8r':
10436  return 'KOI8-R';
10437 
10438  case 'koi8u':
10439  return 'KOI8-U';
10440 
10441  case 'csksc5636':
10442  case 'iso646kr':
10443  case 'ksc5636':
10444  return 'KSC5636';
10445 
10446  case 'cskz1048':
10447  case 'kz1048':
10448  case 'rk1048':
10449  case 'strk10482002':
10450  return 'KZ-1048';
10451 
10452  case 'csiso19latingreek':
10453  case 'isoir19':
10454  case 'latingreek':
10455  return 'latin-greek';
10456 
10457  case 'csiso27latingreek1':
10458  case 'isoir27':
10459  case 'latingreek1':
10460  return 'Latin-greek-1';
10461 
10462  case 'csiso158lap':
10463  case 'isoir158':
10464  case 'lap':
10465  case 'latinlap':
10466  return 'latin-lap';
10467 
10468  case 'csmacintosh':
10469  case 'mac':
10470  case 'macintosh':
10471  return 'macintosh';
10472 
10473  case 'csmicrosoftpublishing':
10474  case 'microsoftpublishing':
10475  return 'Microsoft-Publishing';
10476 
10477  case 'csmnem':
10478  case 'mnem':
10479  return 'MNEM';
10480 
10481  case 'csmnemonic':
10482  case 'mnemonic':
10483  return 'MNEMONIC';
10484 
10485  case 'csiso86hungarian':
10486  case 'hu':
10487  case 'iso646hu':
10488  case 'isoir86':
10489  case 'msz77953':
10490  return 'MSZ_7795.3';
10491 
10492  case 'csnatsdano':
10493  case 'isoir91':
10494  case 'natsdano':
10495  return 'NATS-DANO';
10496 
10497  case 'csnatsdanoadd':
10498  case 'isoir92':
10499  case 'natsdanoadd':
10500  return 'NATS-DANO-ADD';
10501 
10502  case 'csnatssefi':
10503  case 'isoir81':
10504  case 'natssefi':
10505  return 'NATS-SEFI';
10506 
10507  case 'csnatssefiadd':
10508  case 'isoir82':
10509  case 'natssefiadd':
10510  return 'NATS-SEFI-ADD';
10511 
10512  case 'csiso151cuba':
10513  case 'cuba':
10514  case 'iso646cu':
10515  case 'isoir151':
10516  case 'ncnc1081':
10517  return 'NC_NC00-10:81';
10518 
10519  case 'csiso69french':
10520  case 'fr':
10521  case 'iso646fr':
10522  case 'isoir69':
10523  case 'nfz62010':
10524  return 'NF_Z_62-010';
10525 
10526  case 'csiso25french':
10527  case 'iso646fr1':
10528  case 'isoir25':
10529  case 'nfz620101973':
10530  return 'NF_Z_62-010_(1973)';
10531 
10532  case 'csiso60danishnorwegian':
10533  case 'csiso60norwegian1':
10534  case 'iso646no':
10535  case 'isoir60':
10536  case 'no':
10537  case 'ns45511':
10538  return 'NS_4551-1';
10539 
10540  case 'csiso61norwegian2':
10541  case 'iso646no2':
10542  case 'isoir61':
10543  case 'no2':
10544  case 'ns45512':
10545  return 'NS_4551-2';
10546 
10547  case 'osdebcdicdf3irv':
10548  return 'OSD_EBCDIC_DF03_IRV';
10549 
10550  case 'osdebcdicdf41':
10551  return 'OSD_EBCDIC_DF04_1';
10552 
10553  case 'osdebcdicdf415':
10554  return 'OSD_EBCDIC_DF04_15';
10555 
10556  case 'cspc8danishnorwegian':
10557  case 'pc8danishnorwegian':
10558  return 'PC8-Danish-Norwegian';
10559 
10560  case 'cspc8turkish':
10561  case 'pc8turkish':
10562  return 'PC8-Turkish';
10563 
10564  case 'csiso16portuguese':
10565  case 'iso646pt':
10566  case 'isoir16':
10567  case 'pt':
10568  return 'PT';
10569 
10570  case 'csiso84portuguese2':
10571  case 'iso646pt2':
10572  case 'isoir84':
10573  case 'pt2':
10574  return 'PT2';
10575 
10576  case 'cp154':
10577  case 'csptcp154':
10578  case 'cyrillicasian':
10579  case 'pt154':
10580  case 'ptcp154':
10581  return 'PTCP154';
10582 
10583  case 'scsu':
10584  return 'SCSU';
10585 
10586  case 'csiso10swedish':
10587  case 'fi':
10588  case 'iso646fi':
10589  case 'iso646se':
10590  case 'isoir10':
10591  case 'se':
10592  case 'sen850200b':
10593  return 'SEN_850200_B';
10594 
10595  case 'csiso11swedishfornames':
10596  case 'iso646se2':
10597  case 'isoir11':
10598  case 'se2':
10599  case 'sen850200c':
10600  return 'SEN_850200_C';
10601 
10602  case 'csshiftjis':
10603  case 'mskanji':
10604  case 'shiftjis':
10605  return 'Shift_JIS';
10606 
10607  case 'csiso102t617bit':
10608  case 'isoir102':
10609  case 't617bit':
10610  return 'T.61-7bit';
10611 
10612  case 'csiso103t618bit':
10613  case 'isoir103':
10614  case 't61':
10615  case 't618bit':
10616  return 'T.61-8bit';
10617 
10618  case 'csiso128t101g2':
10619  case 'isoir128':
10620  case 't101g2':
10621  return 'T.101-G2';
10622 
10623  case 'cstscii':
10624  case 'tscii':
10625  return 'TSCII';
10626 
10627  case 'csunicode11':
10628  case 'unicode11':
10629  return 'UNICODE-1-1';
10630 
10631  case 'csunicode11utf7':
10632  case 'unicode11utf7':
10633  return 'UNICODE-1-1-UTF-7';
10634 
10635  case 'csunknown8bit':
10636  case 'unknown8bit':
10637  return 'UNKNOWN-8BIT';
10638 
10639  case 'ansix341968':
10640  case 'ansix341986':
10641  case 'ascii':
10642  case 'cp367':
10643  case 'csascii':
10644  case 'ibm367':
10645  case 'iso646irv1991':
10646  case 'iso646us':
10647  case 'isoir6':
10648  case 'us':
10649  case 'usascii':
10650  return 'US-ASCII';
10651 
10652  case 'csusdk':
10653  case 'usdk':
10654  return 'us-dk';
10655 
10656  case 'utf7':
10657  return 'UTF-7';
10658 
10659  case 'utf8':
10660  return 'UTF-8';
10661 
10662  case 'utf16':
10663  return 'UTF-16';
10664 
10665  case 'utf16be':
10666  return 'UTF-16BE';
10667 
10668  case 'utf16le':
10669  return 'UTF-16LE';
10670 
10671  case 'utf32':
10672  return 'UTF-32';
10673 
10674  case 'utf32be':
10675  return 'UTF-32BE';
10676 
10677  case 'utf32le':
10678  return 'UTF-32LE';
10679 
10680  case 'csventurainternational':
10681  case 'venturainternational':
10682  return 'Ventura-International';
10683 
10684  case 'csventuramath':
10685  case 'venturamath':
10686  return 'Ventura-Math';
10687 
10688  case 'csventuraus':
10689  case 'venturaus':
10690  return 'Ventura-US';
10691 
10692  case 'csiso70videotexsupp1':
10693  case 'isoir70':
10694  case 'videotexsuppl':
10695  return 'videotex-suppl';
10696 
10697  case 'csviqr':
10698  case 'viqr':
10699  return 'VIQR';
10700 
10701  case 'csviscii':
10702  case 'viscii':
10703  return 'VISCII';
10704 
10705  case 'cswindows31j':
10706  case 'windows31j':
10707  return 'Windows-31J';
10708 
10709  case 'iso885911':
10710  case 'tis620':
10711  return 'windows-874';
10712 
10713  case 'cseuckr':
10714  case 'csksc56011987':
10715  case 'euckr':
10716  case 'isoir149':
10717  case 'korean':
10718  case 'ksc5601':
10719  case 'ksc56011987':
10720  case 'ksc56011989':
10721  case 'windows949':
10722  return 'windows-949';
10723 
10724  case 'windows1250':
10725  return 'windows-1250';
10726 
10727  case 'windows1251':
10728  return 'windows-1251';
10729 
10730  case 'cp819':
10731  case 'csisolatin1':
10732  case 'ibm819':
10733  case 'iso88591':
10734  case 'iso885911987':
10735  case 'isoir100':
10736  case 'l1':
10737  case 'latin1':
10738  case 'windows1252':
10739  return 'windows-1252';
10740 
10741  case 'windows1253':
10742  return 'windows-1253';
10743 
10744  case 'csisolatin5':
10745  case 'iso88599':
10746  case 'iso885991989':
10747  case 'isoir148':
10748  case 'l5':
10749  case 'latin5':
10750  case 'windows1254':
10751  return 'windows-1254';
10752 
10753  case 'windows1255':
10754  return 'windows-1255';
10755 
10756  case 'windows1256':
10757  return 'windows-1256';
10758 
10759  case 'windows1257':
10760  return 'windows-1257';
10761 
10762  case 'windows1258':
10763  return 'windows-1258';
10764 
10765  default:
10766  return $charset;
10767  }
10768  }
10769 
10770  function get_curl_version()
10771  {
10772  if (is_array($curl = curl_version()))
10773  {
10774  $curl = $curl['version'];
10775  }
10776  elseif (substr($curl, 0, 5) === 'curl/')
10777  {
10778  $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10779  }
10780  elseif (substr($curl, 0, 8) === 'libcurl/')
10781  {
10782  $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10783  }
10784  else
10785  {
10786  $curl = 0;
10787  }
10788  return $curl;
10789  }
10790 
10791  function is_subclass_of($class1, $class2)
10792  {
10793  if (func_num_args() !== 2)
10794  {
10795  trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10796  }
10797  elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10798  {
10799  return is_subclass_of($class1, $class2);
10800  }
10801  elseif (is_string($class1) && is_string($class2))
10802  {
10803  if (class_exists($class1))
10804  {
10805  if (class_exists($class2))
10806  {
10807  $class2 = strtolower($class2);
10808  while ($class1 = strtolower(get_parent_class($class1)))
10809  {
10810  if ($class1 === $class2)
10811  {
10812  return true;
10813  }
10814  }
10815  }
10816  }
10817  else
10818  {
10819  trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10820  }
10821  }
10822  return false;
10823  }
10824 
10825  /**
10826  * Strip HTML comments
10827  *
10828  * @access public
10829  * @param string $data Data to strip comments from
10830  * @return string Comment stripped string
10831  */
10832  function strip_comments($data)
10833  {
10834  $output = '';
10835  while (($start = strpos($data, '<!--')) !== false)
10836  {
10837  $output .= substr($data, 0, $start);
10838  if (($end = strpos($data, '-->', $start)) !== false)
10839  {
10840  $data = substr_replace($data, '', 0, $end + 3);
10841  }
10842  else
10843  {
10844  $data = '';
10845  }
10846  }
10847  return $output . $data;
10848  }
10849 
10850  function parse_date($dt)
10851  {
10852  $parser = SimplePie_Parse_Date::get();
10853  return $parser->parse($dt);
10854  }
10855 
10856  /**
10857  * Decode HTML entities
10858  *
10859  * @static
10860  * @access public
10861  * @param string $data Input data
10862  * @return string Output data
10863  */
10864  function entities_decode($data)
10865  {
10866  $decoder = new SimplePie_Decode_HTML_Entities($data);
10867  return $decoder->parse();
10868  }
10869 
10870  /**
10871  * Remove RFC822 comments
10872  *
10873  * @access public
10874  * @param string $data Data to strip comments from
10875  * @return string Comment stripped string
10876  */
10877  function uncomment_rfc822($string)
10878  {
10879  $string = (string) $string;
10880  $position = 0;
10881  $length = strlen($string);
10882  $depth = 0;
10883 
10884  $output = '';
10885 
10886  while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10887  {
10888  $output .= substr($string, $position, $pos - $position);
10889  $position = $pos + 1;
10890  if ($string[$pos - 1] !== '\\')
10891  {
10892  $depth++;
10893  while ($depth && $position < $length)
10894  {
10895  $position += strcspn($string, '()', $position);
10896  if ($string[$position - 1] === '\\')
10897  {
10898  $position++;
10899  continue;
10900  }
10901  elseif (isset($string[$position]))
10902  {
10903  switch ($string[$position])
10904  {
10905  case '(':
10906  $depth++;
10907  break;
10908 
10909  case ')':
10910  $depth--;
10911  break;
10912  }
10913  $position++;
10914  }
10915  else
10916  {
10917  break;
10918  }
10919  }
10920  }
10921  else
10922  {
10923  $output .= '(';
10924  }
10925  }
10926  $output .= substr($string, $position);
10927 
10928  return $output;
10929  }
10930 
10931  function parse_mime($mime)
10932  {
10933  if (($pos = strpos($mime, ';')) === false)
10934  {
10935  return trim($mime);
10936  }
10937  else
10938  {
10939  return trim(substr($mime, 0, $pos));
10940  }
10941  }
10942 
10943  function htmlspecialchars_decode($string, $quote_style)
10944  {
10945  if (function_exists('htmlspecialchars_decode'))
10946  {
10947  return htmlspecialchars_decode($string, $quote_style);
10948  }
10949  else
10950  {
10951  return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10952  }
10953  }
10954 
10955  function atom_03_construct_type($attribs)
10956  {
10957  if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
10958  {
10960  }
10961  else
10962  {
10963  $mode = SIMPLEPIE_CONSTRUCT_NONE;
10964  }
10965  if (isset($attribs['']['type']))
10966  {
10967  switch (strtolower(trim($attribs['']['type'])))
10968  {
10969  case 'text':
10970  case 'text/plain':
10971  return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10972 
10973  case 'html':
10974  case 'text/html':
10975  return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10976 
10977  case 'xhtml':
10978  case 'application/xhtml+xml':
10979  return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10980 
10981  default:
10982  return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10983  }
10984  }
10985  else
10986  {
10987  return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10988  }
10989  }
10990 
10991  function atom_10_construct_type($attribs)
10992  {
10993  if (isset($attribs['']['type']))
10994  {
10995  switch (strtolower(trim($attribs['']['type'])))
10996  {
10997  case 'text':
10998  return SIMPLEPIE_CONSTRUCT_TEXT;
10999 
11000  case 'html':
11001  return SIMPLEPIE_CONSTRUCT_HTML;
11002 
11003  case 'xhtml':
11005 
11006  default:
11007  return SIMPLEPIE_CONSTRUCT_NONE;
11008  }
11009  }
11010  return SIMPLEPIE_CONSTRUCT_TEXT;
11011  }
11012 
11013  function atom_10_content_construct_type($attribs)
11014  {
11015  if (isset($attribs['']['type']))
11016  {
11017  $type = strtolower(trim($attribs['']['type']));
11018  switch ($type)
11019  {
11020  case 'text':
11021  return SIMPLEPIE_CONSTRUCT_TEXT;
11022 
11023  case 'html':
11024  return SIMPLEPIE_CONSTRUCT_HTML;
11025 
11026  case 'xhtml':
11028  }
11029  if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
11030  {
11031  return SIMPLEPIE_CONSTRUCT_NONE;
11032  }
11033  else
11034  {
11036  }
11037  }
11038  else
11039  {
11040  return SIMPLEPIE_CONSTRUCT_TEXT;
11041  }
11042  }
11043 
11044  function is_isegment_nz_nc($string)
11045  {
11046  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);
11047  }
11048 
11049  function space_seperated_tokens($string)
11050  {
11051  $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
11052  $string_length = strlen($string);
11053 
11054  $position = strspn($string, $space_characters);
11055  $tokens = array();
11056 
11057  while ($position < $string_length)
11058  {
11059  $len = strcspn($string, $space_characters, $position);
11060  $tokens[] = substr($string, $position, $len);
11061  $position += $len;
11062  $position += strspn($string, $space_characters, $position);
11063  }
11064 
11065  return $tokens;
11066  }
11067 
11068  function array_unique($array)
11069  {
11070  if (version_compare(PHP_VERSION, '5.2', '>='))
11071  {
11072  return array_unique($array);
11073  }
11074  else
11075  {
11076  $array = (array) $array;
11077  $new_array = array();
11078  $new_array_strings = array();
11079  foreach ($array as $key => $value)
11080  {
11081  if (is_object($value))
11082  {
11083  if (method_exists($value, '__toString'))
11084  {
11085  $cmp = $value->__toString();
11086  }
11087  else
11088  {
11089  trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
11090  }
11091  }
11092  elseif (is_array($value))
11093  {
11094  $cmp = (string) reset($value);
11095  }
11096  else
11097  {
11098  $cmp = (string) $value;
11099  }
11100  if (!in_array($cmp, $new_array_strings))
11101  {
11102  $new_array[$key] = $value;
11103  $new_array_strings[] = $cmp;
11104  }
11105  }
11106  return $new_array;
11107  }
11108  }
11109 
11110  /**
11111  * Converts a unicode codepoint to a UTF-8 character
11112  *
11113  * @static
11114  * @access public
11115  * @param int $codepoint Unicode codepoint
11116  * @return string UTF-8 character
11117  */
11118  function codepoint_to_utf8($codepoint)
11119  {
11120  $codepoint = (int) $codepoint;
11121  if ($codepoint < 0)
11122  {
11123  return false;
11124  }
11125  else if ($codepoint <= 0x7f)
11126  {
11127  return chr($codepoint);
11128  }
11129  else if ($codepoint <= 0x7ff)
11130  {
11131  return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
11132  }
11133  else if ($codepoint <= 0xffff)
11134  {
11135  return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
11136  }
11137  else if ($codepoint <= 0x10ffff)
11138  {
11139  return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
11140  }
11141  else
11142  {
11143  // U+FFFD REPLACEMENT CHARACTER
11144  return "\xEF\xBF\xBD";
11145  }
11146  }
11147 
11148  /**
11149  * Re-implementation of PHP 5's stripos()
11150  *
11151  * Returns the numeric position of the first occurrence of needle in the
11152  * haystack string.
11153  *
11154  * @static
11155  * @access string
11156  * @param object $haystack
11157  * @param string $needle Note that the needle may be a string of one or more
11158  * characters. If needle is not a string, it is converted to an integer
11159  * and applied as the ordinal value of a character.
11160  * @param int $offset The optional offset parameter allows you to specify which
11161  * character in haystack to start searching. The position returned is still
11162  * relative to the beginning of haystack.
11163  * @return bool If needle is not found, stripos() will return boolean false.
11164  */
11165  function stripos($haystack, $needle, $offset = 0)
11166  {
11167  if (function_exists('stripos'))
11168  {
11169  return stripos($haystack, $needle, $offset);
11170  }
11171  else
11172  {
11173  if (is_string($needle))
11174  {
11175  $needle = strtolower($needle);
11176  }
11177  elseif (is_int($needle) || is_bool($needle) || is_double($needle))
11178  {
11179  $needle = strtolower(chr($needle));
11180  }
11181  else
11182  {
11183  trigger_error('needle is not a string or an integer', E_USER_WARNING);
11184  return false;
11185  }
11186 
11187  return strpos(strtolower($haystack), $needle, $offset);
11188  }
11189  }
11190 
11191  /**
11192  * Similar to parse_str()
11193  *
11194  * Returns an associative array of name/value pairs, where the value is an
11195  * array of values that have used the same name
11196  *
11197  * @static
11198  * @access string
11199  * @param string $str The input string.
11200  * @return array
11201  */
11202  function parse_str($str)
11203  {
11204  $return = array();
11205  $str = explode('&', $str);
11206 
11207  foreach ($str as $section)
11208  {
11209  if (strpos($section, '=') !== false)
11210  {
11211  list($name, $value) = explode('=', $section, 2);
11212  $return[urldecode($name)][] = urldecode($value);
11213  }
11214  else
11215  {
11216  $return[urldecode($section)][] = null;
11217  }
11218  }
11219 
11220  return $return;
11221  }
11222 
11223  /**
11224  * Detect XML encoding, as per XML 1.0 Appendix F.1
11225  *
11226  * @todo Add support for EBCDIC
11227  * @param string $data XML data
11228  * @return array Possible encodings
11229  */
11230  function xml_encoding($data)
11231  {
11232  // UTF-32 Big Endian BOM
11233  if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
11234  {
11235  $encoding[] = 'UTF-32BE';
11236  }
11237  // UTF-32 Little Endian BOM
11238  elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
11239  {
11240  $encoding[] = 'UTF-32LE';
11241  }
11242  // UTF-16 Big Endian BOM
11243  elseif (substr($data, 0, 2) === "\xFE\xFF")
11244  {
11245  $encoding[] = 'UTF-16BE';
11246  }
11247  // UTF-16 Little Endian BOM
11248  elseif (substr($data, 0, 2) === "\xFF\xFE")
11249  {
11250  $encoding[] = 'UTF-16LE';
11251  }
11252  // UTF-8 BOM
11253  elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
11254  {
11255  $encoding[] = 'UTF-8';
11256  }
11257  // UTF-32 Big Endian Without BOM
11258  elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C")
11259  {
11260  if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
11261  {
11262  $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
11263  if ($parser->parse())
11264  {
11265  $encoding[] = $parser->encoding;
11266  }
11267  }
11268  $encoding[] = 'UTF-32BE';
11269  }
11270  // UTF-32 Little Endian Without BOM
11271  elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00")
11272  {
11273  if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
11274  {
11275  $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
11276  if ($parser->parse())
11277  {
11278  $encoding[] = $parser->encoding;
11279  }
11280  }
11281  $encoding[] = 'UTF-32LE';
11282  }
11283  // UTF-16 Big Endian Without BOM
11284  elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
11285  {
11286  if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
11287  {
11288  $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
11289  if ($parser->parse())
11290  {
11291  $encoding[] = $parser->encoding;
11292  }
11293  }
11294  $encoding[] = 'UTF-16BE';
11295  }
11296  // UTF-16 Little Endian Without BOM
11297  elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
11298  {
11299  if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
11300  {
11301  $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
11302  if ($parser->parse())
11303  {
11304  $encoding[] = $parser->encoding;
11305  }
11306  }
11307  $encoding[] = 'UTF-16LE';
11308  }
11309  // US-ASCII (or superset)
11310  elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
11311  {
11312  if ($pos = strpos($data, "\x3F\x3E"))
11313  {
11314  $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
11315  if ($parser->parse())
11316  {
11317  $encoding[] = $parser->encoding;
11318  }
11319  }
11320  $encoding[] = 'UTF-8';
11321  }
11322  // Fallback to UTF-8
11323  else
11324  {
11325  $encoding[] = 'UTF-8';
11326  }
11327  return $encoding;
11328  }
11329 
11330  function output_javascript()
11331  {
11332  if (function_exists('ob_gzhandler'))
11333  {
11334  ob_start('ob_gzhandler');
11335  }
11336  header('Content-type: text/javascript; charset: UTF-8');
11337  header('Cache-Control: must-revalidate');
11338  header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
11339  ?>
11340 function embed_odeo(link) {
11341  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>');
11342 }
11343 
11344 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
11345  if (placeholder != '')
11346  {
11347  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>');
11348  }
11349  else {
11350  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>');
11351  }
11352 }
11353 
11354 function embed_flash(bgcolor, width, height, link, loop, type) {
11355  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>');
11356 }
11357 
11358 function embed_flv(width, height, link, placeholder, loop, player) {
11359  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>');
11360 }
11361 
11362 function embed_wmedia(width, height, link) {
11363  document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
11364 }
11365  <?php
11366  }
11367 }
11368 
11369 /**
11370  * Decode HTML Entities
11371  *
11372  * This implements HTML5 as of revision 967 (2007-06-28)
11373  *
11374  * @package SimplePie
11375  */
11377 {
11378  /**
11379  * Data to be parsed
11380  *
11381  * @access private
11382  * @var string
11383  */
11384  var $data = '';
11385 
11386  /**
11387  * Currently consumed bytes
11388  *
11389  * @access private
11390  * @var string
11391  */
11392  var $consumed = '';
11393 
11394  /**
11395  * Position of the current byte being parsed
11396  *
11397  * @access private
11398  * @var int
11399  */
11400  var $position = 0;
11401 
11402  /**
11403  * Create an instance of the class with the input data
11404  *
11405  * @access public
11406  * @param string $data Input data
11407  */
11409  {
11410  $this->data = $data;
11411  }
11412 
11413  /**
11414  * Parse the input data
11415  *
11416  * @access public
11417  * @return string Output data
11418  */
11419  function parse()
11420  {
11421  while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11422  {
11423  $this->consume();
11424  $this->entity();
11425  $this->consumed = '';
11426  }
11427  return $this->data;
11428  }
11429 
11430  /**
11431  * Consume the next byte
11432  *
11433  * @access private
11434  * @return mixed The next byte, or false, if there is no more data
11435  */
11436  function consume()
11437  {
11438  if (isset($this->data[$this->position]))
11439  {
11440  $this->consumed .= $this->data[$this->position];
11441  return $this->data[$this->position++];
11442  }
11443  else
11444  {
11445  return false;
11446  }
11447  }
11448 
11449  /**
11450  * Consume a range of characters
11451  *
11452  * @access private
11453  * @param string $chars Characters to consume
11454  * @return mixed A series of characters that match the range, or false
11455  */
11456  function consume_range($chars)
11457  {
11458  if ($len = strspn($this->data, $chars, $this->position))
11459  {
11460  $data = substr($this->data, $this->position, $len);
11461  $this->consumed .= $data;
11462  $this->position += $len;
11463  return $data;
11464  }
11465  else
11466  {
11467  return false;
11468  }
11469  }
11470 
11471  /**
11472  * Unconsume one byte
11473  *
11474  * @access private
11475  */
11476  function unconsume()
11477  {
11478  $this->consumed = substr($this->consumed, 0, -1);
11479  $this->position--;
11480  }
11481 
11482  /**
11483  * Decode an entity
11484  *
11485  * @access private
11486  */
11487  function entity()
11488  {
11489  switch ($this->consume())
11490  {
11491  case "\x09":
11492  case "\x0A":
11493  case "\x0B":
11494  case "\x0B":
11495  case "\x0C":
11496  case "\x20":
11497  case "\x3C":
11498  case "\x26":
11499  case false:
11500  break;
11501 
11502  case "\x23":
11503  switch ($this->consume())
11504  {
11505  case "\x78":
11506  case "\x58":
11507  $range = '0123456789ABCDEFabcdef';
11508  $hex = true;
11509  break;
11510 
11511  default:
11512  $range = '0123456789';
11513  $hex = false;
11514  $this->unconsume();
11515  break;
11516  }
11517 
11518  if ($codepoint = $this->consume_range($range))
11519  {
11520  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");
11521 
11522  if ($hex)
11523  {
11524  $codepoint = hexdec($codepoint);
11525  }
11526  else
11527  {
11528  $codepoint = intval($codepoint);
11529  }
11530 
11531  if (isset($windows_1252_specials[$codepoint]))
11532  {
11533  $replacement = $windows_1252_specials[$codepoint];
11534  }
11535  else
11536  {
11537  $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11538  }
11539 
11540  if (!in_array($this->consume(), array(';', false), true))
11541  {
11542  $this->unconsume();
11543  }
11544 
11545  $consumed_length = strlen($this->consumed);
11546  $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11547  $this->position += strlen($replacement) - $consumed_length;
11548  }
11549  break;
11550 
11551  default:
11552  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");
11553 
11554  for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11555  {
11556  $consumed = substr($this->consumed, 1);
11557  if (isset($entities[$consumed]))
11558  {
11559  $match = $consumed;
11560  }
11561  }
11562 
11563  if ($match !== null)
11564  {
11565  $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11566  $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11567  }
11568  break;
11569  }
11570  }
11571 }
11572 
11573 /**
11574  * IRI parser/serialiser
11575  *
11576  * @package SimplePie
11577  */
11579 {
11580  /**
11581  * Scheme
11582  *
11583  * @access private
11584  * @var string
11585  */
11586  var $scheme;
11587 
11588  /**
11589  * User Information
11590  *
11591  * @access private
11592  * @var string
11593  */
11595 
11596  /**
11597  * Host
11598  *
11599  * @access private
11600  * @var string
11601  */
11602  var $host;
11603 
11604  /**
11605  * Port
11606  *
11607  * @access private
11608  * @var string
11609  */
11610  var $port;
11611 
11612  /**
11613  * Path
11614  *
11615  * @access private
11616  * @var string
11617  */
11618  var $path;
11619 
11620  /**
11621  * Query
11622  *
11623  * @access private
11624  * @var string
11625  */
11626  var $query;
11627 
11628  /**
11629  * Fragment
11630  *
11631  * @access private
11632  * @var string
11633  */
11635 
11636  /**
11637  * Whether the object represents a valid IRI
11638  *
11639  * @access private
11640  * @var array
11641  */
11642  var $valid = array();
11643 
11644  /**
11645  * Return the entire IRI when you try and read the object as a string
11646  *
11647  * @access public
11648  * @return string
11649  */
11650  function __toString()
11651  {
11652  return $this->get_iri();
11653  }
11654 
11655  /**
11656  * Create a new IRI object, from a specified string
11657  *
11658  * @access public
11659  * @param string $iri
11660  * @return SimplePie_IRI
11661  */
11662  function SimplePie_IRI($iri)
11663  {
11664  $iri = (string) $iri;
11665  if ($iri !== '')
11666  {
11667  $parsed = $this->parse_iri($iri);
11668  $this->set_scheme($parsed['scheme']);
11669  $this->set_authority($parsed['authority']);
11670  $this->set_path($parsed['path']);
11671  $this->set_query($parsed['query']);
11672  $this->set_fragment($parsed['fragment']);
11673  }
11674  }
11675 
11676  /**
11677  * Create a new IRI object by resolving a relative IRI
11678  *
11679  * @static
11680  * @access public
11681  * @param SimplePie_IRI $base Base IRI
11682  * @param string $relative Relative IRI
11683  * @return SimplePie_IRI
11684  */
11685  function absolutize($base, $relative)
11686  {
11687  $relative = (string) $relative;
11688  if ($relative !== '')
11689  {
11690  $relative = new SimplePie_IRI($relative);
11691  if ($relative->get_scheme() !== null)
11692  {
11693  $target = $relative;
11694  }
11695  elseif ($base->get_iri() !== null)
11696  {
11697  if ($relative->get_authority() !== null)
11698  {
11699  $target = $relative;
11700  $target->set_scheme($base->get_scheme());
11701  }
11702  else
11703  {
11704  $target = new SimplePie_IRI('');
11705  $target->set_scheme($base->get_scheme());
11706  $target->set_userinfo($base->get_userinfo());
11707  $target->set_host($base->get_host());
11708  $target->set_port($base->get_port());
11709  if ($relative->get_path() !== null)
11710  {
11711  if (strpos($relative->get_path(), '/') === 0)
11712  {
11713  $target->set_path($relative->get_path());
11714  }
11715  elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)
11716  {
11717  $target->set_path('/' . $relative->get_path());
11718  }
11719  elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
11720  {
11721  $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());
11722  }
11723  else
11724  {
11725  $target->set_path($relative->get_path());
11726  }
11727  $target->set_query($relative->get_query());
11728  }
11729  else
11730  {
11731  $target->set_path($base->get_path());
11732  if ($relative->get_query() !== null)
11733  {
11734  $target->set_query($relative->get_query());
11735  }
11736  elseif ($base->get_query() !== null)
11737  {
11738  $target->set_query($base->get_query());
11739  }
11740  }
11741  }
11742  $target->set_fragment($relative->get_fragment());
11743  }
11744  else
11745  {
11746  // No base URL, just return the relative URL
11747  $target = $relative;
11748  }
11749  }
11750  else
11751  {
11752  $target = $base;
11753  }
11754  return $target;
11755  }
11756 
11757  /**
11758  * Parse an IRI into scheme/authority/path/query/fragment segments
11759  *
11760  * @access private
11761  * @param string $iri
11762  * @return array
11763  */
11764  function parse_iri($iri)
11765  {
11766  preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
11767  for ($i = count($match); $i <= 9; $i++)
11768  {
11769  $match[$i] = '';
11770  }
11771  return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
11772  }
11773 
11774  /**
11775  * Remove dot segments from a path
11776  *
11777  * @access private
11778  * @param string $input
11779  * @return string
11780  */
11781  function remove_dot_segments($input)
11782  {
11783  $output = '';
11784  while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
11785  {
11786  // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
11787  if (strpos($input, '../') === 0)
11788  {
11789  $input = substr($input, 3);
11790  }
11791  elseif (strpos($input, './') === 0)
11792  {
11793  $input = substr($input, 2);
11794  }
11795  // 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,
11796  elseif (strpos($input, '/./') === 0)
11797  {
11798  $input = substr_replace($input, '/', 0, 3);
11799  }
11800  elseif ($input === '/.')
11801  {
11802  $input = '/';
11803  }
11804  // 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,
11805  elseif (strpos($input, '/../') === 0)
11806  {
11807  $input = substr_replace($input, '/', 0, 4);
11808  $output = substr_replace($output, '', strrpos($output, '/'));
11809  }
11810  elseif ($input === '/..')
11811  {
11812  $input = '/';
11813  $output = substr_replace($output, '', strrpos($output, '/'));
11814  }
11815  // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
11816  elseif ($input === '.' || $input === '..')
11817  {
11818  $input = '';
11819  }
11820  // 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
11821  elseif (($pos = strpos($input, '/', 1)) !== false)
11822  {
11823  $output .= substr($input, 0, $pos);
11824  $input = substr_replace($input, '', 0, $pos);
11825  }
11826  else
11827  {
11828  $output .= $input;
11829  $input = '';
11830  }
11831  }
11832  return $output . $input;
11833  }
11834 
11835  /**
11836  * Replace invalid character with percent encoding
11837  *
11838  * @access private
11839  * @param string $string Input string
11840  * @param string $valid_chars Valid characters
11841  * @param int $case Normalise case
11842  * @return string
11843  */
11844  function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE)
11845  {
11846  // Normalise case
11847  if ($case & SIMPLEPIE_LOWERCASE)
11848  {
11849  $string = strtolower($string);
11850  }
11851  elseif ($case & SIMPLEPIE_UPPERCASE)
11852  {
11853  $string = strtoupper($string);
11854  }
11855 
11856  // Store position and string length (to avoid constantly recalculating this)
11857  $position = 0;
11858  $strlen = strlen($string);
11859 
11860  // Loop as long as we have invalid characters, advancing the position to the next invalid character
11861  while (($position += strspn($string, $valid_chars, $position)) < $strlen)
11862  {
11863  // If we have a % character
11864  if ($string[$position] === '%')
11865  {
11866  // If we have a pct-encoded section
11867  if ($position + 2 < $strlen && strspn($string, '0123456789ABCDEFabcdef', $position + 1, 2) === 2)
11868  {
11869  // Get the the represented character
11870  $chr = chr(hexdec(substr($string, $position + 1, 2)));
11871 
11872  // If the character is valid, replace the pct-encoded with the actual character while normalising case
11873  if (strpos($valid_chars, $chr) !== false)
11874  {
11875  if ($case & SIMPLEPIE_LOWERCASE)
11876  {
11877  $chr = strtolower($chr);
11878  }
11879  elseif ($case & SIMPLEPIE_UPPERCASE)
11880  {
11881  $chr = strtoupper($chr);
11882  }
11883  $string = substr_replace($string, $chr, $position, 3);
11884  $strlen -= 2;
11885  $position++;
11886  }
11887 
11888  // Otherwise just normalise the pct-encoded to uppercase
11889  else
11890  {
11891  $string = substr_replace($string, strtoupper(substr($string, $position + 1, 2)), $position + 1, 2);
11892  $position += 3;
11893  }
11894  }
11895  // If we don't have a pct-encoded section, just replace the % with its own esccaped form
11896  else
11897  {
11898  $string = substr_replace($string, '%25', $position, 1);
11899  $strlen += 2;
11900  $position += 3;
11901  }
11902  }
11903  // If we have an invalid character, change into its pct-encoded form
11904  else
11905  {
11906  $replacement = sprintf("%%%02X", ord($string[$position]));
11907  $string = str_replace($string[$position], $replacement, $string);
11908  $strlen = strlen($string);
11909  }
11910  }
11911  return $string;
11912  }
11913 
11914  /**
11915  * Check if the object represents a valid IRI
11916  *
11917  * @access public
11918  * @return bool
11919  */
11920  function is_valid()
11921  {
11922  return array_sum($this->valid) === count($this->valid);
11923  }
11924 
11925  /**
11926  * Set the scheme. Returns true on success, false on failure (if there are
11927  * any invalid characters).
11928  *
11929  * @access public
11930  * @param string $scheme
11931  * @return bool
11932  */
11933  function set_scheme($scheme)
11934  {
11935  if ($scheme === null || $scheme === '')
11936  {
11937  $this->scheme = null;
11938  }
11939  else
11940  {
11941  $len = strlen($scheme);
11942  switch (true)
11943  {
11944  case $len > 1:
11945  if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
11946  {
11947  $this->scheme = null;
11948  $this->valid[__FUNCTION__] = false;
11949  return false;
11950  }
11951 
11952  case $len > 0:
11953  if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
11954  {
11955  $this->scheme = null;
11956  $this->valid[__FUNCTION__] = false;
11957  return false;
11958  }
11959  }
11960  $this->scheme = strtolower($scheme);
11961  }
11962  $this->valid[__FUNCTION__] = true;
11963  return true;
11964  }
11965 
11966  /**
11967  * Set the authority. Returns true on success, false on failure (if there are
11968  * any invalid characters).
11969  *
11970  * @access public
11971  * @param string $authority
11972  * @return bool
11973  */
11974  function set_authority($authority)
11975  {
11976  if (($userinfo_end = strrpos($authority, '@')) !== false)
11977  {
11978  $userinfo = substr($authority, 0, $userinfo_end);
11979  $authority = substr($authority, $userinfo_end + 1);
11980  }
11981  else
11982  {
11983  $userinfo = null;
11984  }
11985 
11986  if (($port_start = strpos($authority, ':')) !== false)
11987  {
11988  $port = substr($authority, $port_start + 1);
11989  $authority = substr($authority, 0, $port_start);
11990  }
11991  else
11992  {
11993  $port = null;
11994  }
11995 
11996  return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
11997  }
11998 
11999  /**
12000  * Set the userinfo.
12001  *
12002  * @access public
12003  * @param string $userinfo
12004  * @return bool
12005  */
12006  function set_userinfo($userinfo)
12007  {
12008  if ($userinfo === null || $userinfo === '')
12009  {
12010  $this->userinfo = null;
12011  }
12012  else
12013  {
12014  $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
12015  }
12016  $this->valid[__FUNCTION__] = true;
12017  return true;
12018  }
12019 
12020  /**
12021  * Set the host. Returns true on success, false on failure (if there are
12022  * any invalid characters).
12023  *
12024  * @access public
12025  * @param string $host
12026  * @return bool
12027  */
12028  function set_host($host)
12029  {
12030  if ($host === null || $host === '')
12031  {
12032  $this->host = null;
12033  $this->valid[__FUNCTION__] = true;
12034  return true;
12035  }
12036  elseif ($host[0] === '[' && substr($host, -1) === ']')
12037  {
12038  if (Net_IPv6::checkIPv6(substr($host, 1, -1)))
12039  {
12040  $this->host = $host;
12041  $this->valid[__FUNCTION__] = true;
12042  return true;
12043  }
12044  else
12045  {
12046  $this->host = null;
12047  $this->valid[__FUNCTION__] = false;
12048  return false;
12049  }
12050  }
12051  else
12052  {
12053  $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);
12054  $this->valid[__FUNCTION__] = true;
12055  return true;
12056  }
12057  }
12058 
12059  /**
12060  * Set the port. Returns true on success, false on failure (if there are
12061  * any invalid characters).
12062  *
12063  * @access public
12064  * @param string $port
12065  * @return bool
12066  */
12067  function set_port($port)
12068  {
12069  if ($port === null || $port === '')
12070  {
12071  $this->port = null;
12072  $this->valid[__FUNCTION__] = true;
12073  return true;
12074  }
12075  elseif (strspn($port, '0123456789') === strlen($port))
12076  {
12077  $this->port = (int) $port;
12078  $this->valid[__FUNCTION__] = true;
12079  return true;
12080  }
12081  else
12082  {
12083  $this->port = null;
12084  $this->valid[__FUNCTION__] = false;
12085  return false;
12086  }
12087  }
12088 
12089  /**
12090  * Set the path.
12091  *
12092  * @access public
12093  * @param string $path
12094  * @return bool
12095  */
12096  function set_path($path)
12097  {
12098  if ($path === null || $path === '')
12099  {
12100  $this->path = null;
12101  $this->valid[__FUNCTION__] = true;
12102  return true;
12103  }
12104  elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)
12105  {
12106  $this->path = null;
12107  $this->valid[__FUNCTION__] = false;
12108  return false;
12109  }
12110  else
12111  {
12112  $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
12113  if ($this->scheme !== null)
12114  {
12115  $this->path = $this->remove_dot_segments($this->path);
12116  }
12117  $this->valid[__FUNCTION__] = true;
12118  return true;
12119  }
12120  }
12121 
12122  /**
12123  * Set the query.
12124  *
12125  * @access public
12126  * @param string $query
12127  * @return bool
12128  */
12129  function set_query($query)
12130  {
12131  if ($query === null || $query === '')
12132  {
12133  $this->query = null;
12134  }
12135  else
12136  {
12137  $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
12138  }
12139  $this->valid[__FUNCTION__] = true;
12140  return true;
12141  }
12142 
12143  /**
12144  * Set the fragment.
12145  *
12146  * @access public
12147  * @param string $fragment
12148  * @return bool
12149  */
12150  function set_fragment($fragment)
12151  {
12152  if ($fragment === null || $fragment === '')
12153  {
12154  $this->fragment = null;
12155  }
12156  else
12157  {
12158  $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
12159  }
12160  $this->valid[__FUNCTION__] = true;
12161  return true;
12162  }
12163 
12164  /**
12165  * Get the complete IRI
12166  *
12167  * @access public
12168  * @return string
12169  */
12170  function get_iri()
12171  {
12172  $iri = '';
12173  if ($this->scheme !== null)
12174  {
12175  $iri .= $this->scheme . ':';
12176  }
12177  if (($authority = $this->get_authority()) !== null)
12178  {
12179  $iri .= '//' . $authority;
12180  }
12181  if ($this->path !== null)
12182  {
12183  $iri .= $this->path;
12184  }
12185  if ($this->query !== null)
12186  {
12187  $iri .= '?' . $this->query;
12188  }
12189  if ($this->fragment !== null)
12190  {
12191  $iri .= '#' . $this->fragment;
12192  }
12193 
12194  if ($iri !== '')
12195  {
12196  return $iri;
12197  }
12198  else
12199  {
12200  return null;
12201  }
12202  }
12203 
12204  /**
12205  * Get the scheme
12206  *
12207  * @access public
12208  * @return string
12209  */
12210  function get_scheme()
12211  {
12212  return $this->scheme;
12213  }
12214 
12215  /**
12216  * Get the complete authority
12217  *
12218  * @access public
12219  * @return string
12220  */
12221  function get_authority()
12222  {
12223  $authority = '';
12224  if ($this->userinfo !== null)
12225  {
12226  $authority .= $this->userinfo . '@';
12227  }
12228  if ($this->host !== null)
12229  {
12230  $authority .= $this->host;
12231  }
12232  if ($this->port !== null)
12233  {
12234  $authority .= ':' . $this->port;
12235  }
12236 
12237  if ($authority !== '')
12238  {
12239  return $authority;
12240  }
12241  else
12242  {
12243  return null;
12244  }
12245  }
12246 
12247  /**
12248  * Get the user information
12249  *
12250  * @access public
12251  * @return string
12252  */
12253  function get_userinfo()
12254  {
12255  return $this->userinfo;
12256  }
12257 
12258  /**
12259  * Get the host
12260  *
12261  * @access public
12262  * @return string
12263  */
12264  function get_host()
12265  {
12266  return $this->host;
12267  }
12268 
12269  /**
12270  * Get the port
12271  *
12272  * @access public
12273  * @return string
12274  */
12275  function get_port()
12276  {
12277  return $this->port;
12278  }
12279 
12280  /**
12281  * Get the path
12282  *
12283  * @access public
12284  * @return string
12285  */
12286  function get_path()
12287  {
12288  return $this->path;
12289  }
12290 
12291  /**
12292  * Get the query
12293  *
12294  * @access public
12295  * @return string
12296  */
12297  function get_query()
12298  {
12299  return $this->query;
12300  }
12301 
12302  /**
12303  * Get the fragment
12304  *
12305  * @access public
12306  * @return string
12307  */
12308  function get_fragment()
12309  {
12310  return $this->fragment;
12311  }
12312 }
12313 
12314 /**
12315  * Class to validate and to work with IPv6 addresses.
12316  *
12317  * @package SimplePie
12318  * @copyright 2003-2005 The PHP Group
12319  * @license http://www.opensource.org/licenses/bsd-license.php
12320  * @link http://pear.php.net/package/Net_IPv6
12321  * @author Alexander Merz <alexander.merz@web.de>
12322  * @author elfrink at introweb dot nl
12323  * @author Josh Peck <jmp at joshpeck dot org>
12324  * @author Geoffrey Sneddon <geoffers@gmail.com>
12325  */
12327 {
12328  /**
12329  * Removes a possible existing netmask specification of an IP address.
12330  *
12331  * @param string $ip the (compressed) IP as Hex representation
12332  * @return string the IP the without netmask
12333  * @since 1.1.0
12334  * @access public
12335  * @static
12336  */
12337  function removeNetmaskSpec($ip)
12338  {
12339  if (strpos($ip, '/') !== false)
12340  {
12341  list($addr, $nm) = explode('/', $ip);
12342  }
12343  else
12344  {
12345  $addr = $ip;
12346  }
12347  return $addr;
12348  }
12349 
12350  /**
12351  * Uncompresses an IPv6 address
12352  *
12353  * RFC 2373 allows you to compress zeros in an address to '::'. This
12354  * function expects an valid IPv6 address and expands the '::' to
12355  * the required zeros.
12356  *
12357  * Example: FF01::101 -> FF01:0:0:0:0:0:0:101
12358  * ::1 -> 0:0:0:0:0:0:0:1
12359  *
12360  * @access public
12361  * @static
12362  * @param string $ip a valid IPv6-address (hex format)
12363  * @return string the uncompressed IPv6-address (hex format)
12364  */
12365  function Uncompress($ip)
12366  {
12368  $c1 = -1;
12369  $c2 = -1;
12370  if (strpos($ip, '::') !== false)
12371  {
12372  list($ip1, $ip2) = explode('::', $ip);
12373  if ($ip1 === '')
12374  {
12375  $c1 = -1;
12376  }
12377  else
12378  {
12379  $pos = 0;
12380  if (($pos = substr_count($ip1, ':')) > 0)
12381  {
12382  $c1 = $pos;
12383  }
12384  else
12385  {
12386  $c1 = 0;
12387  }
12388  }
12389  if ($ip2 === '')
12390  {
12391  $c2 = -1;
12392  }
12393  else
12394  {
12395  $pos = 0;
12396  if (($pos = substr_count($ip2, ':')) > 0)
12397  {
12398  $c2 = $pos;
12399  }
12400  else
12401  {
12402  $c2 = 0;
12403  }
12404  }
12405  if (strstr($ip2, '.'))
12406  {
12407  $c2++;
12408  }
12409  // ::
12410  if ($c1 === -1 && $c2 === -1)
12411  {
12412  $uip = '0:0:0:0:0:0:0:0';
12413  }
12414  // ::xxx
12415  else if ($c1 === -1)
12416  {
12417  $fill = str_repeat('0:', 7 - $c2);
12418  $uip = str_replace('::', $fill, $uip);
12419  }
12420  // xxx::
12421  else if ($c2 === -1)
12422  {
12423  $fill = str_repeat(':0', 7 - $c1);
12424  $uip = str_replace('::', $fill, $uip);
12425  }
12426  // xxx::xxx
12427  else
12428  {
12429  $fill = str_repeat(':0:', 6 - $c2 - $c1);
12430  $uip = str_replace('::', $fill, $uip);
12431  $uip = str_replace('::', ':', $uip);
12432  }
12433  }
12434  return $uip;
12435  }
12436 
12437  /**
12438  * Splits an IPv6 address into the IPv6 and a possible IPv4 part
12439  *
12440  * RFC 2373 allows you to note the last two parts of an IPv6 address as
12441  * an IPv4 compatible address
12442  *
12443  * Example: 0:0:0:0:0:0:13.1.68.3
12444  * 0:0:0:0:0:FFFF:129.144.52.38
12445  *
12446  * @access public
12447  * @static
12448  * @param string $ip a valid IPv6-address (hex format)
12449  * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)
12450  */
12451  function SplitV64($ip)
12452  {
12453  $ip = SimplePie_Net_IPv6::Uncompress($ip);
12454  if (strstr($ip, '.'))
12455  {
12456  $pos = strrpos($ip, ':');
12457  $ip[$pos] = '_';
12458  $ipPart = explode('_', $ip);
12459  return $ipPart;
12460  }
12461  else
12462  {
12463  return array($ip, '');
12464  }
12465  }
12466 
12467  /**
12468  * Checks an IPv6 address
12469  *
12470  * Checks if the given IP is IPv6-compatible
12471  *
12472  * @access public
12473  * @static
12474  * @param string $ip a valid IPv6-address
12475  * @return bool true if $ip is an IPv6 address
12476  */
12477  function checkIPv6($ip)
12478  {
12479  $ipPart = SimplePie_Net_IPv6::SplitV64($ip);
12480  $count = 0;
12481  if (!empty($ipPart[0]))
12482  {
12483  $ipv6 = explode(':', $ipPart[0]);
12484  for ($i = 0; $i < count($ipv6); $i++)
12485  {
12486  $dec = hexdec($ipv6[$i]);
12487  $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));
12488  if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))
12489  {
12490  $count++;
12491  }
12492  }
12493  if ($count === 8)
12494  {
12495  return true;
12496  }
12497  elseif ($count === 6 && !empty($ipPart[1]))
12498  {
12499  $ipv4 = explode('.', $ipPart[1]);
12500  $count = 0;
12501  foreach ($ipv4 as $ipv4_part)
12502  {
12503  if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))
12504  {
12505  $count++;
12506  }
12507  }
12508  if ($count === 4)
12509  {
12510  return true;
12511  }
12512  }
12513  else
12514  {
12515  return false;
12516  }
12517 
12518  }
12519  else
12520  {
12521  return false;
12522  }
12523  }
12524 }
12525 
12526 /**
12527  * Date Parser
12528  *
12529  * @package SimplePie
12530  */
12532 {
12533  /**
12534  * Input data
12535  *
12536  * @access protected
12537  * @var string
12538  */
12539  var $date;
12540 
12541  /**
12542  * List of days, calendar day name => ordinal day number in the week
12543  *
12544  * @access protected
12545  * @var array
12546  */
12547  var $day = array(
12548  // English
12549  'mon' => 1,
12550  'monday' => 1,
12551  'tue' => 2,
12552  'tuesday' => 2,
12553  'wed' => 3,
12554  'wednesday' => 3,
12555  'thu' => 4,
12556  'thursday' => 4,
12557  'fri' => 5,
12558  'friday' => 5,
12559  'sat' => 6,
12560  'saturday' => 6,
12561  'sun' => 7,
12562  'sunday' => 7,
12563  // Dutch
12564  'maandag' => 1,
12565  'dinsdag' => 2,
12566  'woensdag' => 3,
12567  'donderdag' => 4,
12568  'vrijdag' => 5,
12569  'zaterdag' => 6,
12570  'zondag' => 7,
12571  // French
12572  'lundi' => 1,
12573  'mardi' => 2,
12574  'mercredi' => 3,
12575  'jeudi' => 4,
12576  'vendredi' => 5,
12577  'samedi' => 6,
12578  'dimanche' => 7,
12579  // German
12580  'montag' => 1,
12581  'dienstag' => 2,
12582  'mittwoch' => 3,
12583  'donnerstag' => 4,
12584  'freitag' => 5,
12585  'samstag' => 6,
12586  'sonnabend' => 6,
12587  'sonntag' => 7,
12588  // Italian
12589  'lunedì' => 1,
12590  'martedì' => 2,
12591  'mercoledì' => 3,
12592  'giovedì' => 4,
12593  'venerdì' => 5,
12594  'sabato' => 6,
12595  'domenica' => 7,
12596  // Spanish
12597  'lunes' => 1,
12598  'martes' => 2,
12599  'miércoles' => 3,
12600  'jueves' => 4,
12601  'viernes' => 5,
12602  'sábado' => 6,
12603  'domingo' => 7,
12604  // Finnish
12605  'maanantai' => 1,
12606  'tiistai' => 2,
12607  'keskiviikko' => 3,
12608  'torstai' => 4,
12609  'perjantai' => 5,
12610  'lauantai' => 6,
12611  'sunnuntai' => 7,
12612  // Hungarian
12613  'hétfő' => 1,
12614  'kedd' => 2,
12615  'szerda' => 3,
12616  'csütörtok' => 4,
12617  'péntek' => 5,
12618  'szombat' => 6,
12619  'vasárnap' => 7,
12620  // Greek
12621  'Δευ' => 1,
12622  'Τρι' => 2,
12623  'Τετ' => 3,
12624  'Πεμ' => 4,
12625  'Παρ' => 5,
12626  'Σαβ' => 6,
12627  'Κυρ' => 7,
12628  );
12629 
12630  /**
12631  * List of months, calendar month name => calendar month number
12632  *
12633  * @access protected
12634  * @var array
12635  */
12636  var $month = array(
12637  // English
12638  'jan' => 1,
12639  'january' => 1,
12640  'feb' => 2,
12641  'february' => 2,
12642  'mar' => 3,
12643  'march' => 3,
12644  'apr' => 4,
12645  'april' => 4,
12646  'may' => 5,
12647  // No long form of May
12648  'jun' => 6,
12649  'june' => 6,
12650  'jul' => 7,
12651  'july' => 7,
12652  'aug' => 8,
12653  'august' => 8,
12654  'sep' => 9,
12655  'september' => 8,
12656  'oct' => 10,
12657  'october' => 10,
12658  'nov' => 11,
12659  'november' => 11,
12660  'dec' => 12,
12661  'december' => 12,
12662  // Dutch
12663  'januari' => 1,
12664  'februari' => 2,
12665  'maart' => 3,
12666  'april' => 4,
12667  'mei' => 5,
12668  'juni' => 6,
12669  'juli' => 7,
12670  'augustus' => 8,
12671  'september' => 9,
12672  'oktober' => 10,
12673  'november' => 11,
12674  'december' => 12,
12675  // French
12676  'janvier' => 1,
12677  'février' => 2,
12678  'mars' => 3,
12679  'avril' => 4,
12680  'mai' => 5,
12681  'juin' => 6,
12682  'juillet' => 7,
12683  'août' => 8,
12684  'septembre' => 9,
12685  'octobre' => 10,
12686  'novembre' => 11,
12687  'décembre' => 12,
12688  // German
12689  'januar' => 1,
12690  'februar' => 2,
12691  'märz' => 3,
12692  'april' => 4,
12693  'mai' => 5,
12694  'juni' => 6,
12695  'juli' => 7,
12696  'august' => 8,
12697  'september' => 9,
12698  'oktober' => 10,
12699  'november' => 11,
12700  'dezember' => 12,
12701  // Italian
12702  'gennaio' => 1,
12703  'febbraio' => 2,
12704  'marzo' => 3,
12705  'aprile' => 4,
12706  'maggio' => 5,
12707  'giugno' => 6,
12708  'luglio' => 7,
12709  'agosto' => 8,
12710  'settembre' => 9,
12711  'ottobre' => 10,
12712  'novembre' => 11,
12713  'dicembre' => 12,
12714  // Spanish
12715  'enero' => 1,
12716  'febrero' => 2,
12717  'marzo' => 3,
12718  'abril' => 4,
12719  'mayo' => 5,
12720  'junio' => 6,
12721  'julio' => 7,
12722  'agosto' => 8,
12723  'septiembre' => 9,
12724  'setiembre' => 9,
12725  'octubre' => 10,
12726  'noviembre' => 11,
12727  'diciembre' => 12,
12728  // Finnish
12729  'tammikuu' => 1,
12730  'helmikuu' => 2,
12731  'maaliskuu' => 3,
12732  'huhtikuu' => 4,
12733  'toukokuu' => 5,
12734  'kesäkuu' => 6,
12735  'heinäkuu' => 7,
12736  'elokuu' => 8,
12737  'suuskuu' => 9,
12738  'lokakuu' => 10,
12739  'marras' => 11,
12740  'joulukuu' => 12,
12741  // Hungarian
12742  'január' => 1,
12743  'február' => 2,
12744  'március' => 3,
12745  'április' => 4,
12746  'május' => 5,
12747  'június' => 6,
12748  'július' => 7,
12749  'augusztus' => 8,
12750  'szeptember' => 9,
12751  'október' => 10,
12752  'november' => 11,
12753  'december' => 12,
12754  // Greek
12755  'Ιαν' => 1,
12756  'Φεβ' => 2,
12757  'Μάώ' => 3,
12758  'Μαώ' => 3,
12759  'Απρ' => 4,
12760  'Μάι' => 5,
12761  'Μαϊ' => 5,
12762  'Μαι' => 5,
12763  'Ιούν' => 6,
12764  'Ιον' => 6,
12765  'Ιούλ' => 7,
12766  'Ιολ' => 7,
12767  'Αύγ' => 8,
12768  'Αυγ' => 8,
12769  'Σεπ' => 9,
12770  'Οκτ' => 10,
12771  'Νοέ' => 11,
12772  'Δεκ' => 12,
12773  );
12774 
12775  /**
12776  * List of timezones, abbreviation => offset from UTC
12777  *
12778  * @access protected
12779  * @var array
12780  */
12781  var $timezone = array(
12782  'ACDT' => 37800,
12783  'ACIT' => 28800,
12784  'ACST' => 34200,
12785  'ACT' => -18000,
12786  'ACWDT' => 35100,
12787  'ACWST' => 31500,
12788  'AEDT' => 39600,
12789  'AEST' => 36000,
12790  'AFT' => 16200,
12791  'AKDT' => -28800,
12792  'AKST' => -32400,
12793  'AMDT' => 18000,
12794  'AMT' => -14400,
12795  'ANAST' => 46800,
12796  'ANAT' => 43200,
12797  'ART' => -10800,
12798  'AZOST' => -3600,
12799  'AZST' => 18000,
12800  'AZT' => 14400,
12801  'BIOT' => 21600,
12802  'BIT' => -43200,
12803  'BOT' => -14400,
12804  'BRST' => -7200,
12805  'BRT' => -10800,
12806  'BST' => 3600,
12807  'BTT' => 21600,
12808  'CAST' => 18000,
12809  'CAT' => 7200,
12810  'CCT' => 23400,
12811  'CDT' => -18000,
12812  'CEDT' => 7200,
12813  'CET' => 3600,
12814  'CGST' => -7200,
12815  'CGT' => -10800,
12816  'CHADT' => 49500,
12817  'CHAST' => 45900,
12818  'CIST' => -28800,
12819  'CKT' => -36000,
12820  'CLDT' => -10800,
12821  'CLST' => -14400,
12822  'COT' => -18000,
12823  'CST' => -21600,
12824  'CVT' => -3600,
12825  'CXT' => 25200,
12826  'DAVT' => 25200,
12827  'DTAT' => 36000,
12828  'EADT' => -18000,
12829  'EAST' => -21600,
12830  'EAT' => 10800,
12831  'ECT' => -18000,
12832  'EDT' => -14400,
12833  'EEST' => 10800,
12834  'EET' => 7200,
12835  'EGT' => -3600,
12836  'EKST' => 21600,
12837  'EST' => -18000,
12838  'FJT' => 43200,
12839  'FKDT' => -10800,
12840  'FKST' => -14400,
12841  'FNT' => -7200,
12842  'GALT' => -21600,
12843  'GEDT' => 14400,
12844  'GEST' => 10800,
12845  'GFT' => -10800,
12846  'GILT' => 43200,
12847  'GIT' => -32400,
12848  'GST' => 14400,
12849  'GST' => -7200,
12850  'GYT' => -14400,
12851  'HAA' => -10800,
12852  'HAC' => -18000,
12853  'HADT' => -32400,
12854  'HAE' => -14400,
12855  'HAP' => -25200,
12856  'HAR' => -21600,
12857  'HAST' => -36000,
12858  'HAT' => -9000,
12859  'HAY' => -28800,
12860  'HKST' => 28800,
12861  'HMT' => 18000,
12862  'HNA' => -14400,
12863  'HNC' => -21600,
12864  'HNE' => -18000,
12865  'HNP' => -28800,
12866  'HNR' => -25200,
12867  'HNT' => -12600,
12868  'HNY' => -32400,
12869  'IRDT' => 16200,
12870  'IRKST' => 32400,
12871  'IRKT' => 28800,
12872  'IRST' => 12600,
12873  'JFDT' => -10800,
12874  'JFST' => -14400,
12875  'JST' => 32400,
12876  'KGST' => 21600,
12877  'KGT' => 18000,
12878  'KOST' => 39600,
12879  'KOVST' => 28800,
12880  'KOVT' => 25200,
12881  'KRAST' => 28800,
12882  'KRAT' => 25200,
12883  'KST' => 32400,
12884  'LHDT' => 39600,
12885  'LHST' => 37800,
12886  'LINT' => 50400,
12887  'LKT' => 21600,
12888  'MAGST' => 43200,
12889  'MAGT' => 39600,
12890  'MAWT' => 21600,
12891  'MDT' => -21600,
12892  'MESZ' => 7200,
12893  'MEZ' => 3600,
12894  'MHT' => 43200,
12895  'MIT' => -34200,
12896  'MNST' => 32400,
12897  'MSDT' => 14400,
12898  'MSST' => 10800,
12899  'MST' => -25200,
12900  'MUT' => 14400,
12901  'MVT' => 18000,
12902  'MYT' => 28800,
12903  'NCT' => 39600,
12904  'NDT' => -9000,
12905  'NFT' => 41400,
12906  'NMIT' => 36000,
12907  'NOVST' => 25200,
12908  'NOVT' => 21600,
12909  'NPT' => 20700,
12910  'NRT' => 43200,
12911  'NST' => -12600,
12912  'NUT' => -39600,
12913  'NZDT' => 46800,
12914  'NZST' => 43200,
12915  'OMSST' => 25200,
12916  'OMST' => 21600,
12917  'PDT' => -25200,
12918  'PET' => -18000,
12919  'PETST' => 46800,
12920  'PETT' => 43200,
12921  'PGT' => 36000,
12922  'PHOT' => 46800,
12923  'PHT' => 28800,
12924  'PKT' => 18000,
12925  'PMDT' => -7200,
12926  'PMST' => -10800,
12927  'PONT' => 39600,
12928  'PST' => -28800,
12929  'PWT' => 32400,
12930  'PYST' => -10800,
12931  'PYT' => -14400,
12932  'RET' => 14400,
12933  'ROTT' => -10800,
12934  'SAMST' => 18000,
12935  'SAMT' => 14400,
12936  'SAST' => 7200,
12937  'SBT' => 39600,
12938  'SCDT' => 46800,
12939  'SCST' => 43200,
12940  'SCT' => 14400,
12941  'SEST' => 3600,
12942  'SGT' => 28800,
12943  'SIT' => 28800,
12944  'SRT' => -10800,
12945  'SST' => -39600,
12946  'SYST' => 10800,
12947  'SYT' => 7200,
12948  'TFT' => 18000,
12949  'THAT' => -36000,
12950  'TJT' => 18000,
12951  'TKT' => -36000,
12952  'TMT' => 18000,
12953  'TOT' => 46800,
12954  'TPT' => 32400,
12955  'TRUT' => 36000,
12956  'TVT' => 43200,
12957  'TWT' => 28800,
12958  'UYST' => -7200,
12959  'UYT' => -10800,
12960  'UZT' => 18000,
12961  'VET' => -14400,
12962  'VLAST' => 39600,
12963  'VLAT' => 36000,
12964  'VOST' => 21600,
12965  'VUT' => 39600,
12966  'WAST' => 7200,
12967  'WAT' => 3600,
12968  'WDT' => 32400,
12969  'WEST' => 3600,
12970  'WFT' => 43200,
12971  'WIB' => 25200,
12972  'WIT' => 32400,
12973  'WITA' => 28800,
12974  'WKST' => 18000,
12975  'WST' => 28800,
12976  'YAKST' => 36000,
12977  'YAKT' => 32400,
12978  'YAPT' => 36000,
12979  'YEKST' => 21600,
12980  'YEKT' => 18000,
12981  );
12982 
12983  /**
12984  * Cached PCRE for SimplePie_Parse_Date::$day
12985  *
12986  * @access protected
12987  * @var string
12988  */
12990 
12991  /**
12992  * Cached PCRE for SimplePie_Parse_Date::$month
12993  *
12994  * @access protected
12995  * @var string
12996  */
12998 
12999  /**
13000  * Array of user-added callback methods
13001  *
13002  * @access private
13003  * @var array
13004  */
13005  var $built_in = array();
13006 
13007  /**
13008  * Array of user-added callback methods
13009  *
13010  * @access private
13011  * @var array
13012  */
13013  var $user = array();
13014 
13015  /**
13016  * Create new SimplePie_Parse_Date object, and set self::day_pcre,
13017  * self::month_pcre, and self::built_in
13018  *
13019  * @access private
13020  */
13022  {
13023  $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
13024  $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
13025 
13026  static $cache;
13027  if (!isset($cache[get_class($this)]))
13028  {
13029  $all_methods = get_class_methods($this);
13030 
13031  foreach ($all_methods as $method)
13032  {
13033  if (strtolower(substr($method, 0, 5)) === 'date_')
13034  {
13035  $cache[get_class($this)][] = $method;
13036  }
13037  }
13038  }
13039 
13040  foreach ($cache[get_class($this)] as $method)
13041  {
13042  $this->built_in[] = $method;
13043  }
13044  }
13045 
13046  /**
13047  * Get the object
13048  *
13049  * @access public
13050  */
13051  function get()
13052  {
13053  static $object;
13054  if (!$object)
13055  {
13056  $object = new SimplePie_Parse_Date;
13057  }
13058  return $object;
13059  }
13060 
13061  /**
13062  * Parse a date
13063  *
13064  * @final
13065  * @access public
13066  * @param string $date Date to parse
13067  * @return int Timestamp corresponding to date string, or false on failure
13068  */
13069  function parse($date)
13070  {
13071  foreach ($this->user as $method)
13072  {
13073  if (($returned = call_user_func($method, $date)) !== false)
13074  {
13075  return $returned;
13076  }
13077  }
13078 
13079  foreach ($this->built_in as $method)
13080  {
13081  if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
13082  {
13083  return $returned;
13084  }
13085  }
13086 
13087  return false;
13088  }
13089 
13090  /**
13091  * Add a callback method to parse a date
13092  *
13093  * @final
13094  * @access public
13095  * @param callback $callback
13096  */
13097  function add_callback($callback)
13098  {
13099  if (is_callable($callback))
13100  {
13101  $this->user[] = $callback;
13102  }
13103  else
13104  {
13105  trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
13106  }
13107  }
13108 
13109  /**
13110  * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
13111  * well as allowing any of upper or lower case "T", horizontal tabs, or
13112  * spaces to be used as the time seperator (including more than one))
13113  *
13114  * @access protected
13115  * @return int Timestamp
13116  */
13117  function date_w3cdtf($date)
13118  {
13119  static $pcre;
13120  if (!$pcre)
13121  {
13122  $year = '([0-9]{4})';
13123  $month = $day = $hour = $minute = $second = '([0-9]{2})';
13124  $decimal = '([0-9]*)';
13125  $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
13126  $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
13127  }
13128  if (preg_match($pcre, $date, $match))
13129  {
13130  /*
13131  Capturing subpatterns:
13132  1: Year
13133  2: Month
13134  3: Day
13135  4: Hour
13136  5: Minute
13137  6: Second
13138  7: Decimal fraction of a second
13139  8: Zulu
13140  9: Timezone ±
13141  10: Timezone hours
13142  11: Timezone minutes
13143  */
13144 
13145  // Fill in empty matches
13146  for ($i = count($match); $i <= 3; $i++)
13147  {
13148  $match[$i] = '1';
13149  }
13150 
13151  for ($i = count($match); $i <= 7; $i++)
13152  {
13153  $match[$i] = '0';
13154  }
13155 
13156  // Numeric timezone
13157  if (isset($match[9]) && $match[9] !== '')
13158  {
13159  $timezone = $match[10] * 3600;
13160  $timezone += $match[11] * 60;
13161  if ($match[9] === '-')
13162  {
13163  $timezone = 0 - $timezone;
13164  }
13165  }
13166  else
13167  {
13168  $timezone = 0;
13169  }
13170 
13171  // Convert the number of seconds to an integer, taking decimals into account
13172  $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
13173 
13174  return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
13175  }
13176  else
13177  {
13178  return false;
13179  }
13180  }
13181 
13182  /**
13183  * Remove RFC822 comments
13184  *
13185  * @access protected
13186  * @param string $data Data to strip comments from
13187  * @return string Comment stripped string
13188  */
13189  function remove_rfc2822_comments($string)
13190  {
13191  $string = (string) $string;
13192  $position = 0;
13193  $length = strlen($string);
13194  $depth = 0;
13195 
13196  $output = '';
13197 
13198  while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
13199  {
13200  $output .= substr($string, $position, $pos - $position);
13201  $position = $pos + 1;
13202  if ($string[$pos - 1] !== '\\')
13203  {
13204  $depth++;
13205  while ($depth && $position < $length)
13206  {
13207  $position += strcspn($string, '()', $position);
13208  if ($string[$position - 1] === '\\')
13209  {
13210  $position++;
13211  continue;
13212  }
13213  elseif (isset($string[$position]))
13214  {
13215  switch ($string[$position])
13216  {
13217  case '(':
13218  $depth++;
13219  break;
13220 
13221  case ')':
13222  $depth--;
13223  break;
13224  }
13225  $position++;
13226  }
13227  else
13228  {
13229  break;
13230  }
13231  }
13232  }
13233  else
13234  {
13235  $output .= '(';
13236  }
13237  }
13238  $output .= substr($string, $position);
13239 
13240  return $output;
13241  }
13242 
13243  /**
13244  * Parse RFC2822's date format
13245  *
13246  * @access protected
13247  * @return int Timestamp
13248  */
13249  function date_rfc2822($date)
13250  {
13251  static $pcre;
13252  if (!$pcre)
13253  {
13254  $wsp = '[\x09\x20]';
13255  $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
13256  $optional_fws = $fws . '?';
13257  $day_name = $this->day_pcre;
13258  $month = $this->month_pcre;
13259  $day = '([0-9]{1,2})';
13260  $hour = $minute = $second = '([0-9]{2})';
13261  $year = '([0-9]{2,4})';
13262  $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
13263  $character_zone = '([A-Z]{1,5})';
13264  $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
13265  $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
13266  }
13267  if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
13268  {
13269  /*
13270  Capturing subpatterns:
13271  1: Day name
13272  2: Day
13273  3: Month
13274  4: Year
13275  5: Hour
13276  6: Minute
13277  7: Second
13278  8: Timezone ±
13279  9: Timezone hours
13280  10: Timezone minutes
13281  11: Alphabetic timezone
13282  */
13283 
13284  // Find the month number
13285  $month = $this->month[strtolower($match[3])];
13286 
13287  // Numeric timezone
13288  if ($match[8] !== '')
13289  {
13290  $timezone = $match[9] * 3600;
13291  $timezone += $match[10] * 60;
13292  if ($match[8] === '-')
13293  {
13294  $timezone = 0 - $timezone;
13295  }
13296  }
13297  // Character timezone
13298  elseif (isset($this->timezone[strtoupper($match[11])]))
13299  {
13300  $timezone = $this->timezone[strtoupper($match[11])];
13301  }
13302  // Assume everything else to be -0000
13303  else
13304  {
13305  $timezone = 0;
13306  }
13307 
13308  // Deal with 2/3 digit years
13309  if ($match[4] < 50)
13310  {
13311  $match[4] += 2000;
13312  }
13313  elseif ($match[4] < 1000)
13314  {
13315  $match[4] += 1900;
13316  }
13317 
13318  // Second is optional, if it is empty set it to zero
13319  if ($match[7] !== '')
13320  {
13321  $second = $match[7];
13322  }
13323  else
13324  {
13325  $second = 0;
13326  }
13327 
13328  return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
13329  }
13330  else
13331  {
13332  return false;
13333  }
13334  }
13335 
13336  /**
13337  * Parse RFC850's date format
13338  *
13339  * @access protected
13340  * @return int Timestamp
13341  */
13342  function date_rfc850($date)
13343  {
13344  static $pcre;
13345  if (!$pcre)
13346  {
13347  $space = '[\x09\x20]+';
13348  $day_name = $this->day_pcre;
13349  $month = $this->month_pcre;
13350  $day = '([0-9]{1,2})';
13351  $year = $hour = $minute = $second = '([0-9]{2})';
13352  $zone = '([A-Z]{1,5})';
13353  $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
13354  }
13355  if (preg_match($pcre, $date, $match))
13356  {
13357  /*
13358  Capturing subpatterns:
13359  1: Day name
13360  2: Day
13361  3: Month
13362  4: Year
13363  5: Hour
13364  6: Minute
13365  7: Second
13366  8: Timezone
13367  */
13368 
13369  // Month
13370  $month = $this->month[strtolower($match[3])];
13371 
13372  // Character timezone
13373  if (isset($this->timezone[strtoupper($match[8])]))
13374  {
13375  $timezone = $this->timezone[strtoupper($match[8])];
13376  }
13377  // Assume everything else to be -0000
13378  else
13379  {
13380  $timezone = 0;
13381  }
13382 
13383  // Deal with 2 digit year
13384  if ($match[4] < 50)
13385  {
13386  $match[4] += 2000;
13387  }
13388  else
13389  {
13390  $match[4] += 1900;
13391  }
13392 
13393  return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
13394  }
13395  else
13396  {
13397  return false;
13398  }
13399  }
13400 
13401  /**
13402  * Parse C99's asctime()'s date format
13403  *
13404  * @access protected
13405  * @return int Timestamp
13406  */
13407  function date_asctime($date)
13408  {
13409  static $pcre;
13410  if (!$pcre)
13411  {
13412  $space = '[\x09\x20]+';
13413  $wday_name = $this->day_pcre;
13414  $mon_name = $this->month_pcre;
13415  $day = '([0-9]{1,2})';
13416  $hour = $sec = $min = '([0-9]{2})';
13417  $year = '([0-9]{4})';
13418  $terminator = '\x0A?\x00?';
13419  $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
13420  }
13421  if (preg_match($pcre, $date, $match))
13422  {
13423  /*
13424  Capturing subpatterns:
13425  1: Day name
13426  2: Month
13427  3: Day
13428  4: Hour
13429  5: Minute
13430  6: Second
13431  7: Year
13432  */
13433 
13434  $month = $this->month[strtolower($match[2])];
13435  return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
13436  }
13437  else
13438  {
13439  return false;
13440  }
13441  }
13442 
13443  /**
13444  * Parse dates using strtotime()
13445  *
13446  * @access protected
13447  * @return int Timestamp
13448  */
13449  function date_strtotime($date)
13450  {
13451  $strtotime = strtotime($date);
13452  if ($strtotime === -1 || $strtotime === false)
13453  {
13454  return false;
13455  }
13456  else
13457  {
13458  return $strtotime;
13459  }
13460  }
13461 }
13462 
13463 /**
13464  * Content-type sniffing
13465  *
13466  * @package SimplePie
13467  */
13469 {
13470  /**
13471  * File object
13472  *
13473  * @var SimplePie_File
13474  * @access private
13475  */
13476  var $file;
13477 
13478  /**
13479  * Create an instance of the class with the input file
13480  *
13481  * @access public
13482  * @param SimplePie_Content_Type_Sniffer $file Input file
13483  */
13485  {
13486  $this->file = $file;
13487  }
13488 
13489  /**
13490  * Get the Content-Type of the specified file
13491  *
13492  * @access public
13493  * @return string Actual Content-Type
13494  */
13495  function get_type()
13496  {
13497  if (isset($this->file->headers['content-type']))
13498  {
13499  if (!isset($this->file->headers['content-encoding'])
13500  && ($this->file->headers['content-type'] === 'text/plain'
13501  || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
13502  || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
13503  {
13504  return $this->text_or_binary();
13505  }
13506 
13507  if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
13508  {
13509  $official = substr($this->file->headers['content-type'], 0, $pos);
13510  }
13511  else
13512  {
13513  $official = $this->file->headers['content-type'];
13514  }
13515  $official = strtolower($official);
13516 
13517  if ($official === 'unknown/unknown'
13518  || $official === 'application/unknown')
13519  {
13520  return $this->unknown();
13521  }
13522  elseif (substr($official, -4) === '+xml'
13523  || $official === 'text/xml'
13524  || $official === 'application/xml')
13525  {
13526  return $official;
13527  }
13528  elseif (substr($official, 0, 6) === 'image/')
13529  {
13530  if ($return = $this->image())
13531  {
13532  return $return;
13533  }
13534  else
13535  {
13536  return $official;
13537  }
13538  }
13539  elseif ($official === 'text/html')
13540  {
13541  return $this->feed_or_html();
13542  }
13543  else
13544  {
13545  return $official;
13546  }
13547  }
13548  else
13549  {
13550  return $this->unknown();
13551  }
13552  }
13553 
13554  /**
13555  * Sniff text or binary
13556  *
13557  * @access private
13558  * @return string Actual Content-Type
13559  */
13560  function text_or_binary()
13561  {
13562  if (substr($this->file->body, 0, 2) === "\xFE\xFF"
13563  || substr($this->file->body, 0, 2) === "\xFF\xFE"
13564  || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
13565  || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
13566  {
13567  return 'text/plain';
13568  }
13569  elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
13570  {
13571  return 'application/octect-stream';
13572  }
13573  else
13574  {
13575  return 'text/plain';
13576  }
13577  }
13578 
13579  /**
13580  * Sniff unknown
13581  *
13582  * @access private
13583  * @return string Actual Content-Type
13584  */
13585  function unknown()
13586  {
13587  $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
13588  if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
13589  || strtolower(substr($this->file->body, $ws, 5)) === '<html'
13590  || strtolower(substr($this->file->body, $ws, 7)) === '<script')
13591  {
13592  return 'text/html';
13593  }
13594  elseif (substr($this->file->body, 0, 5) === '%PDF-')
13595  {
13596  return 'application/pdf';
13597  }
13598  elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
13599  {
13600  return 'application/postscript';
13601  }
13602  elseif (substr($this->file->body, 0, 6) === 'GIF87a'
13603  || substr($this->file->body, 0, 6) === 'GIF89a')
13604  {
13605  return 'image/gif';
13606  }
13607  elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
13608  {
13609  return 'image/png';
13610  }
13611  elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
13612  {
13613  return 'image/jpeg';
13614  }
13615  elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
13616  {
13617  return 'image/bmp';
13618  }
13619  else
13620  {
13621  return $this->text_or_binary();
13622  }
13623  }
13624 
13625  /**
13626  * Sniff images
13627  *
13628  * @access private
13629  * @return string Actual Content-Type
13630  */
13631  function image()
13632  {
13633  if (substr($this->file->body, 0, 6) === 'GIF87a'
13634  || substr($this->file->body, 0, 6) === 'GIF89a')
13635  {
13636  return 'image/gif';
13637  }
13638  elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
13639  {
13640  return 'image/png';
13641  }
13642  elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
13643  {
13644  return 'image/jpeg';
13645  }
13646  elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
13647  {
13648  return 'image/bmp';
13649  }
13650  else
13651  {
13652  return false;
13653  }
13654  }
13655 
13656  /**
13657  * Sniff HTML
13658  *
13659  * @access private
13660  * @return string Actual Content-Type
13661  */
13662  function feed_or_html()
13663  {
13664  $len = strlen($this->file->body);
13665  $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
13666 
13667  while ($pos < $len)
13668  {
13669  switch ($this->file->body[$pos])
13670  {
13671  case "\x09":
13672  case "\x0A":
13673  case "\x0D":
13674  case "\x20":
13675  $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
13676  continue 2;
13677 
13678  case '<':
13679  $pos++;
13680  break;
13681 
13682  default:
13683  return 'text/html';
13684  }
13685 
13686  if (substr($this->file->body, $pos, 3) === '!--')
13687  {
13688  $pos += 3;
13689  if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
13690  {
13691  $pos += 3;
13692  }
13693  else
13694  {
13695  return 'text/html';
13696  }
13697  }
13698  elseif (substr($this->file->body, $pos, 1) === '!')
13699  {
13700  if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
13701  {
13702  $pos++;
13703  }
13704  else
13705  {
13706  return 'text/html';
13707  }
13708  }
13709  elseif (substr($this->file->body, $pos, 1) === '?')
13710  {
13711  if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
13712  {
13713  $pos += 2;
13714  }
13715  else
13716  {
13717  return 'text/html';
13718  }
13719  }
13720  elseif (substr($this->file->body, $pos, 3) === 'rss'
13721  || substr($this->file->body, $pos, 7) === 'rdf:RDF')
13722  {
13723  return 'application/rss+xml';
13724  }
13725  elseif (substr($this->file->body, $pos, 4) === 'feed')
13726  {
13727  return 'application/atom+xml';
13728  }
13729  else
13730  {
13731  return 'text/html';
13732  }
13733  }
13734 
13735  return 'text/html';
13736  }
13737 }
13738 
13739 /**
13740  * Parses the XML Declaration
13741  *
13742  * @package SimplePie
13743  */
13745 {
13746  /**
13747  * XML Version
13748  *
13749  * @access public
13750  * @var string
13751  */
13752  var $version = '1.0';
13753 
13754  /**
13755  * Encoding
13756  *
13757  * @access public
13758  * @var string
13759  */
13760  var $encoding = 'UTF-8';
13761 
13762  /**
13763  * Standalone
13764  *
13765  * @access public
13766  * @var bool
13767  */
13768  var $standalone = false;
13769 
13770  /**
13771  * Current state of the state machine
13772  *
13773  * @access private
13774  * @var string
13775  */
13776  var $state = 'before_version_name';
13777 
13778  /**
13779  * Input data
13780  *
13781  * @access private
13782  * @var string
13783  */
13784  var $data = '';
13785 
13786  /**
13787  * Input data length (to avoid calling strlen() everytime this is needed)
13788  *
13789  * @access private
13790  * @var int
13791  */
13792  var $data_length = 0;
13793 
13794  /**
13795  * Current position of the pointer
13796  *
13797  * @var int
13798  * @access private
13799  */
13800  var $position = 0;
13801 
13802  /**
13803  * Create an instance of the class with the input data
13804  *
13805  * @access public
13806  * @param string $data Input data
13807  */
13809  {
13810  $this->data = $data;
13811  $this->data_length = strlen($this->data);
13812  }
13813 
13814  /**
13815  * Parse the input data
13816  *
13817  * @access public
13818  * @return bool true on success, false on failure
13819  */
13820  function parse()
13821  {
13822  while ($this->state && $this->state !== 'emit' && $this->has_data())
13823  {
13824  $state = $this->state;
13825  $this->$state();
13826  }
13827  $this->data = '';
13828  if ($this->state === 'emit')
13829  {
13830  return true;
13831  }
13832  else
13833  {
13834  $this->version = '';
13835  $this->encoding = '';
13836  $this->standalone = '';
13837  return false;
13838  }
13839  }
13840 
13841  /**
13842  * Check whether there is data beyond the pointer
13843  *
13844  * @access private
13845  * @return bool true if there is further data, false if not
13846  */
13847  function has_data()
13848  {
13849  return (bool) ($this->position < $this->data_length);
13850  }
13851 
13852  /**
13853  * Advance past any whitespace
13854  *
13855  * @return int Number of whitespace characters passed
13856  */
13857  function skip_whitespace()
13858  {
13859  $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
13860  $this->position += $whitespace;
13861  return $whitespace;
13862  }
13863 
13864  /**
13865  * Read value
13866  */
13867  function get_value()
13868  {
13869  $quote = substr($this->data, $this->position, 1);
13870  if ($quote === '"' || $quote === "'")
13871  {
13872  $this->position++;
13873  $len = strcspn($this->data, $quote, $this->position);
13874  if ($this->has_data())
13875  {
13876  $value = substr($this->data, $this->position, $len);
13877  $this->position += $len + 1;
13878  return $value;
13879  }
13880  }
13881  return false;
13882  }
13883 
13884  function before_version_name()
13885  {
13886  if ($this->skip_whitespace())
13887  {
13888  $this->state = 'version_name';
13889  }
13890  else
13891  {
13892  $this->state = false;
13893  }
13894  }
13895 
13896  function version_name()
13897  {
13898  if (substr($this->data, $this->position, 7) === 'version')
13899  {
13900  $this->position += 7;
13901  $this->skip_whitespace();
13902  $this->state = 'version_equals';
13903  }
13904  else
13905  {
13906  $this->state = false;
13907  }
13908  }
13909 
13910  function version_equals()
13911  {
13912  if (substr($this->data, $this->position, 1) === '=')
13913  {
13914  $this->position++;
13915  $this->skip_whitespace();
13916  $this->state = 'version_value';
13917  }
13918  else
13919  {
13920  $this->state = false;
13921  }
13922  }
13923 
13924  function version_value()
13925  {
13926  if ($this->version = $this->get_value())
13927  {
13928  $this->skip_whitespace();
13929  if ($this->has_data())
13930  {
13931  $this->state = 'encoding_name';
13932  }
13933  else
13934  {
13935  $this->state = 'emit';
13936  }
13937  }
13938  else
13939  {
13940  $this->state = 'standalone_name';
13941  }
13942  }
13943 
13944  function encoding_name()
13945  {
13946  if (substr($this->data, $this->position, 8) === 'encoding')
13947  {
13948  $this->position += 8;
13949  $this->skip_whitespace();
13950  $this->state = 'encoding_equals';
13951  }
13952  else
13953  {
13954  $this->state = false;
13955  }
13956  }
13957 
13958  function encoding_equals()
13959  {
13960  if (substr($this->data, $this->position, 1) === '=')
13961  {
13962  $this->position++;
13963  $this->skip_whitespace();
13964  $this->state = 'encoding_value';
13965  }
13966  else
13967  {
13968  $this->state = false;
13969  }
13970  }
13971 
13972  function encoding_value()
13973  {
13974  if ($this->encoding = $this->get_value())
13975  {
13976  $this->skip_whitespace();
13977  if ($this->has_data())
13978  {
13979  $this->state = 'standalone_name';
13980  }
13981  else
13982  {
13983  $this->state = 'emit';
13984  }
13985  }
13986  else
13987  {
13988  $this->state = false;
13989  }
13990  }
13991 
13992  function standalone_name()
13993  {
13994  if (substr($this->data, $this->position, 10) === 'standalone')
13995  {
13996  $this->position += 10;
13997  $this->skip_whitespace();
13998  $this->state = 'standalone_equals';
13999  }
14000  else
14001  {
14002  $this->state = false;
14003  }
14004  }
14005 
14006  function standalone_equals()
14007  {
14008  if (substr($this->data, $this->position, 1) === '=')
14009  {
14010  $this->position++;
14011  $this->skip_whitespace();
14012  $this->state = 'standalone_value';
14013  }
14014  else
14015  {
14016  $this->state = false;
14017  }
14018  }
14019 
14020  function standalone_value()
14021  {
14022  if ($standalone = $this->get_value())
14023  {
14024  switch ($standalone)
14025  {
14026  case 'yes':
14027  $this->standalone = true;
14028  break;
14029 
14030  case 'no':
14031  $this->standalone = false;
14032  break;
14033 
14034  default:
14035  $this->state = false;
14036  return;
14037  }
14038 
14039  $this->skip_whitespace();
14040  if ($this->has_data())
14041  {
14042  $this->state = false;
14043  }
14044  else
14045  {
14046  $this->state = 'emit';
14047  }
14048  }
14049  else
14050  {
14051  $this->state = false;
14052  }
14053  }
14054 }
14055 
14057 {
14060  var $file;
14061  var $local = array();
14062  var $elsewhere = array();
14063  var $file_class = 'SimplePie_File';
14064  var $cached_entities = array();
14066  var $base;
14067  var $base_location = 0;
14068  var $checked_feeds = 0;
14069  var $max_checked_feeds = 10;
14070  var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
14071 
14072  function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
14073  {
14074  $this->file =& $file;
14075  $this->file_class = $file_class;
14076  $this->useragent = $useragent;
14077  $this->timeout = $timeout;
14078  $this->max_checked_feeds = $max_checked_feeds;
14079  $this->content_type_sniffer_class = $content_type_sniffer_class;
14080  }
14081 
14082  function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
14083  {
14084  if ($this->is_feed($this->file))
14085  {
14086  return $this->file;
14087  }
14088 
14089  if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
14090  {
14091  $sniffer = new $this->content_type_sniffer_class($this->file);
14092  if ($sniffer->get_type() !== 'text/html')
14093  {
14094  return null;
14095  }
14096  }
14097 
14098  if ($type & ~SIMPLEPIE_LOCATOR_NONE)
14099  {
14100  $this->get_base();
14101  }
14102 
14103  if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
14104  {
14105  return $working[0];
14106  }
14107 
14109  {
14110  if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
14111  {
14112  return $working;
14113  }
14114 
14115  if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
14116  {
14117  return $working;
14118  }
14119 
14120  if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
14121  {
14122  return $working;
14123  }
14124 
14125  if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
14126  {
14127  return $working;
14128  }
14129  }
14130  return null;
14131  }
14132 
14133  function is_feed(&$file)
14134  {
14135  if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
14136  {
14137  $sniffer = new $this->content_type_sniffer_class($file);
14138  $sniffed = $sniffer->get_type();
14139  if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
14140  {
14141  return true;
14142  }
14143  else
14144  {
14145  return false;
14146  }
14147  }
14148  elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
14149  {
14150  return true;
14151  }
14152  else
14153  {
14154  return false;
14155  }
14156  }
14157 
14158  function get_base()
14159  {
14160  $this->http_base = $this->file->url;
14161  $this->base = $this->http_base;
14162  $elements = SimplePie_Misc::get_element('base', $this->file->body);
14163  foreach ($elements as $element)
14164  {
14165  if ($element['attribs']['href']['data'] !== '')
14166  {
14167  $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
14168  $this->base_location = $element['offset'];
14169  break;
14170  }
14171  }
14172  }
14173 
14174  function autodiscovery()
14175  {
14176  $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));
14177  $done = array();
14178  $feeds = array();
14179  foreach ($links as $link)
14180  {
14181  if ($this->checked_feeds === $this->max_checked_feeds)
14182  {
14183  break;
14184  }
14185  if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
14186  {
14187  $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
14188 
14189  if ($this->base_location < $link['offset'])
14190  {
14191  $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
14192  }
14193  else
14194  {
14195  $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
14196  }
14197 
14198  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'))) && !isset($feeds[$href]))
14199  {
14200  $this->checked_feeds++;
14201  $feed = new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
14202  if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
14203  {
14204  $feeds[$href] = $feed;
14205  }
14206  }
14207  $done[] = $href;
14208  }
14209  }
14210 
14211  if (!empty($feeds))
14212  {
14213  return array_values($feeds);
14214  }
14215  else
14216  {
14217  return null;
14218  }
14219  }
14220 
14221  function get_links()
14222  {
14223  $links = SimplePie_Misc::get_element('a', $this->file->body);
14224  foreach ($links as $link)
14225  {
14226  if (isset($link['attribs']['href']['data']))
14227  {
14228  $href = trim($link['attribs']['href']['data']);
14229  $parsed = SimplePie_Misc::parse_url($href);
14230  if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
14231  {
14232  if ($this->base_location < $link['offset'])
14233  {
14234  $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
14235  }
14236  else
14237  {
14238  $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
14239  }
14240 
14241  $current = SimplePie_Misc::parse_url($this->file->url);
14242 
14243  if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
14244  {
14245  $this->local[] = $href;
14246  }
14247  else
14248  {
14249  $this->elsewhere[] = $href;
14250  }
14251  }
14252  }
14253  }
14254  $this->local = array_unique($this->local);
14255  $this->elsewhere = array_unique($this->elsewhere);
14256  if (!empty($this->local) || !empty($this->elsewhere))
14257  {
14258  return true;
14259  }
14260  return null;
14261  }
14262 
14263  function extension(&$array)
14264  {
14265  foreach ($array as $key => $value)
14266  {
14267  if ($this->checked_feeds === $this->max_checked_feeds)
14268  {
14269  break;
14270  }
14271  if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
14272  {
14273  $this->checked_feeds++;
14274  $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
14275  if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
14276  {
14277  return $feed;
14278  }
14279  else
14280  {
14281  unset($array[$key]);
14282  }
14283  }
14284  }
14285  return null;
14286  }
14287 
14288  function body(&$array)
14289  {
14290  foreach ($array as $key => $value)
14291  {
14292  if ($this->checked_feeds === $this->max_checked_feeds)
14293  {
14294  break;
14295  }
14296  if (preg_match('/(rss|rdf|atom|xml)/i', $value))
14297  {
14298  $this->checked_feeds++;
14299  $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
14300  if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
14301  {
14302  return $feed;
14303  }
14304  else
14305  {
14306  unset($array[$key]);
14307  }
14308  }
14309  }
14310  return null;
14311  }
14312 }
14313 
14315 {
14321  var $separator = ' ';
14322  var $namespace = array('');
14323  var $element = array('');
14324  var $xml_base = array('');
14325  var $xml_base_explicit = array(false);
14326  var $xml_lang = array('');
14327  var $data = array();
14328  var $datas = array(array());
14329  var $current_xhtml_construct = -1;
14331 
14332  function parse(&$data, $encoding)
14333  {
14334  // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
14335  if (strtoupper($encoding) === 'US-ASCII')
14336  {
14337  $this->encoding = 'UTF-8';
14338  }
14339  else
14340  {
14341  $this->encoding = $encoding;
14342  }
14343 
14344  // Strip BOM:
14345  // UTF-32 Big Endian BOM
14346  if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
14347  {
14348  $data = substr($data, 4);
14349  }
14350  // UTF-32 Little Endian BOM
14351  elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
14352  {
14353  $data = substr($data, 4);
14354  }
14355  // UTF-16 Big Endian BOM
14356  elseif (substr($data, 0, 2) === "\xFE\xFF")
14357  {
14358  $data = substr($data, 2);
14359  }
14360  // UTF-16 Little Endian BOM
14361  elseif (substr($data, 0, 2) === "\xFF\xFE")
14362  {
14363  $data = substr($data, 2);
14364  }
14365  // UTF-8 BOM
14366  elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
14367  {
14368  $data = substr($data, 3);
14369  }
14370 
14371  if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
14372  {
14373  $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
14374  if ($declaration->parse())
14375  {
14376  $data = substr($data, $pos + 2);
14377  $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
14378  }
14379  else
14380  {
14381  $this->error_string = 'SimplePie bug! Please report this!';
14382  return false;
14383  }
14384  }
14385 
14386  $return = true;
14387 
14388  static $xml_is_sane = null;
14389  if ($xml_is_sane === null)
14390  {
14391  $parser_check = xml_parser_create();
14392  xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
14393  xml_parser_free($parser_check);
14394  $xml_is_sane = isset($values[0]['value']);
14395  }
14396 
14397  // Create the parser
14398  if ($xml_is_sane)
14399  {
14400  $xml = xml_parser_create_ns($this->encoding, $this->separator);
14401  xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
14402  xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
14403  xml_set_object($xml, $this);
14404  xml_set_character_data_handler($xml, 'cdata');
14405  xml_set_element_handler($xml, 'tag_open', 'tag_close');
14406 
14407  // Parse!
14408  if (!xml_parse($xml, $data, true))
14409  {
14410  $this->error_code = xml_get_error_code($xml);
14411  $this->error_string = xml_error_string($this->error_code);
14412  $return = false;
14413  }
14414  $this->current_line = xml_get_current_line_number($xml);
14415  $this->current_column = xml_get_current_column_number($xml);
14416  $this->current_byte = xml_get_current_byte_index($xml);
14417  xml_parser_free($xml);
14418  return $return;
14419  }
14420  else
14421  {
14422  libxml_clear_errors();
14423  $xml = new XMLReader();
14424  $xml->xml($data);
14425  while (@$xml->read())
14426  {
14427  switch ($xml->nodeType)
14428  {
14429 
14430  case constant('XMLReader::END_ELEMENT'):
14431  if ($xml->namespaceURI !== '')
14432  {
14433  $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
14434  }
14435  else
14436  {
14437  $tagName = $xml->localName;
14438  }
14439  $this->tag_close(null, $tagName);
14440  break;
14441  case constant('XMLReader::ELEMENT'):
14442  $empty = $xml->isEmptyElement;
14443  if ($xml->namespaceURI !== '')
14444  {
14445  $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
14446  }
14447  else
14448  {
14449  $tagName = $xml->localName;
14450  }
14451  $attributes = array();
14452  while ($xml->moveToNextAttribute())
14453  {
14454  if ($xml->namespaceURI !== '')
14455  {
14456  $attrName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
14457  }
14458  else
14459  {
14460  $attrName = $xml->localName;
14461  }
14462  $attributes[$attrName] = $xml->value;
14463  }
14464  $this->tag_open(null, $tagName, $attributes);
14465  if ($empty)
14466  {
14467  $this->tag_close(null, $tagName);
14468  }
14469  break;
14470  case constant('XMLReader::TEXT'):
14471 
14472  case constant('XMLReader::CDATA'):
14473  $this->cdata(null, $xml->value);
14474  break;
14475  }
14476  }
14477  if ($error = libxml_get_last_error())
14478  {
14479  $this->error_code = $error->code;
14480  $this->error_string = $error->message;
14481  $this->current_line = $error->line;
14482  $this->current_column = $error->column;
14483  return false;
14484  }
14485  else
14486  {
14487  return true;
14488  }
14489  }
14490  }
14491 
14492  function get_error_code()
14493  {
14494  return $this->error_code;
14495  }
14496 
14497  function get_error_string()
14498  {
14499  return $this->error_string;
14500  }
14501 
14502  function get_current_line()
14503  {
14504  return $this->current_line;
14505  }
14506 
14507  function get_current_column()
14508  {
14509  return $this->current_column;
14510  }
14511 
14512  function get_current_byte()
14513  {
14514  return $this->current_byte;
14515  }
14516 
14517  function get_data()
14518  {
14519  return $this->data;
14520  }
14521 
14522  function tag_open($parser, $tag, $attributes)
14523  {
14524  list($this->namespace[], $this->element[]) = $this->split_ns($tag);
14525 
14526  $attribs = array();
14527  foreach ($attributes as $name => $value)
14528  {
14529  list($attrib_namespace, $attribute) = $this->split_ns($name);
14530  $attribs[$attrib_namespace][$attribute] = $value;
14531  }
14532 
14533  if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
14534  {
14535  $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
14536  $this->xml_base_explicit[] = true;
14537  }
14538  else
14539  {
14540  $this->xml_base[] = end($this->xml_base);
14541  $this->xml_base_explicit[] = end($this->xml_base_explicit);
14542  }
14543 
14544  if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
14545  {
14546  $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
14547  }
14548  else
14549  {
14550  $this->xml_lang[] = end($this->xml_lang);
14551  }
14552 
14553  if ($this->current_xhtml_construct >= 0)
14554  {
14555  $this->current_xhtml_construct++;
14556  if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
14557  {
14558  $this->data['data'] .= '<' . end($this->element);
14559  if (isset($attribs['']))
14560  {
14561  foreach ($attribs[''] as $name => $value)
14562  {
14563  $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
14564  }
14565  }
14566  $this->data['data'] .= '>';
14567  }
14568  }
14569  else
14570  {
14571  $this->datas[] =& $this->data;
14572  $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
14573  $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));
14574  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')
14575  || (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'))
14576  {
14577  $this->current_xhtml_construct = 0;
14578  }
14579  }
14580  }
14581 
14582  function cdata($parser, $cdata)
14583  {
14584  if ($this->current_xhtml_construct >= 0)
14585  {
14586  $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
14587  }
14588  else
14589  {
14590  $this->data['data'] .= $cdata;
14591  }
14592  }
14593 
14594  function tag_close($parser, $tag)
14595  {
14596  if ($this->current_xhtml_construct >= 0)
14597  {
14598  $this->current_xhtml_construct--;
14599  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')))
14600  {
14601  $this->data['data'] .= '</' . end($this->element) . '>';
14602  }
14603  }
14604  if ($this->current_xhtml_construct === -1)
14605  {
14606  $this->data =& $this->datas[count($this->datas) - 1];
14607  array_pop($this->datas);
14608  }
14609 
14610  array_pop($this->element);
14611  array_pop($this->namespace);
14612  array_pop($this->xml_base);
14613  array_pop($this->xml_base_explicit);
14614  array_pop($this->xml_lang);
14615  }
14616 
14617  function split_ns($string)
14618  {
14619  static $cache = array();
14620  if (!isset($cache[$string]))
14621  {
14622  if ($pos = strpos($string, $this->separator))
14623  {
14624  static $separator_length;
14625  if (!$separator_length)
14626  {
14627  $separator_length = strlen($this->separator);
14628  }
14629  $namespace = substr($string, 0, $pos);
14630  $local_name = substr($string, $pos + $separator_length);
14631  if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
14632  {
14633  $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
14634  }
14635 
14636  // Normalize the Media RSS namespaces
14637  if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
14638  {
14639  $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
14640  }
14641  $cache[$string] = array($namespace, $local_name);
14642  }
14643  else
14644  {
14645  $cache[$string] = array('', $string);
14646  }
14647  }
14648  return $cache[$string];
14649  }
14650 }
14651 
14652 /**
14653  * @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 shorten a string while preserving HTML tags
14654  */
14656 {
14657  // Private vars
14658  var $base;
14659 
14660  // Options
14661  var $remove_div = true;
14662  var $image_handler = '';
14663  var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
14664  var $encode_instead_of_strip = false;
14665  var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
14666  var $strip_comments = false;
14667  var $output_encoding = 'UTF-8';
14668  var $enable_cache = true;
14669  var $cache_location = './cache';
14670  var $cache_name_function = 'md5';
14671  var $cache_class = 'SimplePie_Cache';
14672  var $file_class = 'SimplePie_File';
14673  var $timeout = 10;
14674  var $useragent = '';
14675  var $force_fsockopen = false;
14676 
14677  var $replace_url_attributes = array(
14678  'a' => 'href',
14679  'area' => 'href',
14680  'blockquote' => 'cite',
14681  'del' => 'cite',
14682  'form' => 'action',
14683  'img' => array('longdesc', 'src'),
14684  'input' => 'src',
14685  'ins' => 'cite',
14686  'q' => 'cite'
14687  );
14688 
14689  function remove_div($enable = true)
14690  {
14691  $this->remove_div = (bool) $enable;
14692  }
14693 
14694  function set_image_handler($page = false)
14695  {
14696  if ($page)
14697  {
14698  $this->image_handler = (string) $page;
14699  }
14700  else
14701  {
14702  $this->image_handler = false;
14703  }
14704  }
14705 
14706  function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
14707  {
14708  if (isset($enable_cache))
14709  {
14710  $this->enable_cache = (bool) $enable_cache;
14711  }
14712 
14713  if ($cache_location)
14714  {
14715  $this->cache_location = (string) $cache_location;
14716  }
14717 
14718  if ($cache_name_function)
14719  {
14720  $this->cache_name_function = (string) $cache_name_function;
14721  }
14722 
14723  if ($cache_class)
14724  {
14725  $this->cache_class = (string) $cache_class;
14726  }
14727  }
14728 
14729  function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
14730  {
14731  if ($file_class)
14732  {
14733  $this->file_class = (string) $file_class;
14734  }
14735 
14736  if ($timeout)
14737  {
14738  $this->timeout = (string) $timeout;
14739  }
14740 
14741  if ($useragent)
14742  {
14743  $this->useragent = (string) $useragent;
14744  }
14745 
14746  if ($force_fsockopen)
14747  {
14748  $this->force_fsockopen = (string) $force_fsockopen;
14749  }
14750  }
14751 
14752  function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
14753  {
14754  if ($tags)
14755  {
14756  if (is_array($tags))
14757  {
14758  $this->strip_htmltags = $tags;
14759  }
14760  else
14761  {
14762  $this->strip_htmltags = explode(',', $tags);
14763  }
14764  }
14765  else
14766  {
14767  $this->strip_htmltags = false;
14768  }
14769  }
14770 
14771  function encode_instead_of_strip($encode = false)
14772  {
14773  $this->encode_instead_of_strip = (bool) $encode;
14774  }
14775 
14776  function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
14777  {
14778  if ($attribs)
14779  {
14780  if (is_array($attribs))
14781  {
14782  $this->strip_attributes = $attribs;
14783  }
14784  else
14785  {
14786  $this->strip_attributes = explode(',', $attribs);
14787  }
14788  }
14789  else
14790  {
14791  $this->strip_attributes = false;
14792  }
14793  }
14794 
14795  function strip_comments($strip = false)
14796  {
14797  $this->strip_comments = (bool) $strip;
14798  }
14799 
14800  function set_output_encoding($encoding = 'UTF-8')
14801  {
14802  $this->output_encoding = (string) $encoding;
14803  }
14804 
14805  /**
14806  * Set element/attribute key/value pairs of HTML attributes
14807  * containing URLs that need to be resolved relative to the feed
14808  *
14809  * @access public
14810  * @since 1.0
14811  * @param array $element_attribute Element/attribute key/value pairs
14812  */
14813  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'))
14814  {
14815  $this->replace_url_attributes = (array) $element_attribute;
14816  }
14817 
14818  function sanitize($data, $type, $base = '')
14819  {
14820  $data = trim($data);
14821  if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
14822  {
14823  if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
14824  {
14825  if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
14826  {
14827  $type |= SIMPLEPIE_CONSTRUCT_HTML;
14828  }
14829  else
14830  {
14831  $type |= SIMPLEPIE_CONSTRUCT_TEXT;
14832  }
14833  }
14834 
14835  if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
14836  {
14837  $data = base64_decode($data);
14838  }
14839 
14840  if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
14841  {
14842  if ($this->remove_div)
14843  {
14844  $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
14845  $data = preg_replace('/<\/div>$/', '', $data);
14846  }
14847  else
14848  {
14849  $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
14850  }
14851  }
14852 
14853  if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
14854  {
14855  // Strip comments
14856  if ($this->strip_comments)
14857  {
14858  $data = SimplePie_Misc::strip_comments($data);
14859  }
14860 
14861  // Strip out HTML tags and attributes that might cause various security problems.
14862  // Based on recommendations by Mark Pilgrim at:
14863  // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
14864  if ($this->strip_htmltags)
14865  {
14866  foreach ($this->strip_htmltags as $tag)
14867  {
14868  $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
14869  while (preg_match($pcre, $data))
14870  {
14871  $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
14872  }
14873  }
14874  }
14875 
14876  if ($this->strip_attributes)
14877  {
14878  foreach ($this->strip_attributes as $attrib)
14879  {
14880  $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data);
14881  }
14882  }
14883 
14884  // Replace relative URLs
14885  $this->base = $base;
14886  foreach ($this->replace_url_attributes as $element => $attributes)
14887  {
14888  $data = $this->replace_urls($data, $element, $attributes);
14889  }
14890 
14891  // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
14892  if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
14893  {
14894  $images = SimplePie_Misc::get_element('img', $data);
14895  foreach ($images as $img)
14896  {
14897  if (isset($img['attribs']['src']['data']))
14898  {
14899  $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
14900  $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
14901 
14902  if ($cache->load())
14903  {
14904  $img['attribs']['src']['data'] = $this->image_handler . $image_url;
14905  $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
14906  }
14907  else
14908  {
14909  $file = new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
14910  $headers = $file->headers;
14911 
14912  if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
14913  {
14914  if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
14915  {
14916  $img['attribs']['src']['data'] = $this->image_handler . $image_url;
14917  $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
14918  }
14919  else
14920  {
14921  trigger_error("$this->cache_location is not writeable", E_USER_WARNING);
14922  }
14923  }
14924  }
14925  }
14926  }
14927  }
14928 
14929  // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
14930  $data = trim($data);
14931  }
14932 
14933  if ($type & SIMPLEPIE_CONSTRUCT_IRI)
14934  {
14935  $data = SimplePie_Misc::absolutize_url($data, $base);
14936  }
14937 
14938  if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
14939  {
14940  $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
14941  }
14942 
14943  if ($this->output_encoding !== 'UTF-8')
14944  {
14945  $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
14946  }
14947  }
14948  return $data;
14949  }
14950 
14951  function replace_urls($data, $tag, $attributes)
14952  {
14953  if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
14954  {
14955  $elements = SimplePie_Misc::get_element($tag, $data);
14956  foreach ($elements as $element)
14957  {
14958  if (is_array($attributes))
14959  {
14960  foreach ($attributes as $attribute)
14961  {
14962  if (isset($element['attribs'][$attribute]['data']))
14963  {
14964  $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
14965  $new_element = SimplePie_Misc::element_implode($element);
14966  $data = str_replace($element['full'], $new_element, $data);
14967  $element['full'] = $new_element;
14968  }
14969  }
14970  }
14971  elseif (isset($element['attribs'][$attributes]['data']))
14972  {
14973  $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
14974  $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
14975  }
14976  }
14977  }
14978  return $data;
14979  }
14980 
14981  function do_strip_htmltags($match)
14982  {
14983  if ($this->encode_instead_of_strip)
14984  {
14985  if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
14986  {
14987  $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
14988  $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
14989  return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
14990  }
14991  else
14992  {
14993  return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
14994  }
14995  }
14996  elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
14997  {
14998  return $match[4];
14999  }
15000  else
15001  {
15002  return '';
15003  }
15004  }
15005 }
15006 
15007 ?>