]> git.wh0rd.org - tt-rss.git/blob - simplepie/simplepie.inc
78ccfb8b3c24c4f9c06689e236c898b4f2d76077
[tt-rss.git] / simplepie / simplepie.inc
1 <?php
2 /**
3 * SimplePie
4 *
5 * A PHP-Based RSS and Atom Feed Framework.
6 * Takes the hard work out of managing a complete RSS/Atom solution.
7 *
8 * Copyright (c) 2004-2007, Ryan Parman and Geoffrey Sneddon
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without modification, are
12 * permitted provided that the following conditions are met:
13 *
14 * * Redistributions of source code must retain the above copyright notice, this list of
15 * conditions and the following disclaimer.
16 *
17 * * Redistributions in binary form must reproduce the above copyright notice, this list
18 * of conditions and the following disclaimer in the documentation and/or other materials
19 * provided with the distribution.
20 *
21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used
22 * to endorse or promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 * @package SimplePie
36 * @version 1.1
37 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
38 * @author Ryan Parman
39 * @author Geoffrey Sneddon
40 * @link http://simplepie.org/ SimplePie
41 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43 * @todo phpDoc comments
44 */
45
46 /**
47 * SimplePie Name
48 */
49 define('SIMPLEPIE_NAME', 'SimplePie');
50
51 /**
52 * SimplePie Version
53 */
54 define('SIMPLEPIE_VERSION', '1.1');
55
56 /**
57 * SimplePie Build
58 */
59 define('SIMPLEPIE_BUILD', 20080102221556);
60
61 /**
62 * SimplePie Website URL
63 */
64 define('SIMPLEPIE_URL', 'http://simplepie.org');
65
66 /**
67 * SimplePie Useragent
68 * @see SimplePie::set_useragent()
69 */
70 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
71
72 /**
73 * SimplePie Linkback
74 */
75 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
76
77 /**
78 * No Autodiscovery
79 * @see SimplePie::set_autodiscovery_level()
80 */
81 define('SIMPLEPIE_LOCATOR_NONE', 0);
82
83 /**
84 * Feed Link Element Autodiscovery
85 * @see SimplePie::set_autodiscovery_level()
86 */
87 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
88
89 /**
90 * Local Feed Extension Autodiscovery
91 * @see SimplePie::set_autodiscovery_level()
92 */
93 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
94
95 /**
96 * Local Feed Body Autodiscovery
97 * @see SimplePie::set_autodiscovery_level()
98 */
99 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
100
101 /**
102 * Remote Feed Extension Autodiscovery
103 * @see SimplePie::set_autodiscovery_level()
104 */
105 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
106
107 /**
108 * Remote Feed Body Autodiscovery
109 * @see SimplePie::set_autodiscovery_level()
110 */
111 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
112
113 /**
114 * All Feed Autodiscovery
115 * @see SimplePie::set_autodiscovery_level()
116 */
117 define('SIMPLEPIE_LOCATOR_ALL', 31);
118
119 /**
120 * No known feed type
121 */
122 define('SIMPLEPIE_TYPE_NONE', 0);
123
124 /**
125 * RSS 0.90
126 */
127 define('SIMPLEPIE_TYPE_RSS_090', 1);
128
129 /**
130 * RSS 0.91 (Netscape)
131 */
132 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
133
134 /**
135 * RSS 0.91 (Userland)
136 */
137 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
138
139 /**
140 * RSS 0.91 (both Netscape and Userland)
141 */
142 define('SIMPLEPIE_TYPE_RSS_091', 6);
143
144 /**
145 * RSS 0.92
146 */
147 define('SIMPLEPIE_TYPE_RSS_092', 8);
148
149 /**
150 * RSS 0.93
151 */
152 define('SIMPLEPIE_TYPE_RSS_093', 16);
153
154 /**
155 * RSS 0.94
156 */
157 define('SIMPLEPIE_TYPE_RSS_094', 32);
158
159 /**
160 * RSS 1.0
161 */
162 define('SIMPLEPIE_TYPE_RSS_10', 64);
163
164 /**
165 * RSS 2.0
166 */
167 define('SIMPLEPIE_TYPE_RSS_20', 128);
168
169 /**
170 * RDF-based RSS
171 */
172 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
173
174 /**
175 * Non-RDF-based RSS (truly intended as syndication format)
176 */
177 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
178
179 /**
180 * All RSS
181 */
182 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
183
184 /**
185 * Atom 0.3
186 */
187 define('SIMPLEPIE_TYPE_ATOM_03', 256);
188
189 /**
190 * Atom 1.0
191 */
192 define('SIMPLEPIE_TYPE_ATOM_10', 512);
193
194 /**
195 * All Atom
196 */
197 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
198
199 /**
200 * All feed types
201 */
202 define('SIMPLEPIE_TYPE_ALL', 1023);
203
204 /**
205 * No construct
206 */
207 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
208
209 /**
210 * Text construct
211 */
212 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
213
214 /**
215 * HTML construct
216 */
217 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
218
219 /**
220 * XHTML construct
221 */
222 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
223
224 /**
225 * base64-encoded construct
226 */
227 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
228
229 /**
230 * IRI construct
231 */
232 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
233
234 /**
235 * A construct that might be HTML
236 */
237 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
238
239 /**
240 * All constructs
241 */
242 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
243
244 /**
245 * PCRE for HTML attributes
246 */
247 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]*');
248
249 /**
250 * PCRE for XML attributes
251 */
252 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
253
254 /**
255 * XML Namespace
256 */
257 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
258
259 /**
260 * Atom 1.0 Namespace
261 */
262 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
263
264 /**
265 * Atom 0.3 Namespace
266 */
267 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
268
269 /**
270 * RDF Namespace
271 */
272 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
273
274 /**
275 * RSS 0.90 Namespace
276 */
277 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
278
279 /**
280 * RSS 1.0 Namespace
281 */
282 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
283
284 /**
285 * RSS 1.0 Content Module Namespace
286 */
287 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
288
289 /**
290 * DC 1.0 Namespace
291 */
292 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
293
294 /**
295 * DC 1.1 Namespace
296 */
297 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
298
299 /**
300 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
301 */
302 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
303
304 /**
305 * GeoRSS Namespace
306 */
307 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
308
309 /**
310 * Media RSS Namespace
311 */
312 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
313
314 /**
315 * iTunes RSS Namespace
316 */
317 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
318
319 /**
320 * XHTML Namespace
321 */
322 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
323
324 /**
325 * IANA Link Relations Registry
326 */
327 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
328
329 /**
330 * Whether we're running on PHP5
331 */
332 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
333
334 /**
335 * No file source
336 */
337 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
338
339 /**
340 * Remote file source
341 */
342 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
343
344 /**
345 * Local file source
346 */
347 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
348
349 /**
350 * fsockopen() file source
351 */
352 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
353
354 /**
355 * cURL file source
356 */
357 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
358
359 /**
360 * file_get_contents() file source
361 */
362 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
363
364 /**
365 * SimplePie
366 *
367 * @package SimplePie
368 * @version "Razzleberry"
369 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
370 * @author Ryan Parman
371 * @author Geoffrey Sneddon
372 * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
373 */
374 class SimplePie
375 {
376 /**
377 * @var array Raw data
378 * @access private
379 */
380 var $data = array();
381
382 /**
383 * @var mixed Error string
384 * @access private
385 */
386 var $error;
387
388 /**
389 * @var object Instance of SimplePie_Sanitize (or other class)
390 * @see SimplePie::set_sanitize_class()
391 * @access private
392 */
393 var $sanitize;
394
395 /**
396 * @var string SimplePie Useragent
397 * @see SimplePie::set_useragent()
398 * @access private
399 */
400 var $useragent = SIMPLEPIE_USERAGENT;
401
402 /**
403 * @var string Feed URL
404 * @see SimplePie::set_feed_url()
405 * @access private
406 */
407 var $feed_url;
408
409 /**
410 * @var object Instance of SimplePie_File to use as a feed
411 * @see SimplePie::set_file()
412 * @access private
413 */
414 var $file;
415
416 /**
417 * @var string Raw feed data
418 * @see SimplePie::set_raw_data()
419 * @access private
420 */
421 var $raw_data;
422
423 /**
424 * @var int Timeout for fetching remote files
425 * @see SimplePie::set_timeout()
426 * @access private
427 */
428 var $timeout = 10;
429
430 /**
431 * @var bool Forces fsockopen() to be used for remote files instead
432 * of cURL, even if a new enough version is installed
433 * @see SimplePie::force_fsockopen()
434 * @access private
435 */
436 var $force_fsockopen = false;
437
438 /**
439 * @var bool Force the given data/URL to be treated as a feed no matter what
440 * it appears like
441 * @see SimplePie::force_feed()
442 * @access private
443 */
444 var $force_feed = false;
445
446 /**
447 * @var bool Enable/Disable XML dump
448 * @see SimplePie::enable_xml_dump()
449 * @access private
450 */
451 var $xml_dump = false;
452
453 /**
454 * @var bool Enable/Disable Caching
455 * @see SimplePie::enable_cache()
456 * @access private
457 */
458 var $cache = true;
459
460 /**
461 * @var int Cache duration (in seconds)
462 * @see SimplePie::set_cache_duration()
463 * @access private
464 */
465 var $cache_duration = 3600;
466
467 /**
468 * @var int Auto-discovery cache duration (in seconds)
469 * @see SimplePie::set_autodiscovery_cache_duration()
470 * @access private
471 */
472 var $autodiscovery_cache_duration = 604800; // 7 Days.
473
474 /**
475 * @var string Cache location (relative to executing script)
476 * @see SimplePie::set_cache_location()
477 * @access private
478 */
479 var $cache_location = './cache';
480
481 /**
482 * @var string Function that creates the cache filename
483 * @see SimplePie::set_cache_name_function()
484 * @access private
485 */
486 var $cache_name_function = 'md5';
487
488 /**
489 * @var bool Reorder feed by date descending
490 * @see SimplePie::enable_order_by_date()
491 * @access private
492 */
493 var $order_by_date = true;
494
495 /**
496 * @var mixed Force input encoding to be set to the follow value
497 * (false, or anything type-cast to false, disables this feature)
498 * @see SimplePie::set_input_encoding()
499 * @access private
500 */
501 var $input_encoding = false;
502
503 /**
504 * @var int Feed Autodiscovery Level
505 * @see SimplePie::set_autodiscovery_level()
506 * @access private
507 */
508 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
509
510 /**
511 * @var string Class used for caching feeds
512 * @see SimplePie::set_cache_class()
513 * @access private
514 */
515 var $cache_class = 'SimplePie_Cache';
516
517 /**
518 * @var string Class used for locating feeds
519 * @see SimplePie::set_locator_class()
520 * @access private
521 */
522 var $locator_class = 'SimplePie_Locator';
523
524 /**
525 * @var string Class used for parsing feeds
526 * @see SimplePie::set_parser_class()
527 * @access private
528 */
529 var $parser_class = 'SimplePie_Parser';
530
531 /**
532 * @var string Class used for fetching feeds
533 * @see SimplePie::set_file_class()
534 * @access private
535 */
536 var $file_class = 'SimplePie_File';
537
538 /**
539 * @var string Class used for items
540 * @see SimplePie::set_item_class()
541 * @access private
542 */
543 var $item_class = 'SimplePie_Item';
544
545 /**
546 * @var string Class used for authors
547 * @see SimplePie::set_author_class()
548 * @access private
549 */
550 var $author_class = 'SimplePie_Author';
551
552 /**
553 * @var string Class used for categories
554 * @see SimplePie::set_category_class()
555 * @access private
556 */
557 var $category_class = 'SimplePie_Category';
558
559 /**
560 * @var string Class used for enclosures
561 * @see SimplePie::set_enclosures_class()
562 * @access private
563 */
564 var $enclosure_class = 'SimplePie_Enclosure';
565
566 /**
567 * @var string Class used for Media RSS <media:text> captions
568 * @see SimplePie::set_caption_class()
569 * @access private
570 */
571 var $caption_class = 'SimplePie_Caption';
572
573 /**
574 * @var string Class used for Media RSS <media:copyright>
575 * @see SimplePie::set_copyright_class()
576 * @access private
577 */
578 var $copyright_class = 'SimplePie_Copyright';
579
580 /**
581 * @var string Class used for Media RSS <media:credit>
582 * @see SimplePie::set_credit_class()
583 * @access private
584 */
585 var $credit_class = 'SimplePie_Credit';
586
587 /**
588 * @var string Class used for Media RSS <media:rating>
589 * @see SimplePie::set_rating_class()
590 * @access private
591 */
592 var $rating_class = 'SimplePie_Rating';
593
594 /**
595 * @var string Class used for Media RSS <media:restriction>
596 * @see SimplePie::set_restriction_class()
597 * @access private
598 */
599 var $restriction_class = 'SimplePie_Restriction';
600
601 /**
602 * @var string Class used for content-type sniffing
603 * @see SimplePie::set_content_type_sniffer_class()
604 * @access private
605 */
606 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
607
608 /**
609 * @var string Class used for item sources.
610 * @see SimplePie::set_source_class()
611 * @access private
612 */
613 var $source_class = 'SimplePie_Source';
614
615 /**
616 * @var mixed Set javascript query string parameter (false, or
617 * anything type-cast to false, disables this feature)
618 * @see SimplePie::set_javascript()
619 * @access private
620 */
621 var $javascript = 'js';
622
623 /**
624 * @var int Maximum number of feeds to check with autodiscovery
625 * @see SimplePie::set_max_checked_feeds()
626 * @access private
627 */
628 var $max_checked_feeds = 10;
629
630 /**
631 * @var string Web-accessible path to the handler_favicon.php file.
632 * @see SimplePie::set_favicon_handler()
633 * @access private
634 */
635 var $favicon_handler = '';
636
637 /**
638 * @var string Web-accessible path to the handler_image.php file.
639 * @see SimplePie::set_image_handler()
640 * @access private
641 */
642 var $image_handler = '';
643
644 /**
645 * @var array Stores the URLs when multiple feeds are being initialized.
646 * @see SimplePie::set_feed_url()
647 * @access private
648 */
649 var $multifeed_url = array();
650
651 /**
652 * @var array Stores SimplePie objects when multiple feeds initialized.
653 * @access private
654 */
655 var $multifeed_objects = array();
656
657 /**
658 * @var array Stores the get_object_vars() array for use with multifeeds.
659 * @see SimplePie::set_feed_url()
660 * @access private
661 */
662 var $config_settings = null;
663
664 /**
665 * @var integer Stores the number of items to return per-feed with multifeeds.
666 * @see SimplePie::set_item_limit()
667 * @access private
668 */
669 var $item_limit = 0;
670
671 /**
672 * @var array Stores the default attributes to be stripped by strip_attributes().
673 * @see SimplePie::strip_attributes()
674 * @access private
675 */
676 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
677
678 /**
679 * @var array Stores the default tags to be stripped by strip_htmltags().
680 * @see SimplePie::strip_htmltags()
681 * @access private
682 */
683 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
684
685 /**
686 * The SimplePie class contains feed level data and options
687 *
688 * There are two ways that you can create a new SimplePie object. The first
689 * is by passing a feed URL as a parameter to the SimplePie constructor
690 * (as well as optionally setting the cache location and cache expiry). This
691 * will initialise the whole feed with all of the default settings, and you
692 * can begin accessing methods and properties immediately.
693 *
694 * The second way is to create the SimplePie object with no parameters
695 * at all. This will enable you to set configuration options. After setting
696 * them, you must initialise the feed using $feed->init(). At that point the
697 * object's methods and properties will be available to you. This format is
698 * what is used throughout this documentation.
699 *
700 * @access public
701 * @since 1.0 Preview Release
702 * @param string $feed_url This is the URL you want to parse.
703 * @param string $cache_location This is where you want the cache to be stored.
704 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
705 */
706 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
707 {
708 // Other objects, instances created here so we can set options on them
709 $this->sanitize =& new SimplePie_Sanitize;
710
711 // Set options if they're passed to the constructor
712 if ($cache_location !== null)
713 {
714 $this->set_cache_location($cache_location);
715 }
716
717 if ($cache_duration !== null)
718 {
719 $this->set_cache_duration($cache_duration);
720 }
721
722 // Only init the script if we're passed a feed URL
723 if ($feed_url !== null)
724 {
725 $this->set_feed_url($feed_url);
726 $this->init();
727 }
728 }
729
730 /**
731 * Used for converting object to a string
732 */
733 function __toString()
734 {
735 return md5(serialize($this->data));
736 }
737
738 /**
739 * Remove items that link back to this before destroying this object
740 */
741 function __destruct()
742 {
743 if (!empty($this->data['items']))
744 {
745 foreach ($this->data['items'] as $item)
746 {
747 $item->__destruct();
748 }
749 unset($this->data['items']);
750 }
751 if (!empty($this->data['ordered_items']))
752 {
753 foreach ($this->data['ordered_items'] as $item)
754 {
755 $item->__destruct();
756 }
757 unset($this->data['ordered_items']);
758 }
759 }
760
761 /**
762 * Force the given data/URL to be treated as a feed no matter what it
763 * appears like
764 *
765 * @access public
766 * @since 1.1
767 * @param bool $enable Force the given data/URL to be treated as a feed
768 */
769 function force_feed($enable = false)
770 {
771 $this->force_feed = (bool) $enable;
772 }
773
774 /**
775 * This is the URL of the feed you want to parse.
776 *
777 * This allows you to enter the URL of the feed you want to parse, or the
778 * website you want to try to use auto-discovery on. This takes priority
779 * over any set raw data.
780 *
781 * You can set multiple feeds to mash together by passing an array instead
782 * of a string for the $url. Remember that with each additional feed comes
783 * additional processing and resources.
784 *
785 * @access public
786 * @since 1.0 Preview Release
787 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
788 * @see SimplePie::set_raw_data()
789 */
790 function set_feed_url($url)
791 {
792 if (is_array($url))
793 {
794 $this->multifeed_url = array();
795 foreach ($url as $value)
796 {
797 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
798 }
799 }
800 else
801 {
802 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
803 }
804 }
805
806 /**
807 * Provides an instance of SimplePie_File to use as a feed
808 *
809 * @access public
810 * @param object &$file Instance of SimplePie_File (or subclass)
811 * @return bool True on success, false on failure
812 */
813 function set_file(&$file)
814 {
815 if (is_a($file, 'SimplePie_File'))
816 {
817 $this->feed_url = $file->url;
818 $this->file =& $file;
819 return true;
820 }
821 return false;
822 }
823
824 /**
825 * Allows you to use a string of RSS/Atom data instead of a remote feed.
826 *
827 * If you have a feed available as a string in PHP, you can tell SimplePie
828 * to parse that data string instead of a remote feed. Any set feed URL
829 * takes precedence.
830 *
831 * @access public
832 * @since 1.0 Beta 3
833 * @param string $data RSS or Atom data as a string.
834 * @see SimplePie::set_feed_url()
835 */
836 function set_raw_data($data)
837 {
838 $this->raw_data = trim($data);
839 }
840
841 /**
842 * Allows you to override the default timeout for fetching remote feeds.
843 *
844 * This allows you to change the maximum time the feed's server to respond
845 * and send the feed back.
846 *
847 * @access public
848 * @since 1.0 Beta 3
849 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
850 */
851 function set_timeout($timeout = 10)
852 {
853 $this->timeout = (int) $timeout;
854 }
855
856 /**
857 * Forces SimplePie to use fsockopen() instead of the preferred cURL
858 * functions.
859 *
860 * @access public
861 * @since 1.0 Beta 3
862 * @param bool $enable Force fsockopen() to be used
863 */
864 function force_fsockopen($enable = false)
865 {
866 $this->force_fsockopen = (bool) $enable;
867 }
868
869 /**
870 * Outputs the raw XML content of the feed, after it has gone through
871 * SimplePie's filters.
872 *
873 * Used only for debugging, this function will output the XML content as
874 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
875 * before trying to parse it. Many parts of the feed are re-written in
876 * memory, and in the end, you have a parsable feed. XML dump shows you the
877 * actual XML that SimplePie tries to parse, which may or may not be very
878 * different from the original feed.
879 *
880 * @access public
881 * @since 1.0 Preview Release
882 * @param bool $enable Enable XML dump
883 */
884 function enable_xml_dump($enable = false)
885 {
886 $this->xml_dump = (bool) $enable;
887 }
888
889 /**
890 * Enables/disables caching in SimplePie.
891 *
892 * This option allows you to disable caching all-together in SimplePie.
893 * However, disabling the cache can lead to longer load times.
894 *
895 * @access public
896 * @since 1.0 Preview Release
897 * @param bool $enable Enable caching
898 */
899 function enable_cache($enable = true)
900 {
901 $this->cache = (bool) $enable;
902 }
903
904 /**
905 * Set the length of time (in seconds) that the contents of a feed
906 * will be cached.
907 *
908 * @access public
909 * @param int $seconds The feed content cache duration.
910 */
911 function set_cache_duration($seconds = 3600)
912 {
913 $this->cache_duration = (int) $seconds;
914 }
915
916 /**
917 * Set the length of time (in seconds) that the autodiscovered feed
918 * URL will be cached.
919 *
920 * @access public
921 * @param int $seconds The autodiscovered feed URL cache duration.
922 */
923 function set_autodiscovery_cache_duration($seconds = 604800)
924 {
925 $this->autodiscovery_cache_duration = (int) $seconds;
926 }
927
928 /**
929 * Set the file system location where the cached files should be stored.
930 *
931 * @access public
932 * @param string $location The file system location.
933 */
934 function set_cache_location($location = './cache')
935 {
936 $this->cache_location = (string) $location;
937 }
938
939 /**
940 * Determines whether feed items should be sorted into reverse chronological order.
941 *
942 * @access public
943 * @param bool $enable Sort as reverse chronological order.
944 */
945 function enable_order_by_date($enable = true)
946 {
947 $this->order_by_date = (bool) $enable;
948 }
949
950 /**
951 * Allows you to override the character encoding reported by the feed.
952 *
953 * @access public
954 * @param string $encoding Character encoding.
955 */
956 function set_input_encoding($encoding = false)
957 {
958 if ($encoding)
959 {
960 $this->input_encoding = (string) $encoding;
961 }
962 else
963 {
964 $this->input_encoding = false;
965 }
966 }
967
968 /**
969 * Set how much feed autodiscovery to do
970 *
971 * @access public
972 * @see SIMPLEPIE_LOCATOR_NONE
973 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
974 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
975 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
976 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
977 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
978 * @see SIMPLEPIE_LOCATOR_ALL
979 * @param int $level Feed Autodiscovery Level (level can be a
980 * combination of the above constants, see bitwise OR operator)
981 */
982 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
983 {
984 $this->autodiscovery = (int) $level;
985 }
986
987 /**
988 * Allows you to change which class SimplePie uses for caching.
989 * Useful when you are overloading or extending SimplePie's default classes.
990 *
991 * @access public
992 * @param string $class Name of custom class.
993 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
994 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
995 */
996 function set_cache_class($class = 'SimplePie_Cache')
997 {
998 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
999 {
1000 $this->cache_class = $class;
1001 return true;
1002 }
1003 return false;
1004 }
1005
1006 /**
1007 * Allows you to change which class SimplePie uses for auto-discovery.
1008 * Useful when you are overloading or extending SimplePie's default classes.
1009 *
1010 * @access public
1011 * @param string $class Name of custom class.
1012 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1013 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1014 */
1015 function set_locator_class($class = 'SimplePie_Locator')
1016 {
1017 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1018 {
1019 $this->locator_class = $class;
1020 return true;
1021 }
1022 return false;
1023 }
1024
1025 /**
1026 * Allows you to change which class SimplePie uses for XML parsing.
1027 * Useful when you are overloading or extending SimplePie's default classes.
1028 *
1029 * @access public
1030 * @param string $class Name of custom class.
1031 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1032 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1033 */
1034 function set_parser_class($class = 'SimplePie_Parser')
1035 {
1036 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1037 {
1038 $this->parser_class = $class;
1039 return true;
1040 }
1041 return false;
1042 }
1043
1044 /**
1045 * Allows you to change which class SimplePie uses for remote file fetching.
1046 * Useful when you are overloading or extending SimplePie's default classes.
1047 *
1048 * @access public
1049 * @param string $class Name of custom class.
1050 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1051 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1052 */
1053 function set_file_class($class = 'SimplePie_File')
1054 {
1055 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1056 {
1057 $this->file_class = $class;
1058 return true;
1059 }
1060 return false;
1061 }
1062
1063 /**
1064 * Allows you to change which class SimplePie uses for data sanitization.
1065 * Useful when you are overloading or extending SimplePie's default classes.
1066 *
1067 * @access public
1068 * @param string $class Name of custom class.
1069 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1070 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1071 */
1072 function set_sanitize_class($class = 'SimplePie_Sanitize')
1073 {
1074 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1075 {
1076 $this->sanitize =& new $class;
1077 return true;
1078 }
1079 return false;
1080 }
1081
1082 /**
1083 * Allows you to change which class SimplePie uses for handling feed items.
1084 * Useful when you are overloading or extending SimplePie's default classes.
1085 *
1086 * @access public
1087 * @param string $class Name of custom class.
1088 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1089 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1090 */
1091 function set_item_class($class = 'SimplePie_Item')
1092 {
1093 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1094 {
1095 $this->item_class = $class;
1096 return true;
1097 }
1098 return false;
1099 }
1100
1101 /**
1102 * Allows you to change which class SimplePie uses for handling author data.
1103 * Useful when you are overloading or extending SimplePie's default classes.
1104 *
1105 * @access public
1106 * @param string $class Name of custom class.
1107 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1108 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1109 */
1110 function set_author_class($class = 'SimplePie_Author')
1111 {
1112 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1113 {
1114 $this->author_class = $class;
1115 return true;
1116 }
1117 return false;
1118 }
1119
1120 /**
1121 * Allows you to change which class SimplePie uses for handling category data.
1122 * Useful when you are overloading or extending SimplePie's default classes.
1123 *
1124 * @access public
1125 * @param string $class Name of custom class.
1126 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1127 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1128 */
1129 function set_category_class($class = 'SimplePie_Category')
1130 {
1131 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1132 {
1133 $this->category_class = $class;
1134 return true;
1135 }
1136 return false;
1137 }
1138
1139 /**
1140 * Allows you to change which class SimplePie uses for feed enclosures.
1141 * Useful when you are overloading or extending SimplePie's default classes.
1142 *
1143 * @access public
1144 * @param string $class Name of custom class.
1145 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1146 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1147 */
1148 function set_enclosure_class($class = 'SimplePie_Enclosure')
1149 {
1150 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1151 {
1152 $this->enclosure_class = $class;
1153 return true;
1154 }
1155 return false;
1156 }
1157
1158 /**
1159 * Allows you to change which class SimplePie uses for <media:text> captions
1160 * Useful when you are overloading or extending SimplePie's default classes.
1161 *
1162 * @access public
1163 * @param string $class Name of custom class.
1164 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1165 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1166 */
1167 function set_caption_class($class = 'SimplePie_Caption')
1168 {
1169 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1170 {
1171 $this->caption_class = $class;
1172 return true;
1173 }
1174 return false;
1175 }
1176
1177 /**
1178 * Allows you to change which class SimplePie uses for <media:copyright>
1179 * Useful when you are overloading or extending SimplePie's default classes.
1180 *
1181 * @access public
1182 * @param string $class Name of custom class.
1183 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1184 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1185 */
1186 function set_copyright_class($class = 'SimplePie_Copyright')
1187 {
1188 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1189 {
1190 $this->copyright_class = $class;
1191 return true;
1192 }
1193 return false;
1194 }
1195
1196 /**
1197 * Allows you to change which class SimplePie uses for <media:credit>
1198 * Useful when you are overloading or extending SimplePie's default classes.
1199 *
1200 * @access public
1201 * @param string $class Name of custom class.
1202 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1203 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1204 */
1205 function set_credit_class($class = 'SimplePie_Credit')
1206 {
1207 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1208 {
1209 $this->credit_class = $class;
1210 return true;
1211 }
1212 return false;
1213 }
1214
1215 /**
1216 * Allows you to change which class SimplePie uses for <media:rating>
1217 * Useful when you are overloading or extending SimplePie's default classes.
1218 *
1219 * @access public
1220 * @param string $class Name of custom class.
1221 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1222 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1223 */
1224 function set_rating_class($class = 'SimplePie_Rating')
1225 {
1226 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1227 {
1228 $this->rating_class = $class;
1229 return true;
1230 }
1231 return false;
1232 }
1233
1234 /**
1235 * Allows you to change which class SimplePie uses for <media:restriction>
1236 * Useful when you are overloading or extending SimplePie's default classes.
1237 *
1238 * @access public
1239 * @param string $class Name of custom class.
1240 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1241 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1242 */
1243 function set_restriction_class($class = 'SimplePie_Restriction')
1244 {
1245 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1246 {
1247 $this->restriction_class = $class;
1248 return true;
1249 }
1250 return false;
1251 }
1252
1253 /**
1254 * Allows you to change which class SimplePie uses for content-type sniffing.
1255 * Useful when you are overloading or extending SimplePie's default classes.
1256 *
1257 * @access public
1258 * @param string $class Name of custom class.
1259 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1260 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1261 */
1262 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1263 {
1264 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1265 {
1266 $this->content_type_sniffer_class = $class;
1267 return true;
1268 }
1269 return false;
1270 }
1271
1272 /**
1273 * Allows you to change which class SimplePie uses item sources.
1274 * Useful when you are overloading or extending SimplePie's default classes.
1275 *
1276 * @access public
1277 * @param string $class Name of custom class.
1278 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1279 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1280 */
1281 function set_source_class($class = 'SimplePie_Source')
1282 {
1283 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1284 {
1285 $this->source_class = $class;
1286 return true;
1287 }
1288 return false;
1289 }
1290
1291 /**
1292 * Allows you to override the default user agent string.
1293 *
1294 * @access public
1295 * @param string $ua New user agent string.
1296 */
1297 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1298 {
1299 $this->useragent = (string) $ua;
1300 }
1301
1302 /**
1303 * Set callback function to create cache filename with
1304 *
1305 * @access public
1306 * @param mixed $function Callback function
1307 */
1308 function set_cache_name_function($function = 'md5')
1309 {
1310 if (is_callable($function))
1311 {
1312 $this->cache_name_function = $function;
1313 }
1314 }
1315
1316 /**
1317 * Set javascript query string parameter
1318 *
1319 * @access public
1320 * @param mixed $get Javascript query string parameter
1321 */
1322 function set_javascript($get = 'js')
1323 {
1324 if ($get)
1325 {
1326 $this->javascript = (string) $get;
1327 }
1328 else
1329 {
1330 $this->javascript = false;
1331 }
1332 }
1333
1334 /**
1335 * Set options to make SP as fast as possible. Forgoes a
1336 * substantial amount of data sanitization in favor of speed.
1337 *
1338 * @access public
1339 * @param bool $set Whether to set them or not
1340 */
1341 function set_stupidly_fast($set = false)
1342 {
1343 if ($set)
1344 {
1345 $this->enable_order_by_date(false);
1346 $this->remove_div(false);
1347 $this->strip_comments(false);
1348 $this->strip_htmltags(false);
1349 $this->strip_attributes(false);
1350 $this->set_image_handler(false);
1351 }
1352 }
1353
1354 /**
1355 * Set maximum number of feeds to check with autodiscovery
1356 *
1357 * @access public
1358 * @param int $max Maximum number of feeds to check
1359 */
1360 function set_max_checked_feeds($max = 10)
1361 {
1362 $this->max_checked_feeds = (int) $max;
1363 }
1364
1365 function remove_div($enable = true)
1366 {
1367 $this->sanitize->remove_div($enable);
1368 }
1369
1370 function strip_htmltags($tags = '', $encode = null)
1371 {
1372 if ($tags === '')
1373 {
1374 $tags = $this->strip_htmltags;
1375 }
1376 $this->sanitize->strip_htmltags($tags);
1377 if ($encode !== null)
1378 {
1379 $this->sanitize->encode_instead_of_strip($tags);
1380 }
1381 }
1382
1383 function encode_instead_of_strip($enable = true)
1384 {
1385 $this->sanitize->encode_instead_of_strip($enable);
1386 }
1387
1388 function strip_attributes($attribs = '')
1389 {
1390 if ($attribs === '')
1391 {
1392 $attribs = $this->strip_attributes;
1393 }
1394 $this->sanitize->strip_attributes($attribs);
1395 }
1396
1397 function set_output_encoding($encoding = 'UTF-8')
1398 {
1399 $this->sanitize->set_output_encoding($encoding);
1400 }
1401
1402 function strip_comments($strip = false)
1403 {
1404 $this->sanitize->strip_comments($strip);
1405 }
1406
1407 /**
1408 * Set element/attribute key/value pairs of HTML attributes
1409 * containing URLs that need to be resolved relative to the feed
1410 *
1411 * @access public
1412 * @since 1.0
1413 * @param array $element_attribute Element/attribute key/value pairs
1414 */
1415 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'))
1416 {
1417 $this->sanitize->set_url_replacements($element_attribute);
1418 }
1419
1420 /**
1421 * Set the handler to enable the display of cached favicons.
1422 *
1423 * @access public
1424 * @param str $page Web-accessible path to the handler_favicon.php file.
1425 * @param str $qs The query string that the value should be passed to.
1426 */
1427 function set_favicon_handler($page = false, $qs = 'i')
1428 {
1429 if ($page != false)
1430 {
1431 $this->favicon_handler = $page . '?' . $qs . '=';
1432 }
1433 else
1434 {
1435 $this->favicon_handler = '';
1436 }
1437 }
1438
1439 /**
1440 * Set the handler to enable the display of cached images.
1441 *
1442 * @access public
1443 * @param str $page Web-accessible path to the handler_image.php file.
1444 * @param str $qs The query string that the value should be passed to.
1445 */
1446 function set_image_handler($page = false, $qs = 'i')
1447 {
1448 if ($page != false)
1449 {
1450 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1451 }
1452 else
1453 {
1454 $this->image_handler = '';
1455 }
1456 }
1457
1458 /**
1459 * Set the limit for items returned per-feed with multifeeds.
1460 *
1461 * @access public
1462 * @param integer $limit The maximum number of items to return.
1463 */
1464 function set_item_limit($limit = 0)
1465 {
1466 $this->item_limit = (int) $limit;
1467 }
1468
1469 function init()
1470 {
1471 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1472 {
1473 return false;
1474 }
1475 if (isset($_GET[$this->javascript]))
1476 {
1477 if (function_exists('ob_gzhandler'))
1478 {
1479 ob_start('ob_gzhandler');
1480 }
1481 header('Content-type: text/javascript; charset: UTF-8');
1482 header('Cache-Control: must-revalidate');
1483 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1484 ?>
1485 function embed_odeo(link) {
1486 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>');
1487 }
1488
1489 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1490 if (placeholder != '') {
1491 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>');
1492 }
1493 else {
1494 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>');
1495 }
1496 }
1497
1498 function embed_flash(bgcolor, width, height, link, loop, type) {
1499 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>');
1500 }
1501
1502 function embed_flv(width, height, link, placeholder, loop, player) {
1503 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>');
1504 }
1505
1506 function embed_wmedia(width, height, link) {
1507 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1508 }
1509 <?php
1510 exit;
1511 }
1512
1513 // Pass whatever was set with config options over to the sanitizer.
1514 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1515 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1516
1517 if ($this->feed_url !== null || $this->raw_data !== null)
1518 {
1519 $this->data = array();
1520 $this->multifeed_objects = array();
1521 $cache = false;
1522
1523 if ($this->feed_url !== null)
1524 {
1525 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1526 // Decide whether to enable caching
1527 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1528 {
1529 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1530 }
1531 // If it's enabled and we don't want an XML dump, use the cache
1532 if ($cache && !$this->xml_dump)
1533 {
1534 // Load the Cache
1535 $this->data = $cache->load();
1536 if (!empty($this->data))
1537 {
1538 // If the cache is for an outdated build of SimplePie
1539 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1540 {
1541 $cache->unlink();
1542 $this->data = array();
1543 }
1544 // If we've hit a collision just rerun it with caching disabled
1545 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1546 {
1547 $cache = false;
1548 $this->data = array();
1549 }
1550 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1551 elseif (isset($this->data['feed_url']))
1552 {
1553 // If the autodiscovery cache is still valid use it.
1554 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1555 {
1556 // Do not need to do feed autodiscovery yet.
1557 if ($this->data['feed_url'] == $this->data['url'])
1558 {
1559 $cache->unlink();
1560 $this->data = array();
1561 }
1562 else
1563 {
1564 $this->set_feed_url($this->data['feed_url']);
1565 return $this->init();
1566 }
1567 }
1568 }
1569 // Check if the cache has been updated
1570 elseif ($cache->mtime() + $this->cache_duration < time())
1571 {
1572 // If we have last-modified and/or etag set
1573 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1574 {
1575 $headers = array();
1576 if (isset($this->data['headers']['last-modified']))
1577 {
1578 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1579 }
1580 if (isset($this->data['headers']['etag']))
1581 {
1582 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1583 }
1584 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1585 if ($file->success)
1586 {
1587 if ($file->status_code == 304)
1588 {
1589 $cache->touch();
1590 return true;
1591 }
1592 else
1593 {
1594 $headers = $file->headers;
1595 }
1596 }
1597 else
1598 {
1599 unset($file);
1600 }
1601 }
1602 }
1603 // If the cache is still valid, just return true
1604 else
1605 {
1606 return true;
1607 }
1608 }
1609 // If the cache is empty, delete it
1610 else
1611 {
1612 $cache->unlink();
1613 $this->data = array();
1614 }
1615 }
1616 // 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.
1617 if (!isset($file))
1618 {
1619 if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1620 {
1621 $file =& $this->file;
1622 }
1623 else
1624 {
1625 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1626 }
1627 }
1628 // If the file connection has an error, set SimplePie::error to that and quit
1629 if (!$file->success)
1630 {
1631 $this->error = $file->error;
1632 if (!empty($this->data))
1633 {
1634 return true;
1635 }
1636 else
1637 {
1638 return false;
1639 }
1640 }
1641
1642 if (!$this->force_feed)
1643 {
1644 // Check if the supplied URL is a feed, if it isn't, look for it.
1645 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1646 if (!$locate->is_feed($file))
1647 {
1648 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1649 unset($file);
1650 if ($file = $locate->find($this->autodiscovery))
1651 {
1652 if ($cache)
1653 {
1654 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1655 if (!$cache->save($this))
1656 {
1657 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1658 }
1659 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1660 }
1661 $this->feed_url = $file->url;
1662 }
1663 else
1664 {
1665 $this->error = "A feed could not be found at $this->feed_url";
1666 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1667 return false;
1668 }
1669 }
1670 $locate = null;
1671 }
1672
1673 $headers = $file->headers;
1674 $data = $file->body;
1675 $sniffer = new $this->content_type_sniffer_class($file);
1676 $sniffed = $sniffer->get_type();
1677 }
1678 else
1679 {
1680 $data = $this->raw_data;
1681 }
1682
1683 // Set up array of possible encodings
1684 $encodings = array();
1685
1686 // First check to see if input has been overridden.
1687 if ($this->input_encoding !== false)
1688 {
1689 $encodings[] = $this->input_encoding;
1690 }
1691
1692 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1693 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1694
1695 // RFC 3023 (only applies to sniffed content)
1696 if (isset($sniffed))
1697 {
1698 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1699 {
1700 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1701 {
1702 $encodings[] = strtoupper($charset[1]);
1703 }
1704 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1705 $encodings[] = 'UTF-8';
1706 }
1707 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1708 {
1709 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1710 {
1711 $encodings[] = $charset[1];
1712 }
1713 $encodings[] = 'US-ASCII';
1714 }
1715 // Text MIME-type default
1716 elseif (substr($sniffed, 0, 5) === 'text/')
1717 {
1718 $encodings[] = 'US-ASCII';
1719 }
1720 }
1721
1722 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1723 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1724 $encodings[] = 'UTF-8';
1725 $encodings[] = 'ISO-8859-1';
1726
1727 // There's no point in trying an encoding twice
1728 $encodings = array_unique($encodings);
1729
1730 // If we want the XML, just output that with the most likely encoding and quit
1731 if ($this->xml_dump)
1732 {
1733 header('Content-type: text/xml; charset=' . $encodings[0]);
1734 echo $data;
1735 exit;
1736 }
1737
1738 // Loop through each possible encoding, till we return something, or run out of possibilities
1739 foreach ($encodings as $encoding)
1740 {
1741 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1742 $utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8');
1743
1744 // Create new parser
1745 $parser =& new $this->parser_class();
1746
1747 // If it's parsed fine
1748 if ($parser->parse($utf8_data, 'UTF-8'))
1749 {
1750 $this->data = $parser->get_data();
1751 if (isset($this->data['child']))
1752 {
1753 if (isset($headers))
1754 {
1755 $this->data['headers'] = $headers;
1756 }
1757 $this->data['build'] = SIMPLEPIE_BUILD;
1758
1759 // Cache the file if caching is enabled
1760 if ($cache && !$cache->save($this))
1761 {
1762 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1763 }
1764 return true;
1765 }
1766 else
1767 {
1768 $this->error = "A feed could not be found at $this->feed_url";
1769 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1770 return false;
1771 }
1772 }
1773 }
1774 // We have an error, just set SimplePie::error to it and quit
1775 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1776 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1777 return false;
1778 }
1779 elseif (!empty($this->multifeed_url))
1780 {
1781 $i = 0;
1782 $success = 0;
1783 $this->multifeed_objects = array();
1784 foreach ($this->multifeed_url as $url)
1785 {
1786 if (SIMPLEPIE_PHP5)
1787 {
1788 // This keyword needs to defy coding standards for PHP4 compatibility
1789 $this->multifeed_objects[$i] = clone($this);
1790 }
1791 else
1792 {
1793 $this->multifeed_objects[$i] = $this;
1794 }
1795 $this->multifeed_objects[$i]->set_feed_url($url);
1796 $success |= $this->multifeed_objects[$i]->init();
1797 $i++;
1798 }
1799 return (bool) $success;
1800 }
1801 else
1802 {
1803 return false;
1804 }
1805 }
1806
1807 /**
1808 * Return the error message for the occured error
1809 *
1810 * @access public
1811 * @return string Error message
1812 */
1813 function error()
1814 {
1815 return $this->error;
1816 }
1817
1818 function get_encoding()
1819 {
1820 return $this->sanitize->output_encoding;
1821 }
1822
1823 function handle_content_type($mime = 'text/html')
1824 {
1825 if (!headers_sent())
1826 {
1827 $header = "Content-type: $mime;";
1828 if ($this->get_encoding())
1829 {
1830 $header .= ' charset=' . $this->get_encoding();
1831 }
1832 else
1833 {
1834 $header .= ' charset=UTF-8';
1835 }
1836 header($header);
1837 }
1838 }
1839
1840 function get_type()
1841 {
1842 if (!isset($this->data['type']))
1843 {
1844 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1845 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1846 {
1847 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1848 }
1849 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1850 {
1851 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1852 }
1853 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1854 {
1855 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1856 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1857 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1858 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1859 {
1860 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1861 }
1862 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1863 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1864 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1865 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1866 {
1867 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1868 }
1869 }
1870 elseif (isset($this->data['child']['']['rss']))
1871 {
1872 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1873 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1874 {
1875 switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1876 {
1877 case '0.91':
1878 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1879 if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1880 {
1881 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1882 {
1883 case '0':
1884 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1885 break;
1886
1887 case '24':
1888 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1889 break;
1890 }
1891 }
1892 break;
1893
1894 case '0.92':
1895 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1896 break;
1897
1898 case '0.93':
1899 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1900 break;
1901
1902 case '0.94':
1903 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1904 break;
1905
1906 case '2.0':
1907 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1908 break;
1909 }
1910 }
1911 }
1912 else
1913 {
1914 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1915 }
1916 }
1917 return $this->data['type'];
1918 }
1919
1920 /**
1921 * Returns the URL for the favicon of the feed's website.
1922 *
1923 * @todo Cache atom:icon
1924 * @access public
1925 * @since 1.0
1926 */
1927 function get_favicon()
1928 {
1929 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1930 {
1931 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1932 }
1933 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1934 {
1935 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1936
1937 if ($this->cache && $this->favicon_handler)
1938 {
1939 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1940 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1941
1942 if ($cache->load())
1943 {
1944 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1945 }
1946 else
1947 {
1948 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1949
1950 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1951 {
1952 $sniffer = new $this->content_type_sniffer_class($file);
1953 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1954 {
1955 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1956 {
1957 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1958 }
1959 else
1960 {
1961 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1962 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1963 }
1964 }
1965 }
1966 }
1967 }
1968 else
1969 {
1970 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1971 }
1972 }
1973 return false;
1974 }
1975
1976 /**
1977 * @todo If we have a perm redirect we should return the new URL
1978 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1979 * @todo Also, |atom:link|@rel=self
1980 */
1981 function subscribe_url()
1982 {
1983 if ($this->feed_url !== null)
1984 {
1985 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1986 }
1987 else
1988 {
1989 return null;
1990 }
1991 }
1992
1993 function subscribe_feed()
1994 {
1995 if ($this->feed_url !== null)
1996 {
1997 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
1998 }
1999 else
2000 {
2001 return null;
2002 }
2003 }
2004
2005 function subscribe_outlook()
2006 {
2007 if ($this->feed_url !== null)
2008 {
2009 return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2010 }
2011 else
2012 {
2013 return null;
2014 }
2015 }
2016
2017 function subscribe_podcast()
2018 {
2019 if ($this->feed_url !== null)
2020 {
2021 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2022 }
2023 else
2024 {
2025 return null;
2026 }
2027 }
2028
2029 function subscribe_itunes()
2030 {
2031 if ($this->feed_url !== null)
2032 {
2033 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2034 }
2035 else
2036 {
2037 return null;
2038 }
2039 }
2040
2041 /**
2042 * Creates the subscribe_* methods' return data
2043 *
2044 * @access private
2045 * @param string $feed_url String to prefix to the feed URL
2046 * @param string $site_url String to prefix to the site URL (and
2047 * suffix to the feed URL)
2048 * @return mixed URL if feed exists, false otherwise
2049 */
2050 function subscribe_service($feed_url, $site_url = null)
2051 {
2052 if ($this->subscribe_url())
2053 {
2054 $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2055 if ($site_url !== null && $this->get_link() !== null)
2056 {
2057 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2058 }
2059 return $return;
2060 }
2061 else
2062 {
2063 return null;
2064 }
2065 }
2066
2067 function subscribe_aol()
2068 {
2069 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2070 }
2071
2072 function subscribe_bloglines()
2073 {
2074 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2075 }
2076
2077 function subscribe_eskobo()
2078 {
2079 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2080 }
2081
2082 function subscribe_feedfeeds()
2083 {
2084 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2085 }
2086
2087 function subscribe_feedster()
2088 {
2089 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2090 }
2091
2092 function subscribe_google()
2093 {
2094 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2095 }
2096
2097 function subscribe_gritwire()
2098 {
2099 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2100 }
2101
2102 function subscribe_msn()
2103 {
2104 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2105 }
2106
2107 function subscribe_netvibes()
2108 {
2109 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2110 }
2111
2112 function subscribe_newsburst()
2113 {
2114 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2115 }
2116
2117 function subscribe_newsgator()
2118 {
2119 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2120 }
2121
2122 function subscribe_odeo()
2123 {
2124 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2125 }
2126
2127 function subscribe_podnova()
2128 {
2129 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2130 }
2131
2132 function subscribe_rojo()
2133 {
2134 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2135 }
2136
2137 function subscribe_yahoo()
2138 {
2139 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2140 }
2141
2142 function get_feed_tags($namespace, $tag)
2143 {
2144 $type = $this->get_type();
2145 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2146 {
2147 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2148 {
2149 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2150 }
2151 }
2152 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2153 {
2154 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2155 {
2156 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2157 }
2158 }
2159 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2160 {
2161 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2162 {
2163 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2164 }
2165 }
2166 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2167 {
2168 if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2169 {
2170 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2171 }
2172 }
2173 return null;
2174 }
2175
2176 function get_channel_tags($namespace, $tag)
2177 {
2178 $type = $this->get_type();
2179 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2180 {
2181 if ($return = $this->get_feed_tags($namespace, $tag))
2182 {
2183 return $return;
2184 }
2185 }
2186 if ($type & SIMPLEPIE_TYPE_RSS_10)
2187 {
2188 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2189 {
2190 if (isset($channel[0]['child'][$namespace][$tag]))
2191 {
2192 return $channel[0]['child'][$namespace][$tag];
2193 }
2194 }
2195 }
2196 if ($type & SIMPLEPIE_TYPE_RSS_090)
2197 {
2198 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2199 {
2200 if (isset($channel[0]['child'][$namespace][$tag]))
2201 {
2202 return $channel[0]['child'][$namespace][$tag];
2203 }
2204 }
2205 }
2206 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2207 {
2208 if ($channel = $this->get_feed_tags('', 'channel'))
2209 {
2210 if (isset($channel[0]['child'][$namespace][$tag]))
2211 {
2212 return $channel[0]['child'][$namespace][$tag];
2213 }
2214 }
2215 }
2216 return null;
2217 }
2218
2219 function get_image_tags($namespace, $tag)
2220 {
2221 $type = $this->get_type();
2222 if ($type & SIMPLEPIE_TYPE_RSS_10)
2223 {
2224 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2225 {
2226 if (isset($image[0]['child'][$namespace][$tag]))
2227 {
2228 return $image[0]['child'][$namespace][$tag];
2229 }
2230 }
2231 }
2232 if ($type & SIMPLEPIE_TYPE_RSS_090)
2233 {
2234 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2235 {
2236 if (isset($image[0]['child'][$namespace][$tag]))
2237 {
2238 return $image[0]['child'][$namespace][$tag];
2239 }
2240 }
2241 }
2242 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2243 {
2244 if ($image = $this->get_channel_tags('', 'image'))
2245 {
2246 if (isset($image[0]['child'][$namespace][$tag]))
2247 {
2248 return $image[0]['child'][$namespace][$tag];
2249 }
2250 }
2251 }
2252 return null;
2253 }
2254
2255 function get_base($element = array())
2256 {
2257 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2258 {
2259 return $element['xml_base'];
2260 }
2261 elseif ($this->get_link() !== null)
2262 {
2263 return $this->get_link();
2264 }
2265 else
2266 {
2267 return $this->subscribe_url();
2268 }
2269 }
2270
2271 function sanitize($data, $type, $base = '')
2272 {
2273 return $this->sanitize->sanitize($data, $type, $base);
2274 }
2275
2276 function get_title()
2277 {
2278 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2279 {
2280 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2281 }
2282 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2283 {
2284 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2285 }
2286 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2287 {
2288 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2289 }
2290 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2291 {
2292 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2293 }
2294 elseif ($return = $this->get_channel_tags('', 'title'))
2295 {
2296 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2297 }
2298 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2299 {
2300 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2301 }
2302 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2303 {
2304 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2305 }
2306 else
2307 {
2308 return null;
2309 }
2310 }
2311
2312 function get_category($key = 0)
2313 {
2314 $categories = $this->get_categories();
2315 if (isset($categories[$key]))
2316 {
2317 return $categories[$key];
2318 }
2319 else
2320 {
2321 return null;
2322 }
2323 }
2324
2325 function get_categories()
2326 {
2327 $categories = array();
2328
2329 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2330 {
2331 $term = null;
2332 $scheme = null;
2333 $label = null;
2334 if (isset($category['attribs']['']['term']))
2335 {
2336 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2337 }
2338 if (isset($category['attribs']['']['scheme']))
2339 {
2340 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2341 }
2342 if (isset($category['attribs']['']['label']))
2343 {
2344 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2345 }
2346 $categories[] =& new $this->category_class($term, $scheme, $label);
2347 }
2348 foreach ((array) $this->get_channel_tags('', 'category') as $category)
2349 {
2350 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2351 }
2352 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2353 {
2354 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2355 }
2356 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2357 {
2358 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2359 }
2360
2361 if (!empty($categories))
2362 {
2363 return SimplePie_Misc::array_unique($categories);
2364 }
2365 else
2366 {
2367 return null;
2368 }
2369 }
2370
2371 function get_author($key = 0)
2372 {
2373 $authors = $this->get_authors();
2374 if (isset($authors[$key]))
2375 {
2376 return $authors[$key];
2377 }
2378 else
2379 {
2380 return null;
2381 }
2382 }
2383
2384 function get_authors()
2385 {
2386 $authors = array();
2387 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2388 {
2389 $name = null;
2390 $uri = null;
2391 $email = null;
2392 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2393 {
2394 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2395 }
2396 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2397 {
2398 $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]));
2399 }
2400 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2401 {
2402 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2403 }
2404 if ($name !== null || $email !== null || $uri !== null)
2405 {
2406 $authors[] =& new $this->author_class($name, $uri, $email);
2407 }
2408 }
2409 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2410 {
2411 $name = null;
2412 $url = null;
2413 $email = null;
2414 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2415 {
2416 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2417 }
2418 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2419 {
2420 $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]));
2421 }
2422 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2423 {
2424 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2425 }
2426 if ($name !== null || $email !== null || $url !== null)
2427 {
2428 $authors[] =& new $this->author_class($name, $url, $email);
2429 }
2430 }
2431 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2432 {
2433 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2434 }
2435 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2436 {
2437 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2438 }
2439 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2440 {
2441 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2442 }
2443
2444 if (!empty($authors))
2445 {
2446 return SimplePie_Misc::array_unique($authors);
2447 }
2448 else
2449 {
2450 return null;
2451 }
2452 }
2453
2454 function get_contributor($key = 0)
2455 {
2456 $contributors = $this->get_contributors();
2457 if (isset($contributors[$key]))
2458 {
2459 return $contributors[$key];
2460 }
2461 else
2462 {
2463 return null;
2464 }
2465 }
2466
2467 function get_contributors()
2468 {
2469 $contributors = array();
2470 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2471 {
2472 $name = null;
2473 $uri = null;
2474 $email = null;
2475 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2476 {
2477 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2478 }
2479 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2480 {
2481 $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]));
2482 }
2483 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2484 {
2485 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2486 }
2487 if ($name !== null || $email !== null || $uri !== null)
2488 {
2489 $contributors[] =& new $this->author_class($name, $uri, $email);
2490 }
2491 }
2492 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2493 {
2494 $name = null;
2495 $url = null;
2496 $email = null;
2497 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2498 {
2499 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2500 }
2501 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2502 {
2503 $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]));
2504 }
2505 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2506 {
2507 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2508 }
2509 if ($name !== null || $email !== null || $url !== null)
2510 {
2511 $contributors[] =& new $this->author_class($name, $url, $email);
2512 }
2513 }
2514
2515 if (!empty($contributors))
2516 {
2517 return SimplePie_Misc::array_unique($contributors);
2518 }
2519 else
2520 {
2521 return null;
2522 }
2523 }
2524
2525 function get_link($key = 0, $rel = 'alternate')
2526 {
2527 $links = $this->get_links($rel);
2528 if (isset($links[$key]))
2529 {
2530 return $links[$key];
2531 }
2532 else
2533 {
2534 return null;
2535 }
2536 }
2537
2538 /**
2539 * Added for parity between the parent-level and the item/entry-level.
2540 */
2541 function get_permalink()
2542 {
2543 return $this->get_link(0);
2544 }
2545
2546 function get_links($rel = 'alternate')
2547 {
2548 if (!isset($this->data['links']))
2549 {
2550 $this->data['links'] = array();
2551 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2552 {
2553 foreach ($links as $link)
2554 {
2555 if (isset($link['attribs']['']['href']))
2556 {
2557 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2558 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2559 }
2560 }
2561 }
2562 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2563 {
2564 foreach ($links as $link)
2565 {
2566 if (isset($link['attribs']['']['href']))
2567 {
2568 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2569 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2570
2571 }
2572 }
2573 }
2574 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2575 {
2576 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2577 }
2578 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2579 {
2580 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2581 }
2582 if ($links = $this->get_channel_tags('', 'link'))
2583 {
2584 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2585 }
2586
2587 $keys = array_keys($this->data['links']);
2588 foreach ($keys as $key)
2589 {
2590 if (SimplePie_Misc::is_isegment_nz_nc($key))
2591 {
2592 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2593 {
2594 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2595 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2596 }
2597 else
2598 {
2599 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2600 }
2601 }
2602 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2603 {
2604 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2605 }
2606 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2607 }
2608 }
2609
2610 if (isset($this->data['links'][$rel]))
2611 {
2612 return $this->data['links'][$rel];
2613 }
2614 else
2615 {
2616 return null;
2617 }
2618 }
2619
2620 function get_description()
2621 {
2622 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2623 {
2624 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2625 }
2626 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2627 {
2628 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2629 }
2630 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2631 {
2632 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2633 }
2634 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2635 {
2636 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2637 }
2638 elseif ($return = $this->get_channel_tags('', 'description'))
2639 {
2640 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2641 }
2642 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2643 {
2644 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2645 }
2646 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2647 {
2648 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2649 }
2650 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2651 {
2652 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2653 }
2654 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2655 {
2656 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2657 }
2658 else
2659 {
2660 return null;
2661 }
2662 }
2663
2664 function get_copyright()
2665 {
2666 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2667 {
2668 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2669 }
2670 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2671 {
2672 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2673 }
2674 elseif ($return = $this->get_channel_tags('', 'copyright'))
2675 {
2676 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2677 }
2678 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2679 {
2680 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2681 }
2682 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2683 {
2684 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2685 }
2686 else
2687 {
2688 return null;
2689 }
2690 }
2691
2692 function get_language()
2693 {
2694 if ($return = $this->get_channel_tags('', 'language'))
2695 {
2696 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2697 }
2698 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2699 {
2700 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2701 }
2702 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2703 {
2704 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2705 }
2706 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2707 {
2708 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2709 }
2710 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2711 {
2712 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2713 }
2714 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2715 {
2716 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2717 }
2718 elseif (isset($this->data['headers']['content-language']))
2719 {
2720 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2721 }
2722 else
2723 {
2724 return null;
2725 }
2726 }
2727
2728 function get_latitude()
2729 {
2730 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2731 {
2732 return (float) $return[0]['data'];
2733 }
2734 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2735 {
2736 return (float) $match[1];
2737 }
2738 else
2739 {
2740 return null;
2741 }
2742 }
2743
2744 function get_longitude()
2745 {
2746 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2747 {
2748 return (float) $return[0]['data'];
2749 }
2750 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2751 {
2752 return (float) $return[0]['data'];
2753 }
2754 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2755 {
2756 return (float) $match[2];
2757 }
2758 else
2759 {
2760 return null;
2761 }
2762 }
2763
2764 function get_image_title()
2765 {
2766 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2767 {
2768 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2769 }
2770 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2771 {
2772 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2773 }
2774 elseif ($return = $this->get_image_tags('', 'title'))
2775 {
2776 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2777 }
2778 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2779 {
2780 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2781 }
2782 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2783 {
2784 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2785 }
2786 else
2787 {
2788 return null;
2789 }
2790 }
2791
2792 function get_image_url()
2793 {
2794 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2795 {
2796 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2797 }
2798 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2799 {
2800 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2801 }
2802 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2803 {
2804 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2805 }
2806 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2807 {
2808 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2809 }
2810 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2811 {
2812 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2813 }
2814 elseif ($return = $this->get_image_tags('', 'url'))
2815 {
2816 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2817 }
2818 else
2819 {
2820 return null;
2821 }
2822 }
2823
2824 function get_image_link()
2825 {
2826 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2827 {
2828 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2829 }
2830 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2831 {
2832 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2833 }
2834 elseif ($return = $this->get_image_tags('', 'link'))
2835 {
2836 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2837 }
2838 else
2839 {
2840 return null;
2841 }
2842 }
2843
2844 function get_image_width()
2845 {
2846 if ($return = $this->get_image_tags('', 'width'))
2847 {
2848 return round($return[0]['data']);
2849 }
2850 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2851 {
2852 return 88.0;
2853 }
2854 else
2855 {
2856 return null;
2857 }
2858 }
2859
2860 function get_image_height()
2861 {
2862 if ($return = $this->get_image_tags('', 'height'))
2863 {
2864 return round($return[0]['data']);
2865 }
2866 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2867 {
2868 return 31.0;
2869 }
2870 else
2871 {
2872 return null;
2873 }
2874 }
2875
2876 function get_item_quantity($max = 0)
2877 {
2878 $qty = count($this->get_items());
2879 if ($max == 0)
2880 {
2881 return $qty;
2882 }
2883 else
2884 {
2885 return ($qty > $max) ? $max : $qty;
2886 }
2887 }
2888
2889 function get_item($key = 0)
2890 {
2891 $items = $this->get_items();
2892 if (isset($items[$key]))
2893 {
2894 return $items[$key];
2895 }
2896 else
2897 {
2898 return null;
2899 }
2900 }
2901
2902 function get_items($start = 0, $end = 0)
2903 {
2904 if (!empty($this->multifeed_objects))
2905 {
2906 return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2907 }
2908 elseif (!isset($this->data['items']))
2909 {
2910 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2911 {
2912 $keys = array_keys($items);
2913 foreach ($keys as $key)
2914 {
2915 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2916 }
2917 }
2918 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2919 {
2920 $keys = array_keys($items);
2921 foreach ($keys as $key)
2922 {
2923 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2924 }
2925 }
2926 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2927 {
2928 $keys = array_keys($items);
2929 foreach ($keys as $key)
2930 {
2931 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2932 }
2933 }
2934 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2935 {
2936 $keys = array_keys($items);
2937 foreach ($keys as $key)
2938 {
2939 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2940 }
2941 }
2942 if ($items = $this->get_channel_tags('', 'item'))
2943 {
2944 $keys = array_keys($items);
2945 foreach ($keys as $key)
2946 {
2947 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2948 }
2949 }
2950 }
2951
2952 if (!empty($this->data['items']))
2953 {
2954 // If we want to order it by date, check if all items have a date, and then sort it
2955 if ($this->order_by_date)
2956 {
2957 if (!isset($this->data['ordered_items']))
2958 {
2959 $do_sort = true;
2960 foreach ($this->data['items'] as $item)
2961 {
2962 if (!$item->get_date('U'))
2963 {
2964 $do_sort = false;
2965 break;
2966 }
2967 }
2968 $item = null;
2969 $this->data['ordered_items'] = $this->data['items'];
2970 if ($do_sort)
2971 {
2972 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2973 }
2974 }
2975 $items = $this->data['ordered_items'];
2976 }
2977 else
2978 {
2979 $items = $this->data['items'];
2980 }
2981
2982 // Slice the data as desired
2983 if ($end == 0)
2984 {
2985 return array_slice($items, $start);
2986 }
2987 else
2988 {
2989 return array_slice($items, $start, $end);
2990 }
2991 }
2992 else
2993 {
2994 return array();
2995 }
2996 }
2997
2998 function sort_items($a, $b)
2999 {
3000 return $a->get_date('U') <= $b->get_date('U');
3001 }
3002
3003 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3004 {
3005 if (is_array($urls) && sizeof($urls) > 0)
3006 {
3007 $items = array();
3008 foreach ($urls as $arg)
3009 {
3010 if (is_a($arg, 'SimplePie'))
3011 {
3012 $items = array_merge($items, $arg->get_items(0, $limit));
3013 }
3014 else
3015 {
3016 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3017 }
3018 }
3019
3020 $do_sort = true;
3021 foreach ($items as $item)
3022 {
3023 if (!$item->get_date('U'))
3024 {
3025 $do_sort = false;
3026 break;
3027 }
3028 }
3029 $item = null;
3030 if ($do_sort)
3031 {
3032 usort($items, array('SimplePie', 'sort_items'));
3033 }
3034
3035 if ($end == 0)
3036 {
3037 return array_slice($items, $start);
3038 }
3039 else
3040 {
3041 return array_slice($items, $start, $end);
3042 }
3043 }
3044 else
3045 {
3046 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3047 return array();
3048 }
3049 }
3050 }
3051
3052 class SimplePie_Item
3053 {
3054 var $feed;
3055 var $data = array();
3056
3057 function SimplePie_Item($feed, $data)
3058 {
3059 $this->feed = $feed;
3060 $this->data = $data;
3061 }
3062
3063 function __toString()
3064 {
3065 return md5(serialize($this->data));
3066 }
3067
3068 /**
3069 * Remove items that link back to this before destroying this object
3070 */
3071 function __destruct()
3072 {
3073 unset($this->feed);
3074 }
3075
3076 function get_item_tags($namespace, $tag)
3077 {
3078 if (isset($this->data['child'][$namespace][$tag]))
3079 {
3080 return $this->data['child'][$namespace][$tag];
3081 }
3082 else
3083 {
3084 return null;
3085 }
3086 }
3087
3088 function get_base($element = array())
3089 {
3090 return $this->feed->get_base($element);
3091 }
3092
3093 function sanitize($data, $type, $base = '')
3094 {
3095 return $this->feed->sanitize($data, $type, $base);
3096 }
3097
3098 function get_feed()
3099 {
3100 return $this->feed;
3101 }
3102
3103 function get_id($hash = false)
3104 {
3105 if (!$hash)
3106 {
3107 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3108 {
3109 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3110 }
3111 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3112 {
3113 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3114 }
3115 elseif ($return = $this->get_item_tags('', 'guid'))
3116 {
3117 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3118 }
3119 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3120 {
3121 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3122 }
3123 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3124 {
3125 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3126 }
3127 elseif (($return = $this->get_permalink()) !== null)
3128 {
3129 return $return;
3130 }
3131 elseif (($return = $this->get_title()) !== null)
3132 {
3133 return $return;
3134 }
3135 }
3136 if ($this->get_permalink() !== null || $this->get_title() !== null)
3137 {
3138 return md5($this->get_permalink() . $this->get_title());
3139 }
3140 else
3141 {
3142 return md5(serialize($this->data));
3143 }
3144 }
3145
3146 function get_title()
3147 {
3148 if (!isset($this->data['title']))
3149 {
3150 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3151 {
3152 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3153 }
3154 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3155 {
3156 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3157 }
3158 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3159 {
3160 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3161 }
3162 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3163 {
3164 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3165 }
3166 elseif ($return = $this->get_item_tags('', 'title'))
3167 {
3168 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3169 }
3170 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3171 {
3172 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3173 }
3174 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3175 {
3176 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3177 }
3178 else
3179 {
3180 $this->data['title'] = null;
3181 }
3182 }
3183 return $this->data['title'];
3184 }
3185
3186 function get_description($description_only = false)
3187 {
3188 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3189 {
3190 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3191 }
3192 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3193 {
3194 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3195 }
3196 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3197 {
3198 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3199 }
3200 elseif ($return = $this->get_item_tags('', 'description'))
3201 {
3202 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3203 }
3204 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3205 {
3206 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3207 }
3208 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3209 {
3210 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3211 }
3212 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3213 {
3214 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3215 }
3216 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3217 {
3218 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3219 }
3220 elseif (!$description_only)
3221 {
3222 return $this->get_content(true);
3223 }
3224 else
3225 {
3226 return null;
3227 }
3228 }
3229
3230 function get_content($content_only = false)
3231 {
3232 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3233 {
3234 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3235 }
3236 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3237 {
3238 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3239 }
3240 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3241 {
3242 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3243 }
3244 elseif (!$content_only)
3245 {
3246 return $this->get_description(true);
3247 }
3248 else
3249 {
3250 return null;
3251 }
3252 }
3253
3254 function get_category($key = 0)
3255 {
3256 $categories = $this->get_categories();
3257 if (isset($categories[$key]))
3258 {
3259 return $categories[$key];
3260 }
3261 else
3262 {
3263 return null;
3264 }
3265 }
3266
3267 function get_categories()
3268 {
3269 $categories = array();
3270
3271 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3272 {
3273 $term = null;
3274 $scheme = null;
3275 $label = null;
3276 if (isset($category['attribs']['']['term']))
3277 {
3278 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3279 }
3280 if (isset($category['attribs']['']['scheme']))
3281 {
3282 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3283 }
3284 if (isset($category['attribs']['']['label']))
3285 {
3286 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3287 }
3288 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
3289 }
3290 foreach ((array) $this->get_item_tags('', 'category') as $category)
3291 {
3292 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3293 }
3294 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3295 {
3296 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3297 }
3298 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3299 {
3300 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3301 }
3302
3303 if (!empty($categories))
3304 {
3305 return SimplePie_Misc::array_unique($categories);
3306 }
3307 else
3308 {
3309 return null;
3310 }
3311 }
3312
3313 function get_author($key = 0)
3314 {
3315 $authors = $this->get_authors();
3316 if (isset($authors[$key]))
3317 {
3318 return $authors[$key];
3319 }
3320 else
3321 {
3322 return null;
3323 }
3324 }
3325
3326 function get_contributor($key = 0)
3327 {
3328 $contributors = $this->get_contributors();
3329 if (isset($contributors[$key]))
3330 {
3331 return $contributors[$key];
3332 }
3333 else
3334 {
3335 return null;
3336 }
3337 }
3338
3339 function get_contributors()
3340 {
3341 $contributors = array();
3342 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3343 {
3344 $name = null;
3345 $uri = null;
3346 $email = null;
3347 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3348 {
3349 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3350 }
3351 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3352 {
3353 $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]));
3354 }
3355 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3356 {
3357 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3358 }
3359 if ($name !== null || $email !== null || $uri !== null)
3360 {
3361 $contributors[] =& new $this->feed->author_class($name, $uri, $email);
3362 }
3363 }
3364 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3365 {
3366 $name = null;
3367 $url = null;
3368 $email = null;
3369 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3370 {
3371 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3372 }
3373 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3374 {
3375 $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]));
3376 }
3377 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3378 {
3379 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3380 }
3381 if ($name !== null || $email !== null || $url !== null)
3382 {
3383 $contributors[] =& new $this->feed->author_class($name, $url, $email);
3384 }
3385 }
3386
3387 if (!empty($contributors))
3388 {
3389 return SimplePie_Misc::array_unique($contributors);
3390 }
3391 else
3392 {
3393 return null;
3394 }
3395 }
3396
3397 /**
3398 * @todo Atom inheritance (item author, source author, feed author)
3399 */
3400 function get_authors()
3401 {
3402 $authors = array();
3403 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3404 {
3405 $name = null;
3406 $uri = null;
3407 $email = null;
3408 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3409 {
3410 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3411 }
3412 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3413 {
3414 $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]));
3415 }
3416 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3417 {
3418 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3419 }
3420 if ($name !== null || $email !== null || $uri !== null)
3421 {
3422 $authors[] =& new $this->feed->author_class($name, $uri, $email);
3423 }
3424 }
3425 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3426 {
3427 $name = null;
3428 $url = null;
3429 $email = null;
3430 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3431 {
3432 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3433 }
3434 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3435 {
3436 $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]));
3437 }
3438 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3439 {
3440 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3441 }
3442 if ($name !== null || $email !== null || $url !== null)
3443 {
3444 $authors[] =& new $this->feed->author_class($name, $url, $email);
3445 }
3446 }
3447 if ($author = $this->get_item_tags('', 'author'))
3448 {
3449 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3450 }
3451 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3452 {
3453 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3454 }
3455 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3456 {
3457 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3458 }
3459 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3460 {
3461 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3462 }
3463
3464 if (!empty($authors))
3465 {
3466 return SimplePie_Misc::array_unique($authors);
3467 }
3468 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3469 {
3470 return $authors;
3471 }
3472 elseif ($authors = $this->feed->get_authors())
3473 {
3474 return $authors;
3475 }
3476 else
3477 {
3478 return null;
3479 }
3480 }
3481
3482 function get_copyright()
3483 {
3484 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3485 {
3486 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3487 }
3488 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3489 {
3490 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3491 }
3492 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3493 {
3494 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3495 }
3496 else
3497 {
3498 return null;
3499 }
3500 }
3501
3502 function get_date($date_format = 'j F Y, g:i a')
3503 {
3504 if (!isset($this->data['date']))
3505 {
3506 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3507 {
3508 $this->data['date']['raw'] = $return[0]['data'];
3509 }
3510 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3511 {
3512 $this->data['date']['raw'] = $return[0]['data'];
3513 }
3514 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3515 {
3516 $this->data['date']['raw'] = $return[0]['data'];
3517 }
3518 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3519 {
3520 $this->data['date']['raw'] = $return[0]['data'];
3521 }
3522 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3523 {
3524 $this->data['date']['raw'] = $return[0]['data'];
3525 }
3526 elseif ($return = $this->get_item_tags('', 'pubDate'))
3527 {
3528 $this->data['date']['raw'] = $return[0]['data'];
3529 }
3530 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3531 {
3532 $this->data['date']['raw'] = $return[0]['data'];
3533 }
3534 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3535 {
3536 $this->data['date']['raw'] = $return[0]['data'];
3537 }
3538
3539 if (!empty($this->data['date']['raw']))
3540 {
3541 $parser = SimplePie_Parse_Date::get();
3542 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3543 }
3544 else
3545 {
3546 $this->data['date'] = null;
3547 }
3548 }
3549 if ($this->data['date'])
3550 {
3551 $date_format = (string) $date_format;
3552 switch ($date_format)
3553 {
3554 case '':
3555 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3556
3557 case 'U':
3558 return $this->data['date']['parsed'];
3559
3560 default:
3561 return date($date_format, $this->data['date']['parsed']);
3562 }
3563 }
3564 else
3565 {
3566 return null;
3567 }
3568 }
3569
3570 function get_local_date($date_format = '%c')
3571 {
3572 if (!$date_format)
3573 {
3574 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3575 }
3576 elseif (($date = $this->get_date('U')) !== null)
3577 {
3578 return strftime($date_format, $date);
3579 }
3580 else
3581 {
3582 return null;
3583 }
3584 }
3585
3586 function get_permalink()
3587 {
3588 $link = $this->get_link();
3589 $enclosure = $this->get_enclosure(0);
3590 if ($link !== null)
3591 {
3592 return $link;
3593 }
3594 elseif ($enclosure !== null)
3595 {
3596 return $enclosure->get_link();
3597 }
3598 else
3599 {
3600 return null;
3601 }
3602 }
3603
3604 function get_link($key = 0, $rel = 'alternate')
3605 {
3606 $links = $this->get_links($rel);
3607 if ($links[$key] !== null)
3608 {
3609 return $links[$key];
3610 }
3611 else
3612 {
3613 return null;
3614 }
3615 }
3616
3617 function get_links($rel = 'alternate')
3618 {
3619 if (!isset($this->data['links']))
3620 {
3621 $this->data['links'] = array();
3622 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3623 {
3624 if (isset($link['attribs']['']['href']))
3625 {
3626 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3627 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3628
3629 }
3630 }
3631 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3632 {
3633 if (isset($link['attribs']['']['href']))
3634 {
3635 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3636 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3637 }
3638 }
3639 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3640 {
3641 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3642 }
3643 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3644 {
3645 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3646 }
3647 if ($links = $this->get_item_tags('', 'link'))
3648 {
3649 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3650 }
3651 if ($links = $this->get_item_tags('', 'guid'))
3652 {
3653 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3654 {
3655 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3656 }
3657 }
3658
3659 $keys = array_keys($this->data['links']);
3660 foreach ($keys as $key)
3661 {
3662 if (SimplePie_Misc::is_isegment_nz_nc($key))
3663 {
3664 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3665 {
3666 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3667 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3668 }
3669 else
3670 {
3671 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3672 }
3673 }
3674 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3675 {
3676 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3677 }
3678 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3679 }
3680 }
3681 if (isset($this->data['links'][$rel]))
3682 {
3683 return $this->data['links'][$rel];
3684 }
3685 else
3686 {
3687 return null;
3688 }
3689 }
3690
3691 /**
3692 * @todo Add ability to prefer one type of content over another (in a media group).
3693 */
3694 function get_enclosure($key = 0, $prefer = null)
3695 {
3696 $enclosures = $this->get_enclosures();
3697 if (isset($enclosures[$key]))
3698 {
3699 return $enclosures[$key];
3700 }
3701 else
3702 {
3703 return null;
3704 }
3705 }
3706
3707 /**
3708 * Grabs all available enclosures (podcasts, etc.)
3709 *
3710 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3711 *
3712 * 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.
3713 *
3714 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3715 * @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).
3716 */
3717 function get_enclosures()
3718 {
3719 if (!isset($this->data['enclosures']))
3720 {
3721 $this->data['enclosures'] = array();
3722
3723 // Elements
3724 $captions_parent = null;
3725 $categories_parent = null;
3726 $copyrights_parent = null;
3727 $credits_parent = null;
3728 $description_parent = null;
3729 $duration_parent = null;
3730 $hashes_parent = null;
3731 $keywords_parent = null;
3732 $player_parent = null;
3733 $ratings_parent = null;
3734 $restrictions_parent = null;
3735 $thumbnails_parent = null;
3736 $title_parent = null;
3737
3738 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3739 $parent = $this->get_feed();
3740
3741 // CAPTIONS
3742 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3743 {
3744 foreach ($captions as $caption)
3745 {
3746 $caption_type = null;
3747 $caption_lang = null;
3748 $caption_startTime = null;
3749 $caption_endTime = null;
3750 $caption_text = null;
3751 if (isset($caption['attribs']['']['type']))
3752 {
3753 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3754 }
3755 if (isset($caption['attribs']['']['lang']))
3756 {
3757 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3758 }
3759 if (isset($caption['attribs']['']['start']))
3760 {
3761 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3762 }
3763 if (isset($caption['attribs']['']['end']))
3764 {
3765 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3766 }
3767 if (isset($caption['data']))
3768 {
3769 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3770 }
3771 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3772 }
3773 }
3774 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3775 {
3776 foreach ($captions as $caption)
3777 {
3778 $caption_type = null;
3779 $caption_lang = null;
3780 $caption_startTime = null;
3781 $caption_endTime = null;
3782 $caption_text = null;
3783 if (isset($caption['attribs']['']['type']))
3784 {
3785 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3786 }
3787 if (isset($caption['attribs']['']['lang']))
3788 {
3789 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3790 }
3791 if (isset($caption['attribs']['']['start']))
3792 {
3793 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3794 }
3795 if (isset($caption['attribs']['']['end']))
3796 {
3797 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3798 }
3799 if (isset($caption['data']))
3800 {
3801 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3802 }
3803 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3804 }
3805 }
3806 if (is_array($captions_parent))
3807 {
3808 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3809 }
3810
3811 // CATEGORIES
3812 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3813 {
3814 $term = null;
3815 $scheme = null;
3816 $label = null;
3817 if (isset($category['data']))
3818 {
3819 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3820 }
3821 if (isset($category['attribs']['']['scheme']))
3822 {
3823 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3824 }
3825 else
3826 {
3827 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3828 }
3829 if (isset($category['attribs']['']['label']))
3830 {
3831 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3832 }
3833 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3834 }
3835 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3836 {
3837 $term = null;
3838 $scheme = null;
3839 $label = null;
3840 if (isset($category['data']))
3841 {
3842 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3843 }
3844 if (isset($category['attribs']['']['scheme']))
3845 {
3846 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3847 }
3848 else
3849 {
3850 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3851 }
3852 if (isset($category['attribs']['']['label']))
3853 {
3854 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3855 }
3856 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3857 }
3858 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3859 {
3860 $term = null;
3861 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3862 $label = null;
3863 if (isset($category['attribs']['']['text']))
3864 {
3865 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3866 }
3867 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3868
3869 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3870 {
3871 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3872 {
3873 if (isset($subcategory['attribs']['']['text']))
3874 {
3875 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3876 }
3877 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3878 }
3879 }
3880 }
3881 if (is_array($categories_parent))
3882 {
3883 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3884 }
3885
3886 // COPYRIGHT
3887 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3888 {
3889 $copyright_url = null;
3890 $copyright_label = null;
3891 if (isset($copyright[0]['attribs']['']['url']))
3892 {
3893 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3894 }
3895 if (isset($copyright[0]['data']))
3896 {
3897 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3898 }
3899 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3900 }
3901 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3902 {
3903 $copyright_url = null;
3904 $copyright_label = null;
3905 if (isset($copyright[0]['attribs']['']['url']))
3906 {
3907 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3908 }
3909 if (isset($copyright[0]['data']))
3910 {
3911 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3912 }
3913 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3914 }
3915
3916 // CREDITS
3917 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3918 {
3919 foreach ($credits as $credit)
3920 {
3921 $credit_role = null;
3922 $credit_scheme = null;
3923 $credit_name = null;
3924 if (isset($credit['attribs']['']['role']))
3925 {
3926 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3927 }
3928 if (isset($credit['attribs']['']['scheme']))
3929 {
3930 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3931 }
3932 else
3933 {
3934 $credit_scheme = 'urn:ebu';
3935 }
3936 if (isset($credit['data']))
3937 {
3938 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3939 }
3940 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3941 }
3942 }
3943 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3944 {
3945 foreach ($credits as $credit)
3946 {
3947 $credit_role = null;
3948 $credit_scheme = null;
3949 $credit_name = null;
3950 if (isset($credit['attribs']['']['role']))
3951 {
3952 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3953 }
3954 if (isset($credit['attribs']['']['scheme']))
3955 {
3956 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3957 }
3958 else
3959 {
3960 $credit_scheme = 'urn:ebu';
3961 }
3962 if (isset($credit['data']))
3963 {
3964 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3965 }
3966 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3967 }
3968 }
3969 if (is_array($credits_parent))
3970 {
3971 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3972 }
3973
3974 // DESCRIPTION
3975 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3976 {
3977 if (isset($description_parent[0]['data']))
3978 {
3979 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3980 }
3981 }
3982 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3983 {
3984 if (isset($description_parent[0]['data']))
3985 {
3986 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3987 }
3988 }
3989
3990 // DURATION
3991 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
3992 {
3993 $seconds = null;
3994 $minutes = null;
3995 $hours = null;
3996 if (isset($duration_parent[0]['data']))
3997 {
3998 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3999 if (sizeof($temp) > 0)
4000 {
4001 (int) $seconds = array_pop($temp);
4002 }
4003 if (sizeof($temp) > 0)
4004 {
4005 (int) $minutes = array_pop($temp);
4006 $seconds += $minutes * 60;
4007 }
4008 if (sizeof($temp) > 0)
4009 {
4010 (int) $hours = array_pop($temp);
4011 $seconds += $hours * 3600;
4012 }
4013 unset($temp);
4014 $duration_parent = $seconds;
4015 }
4016 }
4017
4018 // HASHES
4019 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4020 {
4021 foreach ($hashes_iterator as $hash)
4022 {
4023 $value = null;
4024 $algo = null;
4025 if (isset($hash['data']))
4026 {
4027 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4028 }
4029 if (isset($hash['attribs']['']['algo']))
4030 {
4031 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4032 }
4033 else
4034 {
4035 $algo = 'md5';
4036 }
4037 $hashes_parent[] = $algo.':'.$value;
4038 }
4039 }
4040 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4041 {
4042 foreach ($hashes_iterator as $hash)
4043 {
4044 $value = null;
4045 $algo = null;
4046 if (isset($hash['data']))
4047 {
4048 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4049 }
4050 if (isset($hash['attribs']['']['algo']))
4051 {
4052 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4053 }
4054 else
4055 {
4056 $algo = 'md5';
4057 }
4058 $hashes_parent[] = $algo.':'.$value;
4059 }
4060 }
4061 if (is_array($hashes_parent))
4062 {
4063 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4064 }
4065
4066 // KEYWORDS
4067 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4068 {
4069 if (isset($keywords[0]['data']))
4070 {
4071 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4072 foreach ($temp as $word)
4073 {
4074 $keywords_parent[] = trim($word);
4075 }
4076 }
4077 unset($temp);
4078 }
4079 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4080 {
4081 if (isset($keywords[0]['data']))
4082 {
4083 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4084 foreach ($temp as $word)
4085 {
4086 $keywords_parent[] = trim($word);
4087 }
4088 }
4089 unset($temp);
4090 }
4091 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4092 {
4093 if (isset($keywords[0]['data']))
4094 {
4095 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4096 foreach ($temp as $word)
4097 {
4098 $keywords_parent[] = trim($word);
4099 }
4100 }
4101 unset($temp);
4102 }
4103 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4104 {
4105 if (isset($keywords[0]['data']))
4106 {
4107 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4108 foreach ($temp as $word)
4109 {
4110 $keywords_parent[] = trim($word);
4111 }
4112 }
4113 unset($temp);
4114 }
4115 if (is_array($keywords_parent))
4116 {
4117 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4118 }
4119
4120 // PLAYER
4121 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4122 {
4123 if (isset($player_parent[0]['attribs']['']['url']))
4124 {
4125 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4126 }
4127 }
4128 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4129 {
4130 if (isset($player_parent[0]['attribs']['']['url']))
4131 {
4132 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4133 }
4134 }
4135
4136 // RATINGS
4137 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4138 {
4139 foreach ($ratings as $rating)
4140 {
4141 $rating_scheme = null;
4142 $rating_value = null;
4143 if (isset($rating['attribs']['']['scheme']))
4144 {
4145 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4146 }
4147 else
4148 {
4149 $rating_scheme = 'urn:simple';
4150 }
4151 if (isset($rating['data']))
4152 {
4153 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4154 }
4155 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4156 }
4157 }
4158 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4159 {
4160 foreach ($ratings as $rating)
4161 {
4162 $rating_scheme = 'urn:itunes';
4163 $rating_value = null;
4164 if (isset($rating['data']))
4165 {
4166 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4167 }
4168 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4169 }
4170 }
4171 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4172 {
4173 foreach ($ratings as $rating)
4174 {
4175 $rating_scheme = null;
4176 $rating_value = null;
4177 if (isset($rating['attribs']['']['scheme']))
4178 {
4179 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4180 }
4181 else
4182 {
4183 $rating_scheme = 'urn:simple';
4184 }
4185 if (isset($rating['data']))
4186 {
4187 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4188 }
4189 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4190 }
4191 }
4192 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4193 {
4194 foreach ($ratings as $rating)
4195 {
4196 $rating_scheme = 'urn:itunes';
4197 $rating_value = null;
4198 if (isset($rating['data']))
4199 {
4200 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4201 }
4202 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4203 }
4204 }
4205 if (is_array($ratings_parent))
4206 {
4207 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4208 }
4209
4210 // RESTRICTIONS
4211 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4212 {
4213 foreach ($restrictions as $restriction)
4214 {
4215 $restriction_relationship = null;
4216 $restriction_type = null;
4217 $restriction_value = null;
4218 if (isset($restriction['attribs']['']['relationship']))
4219 {
4220 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4221 }
4222 if (isset($restriction['attribs']['']['type']))
4223 {
4224 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4225 }
4226 if (isset($restriction['data']))
4227 {
4228 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4229 }
4230 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4231 }
4232 }
4233 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4234 {
4235 foreach ($restrictions as $restriction)
4236 {
4237 $restriction_relationship = 'allow';
4238 $restriction_type = null;
4239 $restriction_value = 'itunes';
4240 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4241 {
4242 $restriction_relationship = 'deny';
4243 }
4244 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4245 }
4246 }
4247 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4248 {
4249 foreach ($restrictions as $restriction)
4250 {
4251 $restriction_relationship = null;
4252 $restriction_type = null;
4253 $restriction_value = null;
4254 if (isset($restriction['attribs']['']['relationship']))
4255 {
4256 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4257 }
4258 if (isset($restriction['attribs']['']['type']))
4259 {
4260 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4261 }
4262 if (isset($restriction['data']))
4263 {
4264 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4265 }
4266 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4267 }
4268 }
4269 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4270 {
4271 foreach ($restrictions as $restriction)
4272 {
4273 $restriction_relationship = 'allow';
4274 $restriction_type = null;
4275 $restriction_value = 'itunes';
4276 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4277 {
4278 $restriction_relationship = 'deny';
4279 }
4280 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4281 }
4282 }
4283 if (is_array($restrictions_parent))
4284 {
4285 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4286 }
4287
4288 // THUMBNAILS
4289 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4290 {
4291 foreach ($thumbnails as $thumbnail)
4292 {
4293 if (isset($thumbnail['attribs']['']['url']))
4294 {
4295 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4296 }
4297 }
4298 }
4299 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4300 {
4301 foreach ($thumbnails as $thumbnail)
4302 {
4303 if (isset($thumbnail['attribs']['']['url']))
4304 {
4305 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4306 }
4307 }
4308 }
4309
4310 // TITLES
4311 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4312 {
4313 if (isset($title_parent[0]['data']))
4314 {
4315 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4316 }
4317 }
4318 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4319 {
4320 if (isset($title_parent[0]['data']))
4321 {
4322 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4323 }
4324 }
4325
4326 // Clear the memory
4327 unset($parent);
4328
4329 // If we have media:group tags, loop through them.
4330 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4331 {
4332 // If we have media:content tags, loop through them.
4333 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4334 {
4335 if (isset($content['attribs']['']['url']))
4336 {
4337 // Attributes
4338 $bitrate = null;
4339 $channels = null;
4340 $duration = null;
4341 $expression = null;
4342 $framerate = null;
4343 $height = null;
4344 $javascript = null;
4345 $lang = null;
4346 $length = null;
4347 $medium = null;
4348 $samplingrate = null;
4349 $type = null;
4350 $url = null;
4351 $width = null;
4352
4353 // Elements
4354 $captions = null;
4355 $categories = null;
4356 $copyrights = null;
4357 $credits = null;
4358 $description = null;
4359 $hashes = null;
4360 $keywords = null;
4361 $player = null;
4362 $ratings = null;
4363 $restrictions = null;
4364 $thumbnails = null;
4365 $title = null;
4366
4367 // Start checking the attributes of media:content
4368 if (isset($content['attribs']['']['bitrate']))
4369 {
4370 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4371 }
4372 if (isset($content['attribs']['']['channels']))
4373 {
4374 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4375 }
4376 if (isset($content['attribs']['']['duration']))
4377 {
4378 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4379 }
4380 else
4381 {
4382 $duration = $duration_parent;
4383 }
4384 if (isset($content['attribs']['']['expression']))
4385 {
4386 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4387 }
4388 if (isset($content['attribs']['']['framerate']))
4389 {
4390 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4391 }
4392 if (isset($content['attribs']['']['height']))
4393 {
4394 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4395 }
4396 if (isset($content['attribs']['']['lang']))
4397 {
4398 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4399 }
4400 if (isset($content['attribs']['']['fileSize']))
4401 {
4402 $length = ceil($content['attribs']['']['fileSize']);
4403 }
4404 if (isset($content['attribs']['']['medium']))
4405 {
4406 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4407 }
4408 if (isset($content['attribs']['']['samplingrate']))
4409 {
4410 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4411 }
4412 if (isset($content['attribs']['']['type']))
4413 {
4414 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4415 }
4416 if (isset($content['attribs']['']['width']))
4417 {
4418 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4419 }
4420 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4421
4422 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4423
4424 // CAPTIONS
4425 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4426 {
4427 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4428 {
4429 $caption_type = null;
4430 $caption_lang = null;
4431 $caption_startTime = null;
4432 $caption_endTime = null;
4433 $caption_text = null;
4434 if (isset($caption['attribs']['']['type']))
4435 {
4436 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4437 }
4438 if (isset($caption['attribs']['']['lang']))
4439 {
4440 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4441 }
4442 if (isset($caption['attribs']['']['start']))
4443 {
4444 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4445 }
4446 if (isset($caption['attribs']['']['end']))
4447 {
4448 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4449 }
4450 if (isset($caption['data']))
4451 {
4452 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4453 }
4454 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4455 }
4456 if (is_array($captions))
4457 {
4458 $captions = array_values(SimplePie_Misc::array_unique($captions));
4459 }
4460 }
4461 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4462 {
4463 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4464 {
4465 $caption_type = null;
4466 $caption_lang = null;
4467 $caption_startTime = null;
4468 $caption_endTime = null;
4469 $caption_text = null;
4470 if (isset($caption['attribs']['']['type']))
4471 {
4472 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4473 }
4474 if (isset($caption['attribs']['']['lang']))
4475 {
4476 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4477 }
4478 if (isset($caption['attribs']['']['start']))
4479 {
4480 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4481 }
4482 if (isset($caption['attribs']['']['end']))
4483 {
4484 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4485 }
4486 if (isset($caption['data']))
4487 {
4488 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4489 }
4490 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4491 }
4492 if (is_array($captions))
4493 {
4494 $captions = array_values(SimplePie_Misc::array_unique($captions));
4495 }
4496 }
4497 else
4498 {
4499 $captions = $captions_parent;
4500 }
4501
4502 // CATEGORIES
4503 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4504 {
4505 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4506 {
4507 $term = null;
4508 $scheme = null;
4509 $label = null;
4510 if (isset($category['data']))
4511 {
4512 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4513 }
4514 if (isset($category['attribs']['']['scheme']))
4515 {
4516 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4517 }
4518 else
4519 {
4520 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4521 }
4522 if (isset($category['attribs']['']['label']))
4523 {
4524 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4525 }
4526 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4527 }
4528 }
4529 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4530 {
4531 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4532 {
4533 $term = null;
4534 $scheme = null;
4535 $label = null;
4536 if (isset($category['data']))
4537 {
4538 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4539 }
4540 if (isset($category['attribs']['']['scheme']))
4541 {
4542 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4543 }
4544 else
4545 {
4546 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4547 }
4548 if (isset($category['attribs']['']['label']))
4549 {
4550 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4551 }
4552 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4553 }
4554 }
4555 if (is_array($categories) && is_array($categories_parent))
4556 {
4557 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4558 }
4559 elseif (is_array($categories))
4560 {
4561 $categories = array_values(SimplePie_Misc::array_unique($categories));
4562 }
4563 elseif (is_array($categories_parent))
4564 {
4565 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4566 }
4567
4568 // COPYRIGHTS
4569 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4570 {
4571 $copyright_url = null;
4572 $copyright_label = null;
4573 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4574 {
4575 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4576 }
4577 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4578 {
4579 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4580 }
4581 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4582 }
4583 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4584 {
4585 $copyright_url = null;
4586 $copyright_label = null;
4587 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4588 {
4589 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4590 }
4591 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4592 {
4593 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4594 }
4595 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4596 }
4597 else
4598 {
4599 $copyrights = $copyrights_parent;
4600 }
4601
4602 // CREDITS
4603 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4604 {
4605 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4606 {
4607 $credit_role = null;
4608 $credit_scheme = null;
4609 $credit_name = null;
4610 if (isset($credit['attribs']['']['role']))
4611 {
4612 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4613 }
4614 if (isset($credit['attribs']['']['scheme']))
4615 {
4616 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4617 }
4618 else
4619 {
4620 $credit_scheme = 'urn:ebu';
4621 }
4622 if (isset($credit['data']))
4623 {
4624 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4625 }
4626 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4627 }
4628 if (is_array($credits))
4629 {
4630 $credits = array_values(SimplePie_Misc::array_unique($credits));
4631 }
4632 }
4633 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4634 {
4635 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4636 {
4637 $credit_role = null;
4638 $credit_scheme = null;
4639 $credit_name = null;
4640 if (isset($credit['attribs']['']['role']))
4641 {
4642 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4643 }
4644 if (isset($credit['attribs']['']['scheme']))
4645 {
4646 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4647 }
4648 else
4649 {
4650 $credit_scheme = 'urn:ebu';
4651 }
4652 if (isset($credit['data']))
4653 {
4654 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4655 }
4656 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4657 }
4658 if (is_array($credits))
4659 {
4660 $credits = array_values(SimplePie_Misc::array_unique($credits));
4661 }
4662 }
4663 else
4664 {
4665 $credits = $credits_parent;
4666 }
4667
4668 // DESCRIPTION
4669 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4670 {
4671 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4672 }
4673 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4674 {
4675 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4676 }
4677 else
4678 {
4679 $description = $description_parent;
4680 }
4681
4682 // HASHES
4683 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4684 {
4685 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4686 {
4687 $value = null;
4688 $algo = null;
4689 if (isset($hash['data']))
4690 {
4691 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4692 }
4693 if (isset($hash['attribs']['']['algo']))
4694 {
4695 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4696 }
4697 else
4698 {
4699 $algo = 'md5';
4700 }
4701 $hashes[] = $algo.':'.$value;
4702 }
4703 if (is_array($hashes))
4704 {
4705 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4706 }
4707 }
4708 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4709 {
4710 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4711 {
4712 $value = null;
4713 $algo = null;
4714 if (isset($hash['data']))
4715 {
4716 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4717 }
4718 if (isset($hash['attribs']['']['algo']))
4719 {
4720 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4721 }
4722 else
4723 {
4724 $algo = 'md5';
4725 }
4726 $hashes[] = $algo.':'.$value;
4727 }
4728 if (is_array($hashes))
4729 {
4730 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4731 }
4732 }
4733 else
4734 {
4735 $hashes = $hashes_parent;
4736 }
4737
4738 // KEYWORDS
4739 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4740 {
4741 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4742 {
4743 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4744 foreach ($temp as $word)
4745 {
4746 $keywords[] = trim($word);
4747 }
4748 unset($temp);
4749 }
4750 if (is_array($keywords))
4751 {
4752 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4753 }
4754 }
4755 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4756 {
4757 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4758 {
4759 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4760 foreach ($temp as $word)
4761 {
4762 $keywords[] = trim($word);
4763 }
4764 unset($temp);
4765 }
4766 if (is_array($keywords))
4767 {
4768 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4769 }
4770 }
4771 else
4772 {
4773 $keywords = $keywords_parent;
4774 }
4775
4776 // PLAYER
4777 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4778 {
4779 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4780 }
4781 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4782 {
4783 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4784 }
4785 else
4786 {
4787 $player = $player_parent;
4788 }
4789
4790 // RATINGS
4791 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4792 {
4793 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4794 {
4795 $rating_scheme = null;
4796 $rating_value = null;
4797 if (isset($rating['attribs']['']['scheme']))
4798 {
4799 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4800 }
4801 else
4802 {
4803 $rating_scheme = 'urn:simple';
4804 }
4805 if (isset($rating['data']))
4806 {
4807 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4808 }
4809 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4810 }
4811 if (is_array($ratings))
4812 {
4813 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4814 }
4815 }
4816 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4817 {
4818 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4819 {
4820 $rating_scheme = null;
4821 $rating_value = null;
4822 if (isset($rating['attribs']['']['scheme']))
4823 {
4824 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4825 }
4826 else
4827 {
4828 $rating_scheme = 'urn:simple';
4829 }
4830 if (isset($rating['data']))
4831 {
4832 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4833 }
4834 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4835 }
4836 if (is_array($ratings))
4837 {
4838 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4839 }
4840 }
4841 else
4842 {
4843 $ratings = $ratings_parent;
4844 }
4845
4846 // RESTRICTIONS
4847 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4848 {
4849 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4850 {
4851 $restriction_relationship = null;
4852 $restriction_type = null;
4853 $restriction_value = null;
4854 if (isset($restriction['attribs']['']['relationship']))
4855 {
4856 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4857 }
4858 if (isset($restriction['attribs']['']['type']))
4859 {
4860 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4861 }
4862 if (isset($restriction['data']))
4863 {
4864 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4865 }
4866 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4867 }
4868 if (is_array($restrictions))
4869 {
4870 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4871 }
4872 }
4873 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4874 {
4875 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4876 {
4877 $restriction_relationship = null;
4878 $restriction_type = null;
4879 $restriction_value = null;
4880 if (isset($restriction['attribs']['']['relationship']))
4881 {
4882 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4883 }
4884 if (isset($restriction['attribs']['']['type']))
4885 {
4886 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4887 }
4888 if (isset($restriction['data']))
4889 {
4890 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4891 }
4892 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4893 }
4894 if (is_array($restrictions))
4895 {
4896 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4897 }
4898 }
4899 else
4900 {
4901 $restrictions = $restrictions_parent;
4902 }
4903
4904 // THUMBNAILS
4905 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4906 {
4907 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4908 {
4909 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4910 }
4911 if (is_array($thumbnails))
4912 {
4913 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4914 }
4915 }
4916 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4917 {
4918 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4919 {
4920 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4921 }
4922 if (is_array($thumbnails))
4923 {
4924 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4925 }
4926 }
4927 else
4928 {
4929 $thumbnails = $thumbnails_parent;
4930 }
4931
4932 // TITLES
4933 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4934 {
4935 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4936 }
4937 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4938 {
4939 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4940 }
4941 else
4942 {
4943 $title = $title_parent;
4944 }
4945
4946 $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);
4947 }
4948 }
4949 }
4950
4951 // If we have standalone media:content tags, loop through them.
4952 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4953 {
4954 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4955 {
4956 if (isset($content['attribs']['']['url']))
4957 {
4958 // Attributes
4959 $bitrate = null;
4960 $channels = null;
4961 $duration = null;
4962 $expression = null;
4963 $framerate = null;
4964 $height = null;
4965 $javascript = null;
4966 $lang = null;
4967 $length = null;
4968 $medium = null;
4969 $samplingrate = null;
4970 $type = null;
4971 $url = null;
4972 $width = null;
4973
4974 // Elements
4975 $captions = null;
4976 $categories = null;
4977 $copyrights = null;
4978 $credits = null;
4979 $description = null;
4980 $hashes = null;
4981 $keywords = null;
4982 $player = null;
4983 $ratings = null;
4984 $restrictions = null;
4985 $thumbnails = null;
4986 $title = null;
4987
4988 // Start checking the attributes of media:content
4989 if (isset($content['attribs']['']['bitrate']))
4990 {
4991 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4992 }
4993 if (isset($content['attribs']['']['channels']))
4994 {
4995 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4996 }
4997 if (isset($content['attribs']['']['duration']))
4998 {
4999 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5000 }
5001 else
5002 {
5003 $duration = $duration_parent;
5004 }
5005 if (isset($content['attribs']['']['expression']))
5006 {
5007 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5008 }
5009 if (isset($content['attribs']['']['framerate']))
5010 {
5011 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5012 }
5013 if (isset($content['attribs']['']['height']))
5014 {
5015 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5016 }
5017 if (isset($content['attribs']['']['lang']))
5018 {
5019 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5020 }
5021 if (isset($content['attribs']['']['fileSize']))
5022 {
5023 $length = ceil($content['attribs']['']['fileSize']);
5024 }
5025 if (isset($content['attribs']['']['medium']))
5026 {
5027 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5028 }
5029 if (isset($content['attribs']['']['samplingrate']))
5030 {
5031 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5032 }
5033 if (isset($content['attribs']['']['type']))
5034 {
5035 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5036 }
5037 if (isset($content['attribs']['']['width']))
5038 {
5039 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5040 }
5041 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5042
5043 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5044
5045 // CAPTIONS
5046 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5047 {
5048 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5049 {
5050 $caption_type = null;
5051 $caption_lang = null;
5052 $caption_startTime = null;
5053 $caption_endTime = null;
5054 $caption_text = null;
5055 if (isset($caption['attribs']['']['type']))
5056 {
5057 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5058 }
5059 if (isset($caption['attribs']['']['lang']))
5060 {
5061 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5062 }
5063 if (isset($caption['attribs']['']['start']))
5064 {
5065 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5066 }
5067 if (isset($caption['attribs']['']['end']))
5068 {
5069 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5070 }
5071 if (isset($caption['data']))
5072 {
5073 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5074 }
5075 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5076 }
5077 if (is_array($captions))
5078 {
5079 $captions = array_values(SimplePie_Misc::array_unique($captions));
5080 }
5081 }
5082 else
5083 {
5084 $captions = $captions_parent;
5085 }
5086
5087 // CATEGORIES
5088 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5089 {
5090 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5091 {
5092 $term = null;
5093 $scheme = null;
5094 $label = null;
5095 if (isset($category['data']))
5096 {
5097 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5098 }
5099 if (isset($category['attribs']['']['scheme']))
5100 {
5101 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5102 }
5103 else
5104 {
5105 $scheme = 'http://search.yahoo.com/mrss/category_schema';
5106 }
5107 if (isset($category['attribs']['']['label']))
5108 {
5109 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5110 }
5111 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
5112 }
5113 }
5114 if (is_array($categories) && is_array($categories_parent))
5115 {
5116 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5117 }
5118 elseif (is_array($categories))
5119 {
5120 $categories = array_values(SimplePie_Misc::array_unique($categories));
5121 }
5122 elseif (is_array($categories_parent))
5123 {
5124 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5125 }
5126 else
5127 {
5128 $categories = null;
5129 }
5130
5131 // COPYRIGHTS
5132 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5133 {
5134 $copyright_url = null;
5135 $copyright_label = null;
5136 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5137 {
5138 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5139 }
5140 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5141 {
5142 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5143 }
5144 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
5145 }
5146 else
5147 {
5148 $copyrights = $copyrights_parent;
5149 }
5150
5151 // CREDITS
5152 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5153 {
5154 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5155 {
5156 $credit_role = null;
5157 $credit_scheme = null;
5158 $credit_name = null;
5159 if (isset($credit['attribs']['']['role']))
5160 {
5161 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5162 }
5163 if (isset($credit['attribs']['']['scheme']))
5164 {
5165 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5166 }
5167 else
5168 {
5169 $credit_scheme = 'urn:ebu';
5170 }
5171 if (isset($credit['data']))
5172 {
5173 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5174 }
5175 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5176 }
5177 if (is_array($credits))
5178 {
5179 $credits = array_values(SimplePie_Misc::array_unique($credits));
5180 }
5181 }
5182 else
5183 {
5184 $credits = $credits_parent;
5185 }
5186
5187 // DESCRIPTION
5188 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5189 {
5190 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5191 }
5192 else
5193 {
5194 $description = $description_parent;
5195 }
5196
5197 // HASHES
5198 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5199 {
5200 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5201 {
5202 $value = null;
5203 $algo = null;
5204 if (isset($hash['data']))
5205 {
5206 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5207 }
5208 if (isset($hash['attribs']['']['algo']))
5209 {
5210 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5211 }
5212 else
5213 {
5214 $algo = 'md5';
5215 }
5216 $hashes[] = $algo.':'.$value;
5217 }
5218 if (is_array($hashes))
5219 {
5220 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5221 }
5222 }
5223 else
5224 {
5225 $hashes = $hashes_parent;
5226 }
5227
5228 // KEYWORDS
5229 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5230 {
5231 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5232 {
5233 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5234 foreach ($temp as $word)
5235 {
5236 $keywords[] = trim($word);
5237 }
5238 unset($temp);
5239 }
5240 if (is_array($keywords))
5241 {
5242 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5243 }
5244 }
5245 else
5246 {
5247 $keywords = $keywords_parent;
5248 }
5249
5250 // PLAYER
5251 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5252 {
5253 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5254 }
5255 else
5256 {
5257 $player = $player_parent;
5258 }
5259
5260 // RATINGS
5261 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5262 {
5263 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5264 {
5265 $rating_scheme = null;
5266 $rating_value = null;
5267 if (isset($rating['attribs']['']['scheme']))
5268 {
5269 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5270 }
5271 else
5272 {
5273 $rating_scheme = 'urn:simple';
5274 }
5275 if (isset($rating['data']))
5276 {
5277 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5278 }
5279 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
5280 }
5281 if (is_array($ratings))
5282 {
5283 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5284 }
5285 }
5286 else
5287 {
5288 $ratings = $ratings_parent;
5289 }
5290
5291 // RESTRICTIONS
5292 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5293 {
5294 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5295 {
5296 $restriction_relationship = null;
5297 $restriction_type = null;
5298 $restriction_value = null;
5299 if (isset($restriction['attribs']['']['relationship']))
5300 {
5301 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5302 }
5303 if (isset($restriction['attribs']['']['type']))
5304 {
5305 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5306 }
5307 if (isset($restriction['data']))
5308 {
5309 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5310 }
5311 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5312 }
5313 if (is_array($restrictions))
5314 {
5315 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5316 }
5317 }
5318 else
5319 {
5320 $restrictions = $restrictions_parent;
5321 }
5322
5323 // THUMBNAILS
5324 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5325 {
5326 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5327 {
5328 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5329 }
5330 if (is_array($thumbnails))
5331 {
5332 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5333 }
5334 }
5335 else
5336 {
5337 $thumbnails = $thumbnails_parent;
5338 }
5339
5340 // TITLES
5341 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5342 {
5343 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5344 }
5345 else
5346 {
5347 $title = $title_parent;
5348 }
5349
5350 $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);
5351 }
5352 }
5353 }
5354
5355 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5356 {
5357 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5358 {
5359 // Attributes
5360 $bitrate = null;
5361 $channels = null;
5362 $duration = null;
5363 $expression = null;
5364 $framerate = null;
5365 $height = null;
5366 $javascript = null;
5367 $lang = null;
5368 $length = null;
5369 $medium = null;
5370 $samplingrate = null;
5371 $type = null;
5372 $url = null;
5373 $width = null;
5374
5375 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5376 if (isset($link['attribs']['']['type']))
5377 {
5378 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5379 }
5380 if (isset($link['attribs']['']['length']))
5381 {
5382 $length = ceil($link['attribs']['']['length']);
5383 }
5384
5385 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5386 $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);
5387 }
5388 }
5389
5390 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5391 {
5392 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5393 {
5394 // Attributes
5395 $bitrate = null;
5396 $channels = null;
5397 $duration = null;
5398 $expression = null;
5399 $framerate = null;
5400 $height = null;
5401 $javascript = null;
5402 $lang = null;
5403 $length = null;
5404 $medium = null;
5405 $samplingrate = null;
5406 $type = null;
5407 $url = null;
5408 $width = null;
5409
5410 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5411 if (isset($link['attribs']['']['type']))
5412 {
5413 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5414 }
5415 if (isset($link['attribs']['']['length']))
5416 {
5417 $length = ceil($link['attribs']['']['length']);
5418 }
5419
5420 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5421 $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);
5422 }
5423 }
5424
5425 if ($enclosure = $this->get_item_tags('', 'enclosure'))
5426 {
5427 if (isset($enclosure[0]['attribs']['']['url']))
5428 {
5429 // Attributes
5430 $bitrate = null;
5431 $channels = null;
5432 $duration = null;
5433 $expression = null;
5434 $framerate = null;
5435 $height = null;
5436 $javascript = null;
5437 $lang = null;
5438 $length = null;
5439 $medium = null;
5440 $samplingrate = null;
5441 $type = null;
5442 $url = null;
5443 $width = null;
5444
5445 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5446 if (isset($enclosure[0]['attribs']['']['type']))
5447 {
5448 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5449 }
5450 if (isset($enclosure[0]['attribs']['']['length']))
5451 {
5452 $length = ceil($enclosure[0]['attribs']['']['length']);
5453 }
5454
5455 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5456 $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);
5457 }
5458 }
5459
5460 if (sizeof($this->data['enclosures']) == 0)
5461 {
5462 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5463 $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);
5464 }
5465
5466 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5467 }
5468 if (!empty($this->data['enclosures']))
5469 {
5470 return $this->data['enclosures'];
5471 }
5472 else
5473 {
5474 return null;
5475 }
5476 }
5477
5478 function get_latitude()
5479 {
5480 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5481 {
5482 return (float) $return[0]['data'];
5483 }
5484 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5485 {
5486 return (float) $match[1];
5487 }
5488 else
5489 {
5490 return null;
5491 }
5492 }
5493
5494 function get_longitude()
5495 {
5496 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5497 {
5498 return (float) $return[0]['data'];
5499 }
5500 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5501 {
5502 return (float) $return[0]['data'];
5503 }
5504 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5505 {
5506 return (float) $match[2];
5507 }
5508 else
5509 {
5510 return null;
5511 }
5512 }
5513
5514 function get_source()
5515 {
5516 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5517 {
5518 return new $this->feed->source_class($this, $return[0]);
5519 }
5520 else
5521 {
5522 return null;
5523 }
5524 }
5525
5526 /**
5527 * Creates the add_to_* methods' return data
5528 *
5529 * @access private
5530 * @param string $item_url String to prefix to the item permalink
5531 * @param string $title_url String to prefix to the item title
5532 * (and suffix to the item permalink)
5533 * @return mixed URL if feed exists, false otherwise
5534 */
5535 function add_to_service($item_url, $title_url = null)
5536 {
5537 if ($this->get_permalink() !== null)
5538 {
5539 $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5540 if ($title_url !== null && $this->get_title() !== null)
5541 {
5542 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5543 }
5544 return $return;
5545 }
5546 else
5547 {
5548 return null;
5549 }
5550 }
5551
5552 function add_to_blinklist()
5553 {
5554 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5555 }
5556
5557 function add_to_blogmarks()
5558 {
5559 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5560 }
5561
5562 function add_to_delicious()
5563 {
5564 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5565 }
5566
5567 function add_to_digg()
5568 {
5569 return $this->add_to_service('http://digg.com/submit?phase=2&URL=');
5570 }
5571
5572 function add_to_furl()
5573 {
5574 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5575 }
5576
5577 function add_to_magnolia()
5578 {
5579 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5580 }
5581
5582 function add_to_myweb20()
5583 {
5584 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5585 }
5586
5587 function add_to_newsvine()
5588 {
5589 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5590 }
5591
5592 function add_to_reddit()
5593 {
5594 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5595 }
5596
5597 function add_to_segnalo()
5598 {
5599 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5600 }
5601
5602 function add_to_simpy()
5603 {
5604 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5605 }
5606
5607 function add_to_spurl()
5608 {
5609 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5610 }
5611
5612 function add_to_wists()
5613 {
5614 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5615 }
5616
5617 function search_technorati()
5618 {
5619 return $this->add_to_service('http://www.technorati.com/search/');
5620 }
5621 }
5622
5623 class SimplePie_Source
5624 {
5625 var $item;
5626 var $data = array();
5627
5628 function SimplePie_Source($item, $data)
5629 {
5630 $this->item = $item;
5631 $this->data = $data;
5632 }
5633
5634 function __toString()
5635 {
5636 return md5(serialize($this->data));
5637 }
5638
5639 /**
5640 * Remove items that link back to this before destroying this object
5641 */
5642 function __destruct()
5643 {
5644 unset($this->item);
5645 }
5646
5647 function get_source_tags($namespace, $tag)
5648 {
5649 if (isset($this->data['child'][$namespace][$tag]))
5650 {
5651 return $this->data['child'][$namespace][$tag];
5652 }
5653 else
5654 {
5655 return null;
5656 }
5657 }
5658
5659 function get_base($element = array())
5660 {
5661 return $this->item->get_base($element);
5662 }
5663
5664 function sanitize($data, $type, $base = '')
5665 {
5666 return $this->item->sanitize($data, $type, $base);
5667 }
5668
5669 function get_item()
5670 {
5671 return $this->item;
5672 }
5673
5674 function get_title()
5675 {
5676 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5677 {
5678 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5679 }
5680 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5681 {
5682 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5683 }
5684 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5685 {
5686 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5687 }
5688 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5689 {
5690 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5691 }
5692 elseif ($return = $this->get_source_tags('', 'title'))
5693 {
5694 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5695 }
5696 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5697 {
5698 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5699 }
5700 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5701 {
5702 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5703 }
5704 else
5705 {
5706 return null;
5707 }
5708 }
5709
5710 function get_category($key = 0)
5711 {
5712 $categories = $this->get_categories();
5713 if (isset($categories[$key]))
5714 {
5715 return $categories[$key];
5716 }
5717 else
5718 {
5719 return null;
5720 }
5721 }
5722
5723 function get_categories()
5724 {
5725 $categories = array();
5726
5727 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5728 {
5729 $term = null;
5730 $scheme = null;
5731 $label = null;
5732 if (isset($category['attribs']['']['term']))
5733 {
5734 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5735 }
5736 if (isset($category['attribs']['']['scheme']))
5737 {
5738 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5739 }
5740 if (isset($category['attribs']['']['label']))
5741 {
5742 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5743 }
5744 $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
5745 }
5746 foreach ((array) $this->get_source_tags('', 'category') as $category)
5747 {
5748 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5749 }
5750 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5751 {
5752 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5753 }
5754 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5755 {
5756 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5757 }
5758
5759 if (!empty($categories))
5760 {
5761 return SimplePie_Misc::array_unique($categories);
5762 }
5763 else
5764 {
5765 return null;
5766 }
5767 }
5768
5769 function get_author($key = 0)
5770 {
5771 $authors = $this->get_authors();
5772 if (isset($authors[$key]))
5773 {
5774 return $authors[$key];
5775 }
5776 else
5777 {
5778 return null;
5779 }
5780 }
5781
5782 function get_authors()
5783 {
5784 $authors = array();
5785 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5786 {
5787 $name = null;
5788 $uri = null;
5789 $email = null;
5790 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5791 {
5792 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5793 }
5794 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5795 {
5796 $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]));
5797 }
5798 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5799 {
5800 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5801 }
5802 if ($name !== null || $email !== null || $uri !== null)
5803 {
5804 $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
5805 }
5806 }
5807 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5808 {
5809 $name = null;
5810 $url = null;
5811 $email = null;
5812 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5813 {
5814 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5815 }
5816 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5817 {
5818 $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]));
5819 }
5820 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5821 {
5822 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5823 }
5824 if ($name !== null || $email !== null || $url !== null)
5825 {
5826 $authors[] =& new $this->item->feed->author_class($name, $url, $email);
5827 }
5828 }
5829 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5830 {
5831 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5832 }
5833 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5834 {
5835 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5836 }
5837 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5838 {
5839 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5840 }
5841
5842 if (!empty($authors))
5843 {
5844 return SimplePie_Misc::array_unique($authors);
5845 }
5846 else
5847 {
5848 return null;
5849 }
5850 }
5851
5852 function get_contributor($key = 0)
5853 {
5854 $contributors = $this->get_contributors();
5855 if (isset($contributors[$key]))
5856 {
5857 return $contributors[$key];
5858 }
5859 else
5860 {
5861 return null;
5862 }
5863 }
5864
5865 function get_contributors()
5866 {
5867 $contributors = array();
5868 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5869 {
5870 $name = null;
5871 $uri = null;
5872 $email = null;
5873 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5874 {
5875 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5876 }
5877 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5878 {
5879 $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]));
5880 }
5881 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5882 {
5883 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5884 }
5885 if ($name !== null || $email !== null || $uri !== null)
5886 {
5887 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
5888 }
5889 }
5890 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
5891 {
5892 $name = null;
5893 $url = null;
5894 $email = null;
5895 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5896 {
5897 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5898 }
5899 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5900 {
5901 $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]));
5902 }
5903 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5904 {
5905 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5906 }
5907 if ($name !== null || $email !== null || $url !== null)
5908 {
5909 $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
5910 }
5911 }
5912
5913 if (!empty($contributors))
5914 {
5915 return SimplePie_Misc::array_unique($contributors);
5916 }
5917 else
5918 {
5919 return null;
5920 }
5921 }
5922
5923 function get_link($key = 0, $rel = 'alternate')
5924 {
5925 $links = $this->get_links($rel);
5926 if (isset($links[$key]))
5927 {
5928 return $links[$key];
5929 }
5930 else
5931 {
5932 return null;
5933 }
5934 }
5935
5936 /**
5937 * Added for parity between the parent-level and the item/entry-level.
5938 */
5939 function get_permalink()
5940 {
5941 return $this->get_link(0);
5942 }
5943
5944 function get_links($rel = 'alternate')
5945 {
5946 if (!isset($this->data['links']))
5947 {
5948 $this->data['links'] = array();
5949 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
5950 {
5951 foreach ($links as $link)
5952 {
5953 if (isset($link['attribs']['']['href']))
5954 {
5955 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
5956 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5957 }
5958 }
5959 }
5960 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
5961 {
5962 foreach ($links as $link)
5963 {
5964 if (isset($link['attribs']['']['href']))
5965 {
5966 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
5967 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5968
5969 }
5970 }
5971 }
5972 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
5973 {
5974 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
5975 }
5976 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
5977 {
5978 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
5979 }
5980 if ($links = $this->get_source_tags('', 'link'))
5981 {
5982 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
5983 }
5984
5985 $keys = array_keys($this->data['links']);
5986 foreach ($keys as $key)
5987 {
5988 if (SimplePie_Misc::is_isegment_nz_nc($key))
5989 {
5990 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
5991 {
5992 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
5993 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
5994 }
5995 else
5996 {
5997 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
5998 }
5999 }
6000 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6001 {
6002 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6003 }
6004 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6005 }
6006 }
6007
6008 if (isset($this->data['links'][$rel]))
6009 {
6010 return $this->data['links'][$rel];
6011 }
6012 else
6013 {
6014 return null;
6015 }
6016 }
6017
6018 function get_description()
6019 {
6020 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6021 {
6022 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6023 }
6024 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6025 {
6026 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6027 }
6028 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6029 {
6030 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6031 }
6032 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6033 {
6034 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6035 }
6036 elseif ($return = $this->get_source_tags('', 'description'))
6037 {
6038 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6039 }
6040 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6041 {
6042 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6043 }
6044 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6045 {
6046 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6047 }
6048 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6049 {
6050 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6051 }
6052 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6053 {
6054 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6055 }
6056 else
6057 {
6058 return null;
6059 }
6060 }
6061
6062 function get_copyright()
6063 {
6064 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6065 {
6066 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6067 }
6068 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6069 {
6070 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6071 }
6072 elseif ($return = $this->get_source_tags('', 'copyright'))
6073 {
6074 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6075 }
6076 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6077 {
6078 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6079 }
6080 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6081 {
6082 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6083 }
6084 else
6085 {
6086 return null;
6087 }
6088 }
6089
6090 function get_language()
6091 {
6092 if ($return = $this->get_source_tags('', 'language'))
6093 {
6094 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6095 }
6096 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6097 {
6098 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6099 }
6100 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6101 {
6102 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6103 }
6104 elseif (isset($this->data['xml_lang']))
6105 {
6106 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6107 }
6108 else
6109 {
6110 return null;
6111 }
6112 }
6113
6114 function get_latitude()
6115 {
6116 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6117 {
6118 return (float) $return[0]['data'];
6119 }
6120 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6121 {
6122 return (float) $match[1];
6123 }
6124 else
6125 {
6126 return null;
6127 }
6128 }
6129
6130 function get_longitude()
6131 {
6132 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6133 {
6134 return (float) $return[0]['data'];
6135 }
6136 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6137 {
6138 return (float) $return[0]['data'];
6139 }
6140 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6141 {
6142 return (float) $match[2];
6143 }
6144 else
6145 {
6146 return null;
6147 }
6148 }
6149
6150 function get_image_url()
6151 {
6152 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6153 {
6154 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6155 }
6156 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6157 {
6158 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6159 }
6160 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6161 {
6162 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6163 }
6164 else
6165 {
6166 return null;
6167 }
6168 }
6169 }
6170
6171 class SimplePie_Author
6172 {
6173 var $name;
6174 var $link;
6175 var $email;
6176
6177 // Constructor, used to input the data
6178 function SimplePie_Author($name = null, $link = null, $email = null)
6179 {
6180 $this->name = $name;
6181 $this->link = $link;
6182 $this->email = $email;
6183 }
6184
6185 function __toString()
6186 {
6187 // There is no $this->data here
6188 return md5(serialize($this));
6189 }
6190
6191 function get_name()
6192 {
6193 if ($this->name !== null)
6194 {
6195 return $this->name;
6196 }
6197 else
6198 {
6199 return null;
6200 }
6201 }
6202
6203 function get_link()
6204 {
6205 if ($this->link !== null)
6206 {
6207 return $this->link;
6208 }
6209 else
6210 {
6211 return null;
6212 }
6213 }
6214
6215 function get_email()
6216 {
6217 if ($this->email !== null)
6218 {
6219 return $this->email;
6220 }
6221 else
6222 {
6223 return null;
6224 }
6225 }
6226 }
6227
6228 class SimplePie_Category
6229 {
6230 var $term;
6231 var $scheme;
6232 var $label;
6233
6234 // Constructor, used to input the data
6235 function SimplePie_Category($term = null, $scheme = null, $label = null)
6236 {
6237 $this->term = $term;
6238 $this->scheme = $scheme;
6239 $this->label = $label;
6240 }
6241
6242 function __toString()
6243 {
6244 // There is no $this->data here
6245 return md5(serialize($this));
6246 }
6247
6248 function get_term()
6249 {
6250 if ($this->term !== null)
6251 {
6252 return $this->term;
6253 }
6254 else
6255 {
6256 return null;
6257 }
6258 }
6259
6260 function get_scheme()
6261 {
6262 if ($this->scheme !== null)
6263 {
6264 return $this->scheme;
6265 }
6266 else
6267 {
6268 return null;
6269 }
6270 }
6271
6272 function get_label()
6273 {
6274 if ($this->label !== null)
6275 {
6276 return $this->label;
6277 }
6278 else
6279 {
6280 return $this->get_term();
6281 }
6282 }
6283 }
6284
6285 class SimplePie_Enclosure
6286 {
6287 var $bitrate;
6288 var $captions;
6289 var $categories;
6290 var $channels;
6291 var $copyright;
6292 var $credits;
6293 var $description;
6294 var $duration;
6295 var $expression;
6296 var $framerate;
6297 var $handler;
6298 var $hashes;
6299 var $height;
6300 var $javascript;
6301 var $keywords;
6302 var $lang;
6303 var $length;
6304 var $link;
6305 var $medium;
6306 var $player;
6307 var $ratings;
6308 var $restrictions;
6309 var $samplingrate;
6310 var $thumbnails;
6311 var $title;
6312 var $type;
6313 var $width;
6314
6315 // Constructor, used to input the data
6316 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)
6317 {
6318 $this->bitrate = $bitrate;
6319 $this->captions = $captions;
6320 $this->categories = $categories;
6321 $this->channels = $channels;
6322 $this->copyright = $copyright;
6323 $this->credits = $credits;
6324 $this->description = $description;
6325 $this->duration = $duration;
6326 $this->expression = $expression;
6327 $this->framerate = $framerate;
6328 $this->hashes = $hashes;
6329 $this->height = $height;
6330 $this->javascript = $javascript;
6331 $this->keywords = $keywords;
6332 $this->lang = $lang;
6333 $this->length = $length;
6334 $this->link = $link;
6335 $this->medium = $medium;
6336 $this->player = $player;
6337 $this->ratings = $ratings;
6338 $this->restrictions = $restrictions;
6339 $this->samplingrate = $samplingrate;
6340 $this->thumbnails = $thumbnails;
6341 $this->title = $title;
6342 $this->type = $type;
6343 $this->width = $width;
6344 if (class_exists('idna_convert'))
6345 {
6346 $idn =& new idna_convert;
6347 $parsed = SimplePie_Misc::parse_url($link);
6348 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6349 }
6350 $this->handler = $this->get_handler(); // Needs to load last
6351 }
6352
6353 function __toString()
6354 {
6355 // There is no $this->data here
6356 return md5(serialize($this));
6357 }
6358
6359 function get_bitrate()
6360 {
6361 if ($this->bitrate !== null)
6362 {
6363 return $this->bitrate;
6364 }
6365 else
6366 {
6367 return null;
6368 }
6369 }
6370
6371 function get_caption($key = 0)
6372 {
6373 $captions = $this->get_captions();
6374 if (isset($captions[$key]))
6375 {
6376 return $captions[$key];
6377 }
6378 else
6379 {
6380 return null;
6381 }
6382 }
6383
6384 function get_captions()
6385 {
6386 if ($this->captions !== null)
6387 {
6388 return $this->captions;
6389 }
6390 else
6391 {
6392 return null;
6393 }
6394 }
6395
6396 function get_category($key = 0)
6397 {
6398 $categories = $this->get_categories();
6399 if (isset($categories[$key]))
6400 {
6401 return $categories[$key];
6402 }
6403 else
6404 {
6405 return null;
6406 }
6407 }
6408
6409 function get_categories()
6410 {
6411 if ($this->categories !== null)
6412 {
6413 return $this->categories;
6414 }
6415 else
6416 {
6417 return null;
6418 }
6419 }
6420
6421 function get_channels()
6422 {
6423 if ($this->channels !== null)
6424 {
6425 return $this->channels;
6426 }
6427 else
6428 {
6429 return null;
6430 }
6431 }
6432
6433 function get_copyright()
6434 {
6435 if ($this->copyright !== null)
6436 {
6437 return $this->copyright;
6438 }
6439 else
6440 {
6441 return null;
6442 }
6443 }
6444
6445 function get_credit($key = 0)
6446 {
6447 $credits = $this->get_credits();
6448 if (isset($credits[$key]))
6449 {
6450 return $credits[$key];
6451 }
6452 else
6453 {
6454 return null;
6455 }
6456 }
6457
6458 function get_credits()
6459 {
6460 if ($this->credits !== null)
6461 {
6462 return $this->credits;
6463 }
6464 else
6465 {
6466 return null;
6467 }
6468 }
6469
6470 function get_description()
6471 {
6472 if ($this->description !== null)
6473 {
6474 return $this->description;
6475 }
6476 else
6477 {
6478 return null;
6479 }
6480 }
6481
6482 function get_duration($convert = false)
6483 {
6484 if ($this->duration !== null)
6485 {
6486 if ($convert)
6487 {
6488 $time = SimplePie_Misc::time_hms($this->duration);
6489 return $time;
6490 }
6491 else
6492 {
6493 return $this->duration;
6494 }
6495 }
6496 else
6497 {
6498 return null;
6499 }
6500 }
6501
6502 function get_expression()
6503 {
6504 if ($this->expression !== null)
6505 {
6506 return $this->expression;
6507 }
6508 else
6509 {
6510 return 'full';
6511 }
6512 }
6513
6514 function get_extension()
6515 {
6516 if ($this->link !== null)
6517 {
6518 $url = SimplePie_Misc::parse_url($this->link);
6519 if ($url['path'] !== '')
6520 {
6521 return pathinfo($url['path'], PATHINFO_EXTENSION);
6522 }
6523 }
6524 return null;
6525 }
6526
6527 function get_framerate()
6528 {
6529 if ($this->framerate !== null)
6530 {
6531 return $this->framerate;
6532 }
6533 else
6534 {
6535 return null;
6536 }
6537 }
6538
6539 function get_handler()
6540 {
6541 return $this->get_real_type(true);
6542 }
6543
6544 function get_hash($key = 0)
6545 {
6546 $hashes = $this->get_hashes();
6547 if (isset($hashes[$key]))
6548 {
6549 return $hashes[$key];
6550 }
6551 else
6552 {
6553 return null;
6554 }
6555 }
6556
6557 function get_hashes()
6558 {
6559 if ($this->hashes !== null)
6560 {
6561 return $this->hashes;
6562 }
6563 else
6564 {
6565 return null;
6566 }
6567 }
6568
6569 function get_height()
6570 {
6571 if ($this->height !== null)
6572 {
6573 return $this->height;
6574 }
6575 else
6576 {
6577 return null;
6578 }
6579 }
6580
6581 function get_language()
6582 {
6583 if ($this->lang !== null)
6584 {
6585 return $this->lang;
6586 }
6587 else
6588 {
6589 return null;
6590 }
6591 }
6592
6593 function get_keyword($key = 0)
6594 {
6595 $keywords = $this->get_keywords();
6596 if (isset($keywords[$key]))
6597 {
6598 return $keywords[$key];
6599 }
6600 else
6601 {
6602 return null;
6603 }
6604 }
6605
6606 function get_keywords()
6607 {
6608 if ($this->keywords !== null)
6609 {
6610 return $this->keywords;
6611 }
6612 else
6613 {
6614 return null;
6615 }
6616 }
6617
6618 function get_length()
6619 {
6620 if ($this->length !== null)
6621 {
6622 return $this->length;
6623 }
6624 else
6625 {
6626 return null;
6627 }
6628 }
6629
6630 function get_link()
6631 {
6632 if ($this->link !== null)
6633 {
6634 return urldecode($this->link);
6635 }
6636 else
6637 {
6638 return null;
6639 }
6640 }
6641
6642 function get_medium()
6643 {
6644 if ($this->medium !== null)
6645 {
6646 return $this->medium;
6647 }
6648 else
6649 {
6650 return null;
6651 }
6652 }
6653
6654 function get_player()
6655 {
6656 if ($this->player !== null)
6657 {
6658 return $this->player;
6659 }
6660 else
6661 {
6662 return null;
6663 }
6664 }
6665
6666 function get_rating($key = 0)
6667 {
6668 $ratings = $this->get_ratings();
6669 if (isset($ratings[$key]))
6670 {
6671 return $ratings[$key];
6672 }
6673 else
6674 {
6675 return null;
6676 }
6677 }
6678
6679 function get_ratings()
6680 {
6681 if ($this->ratings !== null)
6682 {
6683 return $this->ratings;
6684 }
6685 else
6686 {
6687 return null;
6688 }
6689 }
6690
6691 function get_restriction($key = 0)
6692 {
6693 $restrictions = $this->get_restrictions();
6694 if (isset($restrictions[$key]))
6695 {
6696 return $restrictions[$key];
6697 }
6698 else
6699 {
6700 return null;
6701 }
6702 }
6703
6704 function get_restrictions()
6705 {
6706 if ($this->restrictions !== null)
6707 {
6708 return $this->restrictions;
6709 }
6710 else
6711 {
6712 return null;
6713 }
6714 }
6715
6716 function get_sampling_rate()
6717 {
6718 if ($this->samplingrate !== null)
6719 {
6720 return $this->samplingrate;
6721 }
6722 else
6723 {
6724 return null;
6725 }
6726 }
6727
6728 function get_size()
6729 {
6730 $length = $this->get_length();
6731 if ($length !== null)
6732 {
6733 return round($length/1048576, 2);
6734 }
6735 else
6736 {
6737 return null;
6738 }
6739 }
6740
6741 function get_thumbnail($key = 0)
6742 {
6743 $thumbnails = $this->get_thumbnails();
6744 if (isset($thumbnails[$key]))
6745 {
6746 return $thumbnails[$key];
6747 }
6748 else
6749 {
6750 return null;
6751 }
6752 }
6753
6754 function get_thumbnails()
6755 {
6756 if ($this->thumbnails !== null)
6757 {
6758 return $this->thumbnails;
6759 }
6760 else
6761 {
6762 return null;
6763 }
6764 }
6765
6766 function get_title()
6767 {
6768 if ($this->title !== null)
6769 {
6770 return $this->title;
6771 }
6772 else
6773 {
6774 return null;
6775 }
6776 }
6777
6778 function get_type()
6779 {
6780 if ($this->type !== null)
6781 {
6782 return $this->type;
6783 }
6784 else
6785 {
6786 return null;
6787 }
6788 }
6789
6790 function get_width()
6791 {
6792 if ($this->width !== null)
6793 {
6794 return $this->width;
6795 }
6796 else
6797 {
6798 return null;
6799 }
6800 }
6801
6802 function native_embed($options='')
6803 {
6804 return $this->embed($options, true);
6805 }
6806
6807 /**
6808 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6809 */
6810 function embed($options = '', $native = false)
6811 {
6812 // Set up defaults
6813 $audio = '';
6814 $video = '';
6815 $alt = '';
6816 $altclass = '';
6817 $loop = 'false';
6818 $width = 'auto';
6819 $height = 'auto';
6820 $bgcolor = '#ffffff';
6821 $mediaplayer = '';
6822 $widescreen = false;
6823 $handler = $this->get_handler();
6824 $type = $this->get_real_type();
6825
6826 // Process options and reassign values as necessary
6827 if (is_array($options))
6828 {
6829 extract($options);
6830 }
6831 else
6832 {
6833 $options = explode(',', $options);
6834 foreach($options as $option)
6835 {
6836 $opt = explode(':', $option, 2);
6837 if (isset($opt[0], $opt[1]))
6838 {
6839 $opt[0] = trim($opt[0]);
6840 $opt[1] = trim($opt[1]);
6841 switch ($opt[0])
6842 {
6843 case 'audio':
6844 $audio = $opt[1];
6845 break;
6846
6847 case 'video':
6848 $video = $opt[1];
6849 break;
6850
6851 case 'alt':
6852 $alt = $opt[1];
6853 break;
6854
6855 case 'altclass':
6856 $altclass = $opt[1];
6857 break;
6858
6859 case 'loop':
6860 $loop = $opt[1];
6861 break;
6862
6863 case 'width':
6864 $width = $opt[1];
6865 break;
6866
6867 case 'height':
6868 $height = $opt[1];
6869 break;
6870
6871 case 'bgcolor':
6872 $bgcolor = $opt[1];
6873 break;
6874
6875 case 'mediaplayer':
6876 $mediaplayer = $opt[1];
6877 break;
6878
6879 case 'widescreen':
6880 $widescreen = $opt[1];
6881 break;
6882 }
6883 }
6884 }
6885 }
6886
6887 $mime = explode('/', $type, 2);
6888 $mime = $mime[0];
6889
6890 // Process values for 'auto'
6891 if ($width == 'auto')
6892 {
6893 if ($mime == 'video')
6894 {
6895 if ($height == 'auto')
6896 {
6897 $width = 480;
6898 }
6899 elseif ($widescreen)
6900 {
6901 $width = round((intval($height)/9)*16);
6902 }
6903 else
6904 {
6905 $width = round((intval($height)/3)*4);
6906 }
6907 }
6908 else
6909 {
6910 $width = '100%';
6911 }
6912 }
6913
6914 if ($height == 'auto')
6915 {
6916 if ($mime == 'audio')
6917 {
6918 $height = 0;
6919 }
6920 elseif ($mime == 'video')
6921 {
6922 if ($width == 'auto')
6923 {
6924 if ($widescreen)
6925 {
6926 $height = 270;
6927 }
6928 else
6929 {
6930 $height = 360;
6931 }
6932 }
6933 elseif ($widescreen)
6934 {
6935 $height = round((intval($width)/16)*9);
6936 }
6937 else
6938 {
6939 $height = round((intval($width)/4)*3);
6940 }
6941 }
6942 else
6943 {
6944 $height = 376;
6945 }
6946 }
6947 elseif ($mime == 'audio')
6948 {
6949 $height = 0;
6950 }
6951
6952 // Set proper placeholder value
6953 if ($mime == 'audio')
6954 {
6955 $placeholder = $audio;
6956 }
6957 elseif ($mime == 'video')
6958 {
6959 $placeholder = $video;
6960 }
6961
6962 $embed = '';
6963
6964 // Make sure the JS library is included
6965 if (!$native)
6966 {
6967 static $javascript_outputted = null;
6968 if (!$javascript_outputted && $this->javascript)
6969 {
6970 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
6971 $javascript_outputted = true;
6972 }
6973 }
6974
6975 // Odeo Feed MP3's
6976 if ($handler == 'odeo')
6977 {
6978 if ($native)
6979 {
6980 $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>';
6981 }
6982 else
6983 {
6984 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
6985 }
6986 }
6987
6988 // Flash
6989 elseif ($handler == 'flash')
6990 {
6991 if ($native)
6992 {
6993 $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>";
6994 }
6995 else
6996 {
6997 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
6998 }
6999 }
7000
7001 // Flash Media Player file types.
7002 // Preferred handler for MP3 file types.
7003 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7004 {
7005 $height += 20;
7006 if ($native)
7007 {
7008 $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>";
7009 }
7010 else
7011 {
7012 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7013 }
7014 }
7015
7016 // QuickTime 7 file types. Need to test with QuickTime 6.
7017 // Only handle MP3's if the Flash Media Player is not present.
7018 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7019 {
7020 $height += 16;
7021 if ($native)
7022 {
7023 if ($placeholder != ""){
7024 $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>";
7025 }
7026 else {
7027 $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>";
7028 }
7029 }
7030 else
7031 {
7032 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7033 }
7034 }
7035
7036 // Windows Media
7037 elseif ($handler == 'wmedia')
7038 {
7039 $height += 45;
7040 if ($native)
7041 {
7042 $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>";
7043 }
7044 else
7045 {
7046 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7047 }
7048 }
7049
7050 // Everything else
7051 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7052
7053 return $embed;
7054 }
7055
7056 function get_real_type($find_handler = false)
7057 {
7058 // If it's Odeo, let's get it out of the way.
7059 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
7060 {
7061 return 'odeo';
7062 }
7063
7064 // Mime-types by handler.
7065 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7066 $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
7067 $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
7068 $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
7069 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7070
7071 if ($this->get_type() !== null)
7072 {
7073 $type = strtolower($this->type);
7074 }
7075 else
7076 {
7077 $type = null;
7078 }
7079
7080 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7081 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7082 {
7083 switch (strtolower($this->get_extension()))
7084 {
7085 // Audio mime-types
7086 case 'aac':
7087 case 'adts':
7088 $type = 'audio/acc';
7089 break;
7090
7091 case 'aif':
7092 case 'aifc':
7093 case 'aiff':
7094 case 'cdda':
7095 $type = 'audio/aiff';
7096 break;
7097
7098 case 'bwf':
7099 $type = 'audio/wav';
7100 break;
7101
7102 case 'kar':
7103 case 'mid':
7104 case 'midi':
7105 case 'smf':
7106 $type = 'audio/midi';
7107 break;
7108
7109 case 'm4a':
7110 $type = 'audio/x-m4a';
7111 break;
7112
7113 case 'mp3':
7114 case 'swa':
7115 $type = 'audio/mp3';
7116 break;
7117
7118 case 'wav':
7119 $type = 'audio/wav';
7120 break;
7121
7122 case 'wax':
7123 $type = 'audio/x-ms-wax';
7124 break;
7125
7126 case 'wma':
7127 $type = 'audio/x-ms-wma';
7128 break;
7129
7130 // Video mime-types
7131 case '3gp':
7132 case '3gpp':
7133 $type = 'video/3gpp';
7134 break;
7135
7136 case '3g2':
7137 case '3gp2':
7138 $type = 'video/3gpp2';
7139 break;
7140
7141 case 'asf':
7142 $type = 'video/x-ms-asf';
7143 break;
7144
7145 case 'flv':
7146 $type = 'video/x-flv';
7147 break;
7148
7149 case 'm1a':
7150 case 'm1s':
7151 case 'm1v':
7152 case 'm15':
7153 case 'm75':
7154 case 'mp2':
7155 case 'mpa':
7156 case 'mpeg':
7157 case 'mpg':
7158 case 'mpm':
7159 case 'mpv':
7160 $type = 'video/mpeg';
7161 break;
7162
7163 case 'm4v':
7164 $type = 'video/x-m4v';
7165 break;
7166
7167 case 'mov':
7168 case 'qt':
7169 $type = 'video/quicktime';
7170 break;
7171
7172 case 'mp4':
7173 case 'mpg4':
7174 $type = 'video/mp4';
7175 break;
7176
7177 case 'sdv':
7178 $type = 'video/sd-video';
7179 break;
7180
7181 case 'wm':
7182 $type = 'video/x-ms-wm';
7183 break;
7184
7185 case 'wmv':
7186 $type = 'video/x-ms-wmv';
7187 break;
7188
7189 case 'wvx':
7190 $type = 'video/x-ms-wvx';
7191 break;
7192
7193 // Flash mime-types
7194 case 'spl':
7195 $type = 'application/futuresplash';
7196 break;
7197
7198 case 'swf':
7199 $type = 'application/x-shockwave-flash';
7200 break;
7201 }
7202 }
7203
7204 if ($find_handler)
7205 {
7206 if (in_array($type, $types_flash))
7207 {
7208 return 'flash';
7209 }
7210 elseif (in_array($type, $types_fmedia))
7211 {
7212 return 'fmedia';
7213 }
7214 elseif (in_array($type, $types_quicktime))
7215 {
7216 return 'quicktime';
7217 }
7218 elseif (in_array($type, $types_wmedia))
7219 {
7220 return 'wmedia';
7221 }
7222 elseif (in_array($type, $types_mp3))
7223 {
7224 return 'mp3';
7225 }
7226 else
7227 {
7228 return null;
7229 }
7230 }
7231 else
7232 {
7233 return $type;
7234 }
7235 }
7236 }
7237
7238 class SimplePie_Caption
7239 {
7240 var $type;
7241 var $lang;
7242 var $startTime;
7243 var $endTime;
7244 var $text;
7245
7246 // Constructor, used to input the data
7247 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7248 {
7249 $this->type = $type;
7250 $this->lang = $lang;
7251 $this->startTime = $startTime;
7252 $this->endTime = $endTime;
7253 $this->text = $text;
7254 }
7255
7256 function __toString()
7257 {
7258 // There is no $this->data here
7259 return md5(serialize($this));
7260 }
7261
7262 function get_endtime()
7263 {
7264 if ($this->endTime !== null)
7265 {
7266 return $this->endTime;
7267 }
7268 else
7269 {
7270 return null;
7271 }
7272 }
7273
7274 function get_language()
7275 {
7276 if ($this->lang !== null)
7277 {
7278 return $this->lang;
7279 }
7280 else
7281 {
7282 return null;
7283 }
7284 }
7285
7286 function get_starttime()
7287 {
7288 if ($this->startTime !== null)
7289 {
7290 return $this->startTime;
7291 }
7292 else
7293 {
7294 return null;
7295 }
7296 }
7297
7298 function get_text()
7299 {
7300 if ($this->text !== null)
7301 {
7302 return $this->text;
7303 }
7304 else
7305 {
7306 return null;
7307 }
7308 }
7309
7310 function get_type()
7311 {
7312 if ($this->type !== null)
7313 {
7314 return $this->type;
7315 }
7316 else
7317 {
7318 return null;
7319 }
7320 }
7321 }
7322
7323 class SimplePie_Credit
7324 {
7325 var $role;
7326 var $scheme;
7327 var $name;
7328
7329 // Constructor, used to input the data
7330 function SimplePie_Credit($role = null, $scheme = null, $name = null)
7331 {
7332 $this->role = $role;
7333 $this->scheme = $scheme;
7334 $this->name = $name;
7335 }
7336
7337 function __toString()
7338 {
7339 // There is no $this->data here
7340 return md5(serialize($this));
7341 }
7342
7343 function get_role()
7344 {
7345 if ($this->role !== null)
7346 {
7347 return $this->role;
7348 }
7349 else
7350 {
7351 return null;
7352 }
7353 }
7354
7355 function get_scheme()
7356 {
7357 if ($this->scheme !== null)
7358 {
7359 return $this->scheme;
7360 }
7361 else
7362 {
7363 return null;
7364 }
7365 }
7366
7367 function get_name()
7368 {
7369 if ($this->name !== null)
7370 {
7371 return $this->name;
7372 }
7373 else
7374 {
7375 return null;
7376 }
7377 }
7378 }
7379
7380 class SimplePie_Copyright
7381 {
7382 var $url;
7383 var $label;
7384
7385 // Constructor, used to input the data
7386 function SimplePie_Copyright($url = null, $label = null)
7387 {
7388 $this->url = $url;
7389 $this->label = $label;
7390 }
7391
7392 function __toString()
7393 {
7394 // There is no $this->data here
7395 return md5(serialize($this));
7396 }
7397
7398 function get_url()
7399 {
7400 if ($this->url !== null)
7401 {
7402 return $this->url;
7403 }
7404 else
7405 {
7406 return null;
7407 }
7408 }
7409
7410 function get_attribution()
7411 {
7412 if ($this->label !== null)
7413 {
7414 return $this->label;
7415 }
7416 else
7417 {
7418 return null;
7419 }
7420 }
7421 }
7422
7423 class SimplePie_Rating
7424 {
7425 var $scheme;
7426 var $value;
7427
7428 // Constructor, used to input the data
7429 function SimplePie_Rating($scheme = null, $value = null)
7430 {
7431 $this->scheme = $scheme;
7432 $this->value = $value;
7433 }
7434
7435 function __toString()
7436 {
7437 // There is no $this->data here
7438 return md5(serialize($this));
7439 }
7440
7441 function get_scheme()
7442 {
7443 if ($this->scheme !== null)
7444 {
7445 return $this->scheme;
7446 }
7447 else
7448 {
7449 return null;
7450 }
7451 }
7452
7453 function get_value()
7454 {
7455 if ($this->value !== null)
7456 {
7457 return $this->value;
7458 }
7459 else
7460 {
7461 return null;
7462 }
7463 }
7464 }
7465
7466 class SimplePie_Restriction
7467 {
7468 var $relationship;
7469 var $type;
7470 var $value;
7471
7472 // Constructor, used to input the data
7473 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7474 {
7475 $this->relationship = $relationship;
7476 $this->type = $type;
7477 $this->value = $value;
7478 }
7479
7480 function __toString()
7481 {
7482 // There is no $this->data here
7483 return md5(serialize($this));
7484 }
7485
7486 function get_relationship()
7487 {
7488 if ($this->relationship !== null)
7489 {
7490 return $this->relationship;
7491 }
7492 else
7493 {
7494 return null;
7495 }
7496 }
7497
7498 function get_type()
7499 {
7500 if ($this->type !== null)
7501 {
7502 return $this->type;
7503 }
7504 else
7505 {
7506 return null;
7507 }
7508 }
7509
7510 function get_value()
7511 {
7512 if ($this->value !== null)
7513 {
7514 return $this->value;
7515 }
7516 else
7517 {
7518 return null;
7519 }
7520 }
7521 }
7522
7523 /**
7524 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7525 */
7526 class SimplePie_File
7527 {
7528 var $url;
7529 var $useragent;
7530 var $success = true;
7531 var $headers = array();
7532 var $body;
7533 var $status_code;
7534 var $redirects = 0;
7535 var $error;
7536 var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7537
7538 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7539 {
7540 if (class_exists('idna_convert'))
7541 {
7542 $idn =& new idna_convert;
7543 $parsed = SimplePie_Misc::parse_url($url);
7544 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7545 }
7546 $this->url = $url;
7547 $this->useragent = $useragent;
7548 if (preg_match('/^http(s)?:\/\//i', $url))
7549 {
7550 if ($useragent === null)
7551 {
7552 $useragent = ini_get('user_agent');
7553 $this->useragent = $useragent;
7554 }
7555 if (!is_array($headers))
7556 {
7557 $headers = array();
7558 }
7559 if (!$force_fsockopen && function_exists('curl_exec'))
7560 {
7561 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7562 $fp = curl_init();
7563 $headers2 = array();
7564 foreach ($headers as $key => $value)
7565 {
7566 $headers2[] = "$key: $value";
7567 }
7568 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7569 {
7570 curl_setopt($fp, CURLOPT_ENCODING, '');
7571 }
7572 curl_setopt($fp, CURLOPT_URL, $url);
7573 curl_setopt($fp, CURLOPT_HEADER, 1);
7574 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7575 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7576 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7577 curl_setopt($fp, CURLOPT_REFERER, $url);
7578 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7579 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7580 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7581 {
7582 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7583 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7584 }
7585
7586 $this->headers = curl_exec($fp);
7587 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7588 {
7589 curl_setopt($fp, CURLOPT_ENCODING, 'none');
7590 $this->headers = curl_exec($fp);
7591 }
7592 if (curl_errno($fp))
7593 {
7594 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7595 $this->success = false;
7596 }
7597 else
7598 {
7599 $info = curl_getinfo($fp);
7600 curl_close($fp);
7601 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7602 $this->headers = array_pop($this->headers);
7603 $parser =& new SimplePie_HTTP_Parser($this->headers);
7604 if ($parser->parse())
7605 {
7606 $this->headers = $parser->headers;
7607 $this->body = $parser->body;
7608 $this->status_code = $parser->status_code;
7609 if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7610 {
7611 $this->redirects++;
7612 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7613 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7614 }
7615 }
7616 }
7617 }
7618 else
7619 {
7620 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7621 $url_parts = parse_url($url);
7622 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7623 {
7624 $url_parts['host'] = "ssl://$url_parts[host]";
7625 $url_parts['port'] = 443;
7626 }
7627 if (!isset($url_parts['port']))
7628 {
7629 $url_parts['port'] = 80;
7630 }
7631 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7632 if (!$fp)
7633 {
7634 $this->error = 'fsockopen error: ' . $errstr;
7635 $this->success = false;
7636 }
7637 else
7638 {
7639 stream_set_timeout($fp, $timeout);
7640 if (isset($url_parts['path']))
7641 {
7642 if (isset($url_parts['query']))
7643 {
7644 $get = "$url_parts[path]?$url_parts[query]";
7645 }
7646 else
7647 {
7648 $get = $url_parts['path'];
7649 }
7650 }
7651 else
7652 {
7653 $get = '/';
7654 }
7655 $out = "GET $get HTTP/1.0\r\n";
7656 $out .= "Host: $url_parts[host]\r\n";
7657 $out .= "User-Agent: $useragent\r\n";
7658 if (function_exists('gzinflate'))
7659 {
7660 $out .= "Accept-Encoding: gzip,deflate\r\n";
7661 }
7662
7663 if (isset($url_parts['user']) && isset($url_parts['pass']))
7664 {
7665 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7666 }
7667 foreach ($headers as $key => $value)
7668 {
7669 $out .= "$key: $value\r\n";
7670 }
7671 $out .= "Connection: Close\r\n\r\n";
7672 fwrite($fp, $out);
7673
7674 $info = stream_get_meta_data($fp);
7675
7676 $this->headers = '';
7677 while (!$info['eof'] && !$info['timed_out'])
7678 {
7679 $this->headers .= fread($fp, 1160);
7680 $info = stream_get_meta_data($fp);
7681 }
7682 if (!$info['timed_out'])
7683 {
7684 $parser =& new SimplePie_HTTP_Parser($this->headers);
7685 if ($parser->parse())
7686 {
7687 $this->headers = $parser->headers;
7688 $this->body = $parser->body;
7689 $this->status_code = $parser->status_code;
7690 if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7691 {
7692 $this->redirects++;
7693 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7694 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7695 }
7696 if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
7697 {
7698 if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
7699 {
7700 $this->body = substr($this->body, 10);
7701 }
7702 $this->body = gzinflate($this->body);
7703 }
7704 }
7705 }
7706 else
7707 {
7708 $this->error = 'fsocket timed out';
7709 $this->success = false;
7710 }
7711 fclose($fp);
7712 }
7713 }
7714 }
7715 else
7716 {
7717 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7718 if (!$this->body = file_get_contents($url))
7719 {
7720 $this->error = 'file_get_contents could not read the file';
7721 $this->success = false;
7722 }
7723 }
7724 }
7725 }
7726
7727 /**
7728 * HTTP Response Parser
7729 *
7730 * @package SimplePie
7731 */
7732 class SimplePie_HTTP_Parser
7733 {
7734 /**
7735 * HTTP Version
7736 *
7737 * @access public
7738 * @var float
7739 */
7740 var $http_version = 0.0;
7741
7742 /**
7743 * Status code
7744 *
7745 * @access public
7746 * @var int
7747 */
7748 var $status_code = 0;
7749
7750 /**
7751 * Reason phrase
7752 *
7753 * @access public
7754 * @var string
7755 */
7756 var $reason = '';
7757
7758 /**
7759 * Key/value pairs of the headers
7760 *
7761 * @access public
7762 * @var array
7763 */
7764 var $headers = array();
7765
7766 /**
7767 * Body of the response
7768 *
7769 * @access public
7770 * @var string
7771 */
7772 var $body = '';
7773
7774 /**
7775 * Current state of the state machine
7776 *
7777 * @access private
7778 * @var string
7779 */
7780 var $state = 'http_version';
7781
7782 /**
7783 * Input data
7784 *
7785 * @access private
7786 * @var string
7787 */
7788 var $data = '';
7789
7790 /**
7791 * Input data length (to avoid calling strlen() everytime this is needed)
7792 *
7793 * @access private
7794 * @var int
7795 */
7796 var $data_length = 0;
7797
7798 /**
7799 * Current position of the pointer
7800 *
7801 * @var int
7802 * @access private
7803 */
7804 var $position = 0;
7805
7806 /**
7807 * Name of the hedaer currently being parsed
7808 *
7809 * @access private
7810 * @var string
7811 */
7812 var $name = '';
7813
7814 /**
7815 * Value of the hedaer currently being parsed
7816 *
7817 * @access private
7818 * @var string
7819 */
7820 var $value = '';
7821
7822 /**
7823 * Create an instance of the class with the input data
7824 *
7825 * @access public
7826 * @param string $data Input data
7827 */
7828 function SimplePie_HTTP_Parser($data)
7829 {
7830 $this->data = $data;
7831 $this->data_length = strlen($this->data);
7832 }
7833
7834 /**
7835 * Parse the input data
7836 *
7837 * @access public
7838 * @return bool true on success, false on failure
7839 */
7840 function parse()
7841 {
7842 while ($this->state && $this->state !== 'emit' && $this->has_data())
7843 {
7844 $state = $this->state;
7845 $this->$state();
7846 }
7847 $this->data = '';
7848 if ($this->state === 'emit')
7849 {
7850 return true;
7851 }
7852 else
7853 {
7854 $this->http_version = '';
7855 $this->status_code = '';
7856 $this->reason = '';
7857 $this->headers = array();
7858 $this->body = '';
7859 return false;
7860 }
7861 }
7862
7863 /**
7864 * Check whether there is data beyond the pointer
7865 *
7866 * @access private
7867 * @return bool true if there is further data, false if not
7868 */
7869 function has_data()
7870 {
7871 return (bool) ($this->position < $this->data_length);
7872 }
7873
7874 /**
7875 * See if the next character is LWS
7876 *
7877 * @access private
7878 * @return bool true if the next character is LWS, false if not
7879 */
7880 function is_linear_whitespace()
7881 {
7882 return (bool) ($this->data[$this->position] === "\x09"
7883 || $this->data[$this->position] === "\x20"
7884 || ($this->data[$this->position] === "\x0A"
7885 && isset($this->data[$this->position + 1])
7886 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
7887 }
7888
7889 /**
7890 * Parse the HTTP version
7891 *
7892 * @access private
7893 */
7894 function http_version()
7895 {
7896 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
7897 {
7898 $len = strspn($this->data, '0123456789.', 5);
7899 $this->http_version = substr($this->data, 5, $len);
7900 $this->position += 5 + $len;
7901 if (substr_count($this->http_version, '.') <= 1)
7902 {
7903 $this->http_version = (float) $this->http_version;
7904 $this->position += strspn($this->data, "\x09\x20", $this->position);
7905 $this->state = 'status';
7906 }
7907 else
7908 {
7909 $this->state = false;
7910 }
7911 }
7912 else
7913 {
7914 $this->state = false;
7915 }
7916 }
7917
7918 /**
7919 * Parse the status code
7920 *
7921 * @access private
7922 */
7923 function status()
7924 {
7925 if ($len = strspn($this->data, '0123456789', $this->position))
7926 {
7927 $this->status_code = (int) substr($this->data, $this->position, $len);
7928 $this->position += $len;
7929 $this->state = 'reason';
7930 }
7931 else
7932 {
7933 $this->state = false;
7934 }
7935 }
7936
7937 /**
7938 * Parse the reason phrase
7939 *
7940 * @access private
7941 */
7942 function reason()
7943 {
7944 $len = strcspn($this->data, "\x0A", $this->position);
7945 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
7946 $this->position += $len + 1;
7947 $this->state = 'new_line';
7948 }
7949
7950 /**
7951 * Deal with a new line, shifting data around as needed
7952 *
7953 * @access private
7954 */
7955 function new_line()
7956 {
7957 $this->value = trim($this->value, "\x0D\x20");
7958 if ($this->name !== '' && $this->value !== '')
7959 {
7960 $this->name = strtolower($this->name);
7961 if (isset($this->headers[$this->name]))
7962 {
7963 $this->headers[$this->name] .= ', ' . $this->value;
7964 }
7965 else
7966 {
7967 $this->headers[$this->name] = $this->value;
7968 }
7969 }
7970 $this->name = '';
7971 $this->value = '';
7972 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
7973 {
7974 $this->position += 2;
7975 $this->state = 'body';
7976 }
7977 elseif ($this->data[$this->position] === "\x0A")
7978 {
7979 $this->position++;
7980 $this->state = 'body';
7981 }
7982 else
7983 {
7984 $this->state = 'name';
7985 }
7986 }
7987
7988 /**
7989 * Parse a header name
7990 *
7991 * @access private
7992 */
7993 function name()
7994 {
7995 $len = strcspn($this->data, "\x0A:", $this->position);
7996 if (isset($this->data[$this->position + $len]))
7997 {
7998 if ($this->data[$this->position + $len] === "\x0A")
7999 {
8000 $this->position += $len;
8001 $this->state = 'new_line';
8002 }
8003 else
8004 {
8005 $this->name = substr($this->data, $this->position, $len);
8006 $this->position += $len + 1;
8007 $this->state = 'value';
8008 }
8009 }
8010 else
8011 {
8012 $this->state = false;
8013 }
8014 }
8015
8016 /**
8017 * Parse LWS, replacing consecutive LWS characters with a single space
8018 *
8019 * @access private
8020 */
8021 function linear_whitespace()
8022 {
8023 do
8024 {
8025 if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8026 {
8027 $this->position += 2;
8028 }
8029 elseif ($this->data[$this->position] === "\x0A")
8030 {
8031 $this->position++;
8032 }
8033 $this->position += strspn($this->data, "\x09\x20", $this->position);
8034 } while ($this->has_data() && $this->is_linear_whitespace());
8035 $this->value .= "\x20";
8036 }
8037
8038 /**
8039 * See what state to move to while within non-quoted header values
8040 *
8041 * @access private
8042 */
8043 function value()
8044 {
8045 if ($this->is_linear_whitespace())
8046 {
8047 $this->linear_whitespace();
8048 }
8049 else
8050 {
8051 switch ($this->data[$this->position])
8052 {
8053 case '"':
8054 $this->position++;
8055 $this->state = 'quote';
8056 break;
8057
8058 case "\x0A":
8059 $this->position++;
8060 $this->state = 'new_line';
8061 break;
8062
8063 default:
8064 $this->state = 'value_char';
8065 break;
8066 }
8067 }
8068 }
8069
8070 /**
8071 * Parse a header value while outside quotes
8072 *
8073 * @access private
8074 */
8075 function value_char()
8076 {
8077 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8078 $this->value .= substr($this->data, $this->position, $len);
8079 $this->position += $len;
8080 $this->state = 'value';
8081 }
8082
8083 /**
8084 * See what state to move to while within quoted header values
8085 *
8086 * @access private
8087 */
8088 function quote()
8089 {
8090 if ($this->is_linear_whitespace())
8091 {
8092 $this->linear_whitespace();
8093 }
8094 else
8095 {
8096 switch ($this->data[$this->position])
8097 {
8098 case '"':
8099 $this->position++;
8100 $this->state = 'value';
8101 break;
8102
8103 case "\x0A":
8104 $this->position++;
8105 $this->state = 'new_line';
8106 break;
8107
8108 case '\\':
8109 $this->position++;
8110 $this->state = 'quote_escaped';
8111 break;
8112
8113 default:
8114 $this->state = 'quote_char';
8115 break;
8116 }
8117 }
8118 }
8119
8120 /**
8121 * Parse a header value while within quotes
8122 *
8123 * @access private
8124 */
8125 function quote_char()
8126 {
8127 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8128 $this->value .= substr($this->data, $this->position, $len);
8129 $this->position += $len;
8130 $this->state = 'value';
8131 }
8132
8133 /**
8134 * Parse an escaped character within quotes
8135 *
8136 * @access private
8137 */
8138 function quote_escaped()
8139 {
8140 $this->value .= $this->data[$this->position];
8141 $this->position++;
8142 $this->state = 'quote';
8143 }
8144
8145 /**
8146 * Parse the body
8147 *
8148 * @access private
8149 */
8150 function body()
8151 {
8152 $this->body = substr($this->data, $this->position);
8153 $this->state = 'emit';
8154 }
8155 }
8156
8157 class SimplePie_Cache
8158 {
8159 /**
8160 * Don't call the constructor. Please.
8161 *
8162 * @access private
8163 */
8164 function SimplePie_Cache()
8165 {
8166 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8167 }
8168
8169 /**
8170 * Create a new SimplePie_Cache object
8171 *
8172 * @static
8173 * @access public
8174 */
8175 function create($location, $filename, $extension)
8176 {
8177 return new SimplePie_Cache_File($location, $filename, $extension);
8178 }
8179 }
8180
8181 class SimplePie_Cache_File
8182 {
8183 var $location;
8184 var $filename;
8185 var $extension;
8186 var $name;
8187
8188 function SimplePie_Cache_File($location, $filename, $extension)
8189 {
8190 $this->location = $location;
8191 $this->filename = rawurlencode($filename);
8192 $this->extension = rawurlencode($extension);
8193 $this->name = "$location/$this->filename.$this->extension";
8194 }
8195
8196 function save($data)
8197 {
8198 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8199 {
8200 if (is_a($data, 'SimplePie'))
8201 {
8202 $data = $data->data;
8203 }
8204
8205 $data = serialize($data);
8206
8207 if (function_exists('file_put_contents'))
8208 {
8209 return (bool) file_put_contents($this->name, $data);
8210 }
8211 else
8212 {
8213 $fp = fopen($this->name, 'wb');
8214 if ($fp)
8215 {
8216 fwrite($fp, $data);
8217 fclose($fp);
8218 return true;
8219 }
8220 }
8221 }
8222 return false;
8223 }
8224
8225 function load()
8226 {
8227 if (file_exists($this->name) && is_readable($this->name))
8228 {
8229 return unserialize(file_get_contents($this->name));
8230 }
8231 return false;
8232 }
8233
8234 function mtime()
8235 {
8236 if (file_exists($this->name))
8237 {
8238 return filemtime($this->name);
8239 }
8240 return false;
8241 }
8242
8243 function touch()
8244 {
8245 if (file_exists($this->name))
8246 {
8247 return touch($this->name);
8248 }
8249 return false;
8250 }
8251
8252 function unlink()
8253 {
8254 if (file_exists($this->name))
8255 {
8256 return unlink($this->name);
8257 }
8258 return false;
8259 }
8260 }
8261
8262 class SimplePie_Misc
8263 {
8264 function time_hms($seconds)
8265 {
8266 $time = '';
8267
8268 $hours = floor($seconds / 3600);
8269 $remainder = $seconds % 3600;
8270 if ($hours > 0)
8271 {
8272 $time .= $hours.':';
8273 }
8274
8275 $minutes = floor($remainder / 60);
8276 $seconds = $remainder % 60;
8277 if ($minutes < 10 && $hours > 0)
8278 {
8279 $minutes = '0' . $minutes;
8280 }
8281 if ($seconds < 10)
8282 {
8283 $seconds = '0' . $seconds;
8284 }
8285
8286 $time .= $minutes.':';
8287 $time .= $seconds;
8288
8289 return $time;
8290 }
8291
8292 function absolutize_url($relative, $base)
8293 {
8294 if ($relative !== '')
8295 {
8296 $relative = SimplePie_Misc::parse_url($relative);
8297 if ($relative['scheme'] !== '')
8298 {
8299 $target = $relative;
8300 }
8301 elseif ($base !== '')
8302 {
8303 $base = SimplePie_Misc::parse_url($base);
8304 $target = SimplePie_Misc::parse_url('');
8305 if ($relative['authority'] !== '')
8306 {
8307 $target = $relative;
8308 $target['scheme'] = $base['scheme'];
8309 }
8310 else
8311 {
8312 $target['scheme'] = $base['scheme'];
8313 $target['authority'] = $base['authority'];
8314 if ($relative['path'] !== '')
8315 {
8316 if (strpos($relative['path'], '/') === 0)
8317 {
8318 $target['path'] = $relative['path'];
8319 }
8320 elseif ($base['authority'] !== '' && $base['path'] === '')
8321 {
8322 $target['path'] = '/' . $relative['path'];
8323 }
8324 elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8325 {
8326 $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8327 }
8328 else
8329 {
8330 $target['path'] = $relative['path'];
8331 }
8332 $target['query'] = $relative['query'];
8333 }
8334 else
8335 {
8336 $target['path'] = $base['path'];
8337 if ($relative['query'] !== '')
8338 {
8339 $target['query'] = $relative['query'];
8340 }
8341 elseif ($base['query'] !== '')
8342 {
8343 $target['query'] = $base['query'];
8344 }
8345 }
8346 }
8347 $target['fragment'] = $relative['fragment'];
8348 }
8349 else
8350 {
8351 // No base URL, just return the relative URL
8352 $target = $relative;
8353 }
8354 $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8355 }
8356 else
8357 {
8358 $return = $base;
8359 }
8360 $return = SimplePie_Misc::normalize_url($return);
8361 return $return;
8362 }
8363
8364 function remove_dot_segments($input)
8365 {
8366 $output = '';
8367 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8368 {
8369 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8370 if (strpos($input, '../') === 0)
8371 {
8372 $input = substr($input, 3);
8373 }
8374 elseif (strpos($input, './') === 0)
8375 {
8376 $input = substr($input, 2);
8377 }
8378 // 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,
8379 elseif (strpos($input, '/./') === 0)
8380 {
8381 $input = substr_replace($input, '/', 0, 3);
8382 }
8383 elseif ($input == '/.')
8384 {
8385 $input = '/';
8386 }
8387 // 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,
8388 elseif (strpos($input, '/../') === 0)
8389 {
8390 $input = substr_replace($input, '/', 0, 4);
8391 $output = substr_replace($output, '', strrpos($output, '/'));
8392 }
8393 elseif ($input == '/..')
8394 {
8395 $input = '/';
8396 $output = substr_replace($output, '', strrpos($output, '/'));
8397 }
8398 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8399 elseif ($input == '.' || $input == '..')
8400 {
8401 $input = '';
8402 }
8403 // 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
8404 elseif (($pos = strpos($input, '/', 1)) !== false)
8405 {
8406 $output .= substr($input, 0, $pos);
8407 $input = substr_replace($input, '', 0, $pos);
8408 }
8409 else
8410 {
8411 $output .= $input;
8412 $input = '';
8413 }
8414 }
8415 return $output . $input;
8416 }
8417
8418 function get_element($realname, $string)
8419 {
8420 $return = array();
8421 $name = preg_quote($realname, '/');
8422 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8423 {
8424 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8425 {
8426 $return[$i]['tag'] = $realname;
8427 $return[$i]['full'] = $matches[$i][0][0];
8428 $return[$i]['offset'] = $matches[$i][0][1];
8429 if (strlen($matches[$i][3][0]) <= 2)
8430 {
8431 $return[$i]['self_closing'] = true;
8432 }
8433 else
8434 {
8435 $return[$i]['self_closing'] = false;
8436 $return[$i]['content'] = $matches[$i][4][0];
8437 }
8438 $return[$i]['attribs'] = array();
8439 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))
8440 {
8441 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8442 {
8443 if (count($attribs[$j]) == 2)
8444 {
8445 $attribs[$j][2] = $attribs[$j][1];
8446 }
8447 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8448 }
8449 }
8450 }
8451 }
8452 return $return;
8453 }
8454
8455 function element_implode($element)
8456 {
8457 $full = "<$element[tag]";
8458 foreach ($element['attribs'] as $key => $value)
8459 {
8460 $key = strtolower($key);
8461 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8462 }
8463 if ($element['self_closing'])
8464 {
8465 $full .= ' />';
8466 }
8467 else
8468 {
8469 $full .= ">$element[content]</$element[tag]>";
8470 }
8471 return $full;
8472 }
8473
8474 function error($message, $level, $file, $line)
8475 {
8476 switch ($level)
8477 {
8478 case E_USER_ERROR:
8479 $note = 'PHP Error';
8480 break;
8481 case E_USER_WARNING:
8482 $note = 'PHP Warning';
8483 break;
8484 case E_USER_NOTICE:
8485 $note = 'PHP Notice';
8486 break;
8487 default:
8488 $note = 'Unknown Error';
8489 break;
8490 }
8491 error_log("$note: $message in $file on line $line", 0);
8492 return $message;
8493 }
8494
8495 /**
8496 * If a file has been cached, retrieve and display it.
8497 *
8498 * This is most useful for caching images (get_favicon(), etc.),
8499 * however it works for all cached files. This WILL NOT display ANY
8500 * file/image/page/whatever, but rather only display what has already
8501 * been cached by SimplePie.
8502 *
8503 * @access public
8504 * @see SimplePie::get_favicon()
8505 * @param str $identifier_url URL that is used to identify the content.
8506 * This may or may not be the actual URL of the live content.
8507 * @param str $cache_location Location of SimplePie's cache. Defaults
8508 * to './cache'.
8509 * @param str $cache_extension The file extension that the file was
8510 * cached with. Defaults to 'spc'.
8511 * @param str $cache_class Name of the cache-handling class being used
8512 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
8513 * as-is unless you've overloaded the class.
8514 * @param str $cache_name_function Obsolete. Exists for backwards
8515 * compatibility reasons only.
8516 */
8517 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8518 {
8519 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
8520
8521 if ($file = $cache->load())
8522 {
8523 if (isset($file['headers']['content-type']))
8524 {
8525 header('Content-type:' . $file['headers']['content-type']);
8526 }
8527 else
8528 {
8529 header('Content-type: application/octet-stream');
8530 }
8531 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8532 echo $file['body'];
8533 exit;
8534 }
8535
8536 die('Cached file for ' . $identifier_url . ' cannot be found.');
8537 }
8538
8539 function fix_protocol($url, $http = 1)
8540 {
8541 $url = SimplePie_Misc::normalize_url($url);
8542 $parsed = SimplePie_Misc::parse_url($url);
8543 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8544 {
8545 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8546 }
8547
8548 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8549 {
8550 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8551 }
8552
8553 if ($http == 2 && $parsed['scheme'] !== '')
8554 {
8555 return "feed:$url";
8556 }
8557 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
8558 {
8559 return substr_replace($url, 'podcast', 0, 4);
8560 }
8561 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
8562 {
8563 return substr_replace($url, 'itpc', 0, 4);
8564 }
8565 else
8566 {
8567 return $url;
8568 }
8569 }
8570
8571 function parse_url($url)
8572 {
8573 static $cache = array();
8574 if (isset($cache[$url]))
8575 {
8576 return $cache[$url];
8577 }
8578 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
8579 {
8580 for ($i = count($match); $i <= 9; $i++)
8581 {
8582 $match[$i] = '';
8583 }
8584 return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
8585 }
8586 else
8587 {
8588 return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
8589 }
8590 }
8591
8592 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
8593 {
8594 $return = '';
8595 if ($scheme !== '')
8596 {
8597 $return .= "$scheme:";
8598 }
8599 if ($authority !== '')
8600 {
8601 $return .= "//$authority";
8602 }
8603 if ($path !== '')
8604 {
8605 $return .= $path;
8606 }
8607 if ($query !== '')
8608 {
8609 $return .= "?$query";
8610 }
8611 if ($fragment !== '')
8612 {
8613 $return .= "#$fragment";
8614 }
8615 return $return;
8616 }
8617
8618 function normalize_url($url)
8619 {
8620 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
8621 $url = SimplePie_Misc::parse_url($url);
8622 $url['scheme'] = strtolower($url['scheme']);
8623 if ($url['authority'] !== '')
8624 {
8625 $url['authority'] = strtolower($url['authority']);
8626 $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
8627 }
8628 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
8629 }
8630
8631 function percent_encoding_normalization($match)
8632 {
8633 $integer = hexdec($match[1]);
8634 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
8635 {
8636 return chr($integer);
8637 }
8638 else
8639 {
8640 return strtoupper($match[0]);
8641 }
8642 }
8643
8644 /**
8645 * Remove bad UTF-8 bytes
8646 *
8647 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
8648 * FAQ: Multilingual Forms (modified to include full ASCII range)
8649 *
8650 * @author Geoffrey Sneddon
8651 * @see http://www.w3.org/International/questions/qa-forms-utf-8
8652 * @param string $str String to remove bad UTF-8 bytes from
8653 * @return string UTF-8 string
8654 */
8655 function utf8_bad_replace($str)
8656 {
8657 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
8658 {
8659 return $return;
8660 }
8661 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
8662 {
8663 return $return;
8664 }
8665 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))
8666 {
8667 return implode("\xEF\xBF\xBD", $matches[0]);
8668 }
8669 elseif ($str !== '')
8670 {
8671 return "\xEF\xBF\xBD";
8672 }
8673 else
8674 {
8675 return '';
8676 }
8677 }
8678
8679 /**
8680 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
8681 *
8682 * @static
8683 * @access public
8684 * @param string $string Windows-1252 encoded string
8685 * @return string UTF-8 encoded string
8686 */
8687 function windows_1252_to_utf8($string)
8688 {
8689 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");
8690
8691 return strtr($string, $convert_table);
8692 }
8693
8694 function change_encoding($data, $input, $output)
8695 {
8696 $input = SimplePie_Misc::encoding($input);
8697 $output = SimplePie_Misc::encoding($output);
8698
8699 // We fail to fail on non US-ASCII bytes
8700 if ($input === 'US-ASCII')
8701 {
8702 static $non_ascii_octects = '';
8703 if (!$non_ascii_octects)
8704 {
8705 for ($i = 0x80; $i <= 0xFF; $i++)
8706 {
8707 $non_ascii_octects .= chr($i);
8708 }
8709 }
8710 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
8711 }
8712
8713 if (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
8714 {
8715 return $return;
8716 }
8717 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
8718 {
8719 return $return;
8720 }
8721 elseif ($input == 'windows-1252' && $output == 'UTF-8')
8722 {
8723 return SimplePie_Misc::windows_1252_to_utf8($data);
8724 }
8725 elseif ($input == 'UTF-8' && $output == 'windows-1252')
8726 {
8727 return utf8_decode($data);
8728 }
8729 return $data;
8730 }
8731
8732 function encoding($encoding)
8733 {
8734 // Character sets are case-insensitive (though we'll return them in the form given in their registration)
8735 switch (strtoupper($encoding))
8736 {
8737 case 'ANSI_X3.110-1983':
8738 case 'CSA_T500-1983':
8739 case 'CSISO99NAPLPS':
8740 case 'ISO-IR-99':
8741 case 'NAPLPS':
8742 return 'ANSI_X3.110-1983';
8743
8744 case 'ARABIC7':
8745 case 'ASMO_449':
8746 case 'CSISO89ASMO449':
8747 case 'ISO-IR-89':
8748 case 'ISO_9036':
8749 return 'ASMO_449';
8750
8751 case 'ADOBE-STANDARD-ENCODING':
8752 case 'CSADOBESTANDARDENCODING':
8753 return 'Adobe-Standard-Encoding';
8754
8755 case 'ADOBE-SYMBOL-ENCODING':
8756 case 'CSHPPSMATH':
8757 return 'Adobe-Symbol-Encoding';
8758
8759 case 'AMI-1251':
8760 case 'AMI1251':
8761 case 'AMIGA-1251':
8762 case 'AMIGA1251':
8763 return 'Amiga-1251';
8764
8765 case 'BOCU-1':
8766 case 'CSBOCU-1':
8767 return 'BOCU-1';
8768
8769 case 'BRF':
8770 case 'CSBRF':
8771 return 'BRF';
8772
8773 case 'BS_4730':
8774 case 'CSISO4UNITEDKINGDOM':
8775 case 'GB':
8776 case 'ISO-IR-4':
8777 case 'ISO646-GB':
8778 case 'UK':
8779 return 'BS_4730';
8780
8781 case 'BS_VIEWDATA':
8782 case 'CSISO47BSVIEWDATA':
8783 case 'ISO-IR-47':
8784 return 'BS_viewdata';
8785
8786 case 'BIG5':
8787 case 'CSBIG5':
8788 return 'Big5';
8789
8790 case 'BIG5-HKSCS':
8791 return 'Big5-HKSCS';
8792
8793 case 'CESU-8':
8794 case 'CSCESU-8':
8795 return 'CESU-8';
8796
8797 case 'CA':
8798 case 'CSA7-1':
8799 case 'CSA_Z243.4-1985-1':
8800 case 'CSISO121CANADIAN1':
8801 case 'ISO-IR-121':
8802 case 'ISO646-CA':
8803 return 'CSA_Z243.4-1985-1';
8804
8805 case 'CSA7-2':
8806 case 'CSA_Z243.4-1985-2':
8807 case 'CSISO122CANADIAN2':
8808 case 'ISO-IR-122':
8809 case 'ISO646-CA2':
8810 return 'CSA_Z243.4-1985-2';
8811
8812 case 'CSA_Z243.4-1985-GR':
8813 case 'CSISO123CSAZ24341985GR':
8814 case 'ISO-IR-123':
8815 return 'CSA_Z243.4-1985-gr';
8816
8817 case 'CSISO139CSN369103':
8818 case 'CSN_369103':
8819 case 'ISO-IR-139':
8820 return 'CSN_369103';
8821
8822 case 'CSDECMCS':
8823 case 'DEC':
8824 case 'DEC-MCS':
8825 return 'DEC-MCS';
8826
8827 case 'CSISO21GERMAN':
8828 case 'DE':
8829 case 'DIN_66003':
8830 case 'ISO-IR-21':
8831 case 'ISO646-DE':
8832 return 'DIN_66003';
8833
8834 case 'CSISO646DANISH':
8835 case 'DK':
8836 case 'DS2089':
8837 case 'DS_2089':
8838 case 'ISO646-DK':
8839 return 'DS_2089';
8840
8841 case 'CSIBMEBCDICATDE':
8842 case 'EBCDIC-AT-DE':
8843 return 'EBCDIC-AT-DE';
8844
8845 case 'CSEBCDICATDEA':
8846 case 'EBCDIC-AT-DE-A':
8847 return 'EBCDIC-AT-DE-A';
8848
8849 case 'CSEBCDICCAFR':
8850 case 'EBCDIC-CA-FR':
8851 return 'EBCDIC-CA-FR';
8852
8853 case 'CSEBCDICDKNO':
8854 case 'EBCDIC-DK-NO':
8855 return 'EBCDIC-DK-NO';
8856
8857 case 'CSEBCDICDKNOA':
8858 case 'EBCDIC-DK-NO-A':
8859 return 'EBCDIC-DK-NO-A';
8860
8861 case 'CSEBCDICES':
8862 case 'EBCDIC-ES':
8863 return 'EBCDIC-ES';
8864
8865 case 'CSEBCDICESA':
8866 case 'EBCDIC-ES-A':
8867 return 'EBCDIC-ES-A';
8868
8869 case 'CSEBCDICESS':
8870 case 'EBCDIC-ES-S':
8871 return 'EBCDIC-ES-S';
8872
8873 case 'CSEBCDICFISE':
8874 case 'EBCDIC-FI-SE':
8875 return 'EBCDIC-FI-SE';
8876
8877 case 'CSEBCDICFISEA':
8878 case 'EBCDIC-FI-SE-A':
8879 return 'EBCDIC-FI-SE-A';
8880
8881 case 'CSEBCDICFR':
8882 case 'EBCDIC-FR':
8883 return 'EBCDIC-FR';
8884
8885 case 'CSEBCDICIT':
8886 case 'EBCDIC-IT':
8887 return 'EBCDIC-IT';
8888
8889 case 'CSEBCDICPT':
8890 case 'EBCDIC-PT':
8891 return 'EBCDIC-PT';
8892
8893 case 'CSEBCDICUK':
8894 case 'EBCDIC-UK':
8895 return 'EBCDIC-UK';
8896
8897 case 'CSEBCDICUS':
8898 case 'EBCDIC-US':
8899 return 'EBCDIC-US';
8900
8901 case 'CSISO111ECMACYRILLIC':
8902 case 'ECMA-CYRILLIC':
8903 case 'ISO-IR-111':
8904 case 'KOI8-E':
8905 return 'ECMA-cyrillic';
8906
8907 case 'CSISO17SPANISH':
8908 case 'ES':
8909 case 'ISO-IR-17':
8910 case 'ISO646-ES':
8911 return 'ES';
8912
8913 case 'CSISO85SPANISH2':
8914 case 'ES2':
8915 case 'ISO-IR-85':
8916 case 'ISO646-ES2':
8917 return 'ES2';
8918
8919 case 'CSEUCPKDFMTJAPANESE':
8920 case 'EUC-JP':
8921 case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
8922 return 'EUC-JP';
8923
8924 case 'CSEUCKR':
8925 case 'EUC-KR':
8926 return 'EUC-KR';
8927
8928 case 'CSEUCFIXWIDJAPANESE':
8929 case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
8930 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
8931
8932 case 'GB18030':
8933 return 'GB18030';
8934
8935 case 'CSGB2312':
8936 case 'GB2312':
8937 return 'GB2312';
8938
8939 case 'CP936':
8940 case 'GBK':
8941 case 'MS936':
8942 case 'WINDOWS-936':
8943 return 'GBK';
8944
8945 case 'CN':
8946 case 'CSISO57GB1988':
8947 case 'GB_1988-80':
8948 case 'ISO-IR-57':
8949 case 'ISO646-CN':
8950 return 'GB_1988-80';
8951
8952 case 'CHINESE':
8953 case 'CSISO58GB231280':
8954 case 'GB_2312-80':
8955 case 'ISO-IR-58':
8956 return 'GB_2312-80';
8957
8958 case 'CSISO153GOST1976874':
8959 case 'GOST_19768-74':
8960 case 'ISO-IR-153':
8961 case 'ST_SEV_358-88':
8962 return 'GOST_19768-74';
8963
8964 case 'CSHPDESKTOP':
8965 case 'HP-DESKTOP':
8966 return 'HP-DeskTop';
8967
8968 case 'CSHPLEGAL':
8969 case 'HP-LEGAL':
8970 return 'HP-Legal';
8971
8972 case 'CSHPMATH8':
8973 case 'HP-MATH8':
8974 return 'HP-Math8';
8975
8976 case 'CSHPPIFONT':
8977 case 'HP-PI-FONT':
8978 return 'HP-Pi-font';
8979
8980 case 'HZ-GB-2312':
8981 return 'HZ-GB-2312';
8982
8983 case 'CSIBMSYMBOLS':
8984 case 'IBM-SYMBOLS':
8985 return 'IBM-Symbols';
8986
8987 case 'CSIBMTHAI':
8988 case 'IBM-THAI':
8989 return 'IBM-Thai';
8990
8991 case 'CCSID00858':
8992 case 'CP00858':
8993 case 'IBM00858':
8994 case 'PC-MULTILINGUAL-850+EURO':
8995 return 'IBM00858';
8996
8997 case 'CCSID00924':
8998 case 'CP00924':
8999 case 'EBCDIC-LATIN9--EURO':
9000 case 'IBM00924':
9001 return 'IBM00924';
9002
9003 case 'CCSID01140':
9004 case 'CP01140':
9005 case 'EBCDIC-US-37+EURO':
9006 case 'IBM01140':
9007 return 'IBM01140';
9008
9009 case 'CCSID01141':
9010 case 'CP01141':
9011 case 'EBCDIC-DE-273+EURO':
9012 case 'IBM01141':
9013 return 'IBM01141';
9014
9015 case 'CCSID01142':
9016 case 'CP01142':
9017 case 'EBCDIC-DK-277+EURO':
9018 case 'EBCDIC-NO-277+EURO':
9019 case 'IBM01142':
9020 return 'IBM01142';
9021
9022 case 'CCSID01143':
9023 case 'CP01143':
9024 case 'EBCDIC-FI-278+EURO':
9025 case 'EBCDIC-SE-278+EURO':
9026 case 'IBM01143':
9027 return 'IBM01143';
9028
9029 case 'CCSID01144':
9030 case 'CP01144':
9031 case 'EBCDIC-IT-280+EURO':
9032 case 'IBM01144':
9033 return 'IBM01144';
9034
9035 case 'CCSID01145':
9036 case 'CP01145':
9037 case 'EBCDIC-ES-284+EURO':
9038 case 'IBM01145':
9039 return 'IBM01145';
9040
9041 case 'CCSID01146':
9042 case 'CP01146':
9043 case 'EBCDIC-GB-285+EURO':
9044 case 'IBM01146':
9045 return 'IBM01146';
9046
9047 case 'CCSID01147':
9048 case 'CP01147':
9049 case 'EBCDIC-FR-297+EURO':
9050 case 'IBM01147':
9051 return 'IBM01147';
9052
9053 case 'CCSID01148':
9054 case 'CP01148':
9055 case 'EBCDIC-INTERNATIONAL-500+EURO':
9056 case 'IBM01148':
9057 return 'IBM01148';
9058
9059 case 'CCSID01149':
9060 case 'CP01149':
9061 case 'EBCDIC-IS-871+EURO':
9062 case 'IBM01149':
9063 return 'IBM01149';
9064
9065 case 'CP037':
9066 case 'CSIBM037':
9067 case 'EBCDIC-CP-CA':
9068 case 'EBCDIC-CP-NL':
9069 case 'EBCDIC-CP-US':
9070 case 'EBCDIC-CP-WT':
9071 case 'IBM037':
9072 return 'IBM037';
9073
9074 case 'CP038':
9075 case 'CSIBM038':
9076 case 'EBCDIC-INT':
9077 case 'IBM038':
9078 return 'IBM038';
9079
9080 case 'CP1026':
9081 case 'CSIBM1026':
9082 case 'IBM1026':
9083 return 'IBM1026';
9084
9085 case 'IBM-1047':
9086 case 'IBM1047':
9087 return 'IBM1047';
9088
9089 case 'CP273':
9090 case 'CSIBM273':
9091 case 'IBM273':
9092 return 'IBM273';
9093
9094 case 'CP274':
9095 case 'CSIBM274':
9096 case 'EBCDIC-BE':
9097 case 'IBM274':
9098 return 'IBM274';
9099
9100 case 'CP275':
9101 case 'CSIBM275':
9102 case 'EBCDIC-BR':
9103 case 'IBM275':
9104 return 'IBM275';
9105
9106 case 'CSIBM277':
9107 case 'EBCDIC-CP-DK':
9108 case 'EBCDIC-CP-NO':
9109 case 'IBM277':
9110 return 'IBM277';
9111
9112 case 'CP278':
9113 case 'CSIBM278':
9114 case 'EBCDIC-CP-FI':
9115 case 'EBCDIC-CP-SE':
9116 case 'IBM278':
9117 return 'IBM278';
9118
9119 case 'CP280':
9120 case 'CSIBM280':
9121 case 'EBCDIC-CP-IT':
9122 case 'IBM280':
9123 return 'IBM280';
9124
9125 case 'CP281':
9126 case 'CSIBM281':
9127 case 'EBCDIC-JP-E':
9128 case 'IBM281':
9129 return 'IBM281';
9130
9131 case 'CP284':
9132 case 'CSIBM284':
9133 case 'EBCDIC-CP-ES':
9134 case 'IBM284':
9135 return 'IBM284';
9136
9137 case 'CP285':
9138 case 'CSIBM285':
9139 case 'EBCDIC-CP-GB':
9140 case 'IBM285':
9141 return 'IBM285';
9142
9143 case 'CP290':
9144 case 'CSIBM290':
9145 case 'EBCDIC-JP-KANA':
9146 case 'IBM290':
9147 return 'IBM290';
9148
9149 case 'CP297':
9150 case 'CSIBM297':
9151 case 'EBCDIC-CP-FR':
9152 case 'IBM297':
9153 return 'IBM297';
9154
9155 case 'CP420':
9156 case 'CSIBM420':
9157 case 'EBCDIC-CP-AR1':
9158 case 'IBM420':
9159 return 'IBM420';
9160
9161 case 'CP423':
9162 case 'CSIBM423':
9163 case 'EBCDIC-CP-GR':
9164 case 'IBM423':
9165 return 'IBM423';
9166
9167 case 'CP424':
9168 case 'CSIBM424':
9169 case 'EBCDIC-CP-HE':
9170 case 'IBM424':
9171 return 'IBM424';
9172
9173 case '437':
9174 case 'CP437':
9175 case 'CSPC8CODEPAGE437':
9176 case 'IBM437':
9177 return 'IBM437';
9178
9179 case 'CP500':
9180 case 'CSIBM500':
9181 case 'EBCDIC-CP-BE':
9182 case 'EBCDIC-CP-CH':
9183 case 'IBM500':
9184 return 'IBM500';
9185
9186 case 'CP775':
9187 case 'CSPC775BALTIC':
9188 case 'IBM775':
9189 return 'IBM775';
9190
9191 case '850':
9192 case 'CP850':
9193 case 'CSPC850MULTILINGUAL':
9194 case 'IBM850':
9195 return 'IBM850';
9196
9197 case '851':
9198 case 'CP851':
9199 case 'CSIBM851':
9200 case 'IBM851':
9201 return 'IBM851';
9202
9203 case '852':
9204 case 'CP852':
9205 case 'CSPCP852':
9206 case 'IBM852':
9207 return 'IBM852';
9208
9209 case '855':
9210 case 'CP855':
9211 case 'CSIBM855':
9212 case 'IBM855':
9213 return 'IBM855';
9214
9215 case '857':
9216 case 'CP857':
9217 case 'CSIBM857':
9218 case 'IBM857':
9219 return 'IBM857';
9220
9221 case '860':
9222 case 'CP860':
9223 case 'CSIBM860':
9224 case 'IBM860':
9225 return 'IBM860';
9226
9227 case '861':
9228 case 'CP-IS':
9229 case 'CP861':
9230 case 'CSIBM861':
9231 case 'IBM861':
9232 return 'IBM861';
9233
9234 case '862':
9235 case 'CP862':
9236 case 'CSPC862LATINHEBREW':
9237 case 'IBM862':
9238 return 'IBM862';
9239
9240 case '863':
9241 case 'CP863':
9242 case 'CSIBM863':
9243 case 'IBM863':
9244 return 'IBM863';
9245
9246 case 'CP864':
9247 case 'CSIBM864':
9248 case 'IBM864':
9249 return 'IBM864';
9250
9251 case '865':
9252 case 'CP865':
9253 case 'CSIBM865':
9254 case 'IBM865':
9255 return 'IBM865';
9256
9257 case '866':
9258 case 'CP866':
9259 case 'CSIBM866':
9260 case 'IBM866':
9261 return 'IBM866';
9262
9263 case 'CP-AR':
9264 case 'CP868':
9265 case 'CSIBM868':
9266 case 'IBM868':
9267 return 'IBM868';
9268
9269 case '869':
9270 case 'CP-GR':
9271 case 'CP869':
9272 case 'CSIBM869':
9273 case 'IBM869':
9274 return 'IBM869';
9275
9276 case 'CP870':
9277 case 'CSIBM870':
9278 case 'EBCDIC-CP-ROECE':
9279 case 'EBCDIC-CP-YU':
9280 case 'IBM870':
9281 return 'IBM870';
9282
9283 case 'CP871':
9284 case 'CSIBM871':
9285 case 'EBCDIC-CP-IS':
9286 case 'IBM871':
9287 return 'IBM871';
9288
9289 case 'CP880':
9290 case 'CSIBM880':
9291 case 'EBCDIC-CYRILLIC':
9292 case 'IBM880':
9293 return 'IBM880';
9294
9295 case 'CP891':
9296 case 'CSIBM891':
9297 case 'IBM891':
9298 return 'IBM891';
9299
9300 case 'CP903':
9301 case 'CSIBM903':
9302 case 'IBM903':
9303 return 'IBM903';
9304
9305 case '904':
9306 case 'CP904':
9307 case 'CSIBBM904':
9308 case 'IBM904':
9309 return 'IBM904';
9310
9311 case 'CP905':
9312 case 'CSIBM905':
9313 case 'EBCDIC-CP-TR':
9314 case 'IBM905':
9315 return 'IBM905';
9316
9317 case 'CP918':
9318 case 'CSIBM918':
9319 case 'EBCDIC-CP-AR2':
9320 case 'IBM918':
9321 return 'IBM918';
9322
9323 case 'CSISO143IECP271':
9324 case 'IEC_P27-1':
9325 case 'ISO-IR-143':
9326 return 'IEC_P27-1';
9327
9328 case 'CSISO49INIS':
9329 case 'INIS':
9330 case 'ISO-IR-49':
9331 return 'INIS';
9332
9333 case 'CSISO50INIS8':
9334 case 'INIS-8':
9335 case 'ISO-IR-50':
9336 return 'INIS-8';
9337
9338 case 'CSISO51INISCYRILLIC':
9339 case 'INIS-CYRILLIC':
9340 case 'ISO-IR-51':
9341 return 'INIS-cyrillic';
9342
9343 case 'CSINVARIANT':
9344 case 'INVARIANT':
9345 return 'INVARIANT';
9346
9347 case 'ISO-10646-J-1':
9348 return 'ISO-10646-J-1';
9349
9350 case 'CSUNICODE':
9351 case 'ISO-10646-UCS-2':
9352 return 'ISO-10646-UCS-2';
9353
9354 case 'CSUCS4':
9355 case 'ISO-10646-UCS-4':
9356 return 'ISO-10646-UCS-4';
9357
9358 case 'CSUNICODEASCII':
9359 case 'ISO-10646-UCS-BASIC':
9360 return 'ISO-10646-UCS-Basic';
9361
9362 case 'CSISO10646UTF1':
9363 case 'ISO-10646-UTF-1':
9364 return 'ISO-10646-UTF-1';
9365
9366 case 'CSUNICODELATIN1':
9367 case 'ISO-10646':
9368 case 'ISO-10646-UNICODE-LATIN1':
9369 return 'ISO-10646-Unicode-Latin1';
9370
9371 case 'CSISO115481':
9372 case 'ISO-11548-1':
9373 case 'ISO_11548-1':
9374 case 'ISO_TR_11548-1':
9375 return 'ISO-11548-1';
9376
9377 case 'ISO-2022-CN':
9378 return 'ISO-2022-CN';
9379
9380 case 'ISO-2022-CN-EXT':
9381 return 'ISO-2022-CN-EXT';
9382
9383 case 'CSISO2022JP':
9384 case 'ISO-2022-JP':
9385 return 'ISO-2022-JP';
9386
9387 case 'CSISO2022JP2':
9388 case 'ISO-2022-JP-2':
9389 return 'ISO-2022-JP-2';
9390
9391 case 'CSISO2022KR':
9392 case 'ISO-2022-KR':
9393 return 'ISO-2022-KR';
9394
9395 case 'CSWINDOWS30LATIN1':
9396 case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
9397 return 'ISO-8859-1-Windows-3.0-Latin-1';
9398
9399 case 'CSWINDOWS31LATIN1':
9400 case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
9401 return 'ISO-8859-1-Windows-3.1-Latin-1';
9402
9403 case 'CSISOLATIN6':
9404 case 'ISO-8859-10':
9405 case 'ISO-IR-157':
9406 case 'ISO_8859-10:1992':
9407 case 'L6':
9408 case 'LATIN6':
9409 return 'ISO-8859-10';
9410
9411 case 'ISO-8859-13':
9412 return 'ISO-8859-13';
9413
9414 case 'ISO-8859-14':
9415 case 'ISO-CELTIC':
9416 case 'ISO-IR-199':
9417 case 'ISO_8859-14':
9418 case 'ISO_8859-14:1998':
9419 case 'L8':
9420 case 'LATIN8':
9421 return 'ISO-8859-14';
9422
9423 case 'ISO-8859-15':
9424 case 'ISO_8859-15':
9425 case 'LATIN-9':
9426 return 'ISO-8859-15';
9427
9428 case 'ISO-8859-16':
9429 case 'ISO-IR-226':
9430 case 'ISO_8859-16':
9431 case 'ISO_8859-16:2001':
9432 case 'L10':
9433 case 'LATIN10':
9434 return 'ISO-8859-16';
9435
9436 case 'CSISOLATIN2':
9437 case 'ISO-8859-2':
9438 case 'ISO-IR-101':
9439 case 'ISO_8859-2':
9440 case 'ISO_8859-2:1987':
9441 case 'L2':
9442 case 'LATIN2':
9443 return 'ISO-8859-2';
9444
9445 case 'CSWINDOWS31LATIN2':
9446 case 'ISO-8859-2-WINDOWS-LATIN-2':
9447 return 'ISO-8859-2-Windows-Latin-2';
9448
9449 case 'CSISOLATIN3':
9450 case 'ISO-8859-3':
9451 case 'ISO-IR-109':
9452 case 'ISO_8859-3':
9453 case 'ISO_8859-3:1988':
9454 case 'L3':
9455 case 'LATIN3':
9456 return 'ISO-8859-3';
9457
9458 case 'CSISOLATIN4':
9459 case 'ISO-8859-4':
9460 case 'ISO-IR-110':
9461 case 'ISO_8859-4':
9462 case 'ISO_8859-4:1988':
9463 case 'L4':
9464 case 'LATIN4':
9465 return 'ISO-8859-4';
9466
9467 case 'CSISOLATINCYRILLIC':
9468 case 'CYRILLIC':
9469 case 'ISO-8859-5':
9470 case 'ISO-IR-144':
9471 case 'ISO_8859-5':
9472 case 'ISO_8859-5:1988':
9473 return 'ISO-8859-5';
9474
9475 case 'ARABIC':
9476 case 'ASMO-708':
9477 case 'CSISOLATINARABIC':
9478 case 'ECMA-114':
9479 case 'ISO-8859-6':
9480 case 'ISO-IR-127':
9481 case 'ISO_8859-6':
9482 case 'ISO_8859-6:1987':
9483 return 'ISO-8859-6';
9484
9485 case 'CSISO88596E':
9486 case 'ISO-8859-6-E':
9487 case 'ISO_8859-6-E':
9488 return 'ISO-8859-6-E';
9489
9490 case 'CSISO88596I':
9491 case 'ISO-8859-6-I':
9492 case 'ISO_8859-6-I':
9493 return 'ISO-8859-6-I';
9494
9495 case 'CSISOLATINGREEK':
9496 case 'ECMA-118':
9497 case 'ELOT_928':
9498 case 'GREEK':
9499 case 'GREEK8':
9500 case 'ISO-8859-7':
9501 case 'ISO-IR-126':
9502 case 'ISO_8859-7':
9503 case 'ISO_8859-7:1987':
9504 return 'ISO-8859-7';
9505
9506 case 'CSISOLATINHEBREW':
9507 case 'HEBREW':
9508 case 'ISO-8859-8':
9509 case 'ISO-IR-138':
9510 case 'ISO_8859-8':
9511 case 'ISO_8859-8:1988':
9512 return 'ISO-8859-8';
9513
9514 case 'CSISO88598E':
9515 case 'ISO-8859-8-E':
9516 case 'ISO_8859-8-E':
9517 return 'ISO-8859-8-E';
9518
9519 case 'CSISO88598I':
9520 case 'ISO-8859-8-I':
9521 case 'ISO_8859-8-I':
9522 return 'ISO-8859-8-I';
9523
9524 case 'CSISOLATIN5':
9525 case 'ISO-8859-9':
9526 case 'ISO-IR-148':
9527 case 'ISO_8859-9':
9528 case 'ISO_8859-9:1989':
9529 case 'L5':
9530 case 'LATIN5':
9531 return 'ISO-8859-9';
9532
9533 case 'CSWINDOWS31LATIN5':
9534 case 'ISO-8859-9-WINDOWS-LATIN-5':
9535 return 'ISO-8859-9-Windows-Latin-5';
9536
9537 case 'CSUNICODEIBM1261':
9538 case 'ISO-UNICODE-IBM-1261':
9539 return 'ISO-Unicode-IBM-1261';
9540
9541 case 'CSUNICODEIBM1264':
9542 case 'ISO-UNICODE-IBM-1264':
9543 return 'ISO-Unicode-IBM-1264';
9544
9545 case 'CSUNICODEIBM1265':
9546 case 'ISO-UNICODE-IBM-1265':
9547 return 'ISO-Unicode-IBM-1265';
9548
9549 case 'CSUNICODEIBM1268':
9550 case 'ISO-UNICODE-IBM-1268':
9551 return 'ISO-Unicode-IBM-1268';
9552
9553 case 'CSUNICODEIBM1276':
9554 case 'ISO-UNICODE-IBM-1276':
9555 return 'ISO-Unicode-IBM-1276';
9556
9557 case 'CSISO10367BOX':
9558 case 'ISO-IR-155':
9559 case 'ISO_10367-BOX':
9560 return 'ISO_10367-box';
9561
9562 case 'CSISO2033':
9563 case 'E13B':
9564 case 'ISO-IR-98':
9565 case 'ISO_2033-1983':
9566 return 'ISO_2033-1983';
9567
9568 case 'CSISO5427CYRILLIC':
9569 case 'ISO-IR-37':
9570 case 'ISO_5427':
9571 return 'ISO_5427';
9572
9573 case 'ISO-IR-54':
9574 case 'ISO5427CYRILLIC1981':
9575 case 'ISO_5427:1981':
9576 return 'ISO_5427:1981';
9577
9578 case 'CSISO5428GREEK':
9579 case 'ISO-IR-55':
9580 case 'ISO_5428:1980':
9581 return 'ISO_5428:1980';
9582
9583 case 'CSISO646BASIC1983':
9584 case 'ISO_646.BASIC:1983':
9585 case 'REF':
9586 return 'ISO_646.basic:1983';
9587
9588 case 'CSISO2INTLREFVERSION':
9589 case 'IRV':
9590 case 'ISO-IR-2':
9591 case 'ISO_646.IRV:1983':
9592 return 'ISO_646.irv:1983';
9593
9594 case 'CSISO6937ADD':
9595 case 'ISO-IR-152':
9596 case 'ISO_6937-2-25':
9597 return 'ISO_6937-2-25';
9598
9599 case 'CSISOTEXTCOMM':
9600 case 'ISO-IR-142':
9601 case 'ISO_6937-2-ADD':
9602 return 'ISO_6937-2-add';
9603
9604 case 'CSISO8859SUPP':
9605 case 'ISO-IR-154':
9606 case 'ISO_8859-SUPP':
9607 case 'LATIN1-2-5':
9608 return 'ISO_8859-supp';
9609
9610 case 'CSISO15ITALIAN':
9611 case 'ISO-IR-15':
9612 case 'ISO646-IT':
9613 case 'IT':
9614 return 'IT';
9615
9616 case 'CSISO13JISC6220JP':
9617 case 'ISO-IR-13':
9618 case 'JIS_C6220-1969':
9619 case 'JIS_C6220-1969-JP':
9620 case 'KATAKANA':
9621 case 'X0201-7':
9622 return 'JIS_C6220-1969-jp';
9623
9624 case 'CSISO14JISC6220RO':
9625 case 'ISO-IR-14':
9626 case 'ISO646-JP':
9627 case 'JIS_C6220-1969-RO':
9628 case 'JP':
9629 return 'JIS_C6220-1969-ro';
9630
9631 case 'CSISO42JISC62261978':
9632 case 'ISO-IR-42':
9633 case 'JIS_C6226-1978':
9634 return 'JIS_C6226-1978';
9635
9636 case 'CSISO87JISX0208':
9637 case 'ISO-IR-87':
9638 case 'JIS_C6226-1983':
9639 case 'JIS_X0208-1983':
9640 case 'X0208':
9641 return 'JIS_C6226-1983';
9642
9643 case 'CSISO91JISC62291984A':
9644 case 'ISO-IR-91':
9645 case 'JIS_C6229-1984-A':
9646 case 'JP-OCR-A':
9647 return 'JIS_C6229-1984-a';
9648
9649 case 'CSISO92JISC62991984B':
9650 case 'ISO-IR-92':
9651 case 'ISO646-JP-OCR-B':
9652 case 'JIS_C6229-1984-B':
9653 case 'JP-OCR-B':
9654 return 'JIS_C6229-1984-b';
9655
9656 case 'CSISO93JIS62291984BADD':
9657 case 'ISO-IR-93':
9658 case 'JIS_C6229-1984-B-ADD':
9659 case 'JP-OCR-B-ADD':
9660 return 'JIS_C6229-1984-b-add';
9661
9662 case 'CSISO94JIS62291984HAND':
9663 case 'ISO-IR-94':
9664 case 'JIS_C6229-1984-HAND':
9665 case 'JP-OCR-HAND':
9666 return 'JIS_C6229-1984-hand';
9667
9668 case 'CSISO95JIS62291984HANDADD':
9669 case 'ISO-IR-95':
9670 case 'JIS_C6229-1984-HAND-ADD':
9671 case 'JP-OCR-HAND-ADD':
9672 return 'JIS_C6229-1984-hand-add';
9673
9674 case 'CSISO96JISC62291984KANA':
9675 case 'ISO-IR-96':
9676 case 'JIS_C6229-1984-KANA':
9677 return 'JIS_C6229-1984-kana';
9678
9679 case 'CSJISENCODING':
9680 case 'JIS_ENCODING':
9681 return 'JIS_Encoding';
9682
9683 case 'CSHALFWIDTHKATAKANA':
9684 case 'JIS_X0201':
9685 case 'X0201':
9686 return 'JIS_X0201';
9687
9688 case 'CSISO159JISX02121990':
9689 case 'ISO-IR-159':
9690 case 'JIS_X0212-1990':
9691 case 'X0212':
9692 return 'JIS_X0212-1990';
9693
9694 case 'CSISO141JUSIB1002':
9695 case 'ISO-IR-141':
9696 case 'ISO646-YU':
9697 case 'JS':
9698 case 'JUS_I.B1.002':
9699 case 'YU':
9700 return 'JUS_I.B1.002';
9701
9702 case 'CSISO147MACEDONIAN':
9703 case 'ISO-IR-147':
9704 case 'JUS_I.B1.003-MAC':
9705 case 'MACEDONIAN':
9706 return 'JUS_I.B1.003-mac';
9707
9708 case 'CSISO146SERBIAN':
9709 case 'ISO-IR-146':
9710 case 'JUS_I.B1.003-SERB':
9711 case 'SERBIAN':
9712 return 'JUS_I.B1.003-serb';
9713
9714 case 'KOI7-SWITCHED':
9715 return 'KOI7-switched';
9716
9717 case 'CSKOI8R':
9718 case 'KOI8-R':
9719 return 'KOI8-R';
9720
9721 case 'KOI8-U':
9722 return 'KOI8-U';
9723
9724 case 'CSKSC5636':
9725 case 'ISO646-KR':
9726 case 'KSC5636':
9727 return 'KSC5636';
9728
9729 case 'CSKSC56011987':
9730 case 'ISO-IR-149':
9731 case 'KOREAN':
9732 case 'KSC_5601':
9733 case 'KS_C_5601-1987':
9734 case 'KS_C_5601-1989':
9735 return 'KS_C_5601-1987';
9736
9737 case 'CSKZ1048':
9738 case 'KZ-1048':
9739 case 'RK1048':
9740 case 'STRK1048-2002':
9741 return 'KZ-1048';
9742
9743 case 'CSISO27LATINGREEK1':
9744 case 'ISO-IR-27':
9745 case 'LATIN-GREEK-1':
9746 return 'Latin-greek-1';
9747
9748 case 'CSMNEM':
9749 case 'MNEM':
9750 return 'MNEM';
9751
9752 case 'CSMNEMONIC':
9753 case 'MNEMONIC':
9754 return 'MNEMONIC';
9755
9756 case 'CSISO86HUNGARIAN':
9757 case 'HU':
9758 case 'ISO-IR-86':
9759 case 'ISO646-HU':
9760 case 'MSZ_7795.3':
9761 return 'MSZ_7795.3';
9762
9763 case 'CSMICROSOFTPUBLISHING':
9764 case 'MICROSOFT-PUBLISHING':
9765 return 'Microsoft-Publishing';
9766
9767 case 'CSNATSDANO':
9768 case 'ISO-IR-9-1':
9769 case 'NATS-DANO':
9770 return 'NATS-DANO';
9771
9772 case 'CSNATSDANOADD':
9773 case 'ISO-IR-9-2':
9774 case 'NATS-DANO-ADD':
9775 return 'NATS-DANO-ADD';
9776
9777 case 'CSNATSSEFI':
9778 case 'ISO-IR-8-1':
9779 case 'NATS-SEFI':
9780 return 'NATS-SEFI';
9781
9782 case 'CSNATSSEFIADD':
9783 case 'ISO-IR-8-2':
9784 case 'NATS-SEFI-ADD':
9785 return 'NATS-SEFI-ADD';
9786
9787 case 'CSISO151CUBA':
9788 case 'CUBA':
9789 case 'ISO-IR-151':
9790 case 'ISO646-CU':
9791 case 'NC_NC00-10:81':
9792 return 'NC_NC00-10:81';
9793
9794 case 'CSISO69FRENCH':
9795 case 'FR':
9796 case 'ISO-IR-69':
9797 case 'ISO646-FR':
9798 case 'NF_Z_62-010':
9799 return 'NF_Z_62-010';
9800
9801 case 'CSISO25FRENCH':
9802 case 'ISO-IR-25':
9803 case 'ISO646-FR1':
9804 case 'NF_Z_62-010_(1973)':
9805 return 'NF_Z_62-010_(1973)';
9806
9807 case 'CSISO60DANISHNORWEGIAN':
9808 case 'CSISO60NORWEGIAN1':
9809 case 'ISO-IR-60':
9810 case 'ISO646-NO':
9811 case 'NO':
9812 case 'NS_4551-1':
9813 return 'NS_4551-1';
9814
9815 case 'CSISO61NORWEGIAN2':
9816 case 'ISO-IR-61':
9817 case 'ISO646-NO2':
9818 case 'NO2':
9819 case 'NS_4551-2':
9820 return 'NS_4551-2';
9821
9822 case 'OSD_EBCDIC_DF03_IRV':
9823 return 'OSD_EBCDIC_DF03_IRV';
9824
9825 case 'OSD_EBCDIC_DF04_1':
9826 return 'OSD_EBCDIC_DF04_1';
9827
9828 case 'OSD_EBCDIC_DF04_15':
9829 return 'OSD_EBCDIC_DF04_15';
9830
9831 case 'CSPC8DANISHNORWEGIAN':
9832 case 'PC8-DANISH-NORWEGIAN':
9833 return 'PC8-Danish-Norwegian';
9834
9835 case 'CSPC8TURKISH':
9836 case 'PC8-TURKISH':
9837 return 'PC8-Turkish';
9838
9839 case 'CSISO16PORTUGUESE':
9840 case 'ISO-IR-16':
9841 case 'ISO646-PT':
9842 case 'PT':
9843 return 'PT';
9844
9845 case 'CSISO84PORTUGUESE2':
9846 case 'ISO-IR-84':
9847 case 'ISO646-PT2':
9848 case 'PT2':
9849 return 'PT2';
9850
9851 case 'CP154':
9852 case 'CSPTCP154':
9853 case 'CYRILLIC-ASIAN':
9854 case 'PT154':
9855 case 'PTCP154':
9856 return 'PTCP154';
9857
9858 case 'SCSU':
9859 return 'SCSU';
9860
9861 case 'CSISO10SWEDISH':
9862 case 'FI':
9863 case 'ISO-IR-10':
9864 case 'ISO646-FI':
9865 case 'ISO646-SE':
9866 case 'SE':
9867 case 'SEN_850200_B':
9868 return 'SEN_850200_B';
9869
9870 case 'CSISO11SWEDISHFORNAMES':
9871 case 'ISO-IR-11':
9872 case 'ISO646-SE2':
9873 case 'SE2':
9874 case 'SEN_850200_C':
9875 return 'SEN_850200_C';
9876
9877 case 'CSSHIFTJIS':
9878 case 'MS_KANJI':
9879 case 'SHIFT_JIS':
9880 return 'Shift_JIS';
9881
9882 case 'CSISO128T101G2':
9883 case 'ISO-IR-128':
9884 case 'T.101-G2':
9885 return 'T.101-G2';
9886
9887 case 'CSISO102T617BIT':
9888 case 'ISO-IR-102':
9889 case 'T.61-7BIT':
9890 return 'T.61-7bit';
9891
9892 case 'CSISO103T618BIT':
9893 case 'ISO-IR-103':
9894 case 'T.61':
9895 case 'T.61-8BIT':
9896 return 'T.61-8bit';
9897
9898 case 'CSTSCII':
9899 case 'TSCII':
9900 return 'TSCII';
9901
9902 case 'CSUNICODE11':
9903 case 'UNICODE-1-1':
9904 return 'UNICODE-1-1';
9905
9906 case 'CSUNICODE11UTF7':
9907 case 'UNICODE-1-1-UTF-7':
9908 return 'UNICODE-1-1-UTF-7';
9909
9910 case 'CSUNKNOWN8BIT':
9911 case 'UNKNOWN-8BIT':
9912 return 'UNKNOWN-8BIT';
9913
9914 case 'ANSI':
9915 case 'ANSI_X3.4-1968':
9916 case 'ANSI_X3.4-1986':
9917 case 'ASCII':
9918 case 'CP367':
9919 case 'CSASCII':
9920 case 'IBM367':
9921 case 'ISO-IR-6':
9922 case 'ISO646-US':
9923 case 'ISO_646.IRV:1991':
9924 case 'US':
9925 case 'US-ASCII':
9926 return 'US-ASCII';
9927
9928 case 'UTF-16':
9929 return 'UTF-16';
9930
9931 case 'UTF-16BE':
9932 return 'UTF-16BE';
9933
9934 case 'UTF-16LE':
9935 return 'UTF-16LE';
9936
9937 case 'UTF-32':
9938 return 'UTF-32';
9939
9940 case 'UTF-32BE':
9941 return 'UTF-32BE';
9942
9943 case 'UTF-32LE':
9944 return 'UTF-32LE';
9945
9946 case 'UTF-7':
9947 return 'UTF-7';
9948
9949 case 'UTF-8':
9950 return 'UTF-8';
9951
9952 case 'CSVIQR':
9953 case 'VIQR':
9954 return 'VIQR';
9955
9956 case 'CSVISCII':
9957 case 'VISCII':
9958 return 'VISCII';
9959
9960 case 'CSVENTURAINTERNATIONAL':
9961 case 'VENTURA-INTERNATIONAL':
9962 return 'Ventura-International';
9963
9964 case 'CSVENTURAMATH':
9965 case 'VENTURA-MATH':
9966 return 'Ventura-Math';
9967
9968 case 'CSVENTURAUS':
9969 case 'VENTURA-US':
9970 return 'Ventura-US';
9971
9972 case 'CSWINDOWS31J':
9973 case 'WINDOWS-31J':
9974 return 'Windows-31J';
9975
9976 case 'CSDKUS':
9977 case 'DK-US':
9978 return 'dk-us';
9979
9980 case 'CSISO150':
9981 case 'CSISO150GREEKCCITT':
9982 case 'GREEK-CCITT':
9983 case 'ISO-IR-150':
9984 return 'greek-ccitt';
9985
9986 case 'CSISO88GREEK7':
9987 case 'GREEK7':
9988 case 'ISO-IR-88':
9989 return 'greek7';
9990
9991 case 'CSISO18GREEK7OLD':
9992 case 'GREEK7-OLD':
9993 case 'ISO-IR-18':
9994 return 'greek7-old';
9995
9996 case 'CSHPROMAN8':
9997 case 'HP-ROMAN8':
9998 case 'R8':
9999 case 'ROMAN8':
10000 return 'hp-roman8';
10001
10002 case 'CSISO90':
10003 case 'ISO-IR-90':
10004 return 'iso-ir-90';
10005
10006 case 'CSISO19LATINGREEK':
10007 case 'ISO-IR-19':
10008 case 'LATIN-GREEK':
10009 return 'latin-greek';
10010
10011 case 'CSISO158LAP':
10012 case 'ISO-IR-158':
10013 case 'LAP':
10014 case 'LATIN-LAP':
10015 return 'latin-lap';
10016
10017 case 'CSMACINTOSH':
10018 case 'MAC':
10019 case 'MACINTOSH':
10020 return 'macintosh';
10021
10022 case 'CSUSDK':
10023 case 'US-DK':
10024 return 'us-dk';
10025
10026 case 'CSISO70VIDEOTEXSUPP1':
10027 case 'ISO-IR-70':
10028 case 'VIDEOTEX-SUPPL':
10029 return 'videotex-suppl';
10030
10031 case 'WINDOWS-1250':
10032 return 'windows-1250';
10033
10034 case 'WINDOWS-1251':
10035 return 'windows-1251';
10036
10037 case 'CP819':
10038 case 'CSISOLATIN1':
10039 case 'IBM819':
10040 case 'ISO-8859-1':
10041 case 'ISO-IR-100':
10042 case 'ISO_8859-1':
10043 case 'ISO_8859-1:1987':
10044 case 'L1':
10045 case 'LATIN1':
10046 case 'WINDOWS-1252':
10047 return 'windows-1252';
10048
10049 case 'WINDOWS-1253':
10050 return 'windows-1253';
10051
10052 case 'WINDOWS-1254':
10053 return 'windows-1254';
10054
10055 case 'WINDOWS-1255':
10056 return 'windows-1255';
10057
10058 case 'WINDOWS-1256':
10059 return 'windows-1256';
10060
10061 case 'WINDOWS-1257':
10062 return 'windows-1257';
10063
10064 case 'WINDOWS-1258':
10065 return 'windows-1258';
10066
10067 default:
10068 return $encoding;
10069 }
10070 }
10071
10072 function get_curl_version()
10073 {
10074 if (is_array($curl = curl_version()))
10075 {
10076 $curl = $curl['version'];
10077 }
10078 elseif (substr($curl, 0, 5) == 'curl/')
10079 {
10080 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10081 }
10082 elseif (substr($curl, 0, 8) == 'libcurl/')
10083 {
10084 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10085 }
10086 else
10087 {
10088 $curl = 0;
10089 }
10090 return $curl;
10091 }
10092
10093 function is_subclass_of($class1, $class2)
10094 {
10095 if (func_num_args() != 2)
10096 {
10097 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10098 }
10099 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10100 {
10101 return is_subclass_of($class1, $class2);
10102 }
10103 elseif (is_string($class1) && is_string($class2))
10104 {
10105 if (class_exists($class1))
10106 {
10107 if (class_exists($class2))
10108 {
10109 $class2 = strtolower($class2);
10110 while ($class1 = strtolower(get_parent_class($class1)))
10111 {
10112 if ($class1 == $class2)
10113 {
10114 return true;
10115 }
10116 }
10117 }
10118 }
10119 else
10120 {
10121 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10122 }
10123 }
10124 return false;
10125 }
10126
10127 /**
10128 * Strip HTML comments
10129 *
10130 * @access public
10131 * @param string $data Data to strip comments from
10132 * @return string Comment stripped string
10133 */
10134 function strip_comments($data)
10135 {
10136 $output = '';
10137 while (($start = strpos($data, '<!--')) !== false)
10138 {
10139 $output .= substr($data, 0, $start);
10140 if (($end = strpos($data, '-->', $start)) !== false)
10141 {
10142 $data = substr_replace($data, '', 0, $end + 3);
10143 }
10144 else
10145 {
10146 $data = '';
10147 }
10148 }
10149 return $output . $data;
10150 }
10151
10152 function parse_date($dt)
10153 {
10154 $parser = SimplePie_Parse_Date::get();
10155 return $parser->parse($dt);
10156 }
10157
10158 /**
10159 * Decode HTML entities
10160 *
10161 * @static
10162 * @access public
10163 * @param string $data Input data
10164 * @return string Output data
10165 */
10166 function entities_decode($data)
10167 {
10168 $decoder = new SimplePie_Decode_HTML_Entities($data);
10169 return $decoder->parse();
10170 }
10171
10172 /**
10173 * Remove RFC822 comments
10174 *
10175 * @access public
10176 * @param string $data Data to strip comments from
10177 * @return string Comment stripped string
10178 */
10179 function uncomment_rfc822($string)
10180 {
10181 $string = (string) $string;
10182 $position = 0;
10183 $length = strlen($string);
10184 $depth = 0;
10185
10186 $output = '';
10187
10188 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10189 {
10190 $output .= substr($string, $position, $pos - $position);
10191 $position = $pos + 1;
10192 if ($string[$pos - 1] !== '\\')
10193 {
10194 $depth++;
10195 while ($depth && $position < $length)
10196 {
10197 $position += strcspn($string, '()', $position);
10198 if ($string[$position - 1] === '\\')
10199 {
10200 $position++;
10201 continue;
10202 }
10203 elseif (isset($string[$position]))
10204 {
10205 switch ($string[$position])
10206 {
10207 case '(':
10208 $depth++;
10209 break;
10210
10211 case ')':
10212 $depth--;
10213 break;
10214 }
10215 $position++;
10216 }
10217 else
10218 {
10219 break;
10220 }
10221 }
10222 }
10223 else
10224 {
10225 $output .= '(';
10226 }
10227 }
10228 $output .= substr($string, $position);
10229
10230 return $output;
10231 }
10232
10233 function parse_mime($mime)
10234 {
10235 if (($pos = strpos($mime, ';')) === false)
10236 {
10237 return trim($mime);
10238 }
10239 else
10240 {
10241 return trim(substr($mime, 0, $pos));
10242 }
10243 }
10244
10245 function htmlspecialchars_decode($string, $quote_style)
10246 {
10247 if (function_exists('htmlspecialchars_decode'))
10248 {
10249 return htmlspecialchars_decode($string, $quote_style);
10250 }
10251 else
10252 {
10253 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10254 }
10255 }
10256
10257 function atom_03_construct_type($attribs)
10258 {
10259 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10260 {
10261 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10262 }
10263 else
10264 {
10265 $mode = SIMPLEPIE_CONSTRUCT_NONE;
10266 }
10267 if (isset($attribs['']['type']))
10268 {
10269 switch (strtolower(trim($attribs['']['type'])))
10270 {
10271 case 'text':
10272 case 'text/plain':
10273 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10274
10275 case 'html':
10276 case 'text/html':
10277 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10278
10279 case 'xhtml':
10280 case 'application/xhtml+xml':
10281 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10282
10283 default:
10284 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10285 }
10286 }
10287 else
10288 {
10289 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10290 }
10291 }
10292
10293 function atom_10_construct_type($attribs)
10294 {
10295 if (isset($attribs['']['type']))
10296 {
10297 switch (strtolower(trim($attribs['']['type'])))
10298 {
10299 case 'text':
10300 return SIMPLEPIE_CONSTRUCT_TEXT;
10301
10302 case 'html':
10303 return SIMPLEPIE_CONSTRUCT_HTML;
10304
10305 case 'xhtml':
10306 return SIMPLEPIE_CONSTRUCT_XHTML;
10307
10308 default:
10309 return SIMPLEPIE_CONSTRUCT_NONE;
10310 }
10311 }
10312 return SIMPLEPIE_CONSTRUCT_TEXT;
10313 }
10314
10315 function atom_10_content_construct_type($attribs)
10316 {
10317 if (isset($attribs['']['type']))
10318 {
10319 $type = strtolower(trim($attribs['']['type']));
10320 switch ($type)
10321 {
10322 case 'text':
10323 return SIMPLEPIE_CONSTRUCT_TEXT;
10324
10325 case 'html':
10326 return SIMPLEPIE_CONSTRUCT_HTML;
10327
10328 case 'xhtml':
10329 return SIMPLEPIE_CONSTRUCT_XHTML;
10330 }
10331 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10332 {
10333 return SIMPLEPIE_CONSTRUCT_NONE;
10334 }
10335 else
10336 {
10337 return SIMPLEPIE_CONSTRUCT_BASE64;
10338 }
10339 }
10340 else
10341 {
10342 return SIMPLEPIE_CONSTRUCT_TEXT;
10343 }
10344 }
10345
10346 function is_isegment_nz_nc($string)
10347 {
10348 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);
10349 }
10350
10351 function space_seperated_tokens($string)
10352 {
10353 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10354 $string_length = strlen($string);
10355
10356 $position = strspn($string, $space_characters);
10357 $tokens = array();
10358
10359 while ($position < $string_length)
10360 {
10361 $len = strcspn($string, $space_characters, $position);
10362 $tokens[] = substr($string, $position, $len);
10363 $position += $len;
10364 $position += strspn($string, $space_characters, $position);
10365 }
10366
10367 return $tokens;
10368 }
10369
10370 function array_unique($array)
10371 {
10372 if (version_compare(PHP_VERSION, '5.2', '>='))
10373 {
10374 return array_unique($array);
10375 }
10376 else
10377 {
10378 $array = (array) $array;
10379 $new_array = array();
10380 $new_array_strings = array();
10381 foreach ($array as $key => $value)
10382 {
10383 if (is_object($value))
10384 {
10385 if (method_exists($value, '__toString'))
10386 {
10387 $cmp = $value->__toString();
10388 }
10389 else
10390 {
10391 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10392 }
10393 }
10394 elseif (is_array($value))
10395 {
10396 $cmp = (string) reset($value);
10397 }
10398 else
10399 {
10400 $cmp = (string) $value;
10401 }
10402 if (!in_array($cmp, $new_array_strings))
10403 {
10404 $new_array[$key] = $value;
10405 $new_array_strings[] = $cmp;
10406 }
10407 }
10408 return $new_array;
10409 }
10410 }
10411
10412 /**
10413 * Converts a unicode codepoint to a UTF-8 character
10414 *
10415 * @static
10416 * @access public
10417 * @param int $codepoint Unicode codepoint
10418 * @return string UTF-8 character
10419 */
10420 function codepoint_to_utf8($codepoint)
10421 {
10422 static $cache = array();
10423 $codepoint = (int) $codepoint;
10424 if (isset($cache[$codepoint]))
10425 {
10426 return $cache[$codepoint];
10427 }
10428 elseif ($codepoint < 0)
10429 {
10430 return $cache[$codepoint] = false;
10431 }
10432 else if ($codepoint <= 0x7f)
10433 {
10434 return $cache[$codepoint] = chr($codepoint);
10435 }
10436 else if ($codepoint <= 0x7ff)
10437 {
10438 return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10439 }
10440 else if ($codepoint <= 0xffff)
10441 {
10442 return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10443 }
10444 else if ($codepoint <= 0x10ffff)
10445 {
10446 return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10447 }
10448 else
10449 {
10450 // U+FFFD REPLACEMENT CHARACTER
10451 return $cache[$codepoint] = "\xEF\xBF\xBD";
10452 }
10453 }
10454
10455 /**
10456 * Re-implementation of PHP 5's stripos()
10457 *
10458 * Returns the numeric position of the first occurrence of needle in the
10459 * haystack string.
10460 *
10461 * @static
10462 * @access string
10463 * @param object $haystack
10464 * @param string $needle Note that the needle may be a string of one or more
10465 * characters. If needle is not a string, it is converted to an integer
10466 * and applied as the ordinal value of a character.
10467 * @param int $offset The optional offset parameter allows you to specify which
10468 * character in haystack to start searching. The position returned is still
10469 * relative to the beginning of haystack.
10470 * @return bool If needle is not found, stripos() will return boolean false.
10471 */
10472 function stripos($haystack, $needle, $offset = 0)
10473 {
10474 if (function_exists('stripos'))
10475 {
10476 return stripos($haystack, $needle, $offset);
10477 }
10478 else
10479 {
10480 if (is_string($needle))
10481 {
10482 $needle = strtolower($needle);
10483 }
10484 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10485 {
10486 $needle = strtolower(chr($needle));
10487 }
10488 else
10489 {
10490 trigger_error('needle is not a string or an integer', E_USER_WARNING);
10491 return false;
10492 }
10493
10494 return strpos(strtolower($haystack), $needle, $offset);
10495 }
10496 }
10497
10498 /**
10499 * Similar to parse_str()
10500 *
10501 * Returns an associative array of name/value pairs, where the value is an
10502 * array of values that have used the same name
10503 *
10504 * @static
10505 * @access string
10506 * @param string $str The input string.
10507 * @return array
10508 */
10509 function parse_str($str)
10510 {
10511 $return = array();
10512 $str = explode('&', $str);
10513
10514 foreach ($str as $section)
10515 {
10516 if (strpos($section, '=') !== false)
10517 {
10518 list($name, $value) = explode('=', $section, 2);
10519 $return[urldecode($name)][] = urldecode($value);
10520 }
10521 else
10522 {
10523 $return[urldecode($section)][] = null;
10524 }
10525 }
10526
10527 return $return;
10528 }
10529
10530 /**
10531 * Detect XML encoding, as per XML 1.0 Appendix F.1
10532 *
10533 * @todo Add support for EBCDIC
10534 * @param string $data XML data
10535 * @return array Possible encodings
10536 */
10537 function xml_encoding($data)
10538 {
10539 // UTF-32 Big Endian BOM
10540 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10541 {
10542 $encoding[] = 'UTF-32BE';
10543 }
10544 // UTF-32 Little Endian BOM
10545 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10546 {
10547 $encoding[] = 'UTF-32LE';
10548 }
10549 // UTF-16 Big Endian BOM
10550 elseif (substr($data, 0, 2) === "\xFE\xFF")
10551 {
10552 $encoding[] = 'UTF-16BE';
10553 }
10554 // UTF-16 Little Endian BOM
10555 elseif (substr($data, 0, 2) === "\xFF\xFE")
10556 {
10557 $encoding[] = 'UTF-16LE';
10558 }
10559 // UTF-8 BOM
10560 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10561 {
10562 $encoding[] = 'UTF-8';
10563 }
10564 // UTF-32 Big Endian Without BOM
10565 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")
10566 {
10567 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
10568 {
10569 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
10570 if ($parser->parse())
10571 {
10572 $encoding[] = $parser->encoding;
10573 }
10574 }
10575 $encoding[] = 'UTF-32BE';
10576 }
10577 // UTF-32 Little Endian Without BOM
10578 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")
10579 {
10580 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
10581 {
10582 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
10583 if ($parser->parse())
10584 {
10585 $encoding[] = $parser->encoding;
10586 }
10587 }
10588 $encoding[] = 'UTF-32LE';
10589 }
10590 // UTF-16 Big Endian Without BOM
10591 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
10592 {
10593 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
10594 {
10595 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
10596 if ($parser->parse())
10597 {
10598 $encoding[] = $parser->encoding;
10599 }
10600 }
10601 $encoding[] = 'UTF-16BE';
10602 }
10603 // UTF-16 Little Endian Without BOM
10604 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
10605 {
10606 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
10607 {
10608 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
10609 if ($parser->parse())
10610 {
10611 $encoding[] = $parser->encoding;
10612 }
10613 }
10614 $encoding[] = 'UTF-16LE';
10615 }
10616 // US-ASCII (or superset)
10617 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
10618 {
10619 if ($pos = strpos($data, "\x3F\x3E"))
10620 {
10621 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
10622 if ($parser->parse())
10623 {
10624 $encoding[] = $parser->encoding;
10625 }
10626 }
10627 $encoding[] = 'UTF-8';
10628 }
10629 // Fallback to UTF-8
10630 else
10631 {
10632 $encoding[] = 'UTF-8';
10633 }
10634 return $encoding;
10635 }
10636 }
10637
10638 /**
10639 * Decode HTML Entities
10640 *
10641 * This implements HTML5 as of revision 967 (2007-06-28)
10642 *
10643 * @package SimplePie
10644 */
10645 class SimplePie_Decode_HTML_Entities
10646 {
10647 /**
10648 * Data to be parsed
10649 *
10650 * @access private
10651 * @var string
10652 */
10653 var $data = '';
10654
10655 /**
10656 * Currently consumed bytes
10657 *
10658 * @access private
10659 * @var string
10660 */
10661 var $consumed = '';
10662
10663 /**
10664 * Position of the current byte being parsed
10665 *
10666 * @access private
10667 * @var int
10668 */
10669 var $position = 0;
10670
10671 /**
10672 * Create an instance of the class with the input data
10673 *
10674 * @access public
10675 * @param string $data Input data
10676 */
10677 function SimplePie_Decode_HTML_Entities($data)
10678 {
10679 $this->data = $data;
10680 }
10681
10682 /**
10683 * Parse the input data
10684 *
10685 * @access public
10686 * @return string Output data
10687 */
10688 function parse()
10689 {
10690 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
10691 {
10692 $this->consume();
10693 $this->entity();
10694 $this->consumed = '';
10695 }
10696 return $this->data;
10697 }
10698
10699 /**
10700 * Consume the next byte
10701 *
10702 * @access private
10703 * @return mixed The next byte, or false, if there is no more data
10704 */
10705 function consume()
10706 {
10707 if (isset($this->data[$this->position]))
10708 {
10709 $this->consumed .= $this->data[$this->position];
10710 return $this->data[$this->position++];
10711 }
10712 else
10713 {
10714 $this->consumed = false;
10715 return false;
10716 }
10717 }
10718
10719 /**
10720 * Consume a range of characters
10721 *
10722 * @access private
10723 * @param string $chars Characters to consume
10724 * @return mixed A series of characters that match the range, or false
10725 */
10726 function consume_range($chars)
10727 {
10728 if ($len = strspn($this->data, $chars, $this->position))
10729 {
10730 $data = substr($this->data, $this->position, $len);
10731 $this->consumed .= $data;
10732 $this->position += $len;
10733 return $data;
10734 }
10735 else
10736 {
10737 $this->consumed = false;
10738 return false;
10739 }
10740 }
10741
10742 /**
10743 * Unconsume one byte
10744 *
10745 * @access private
10746 */
10747 function unconsume()
10748 {
10749 $this->consumed = substr($this->consumed, 0, -1);
10750 $this->position--;
10751 }
10752
10753 /**
10754 * Decode an entity
10755 *
10756 * @access private
10757 */
10758 function entity()
10759 {
10760 switch ($this->consume())
10761 {
10762 case "\x09":
10763 case "\x0A":
10764 case "\x0B":
10765 case "\x0B":
10766 case "\x0C":
10767 case "\x20":
10768 case "\x3C":
10769 case "\x26":
10770 case false:
10771 break;
10772
10773 case "\x23":
10774 switch ($this->consume())
10775 {
10776 case "\x78":
10777 case "\x58":
10778 $range = '0123456789ABCDEFabcdef';
10779 $hex = true;
10780 break;
10781
10782 default:
10783 $range = '0123456789';
10784 $hex = false;
10785 $this->unconsume();
10786 break;
10787 }
10788
10789 if ($codepoint = $this->consume_range($range))
10790 {
10791 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");
10792
10793 if ($hex)
10794 {
10795 $codepoint = hexdec($codepoint);
10796 }
10797 else
10798 {
10799 $codepoint = intval($codepoint);
10800 }
10801
10802 if (isset($windows_1252_specials[$codepoint]))
10803 {
10804 $replacement = $windows_1252_specials[$codepoint];
10805 }
10806 else
10807 {
10808 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
10809 }
10810
10811 if ($this->consume() != ';')
10812 {
10813 $this->unconsume();
10814 }
10815
10816 $consumed_length = strlen($this->consumed);
10817 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
10818 $this->position += strlen($replacement) - $consumed_length;
10819 }
10820 break;
10821
10822 default:
10823 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");
10824
10825 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
10826 {
10827 $consumed = substr($this->consumed, 1);
10828 if (isset($entities[$consumed]))
10829 {
10830 $match = $consumed;
10831 }
10832 }
10833
10834 if ($match !== null)
10835 {
10836 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
10837 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
10838 }
10839 break;
10840 }
10841 }
10842 }
10843
10844 /**
10845 * Date Parser
10846 *
10847 * @package SimplePie
10848 */
10849 class SimplePie_Parse_Date
10850 {
10851 /**
10852 * Input data
10853 *
10854 * @access protected
10855 * @var string
10856 */
10857 var $date;
10858
10859 /**
10860 * List of days, calendar day name => ordinal day number in the week
10861 *
10862 * @access protected
10863 * @var array
10864 */
10865 var $day = array(
10866 // English
10867 'mon' => 1,
10868 'monday' => 1,
10869 'tue' => 2,
10870 'tuesday' => 2,
10871 'wed' => 3,
10872 'wednesday' => 3,
10873 'thu' => 4,
10874 'thursday' => 4,
10875 'fri' => 5,
10876 'friday' => 5,
10877 'sat' => 6,
10878 'saturday' => 6,
10879 'sun' => 7,
10880 'sunday' => 7,
10881 // Dutch
10882 'maandag' => 1,
10883 'dinsdag' => 2,
10884 'woensdag' => 3,
10885 'donderdag' => 4,
10886 'vrijdag' => 5,
10887 'zaterdag' => 6,
10888 'zondag' => 7,
10889 // French
10890 'lundi' => 1,
10891 'mardi' => 2,
10892 'mercredi' => 3,
10893 'jeudi' => 4,
10894 'vendredi' => 5,
10895 'samedi' => 6,
10896 'dimanche' => 7,
10897 // German
10898 'montag' => 1,
10899 'dienstag' => 2,
10900 'mittwoch' => 3,
10901 'donnerstag' => 4,
10902 'freitag' => 5,
10903 'samstag' => 6,
10904 'sonnabend' => 6,
10905 'sonntag' => 7,
10906 // Italian
10907 'lunedì' => 1,
10908 'martedì' => 2,
10909 'mercoledì' => 3,
10910 'giovedì' => 4,
10911 'venerdì' => 5,
10912 'sabato' => 6,
10913 'domenica' => 7,
10914 // Spanish
10915 'lunes' => 1,
10916 'martes' => 2,
10917 'miércoles' => 3,
10918 'jueves' => 4,
10919 'viernes' => 5,
10920 'sábado' => 6,
10921 'domingo' => 7,
10922 // Finnish
10923 'maanantai' => 1,
10924 'tiistai' => 2,
10925 'keskiviikko' => 3,
10926 'torstai' => 4,
10927 'perjantai' => 5,
10928 'lauantai' => 6,
10929 'sunnuntai' => 7,
10930 // Hungarian
10931 'hétfő' => 1,
10932 'kedd' => 2,
10933 'szerda' => 3,
10934 'csütörtok' => 4,
10935 'péntek' => 5,
10936 'szombat' => 6,
10937 'vasárnap' => 7,
10938 // Greek
10939 'Δευ' => 1,
10940 'Τρι' => 2,
10941 'Τετ' => 3,
10942 'Πεμ' => 4,
10943 'Παρ' => 5,
10944 'Σαβ' => 6,
10945 'Κυρ' => 7,
10946 );
10947
10948 /**
10949 * List of months, calendar month name => calendar month number
10950 *
10951 * @access protected
10952 * @var array
10953 */
10954 var $month = array(
10955 // English
10956 'jan' => 1,
10957 'january' => 1,
10958 'feb' => 2,
10959 'february' => 2,
10960 'mar' => 3,
10961 'march' => 3,
10962 'apr' => 4,
10963 'april' => 4,
10964 'may' => 5,
10965 // No long form of May
10966 'jun' => 6,
10967 'june' => 6,
10968 'jul' => 7,
10969 'july' => 7,
10970 'aug' => 8,
10971 'august' => 8,
10972 'sep' => 9,
10973 'september' => 8,
10974 'oct' => 10,
10975 'october' => 10,
10976 'nov' => 11,
10977 'november' => 11,
10978 'dec' => 12,
10979 'december' => 12,
10980 // Dutch
10981 'januari' => 1,
10982 'februari' => 2,
10983 'maart' => 3,
10984 'april' => 4,
10985 'mei' => 5,
10986 'juni' => 6,
10987 'juli' => 7,
10988 'augustus' => 8,
10989 'september' => 9,
10990 'oktober' => 10,
10991 'november' => 11,
10992 'december' => 12,
10993 // French
10994 'janvier' => 1,
10995 'février' => 2,
10996 'mars' => 3,
10997 'avril' => 4,
10998 'mai' => 5,
10999 'juin' => 6,
11000 'juillet' => 7,
11001 'août' => 8,
11002 'septembre' => 9,
11003 'octobre' => 10,
11004 'novembre' => 11,
11005 'décembre' => 12,
11006 // German
11007 'januar' => 1,
11008 'februar' => 2,
11009 'märz' => 3,
11010 'april' => 4,
11011 'mai' => 5,
11012 'juni' => 6,
11013 'juli' => 7,
11014 'august' => 8,
11015 'september' => 9,
11016 'oktober' => 10,
11017 'november' => 11,
11018 'dezember' => 12,
11019 // Italian
11020 'gennaio' => 1,
11021 'febbraio' => 2,
11022 'marzo' => 3,
11023 'aprile' => 4,
11024 'maggio' => 5,
11025 'giugno' => 6,
11026 'luglio' => 7,
11027 'agosto' => 8,
11028 'settembre' => 9,
11029 'ottobre' => 10,
11030 'novembre' => 11,
11031 'dicembre' => 12,
11032 // Spanish
11033 'enero' => 1,
11034 'febrero' => 2,
11035 'marzo' => 3,
11036 'abril' => 4,
11037 'mayo' => 5,
11038 'junio' => 6,
11039 'julio' => 7,
11040 'agosto' => 8,
11041 'septiembre' => 9,
11042 'setiembre' => 9,
11043 'octubre' => 10,
11044 'noviembre' => 11,
11045 'diciembre' => 12,
11046 // Finnish
11047 'tammikuu' => 1,
11048 'helmikuu' => 2,
11049 'maaliskuu' => 3,
11050 'huhtikuu' => 4,
11051 'toukokuu' => 5,
11052 'kesäkuu' => 6,
11053 'heinäkuu' => 7,
11054 'elokuu' => 8,
11055 'suuskuu' => 9,
11056 'lokakuu' => 10,
11057 'marras' => 11,
11058 'joulukuu' => 12,
11059 // Hungarian
11060 'január' => 1,
11061 'február' => 2,
11062 'március' => 3,
11063 'április' => 4,
11064 'május' => 5,
11065 'június' => 6,
11066 'július' => 7,
11067 'augusztus' => 8,
11068 'szeptember' => 9,
11069 'október' => 10,
11070 'november' => 11,
11071 'december' => 12,
11072 // Greek
11073 'Ιαν' => 1,
11074 'Φεβ' => 2,
11075 'Μάώ' => 3,
11076 'Μαώ' => 3,
11077 'Απρ' => 4,
11078 'Μάι' => 5,
11079 'Μαϊ' => 5,
11080 'Μαι' => 5,
11081 'Ιούν' => 6,
11082 'Ιον' => 6,
11083 'Ιούλ' => 7,
11084 'Ιολ' => 7,
11085 'Αύγ' => 8,
11086 'Αυγ' => 8,
11087 'Σεπ' => 9,
11088 'Οκτ' => 10,
11089 'Νοέ' => 11,
11090 'Δεκ' => 12,
11091 );
11092
11093 /**
11094 * List of timezones, abbreviation => offset from UTC
11095 *
11096 * @access protected
11097 * @var array
11098 */
11099 var $timezone = array(
11100 'ACDT' => 37800,
11101 'ACIT' => 28800,
11102 'ACST' => 34200,
11103 'ACT' => -18000,
11104 'ACWDT' => 35100,
11105 'ACWST' => 31500,
11106 'AEDT' => 39600,
11107 'AEST' => 36000,
11108 'AFT' => 16200,
11109 'AKDT' => -28800,
11110 'AKST' => -32400,
11111 'AMDT' => 18000,
11112 'AMT' => -14400,
11113 'ANAST' => 46800,
11114 'ANAT' => 43200,
11115 'ART' => -10800,
11116 'AZOST' => -3600,
11117 'AZST' => 18000,
11118 'AZT' => 14400,
11119 'BIOT' => 21600,
11120 'BIT' => -43200,
11121 'BOT' => -14400,
11122 'BRST' => -7200,
11123 'BRT' => -10800,
11124 'BST' => 3600,
11125 'BTT' => 21600,
11126 'CAST' => 18000,
11127 'CAT' => 7200,
11128 'CCT' => 23400,
11129 'CDT' => -18000,
11130 'CEDT' => 7200,
11131 'CET' => 3600,
11132 'CGST' => -7200,
11133 'CGT' => -10800,
11134 'CHADT' => 49500,
11135 'CHAST' => 45900,
11136 'CIST' => -28800,
11137 'CKT' => -36000,
11138 'CLDT' => -10800,
11139 'CLST' => -14400,
11140 'COT' => -18000,
11141 'CST' => -21600,
11142 'CVT' => -3600,
11143 'CXT' => 25200,
11144 'DAVT' => 25200,
11145 'DTAT' => 36000,
11146 'EADT' => -18000,
11147 'EAST' => -21600,
11148 'EAT' => 10800,
11149 'ECT' => -18000,
11150 'EDT' => -14400,
11151 'EEST' => 10800,
11152 'EET' => 7200,
11153 'EGT' => -3600,
11154 'EKST' => 21600,
11155 'EST' => -18000,
11156 'FJT' => 43200,
11157 'FKDT' => -10800,
11158 'FKST' => -14400,
11159 'FNT' => -7200,
11160 'GALT' => -21600,
11161 'GEDT' => 14400,
11162 'GEST' => 10800,
11163 'GFT' => -10800,
11164 'GILT' => 43200,
11165 'GIT' => -32400,
11166 'GST' => 14400,
11167 'GST' => -7200,
11168 'GYT' => -14400,
11169 'HAA' => -10800,
11170 'HAC' => -18000,
11171 'HADT' => -32400,
11172 'HAE' => -14400,
11173 'HAP' => -25200,
11174 'HAR' => -21600,
11175 'HAST' => -36000,
11176 'HAT' => -9000,
11177 'HAY' => -28800,
11178 'HKST' => 28800,
11179 'HMT' => 18000,
11180 'HNA' => -14400,
11181 'HNC' => -21600,
11182 'HNE' => -18000,
11183 'HNP' => -28800,
11184 'HNR' => -25200,
11185 'HNT' => -12600,
11186 'HNY' => -32400,
11187 'IRDT' => 16200,
11188 'IRKST' => 32400,
11189 'IRKT' => 28800,
11190 'IRST' => 12600,
11191 'JFDT' => -10800,
11192 'JFST' => -14400,
11193 'JST' => 32400,
11194 'KGST' => 21600,
11195 'KGT' => 18000,
11196 'KOST' => 39600,
11197 'KOVST' => 28800,
11198 'KOVT' => 25200,
11199 'KRAST' => 28800,
11200 'KRAT' => 25200,
11201 'KST' => 32400,
11202 'LHDT' => 39600,
11203 'LHST' => 37800,
11204 'LINT' => 50400,
11205 'LKT' => 21600,
11206 'MAGST' => 43200,
11207 'MAGT' => 39600,
11208 'MAWT' => 21600,
11209 'MDT' => -21600,
11210 'MESZ' => 7200,
11211 'MEZ' => 3600,
11212 'MHT' => 43200,
11213 'MIT' => -34200,
11214 'MNST' => 32400,
11215 'MSDT' => 14400,
11216 'MSST' => 10800,
11217 'MST' => -25200,
11218 'MUT' => 14400,
11219 'MVT' => 18000,
11220 'MYT' => 28800,
11221 'NCT' => 39600,
11222 'NDT' => -9000,
11223 'NFT' => 41400,
11224 'NMIT' => 36000,
11225 'NOVST' => 25200,
11226 'NOVT' => 21600,
11227 'NPT' => 20700,
11228 'NRT' => 43200,
11229 'NST' => -12600,
11230 'NUT' => -39600,
11231 'NZDT' => 46800,
11232 'NZST' => 43200,
11233 'OMSST' => 25200,
11234 'OMST' => 21600,
11235 'PDT' => -25200,
11236 'PET' => -18000,
11237 'PETST' => 46800,
11238 'PETT' => 43200,
11239 'PGT' => 36000,
11240 'PHOT' => 46800,
11241 'PHT' => 28800,
11242 'PKT' => 18000,
11243 'PMDT' => -7200,
11244 'PMST' => -10800,
11245 'PONT' => 39600,
11246 'PST' => -28800,
11247 'PWT' => 32400,
11248 'PYST' => -10800,
11249 'PYT' => -14400,
11250 'RET' => 14400,
11251 'ROTT' => -10800,
11252 'SAMST' => 18000,
11253 'SAMT' => 14400,
11254 'SAST' => 7200,
11255 'SBT' => 39600,
11256 'SCDT' => 46800,
11257 'SCST' => 43200,
11258 'SCT' => 14400,
11259 'SEST' => 3600,
11260 'SGT' => 28800,
11261 'SIT' => 28800,
11262 'SRT' => -10800,
11263 'SST' => -39600,
11264 'SYST' => 10800,
11265 'SYT' => 7200,
11266 'TFT' => 18000,
11267 'THAT' => -36000,
11268 'TJT' => 18000,
11269 'TKT' => -36000,
11270 'TMT' => 18000,
11271 'TOT' => 46800,
11272 'TPT' => 32400,
11273 'TRUT' => 36000,
11274 'TVT' => 43200,
11275 'TWT' => 28800,
11276 'UYST' => -7200,
11277 'UYT' => -10800,
11278 'UZT' => 18000,
11279 'VET' => -14400,
11280 'VLAST' => 39600,
11281 'VLAT' => 36000,
11282 'VOST' => 21600,
11283 'VUT' => 39600,
11284 'WAST' => 7200,
11285 'WAT' => 3600,
11286 'WDT' => 32400,
11287 'WEST' => 3600,
11288 'WFT' => 43200,
11289 'WIB' => 25200,
11290 'WIT' => 32400,
11291 'WITA' => 28800,
11292 'WKST' => 18000,
11293 'WST' => 28800,
11294 'YAKST' => 36000,
11295 'YAKT' => 32400,
11296 'YAPT' => 36000,
11297 'YEKST' => 21600,
11298 'YEKT' => 18000,
11299 );
11300
11301 /**
11302 * Cached PCRE for SimplePie_Parse_Date::$day
11303 *
11304 * @access protected
11305 * @var string
11306 */
11307 var $day_pcre;
11308
11309 /**
11310 * Cached PCRE for SimplePie_Parse_Date::$month
11311 *
11312 * @access protected
11313 * @var string
11314 */
11315 var $month_pcre;
11316
11317 /**
11318 * Array of user-added callback methods
11319 *
11320 * @access private
11321 * @var array
11322 */
11323 var $built_in = array();
11324
11325 /**
11326 * Array of user-added callback methods
11327 *
11328 * @access private
11329 * @var array
11330 */
11331 var $user = array();
11332
11333 /**
11334 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11335 * self::month_pcre, and self::built_in
11336 *
11337 * @access private
11338 */
11339 function SimplePie_Parse_Date()
11340 {
11341 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11342 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11343
11344 static $cache;
11345 if (!isset($cache[get_class($this)]))
11346 {
11347 if (extension_loaded('Reflection'))
11348 {
11349 $class = new ReflectionClass(get_class($this));
11350 $methods = $class->getMethods();
11351 $all_methods = array();
11352 foreach ($methods as $method)
11353 {
11354 $all_methods[] = $method->getName();
11355 }
11356 }
11357 else
11358 {
11359 $all_methods = get_class_methods($this);
11360 }
11361
11362 foreach ($all_methods as $method)
11363 {
11364 if (strtolower(substr($method, 0, 5)) === 'date_')
11365 {
11366 $cache[get_class($this)][] = $method;
11367 }
11368 }
11369 }
11370
11371 foreach ($cache[get_class($this)] as $method)
11372 {
11373 $this->built_in[] = $method;
11374 }
11375 }
11376
11377 /**
11378 * Get the object
11379 *
11380 * @access public
11381 */
11382 function get()
11383 {
11384 static $object;
11385 if (!$object)
11386 {
11387 $object = new SimplePie_Parse_Date;
11388 }
11389 return $object;
11390 }
11391
11392 /**
11393 * Parse a date
11394 *
11395 * @final
11396 * @access public
11397 * @param string $date Date to parse
11398 * @return int Timestamp corresponding to date string, or false on failure
11399 */
11400 function parse($date)
11401 {
11402 foreach ($this->user as $method)
11403 {
11404 if (($returned = call_user_func($method, $date)) !== false)
11405 {
11406 return $returned;
11407 }
11408 }
11409
11410 foreach ($this->built_in as $method)
11411 {
11412 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11413 {
11414 return $returned;
11415 }
11416 }
11417
11418 return false;
11419 }
11420
11421 /**
11422 * Add a callback method to parse a date
11423 *
11424 * @final
11425 * @access public
11426 * @param callback $callback
11427 */
11428 function add_callback($callback)
11429 {
11430 if (is_callable($callback))
11431 {
11432 $this->user[] = $callback;
11433 }
11434 else
11435 {
11436 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
11437 }
11438 }
11439
11440 /**
11441 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11442 * well as allowing any of upper or lower case "T", horizontal tabs, or
11443 * spaces to be used as the time seperator (including more than one))
11444 *
11445 * @access protected
11446 * @return int Timestamp
11447 */
11448 function date_w3cdtf($date)
11449 {
11450 static $pcre;
11451 if (!$pcre)
11452 {
11453 $year = '([0-9]{4})';
11454 $month = $day = $hour = $minute = $second = '([0-9]{2})';
11455 $decimal = '([0-9]*)';
11456 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11457 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11458 }
11459 if (preg_match($pcre, $date, $match))
11460 {
11461 /*
11462 Capturing subpatterns:
11463 1: Year
11464 2: Month
11465 3: Day
11466 4: Hour
11467 5: Minute
11468 6: Second
11469 7: Decimal fraction of a second
11470 8: Zulu
11471 9: Timezone ±
11472 10: Timezone hours
11473 11: Timezone minutes
11474 */
11475
11476 // Fill in empty matches
11477 for ($i = count($match); $i <= 3; $i++)
11478 {
11479 $match[$i] = '1';
11480 }
11481
11482 for ($i = count($match); $i <= 7; $i++)
11483 {
11484 $match[$i] = '0';
11485 }
11486
11487 // Numeric timezone
11488 if (isset($match[9]) && $match[9] !== '')
11489 {
11490 $timezone = $match[10] * 3600;
11491 $timezone += $match[11] * 60;
11492 if ($match[9] === '-')
11493 {
11494 $timezone = 0 - $timezone;
11495 }
11496 }
11497 else
11498 {
11499 $timezone = 0;
11500 }
11501
11502 // Convert the number of seconds to an integer, taking decimals into account
11503 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11504
11505 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
11506 }
11507 else
11508 {
11509 return false;
11510 }
11511 }
11512
11513 /**
11514 * Remove RFC822 comments
11515 *
11516 * @access protected
11517 * @param string $data Data to strip comments from
11518 * @return string Comment stripped string
11519 */
11520 function remove_rfc2822_comments($string)
11521 {
11522 $string = (string) $string;
11523 $position = 0;
11524 $length = strlen($string);
11525 $depth = 0;
11526
11527 $output = '';
11528
11529 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
11530 {
11531 $output .= substr($string, $position, $pos - $position);
11532 $position = $pos + 1;
11533 if ($string[$pos - 1] !== '\\')
11534 {
11535 $depth++;
11536 while ($depth && $position < $length)
11537 {
11538 $position += strcspn($string, '()', $position);
11539 if ($string[$position - 1] === '\\')
11540 {
11541 $position++;
11542 continue;
11543 }
11544 elseif (isset($string[$position]))
11545 {
11546 switch ($string[$position])
11547 {
11548 case '(':
11549 $depth++;
11550 break;
11551
11552 case ')':
11553 $depth--;
11554 break;
11555 }
11556 $position++;
11557 }
11558 else
11559 {
11560 break;
11561 }
11562 }
11563 }
11564 else
11565 {
11566 $output .= '(';
11567 }
11568 }
11569 $output .= substr($string, $position);
11570
11571 return $output;
11572 }
11573
11574 /**
11575 * Parse RFC2822's date format
11576 *
11577 * @access protected
11578 * @return int Timestamp
11579 */
11580 function date_rfc2822($date)
11581 {
11582 static $pcre;
11583 if (!$pcre)
11584 {
11585 $wsp = '[\x09\x20]';
11586 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
11587 $optional_fws = $fws . '?';
11588 $day_name = $this->day_pcre;
11589 $month = $this->month_pcre;
11590 $day = '([0-9]{1,2})';
11591 $hour = $minute = $second = '([0-9]{2})';
11592 $year = '([0-9]{2,4})';
11593 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
11594 $character_zone = '([A-Z]{1,5})';
11595 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
11596 $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';
11597 }
11598 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
11599 {
11600 /*
11601 Capturing subpatterns:
11602 1: Day name
11603 2: Day
11604 3: Month
11605 4: Year
11606 5: Hour
11607 6: Minute
11608 7: Second
11609 8: Timezone ±
11610 9: Timezone hours
11611 10: Timezone minutes
11612 11: Alphabetic timezone
11613 */
11614
11615 // Find the month number
11616 $month = $this->month[strtolower($match[3])];
11617
11618 // Numeric timezone
11619 if ($match[8] !== '')
11620 {
11621 $timezone = $match[9] * 3600;
11622 $timezone += $match[10] * 60;
11623 if ($match[8] === '-')
11624 {
11625 $timezone = 0 - $timezone;
11626 }
11627 }
11628 // Character timezone
11629 elseif (isset($this->timezone[strtoupper($match[11])]))
11630 {
11631 $timezone = $this->timezone[strtoupper($match[11])];
11632 }
11633 // Assume everything else to be -0000
11634 else
11635 {
11636 $timezone = 0;
11637 }
11638
11639 // Deal with 2/3 digit years
11640 if ($match[4] < 50)
11641 {
11642 $match[4] += 2000;
11643 }
11644 elseif ($match[4] < 1000)
11645 {
11646 $match[4] += 1900;
11647 }
11648
11649 // Second is optional, if it is empty set it to zero
11650 if ($match[7] !== '')
11651 {
11652 $second = $match[7];
11653 }
11654 else
11655 {
11656 $second = 0;
11657 }
11658
11659 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
11660 }
11661 else
11662 {
11663 return false;
11664 }
11665 }
11666
11667 /**
11668 * Parse RFC850's date format
11669 *
11670 * @access protected
11671 * @return int Timestamp
11672 */
11673 function date_rfc850($date)
11674 {
11675 static $pcre;
11676 if (!$pcre)
11677 {
11678 $space = '[\x09\x20]+';
11679 $day_name = $this->day_pcre;
11680 $month = $this->month_pcre;
11681 $day = '([0-9]{1,2})';
11682 $year = $hour = $minute = $second = '([0-9]{2})';
11683 $zone = '([A-Z]{1,5})';
11684 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
11685 }
11686 if (preg_match($pcre, $date, $match))
11687 {
11688 /*
11689 Capturing subpatterns:
11690 1: Day name
11691 2: Day
11692 3: Month
11693 4: Year
11694 5: Hour
11695 6: Minute
11696 7: Second
11697 8: Timezone
11698 */
11699
11700 // Month
11701 $month = $this->month[strtolower($match[3])];
11702
11703 // Character timezone
11704 if (isset($this->timezone[strtoupper($match[8])]))
11705 {
11706 $timezone = $this->timezone[strtoupper($match[8])];
11707 }
11708 // Assume everything else to be -0000
11709 else
11710 {
11711 $timezone = 0;
11712 }
11713
11714 // Deal with 2 digit year
11715 if ($match[4] < 50)
11716 {
11717 $match[4] += 2000;
11718 }
11719 else
11720 {
11721 $match[4] += 1900;
11722 }
11723
11724 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
11725 }
11726 else
11727 {
11728 return false;
11729 }
11730 }
11731
11732 /**
11733 * Parse C99's asctime()'s date format
11734 *
11735 * @access protected
11736 * @return int Timestamp
11737 */
11738 function date_asctime($date)
11739 {
11740 static $pcre;
11741 if (!$pcre)
11742 {
11743 $space = '[\x09\x20]+';
11744 $wday_name = $this->day_pcre;
11745 $mon_name = $this->month_pcre;
11746 $day = '([0-9]{1,2})';
11747 $hour = $sec = $min = '([0-9]{2})';
11748 $year = '([0-9]{4})';
11749 $terminator = '\x0A?\x00?';
11750 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
11751 }
11752 if (preg_match($pcre, $date, $match))
11753 {
11754 /*
11755 Capturing subpatterns:
11756 1: Day name
11757 2: Month
11758 3: Day
11759 4: Hour
11760 5: Minute
11761 6: Second
11762 7: Year
11763 */
11764
11765 $month = $this->month[strtolower($match[2])];
11766 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
11767 }
11768 else
11769 {
11770 return false;
11771 }
11772 }
11773
11774 /**
11775 * Parse dates using strtotime()
11776 *
11777 * @access protected
11778 * @return int Timestamp
11779 */
11780 function date_strtotime($date)
11781 {
11782 $strtotime = strtotime($date);
11783 if ($strtotime === -1 || $strtotime === false)
11784 {
11785 return false;
11786 }
11787 else
11788 {
11789 return $strtotime;
11790 }
11791 }
11792 }
11793
11794 /**
11795 * Content-type sniffing
11796 *
11797 * @package SimplePie
11798 */
11799 class SimplePie_Content_Type_Sniffer
11800 {
11801 /**
11802 * File object
11803 *
11804 * @var SimplePie_File
11805 * @access private
11806 */
11807 var $file;
11808
11809 /**
11810 * Create an instance of the class with the input file
11811 *
11812 * @access public
11813 * @param SimplePie_Content_Type_Sniffer $file Input file
11814 */
11815 function SimplePie_Content_Type_Sniffer($file)
11816 {
11817 $this->file = $file;
11818 }
11819
11820 /**
11821 * Get the Content-Type of the specified file
11822 *
11823 * @access public
11824 * @return string Actual Content-Type
11825 */
11826 function get_type()
11827 {
11828 if (isset($this->file->headers['content-type']))
11829 {
11830 if (!isset($this->file->headers['content-encoding'])
11831 && ($this->file->headers['content-type'] === 'text/plain'
11832 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
11833 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
11834 {
11835 return $this->text_or_binary();
11836 }
11837
11838 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
11839 {
11840 $official = substr($this->file->headers['content-type'], 0, $pos);
11841 }
11842 else
11843 {
11844 $official = $this->file->headers['content-type'];
11845 }
11846 $official = strtolower($official);
11847
11848 if ($official === 'unknown/unknown'
11849 || $official === 'application/unknown')
11850 {
11851 return $this->unknown();
11852 }
11853 elseif (substr($official, -4) === '+xml'
11854 || $official === 'text/xml'
11855 || $official === 'application/xml')
11856 {
11857 return $official;
11858 }
11859 elseif (substr($official, 0, 6) === 'image/')
11860 {
11861 if ($return = $this->image())
11862 {
11863 return $return;
11864 }
11865 else
11866 {
11867 return $official;
11868 }
11869 }
11870 elseif ($official === 'text/html')
11871 {
11872 return $this->feed_or_html();
11873 }
11874 else
11875 {
11876 return $official;
11877 }
11878 }
11879 else
11880 {
11881 return $this->unknown();
11882 }
11883 }
11884
11885 /**
11886 * Sniff text or binary
11887 *
11888 * @access private
11889 * @return string Actual Content-Type
11890 */
11891 function text_or_binary()
11892 {
11893 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
11894 || substr($this->file->body, 0, 2) === "\xFF\xFE"
11895 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
11896 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
11897 {
11898 return 'text/plain';
11899 }
11900 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
11901 {
11902 return 'application/octect-stream';
11903 }
11904 else
11905 {
11906 return 'text/plain';
11907 }
11908 }
11909
11910 /**
11911 * Sniff unknown
11912 *
11913 * @access private
11914 * @return string Actual Content-Type
11915 */
11916 function unknown()
11917 {
11918 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
11919 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
11920 || strtolower(substr($this->file->body, $ws, 5)) === '<html'
11921 || strtolower(substr($this->file->body, $ws, 7)) === '<script')
11922 {
11923 return 'text/html';
11924 }
11925 elseif (substr($this->file->body, 0, 5) === '%PDF-')
11926 {
11927 return 'application/pdf';
11928 }
11929 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
11930 {
11931 return 'application/postscript';
11932 }
11933 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
11934 || substr($this->file->body, 0, 6) === 'GIF89a')
11935 {
11936 return 'image/gif';
11937 }
11938 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
11939 {
11940 return 'image/png';
11941 }
11942 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
11943 {
11944 return 'image/jpeg';
11945 }
11946 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
11947 {
11948 return 'image/bmp';
11949 }
11950 else
11951 {
11952 return $this->text_or_binary();
11953 }
11954 }
11955
11956 /**
11957 * Sniff images
11958 *
11959 * @access private
11960 * @return string Actual Content-Type
11961 */
11962 function image()
11963 {
11964 if (substr($this->file->body, 0, 6) === 'GIF87a'
11965 || substr($this->file->body, 0, 6) === 'GIF89a')
11966 {
11967 return 'image/gif';
11968 }
11969 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
11970 {
11971 return 'image/png';
11972 }
11973 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
11974 {
11975 return 'image/jpeg';
11976 }
11977 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
11978 {
11979 return 'image/bmp';
11980 }
11981 else
11982 {
11983 return false;
11984 }
11985 }
11986
11987 /**
11988 * Sniff HTML
11989 *
11990 * @access private
11991 * @return string Actual Content-Type
11992 */
11993 function feed_or_html()
11994 {
11995 $len = strlen($this->file->body);
11996 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
11997
11998 while ($pos < $len)
11999 {
12000 switch ($this->file->body[$pos])
12001 {
12002 case "\x09":
12003 case "\x0A":
12004 case "\x0D":
12005 case "\x20":
12006 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12007 continue 2;
12008
12009 case '<':
12010 $pos++;
12011 break;
12012
12013 default:
12014 return 'text/html';
12015 }
12016
12017 if (substr($this->file->body, $pos, 3) === '!--')
12018 {
12019 $pos += 3;
12020 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12021 {
12022 $pos += 3;
12023 }
12024 else
12025 {
12026 return 'text/html';
12027 }
12028 }
12029 elseif (substr($this->file->body, $pos, 1) === '!')
12030 {
12031 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12032 {
12033 $pos++;
12034 }
12035 else
12036 {
12037 return 'text/html';
12038 }
12039 }
12040 elseif (substr($this->file->body, $pos, 1) === '?')
12041 {
12042 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12043 {
12044 $pos += 2;
12045 }
12046 else
12047 {
12048 return 'text/html';
12049 }
12050 }
12051 elseif (substr($this->file->body, $pos, 3) === 'rss'
12052 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
12053 {
12054 return 'application/rss+xml';
12055 }
12056 elseif (substr($this->file->body, $pos, 4) === 'feed')
12057 {
12058 return 'application/atom+xml';
12059 }
12060 else
12061 {
12062 return 'text/html';
12063 }
12064 }
12065
12066 return 'text/html';
12067 }
12068 }
12069
12070 /**
12071 * Parses the XML Declaration
12072 *
12073 * @package SimplePie
12074 */
12075 class SimplePie_XML_Declaration_Parser
12076 {
12077 /**
12078 * XML Version
12079 *
12080 * @access public
12081 * @var string
12082 */
12083 var $version = '1.0';
12084
12085 /**
12086 * Encoding
12087 *
12088 * @access public
12089 * @var string
12090 */
12091 var $encoding = 'UTF-8';
12092
12093 /**
12094 * Standalone
12095 *
12096 * @access public
12097 * @var bool
12098 */
12099 var $standalone = false;
12100
12101 /**
12102 * Current state of the state machine
12103 *
12104 * @access private
12105 * @var string
12106 */
12107 var $state = 'before_version_name';
12108
12109 /**
12110 * Input data
12111 *
12112 * @access private
12113 * @var string
12114 */
12115 var $data = '';
12116
12117 /**
12118 * Input data length (to avoid calling strlen() everytime this is needed)
12119 *
12120 * @access private
12121 * @var int
12122 */
12123 var $data_length = 0;
12124
12125 /**
12126 * Current position of the pointer
12127 *
12128 * @var int
12129 * @access private
12130 */
12131 var $position = 0;
12132
12133 /**
12134 * Create an instance of the class with the input data
12135 *
12136 * @access public
12137 * @param string $data Input data
12138 */
12139 function SimplePie_XML_Declaration_Parser($data)
12140 {
12141 $this->data = $data;
12142 $this->data_length = strlen($this->data);
12143 }
12144
12145 /**
12146 * Parse the input data
12147 *
12148 * @access public
12149 * @return bool true on success, false on failure
12150 */
12151 function parse()
12152 {
12153 while ($this->state && $this->state !== 'emit' && $this->has_data())
12154 {
12155 $state = $this->state;
12156 $this->$state();
12157 }
12158 $this->data = '';
12159 if ($this->state === 'emit')
12160 {
12161 return true;
12162 }
12163 else
12164 {
12165 $this->version = '';
12166 $this->encoding = '';
12167 $this->standalone = '';
12168 return false;
12169 }
12170 }
12171
12172 /**
12173 * Check whether there is data beyond the pointer
12174 *
12175 * @access private
12176 * @return bool true if there is further data, false if not
12177 */
12178 function has_data()
12179 {
12180 return (bool) ($this->position < $this->data_length);
12181 }
12182
12183 /**
12184 * Advance past any whitespace
12185 *
12186 * @return int Number of whitespace characters passed
12187 */
12188 function skip_whitespace()
12189 {
12190 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12191 $this->position += $whitespace;
12192 return $whitespace;
12193 }
12194
12195 /**
12196 * Read value
12197 */
12198 function get_value()
12199 {
12200 $quote = substr($this->data, $this->position, 1);
12201 if ($quote === '"' || $quote === "'")
12202 {
12203 $this->position++;
12204 $len = strcspn($this->data, $quote, $this->position);
12205 if ($this->has_data())
12206 {
12207 $value = substr($this->data, $this->position, $len);
12208 $this->position += $len + 1;
12209 return $value;
12210 }
12211 }
12212 return false;
12213 }
12214
12215 function before_version_name()
12216 {
12217 if ($this->skip_whitespace())
12218 {
12219 $this->state = 'version_name';
12220 }
12221 else
12222 {
12223 $this->state = false;
12224 }
12225 }
12226
12227 function version_name()
12228 {
12229 if (substr($this->data, $this->position, 7) === 'version')
12230 {
12231 $this->position += 7;
12232 $this->skip_whitespace();
12233 $this->state = 'version_equals';
12234 }
12235 else
12236 {
12237 $this->state = false;
12238 }
12239 }
12240
12241 function version_equals()
12242 {
12243 if (substr($this->data, $this->position, 1) === '=')
12244 {
12245 $this->position++;
12246 $this->skip_whitespace();
12247 $this->state = 'version_value';
12248 }
12249 else
12250 {
12251 $this->state = false;
12252 }
12253 }
12254
12255 function version_value()
12256 {
12257 if ($this->version = $this->get_value())
12258 {
12259 $this->skip_whitespace();
12260 if ($this->has_data())
12261 {
12262 $this->state = 'encoding_name';
12263 }
12264 else
12265 {
12266 $this->state = 'emit';
12267 }
12268 }
12269 else
12270 {
12271 $this->state = 'standalone_name';
12272 }
12273 }
12274
12275 function encoding_name()
12276 {
12277 if (substr($this->data, $this->position, 8) === 'encoding')
12278 {
12279 $this->position += 8;
12280 $this->skip_whitespace();
12281 $this->state = 'encoding_equals';
12282 }
12283 else
12284 {
12285 $this->state = false;
12286 }
12287 }
12288
12289 function encoding_equals()
12290 {
12291 if (substr($this->data, $this->position, 1) === '=')
12292 {
12293 $this->position++;
12294 $this->skip_whitespace();
12295 $this->state = 'encoding_value';
12296 }
12297 else
12298 {
12299 $this->state = false;
12300 }
12301 }
12302
12303 function encoding_value()
12304 {
12305 if ($this->encoding = $this->get_value())
12306 {
12307 $this->skip_whitespace();
12308 if ($this->has_data())
12309 {
12310 $this->state = 'standalone_name';
12311 }
12312 else
12313 {
12314 $this->state = 'emit';
12315 }
12316 }
12317 else
12318 {
12319 $this->state = false;
12320 }
12321 }
12322
12323 function standalone_name()
12324 {
12325 if (substr($this->data, $this->position, 10) === 'standalone')
12326 {
12327 $this->position += 10;
12328 $this->skip_whitespace();
12329 $this->state = 'standalone_equals';
12330 }
12331 else
12332 {
12333 $this->state = false;
12334 }
12335 }
12336
12337 function standalone_equals()
12338 {
12339 if (substr($this->data, $this->position, 1) === '=')
12340 {
12341 $this->position++;
12342 $this->skip_whitespace();
12343 $this->state = 'standalone_value';
12344 }
12345 else
12346 {
12347 $this->state = false;
12348 }
12349 }
12350
12351 function standalone_value()
12352 {
12353 if ($standalone = $this->get_value())
12354 {
12355 switch ($standalone)
12356 {
12357 case 'yes':
12358 $this->standalone = true;
12359 break;
12360
12361 case 'no':
12362 $this->standalone = false;
12363 break;
12364
12365 default:
12366 $this->state = false;
12367 return;
12368 }
12369
12370 $this->skip_whitespace();
12371 if ($this->has_data())
12372 {
12373 $this->state = false;
12374 }
12375 else
12376 {
12377 $this->state = 'emit';
12378 }
12379 }
12380 else
12381 {
12382 $this->state = false;
12383 }
12384 }
12385 }
12386
12387 class SimplePie_Locator
12388 {
12389 var $useragent;
12390 var $timeout;
12391 var $file;
12392 var $local = array();
12393 var $elsewhere = array();
12394 var $file_class = 'SimplePie_File';
12395 var $cached_entities = array();
12396 var $http_base;
12397 var $base;
12398 var $base_location = 0;
12399 var $checked_feeds = 0;
12400 var $max_checked_feeds = 10;
12401 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
12402
12403 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
12404 {
12405 $this->file =& $file;
12406 $this->file_class = $file_class;
12407 $this->useragent = $useragent;
12408 $this->timeout = $timeout;
12409 $this->max_checked_feeds = $max_checked_feeds;
12410 $this->content_type_sniffer_class;
12411 }
12412
12413 function find($type = SIMPLEPIE_LOCATOR_ALL)
12414 {
12415 if ($this->is_feed($this->file))
12416 {
12417 return $this->file;
12418 }
12419
12420 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12421 {
12422 $sniffer = new $this->content_type_sniffer_class($this->file);
12423 if ($sniffer->get_type() !== 'text/html')
12424 {
12425 return null;
12426 }
12427 }
12428
12429 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12430 {
12431 $this->get_base();
12432 }
12433
12434 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12435 {
12436 return $working;
12437 }
12438
12439 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12440 {
12441 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12442 {
12443 return $working;
12444 }
12445
12446 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12447 {
12448 return $working;
12449 }
12450
12451 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12452 {
12453 return $working;
12454 }
12455
12456 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12457 {
12458 return $working;
12459 }
12460 }
12461 return null;
12462 }
12463
12464 function is_feed(&$file)
12465 {
12466 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12467 {
12468 $sniffer = new $this->content_type_sniffer_class($file);
12469 $sniffed = $sniffer->get_type();
12470 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'application/atom+xml', 'text/xml', 'application/xml', 'text/plain')))
12471 {
12472 return true;
12473 }
12474 else
12475 {
12476 return false;
12477 }
12478 }
12479 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
12480 {
12481 return true;
12482 }
12483 else
12484 {
12485 return false;
12486 }
12487 }
12488
12489 function get_base()
12490 {
12491 $this->http_base = $this->file->url;
12492 $this->base = $this->http_base;
12493 $elements = SimplePie_Misc::get_element('base', $this->file->body);
12494 foreach ($elements as $element)
12495 {
12496 if ($element['attribs']['href']['data'] !== '')
12497 {
12498 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12499 $this->base_location = $element['offset'];
12500 break;
12501 }
12502 }
12503 }
12504
12505 function autodiscovery()
12506 {
12507 $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));
12508 $done = array();
12509 foreach ($links as $link)
12510 {
12511 if ($this->checked_feeds == $this->max_checked_feeds)
12512 {
12513 break;
12514 }
12515 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12516 {
12517 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12518
12519 if ($this->base_location < $link['offset'])
12520 {
12521 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12522 }
12523 else
12524 {
12525 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12526 }
12527
12528 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'))))
12529 {
12530 $this->checked_feeds++;
12531 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
12532 if ($this->is_feed($feed))
12533 {
12534 return $feed;
12535 }
12536 }
12537 $done[] = $href;
12538 }
12539 }
12540 return null;
12541 }
12542
12543 function get_links()
12544 {
12545 $links = SimplePie_Misc::get_element('a', $this->file->body);
12546 foreach ($links as $link)
12547 {
12548 if (isset($link['attribs']['href']['data']))
12549 {
12550 $href = trim($link['attribs']['href']['data']);
12551 $parsed = SimplePie_Misc::parse_url($href);
12552 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12553 {
12554 if ($this->base_location < $link['offset'])
12555 {
12556 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12557 }
12558 else
12559 {
12560 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12561 }
12562
12563 $current = SimplePie_Misc::parse_url($this->file->url);
12564
12565 if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
12566 {
12567 $this->local[] = $href;
12568 }
12569 else
12570 {
12571 $this->elsewhere[] = $href;
12572 }
12573 }
12574 }
12575 }
12576 $this->local = array_unique($this->local);
12577 $this->elsewhere = array_unique($this->elsewhere);
12578 if (!empty($this->local) || !empty($this->elsewhere))
12579 {
12580 return true;
12581 }
12582 return null;
12583 }
12584
12585 function extension(&$array)
12586 {
12587 foreach ($array as $key => $value)
12588 {
12589 if ($this->checked_feeds == $this->max_checked_feeds)
12590 {
12591 break;
12592 }
12593 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
12594 {
12595 $this->checked_feeds++;
12596 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12597 if ($this->is_feed($feed))
12598 {
12599 return $feed;
12600 }
12601 else
12602 {
12603 unset($array[$key]);
12604 }
12605 }
12606 }
12607 return null;
12608 }
12609
12610 function body(&$array)
12611 {
12612 foreach ($array as $key => $value)
12613 {
12614 if ($this->checked_feeds == $this->max_checked_feeds)
12615 {
12616 break;
12617 }
12618 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
12619 {
12620 $this->checked_feeds++;
12621 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12622 if ($this->is_feed($feed))
12623 {
12624 return $feed;
12625 }
12626 else
12627 {
12628 unset($array[$key]);
12629 }
12630 }
12631 }
12632 return null;
12633 }
12634 }
12635
12636 class SimplePie_Parser
12637 {
12638 var $error_code;
12639 var $error_string;
12640 var $current_line;
12641 var $current_column;
12642 var $current_byte;
12643 var $separator = ' ';
12644 var $feed = false;
12645 var $namespace = array('');
12646 var $element = array('');
12647 var $xml_base = array('');
12648 var $xml_base_explicit = array(false);
12649 var $xml_lang = array('');
12650 var $data = array();
12651 var $datas = array(array());
12652 var $current_xhtml_construct = -1;
12653 var $encoding;
12654
12655 function parse(&$data, $encoding)
12656 {
12657 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
12658 if (strtoupper($encoding) == 'US-ASCII')
12659 {
12660 $this->encoding = 'UTF-8';
12661 }
12662 else
12663 {
12664 $this->encoding = $encoding;
12665 }
12666
12667 // Strip BOM:
12668 // UTF-32 Big Endian BOM
12669 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
12670 {
12671 $data = substr($data, 4);
12672 }
12673 // UTF-32 Little Endian BOM
12674 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
12675 {
12676 $data = substr($data, 4);
12677 }
12678 // UTF-16 Big Endian BOM
12679 elseif (substr($data, 0, 2) === "\xFE\xFF")
12680 {
12681 $data = substr($data, 2);
12682 }
12683 // UTF-16 Little Endian BOM
12684 elseif (substr($data, 0, 2) === "\xFF\xFE")
12685 {
12686 $data = substr($data, 2);
12687 }
12688 // UTF-8 BOM
12689 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
12690 {
12691 $data = substr($data, 3);
12692 }
12693
12694 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
12695 {
12696 $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
12697 if ($declaration->parse())
12698 {
12699 $data = substr($data, $pos + 2);
12700 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
12701 }
12702 else
12703 {
12704 $this->error_string = 'SimplePie bug! Please report this!';
12705 return false;
12706 }
12707 }
12708
12709 $return = true;
12710
12711 // Create the parser
12712 $xml = xml_parser_create_ns($this->encoding, $this->separator);
12713 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
12714 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
12715 xml_set_object($xml, $this);
12716 xml_set_character_data_handler($xml, 'cdata');
12717 xml_set_element_handler($xml, 'tag_open', 'tag_close');
12718
12719 // Parse!
12720 if (!xml_parse($xml, $data, true))
12721 {
12722 $this->error_code = xml_get_error_code($xml);
12723 $this->error_string = xml_error_string($this->error_code);
12724 $return = false;
12725 }
12726 $this->current_line = xml_get_current_line_number($xml);
12727 $this->current_column = xml_get_current_column_number($xml);
12728 $this->current_byte = xml_get_current_byte_index($xml);
12729 xml_parser_free($xml);
12730 return $return;
12731 }
12732
12733 function get_error_code()
12734 {
12735 return $this->error_code;
12736 }
12737
12738 function get_error_string()
12739 {
12740 return $this->error_string;
12741 }
12742
12743 function get_current_line()
12744 {
12745 return $this->current_line;
12746 }
12747
12748 function get_current_column()
12749 {
12750 return $this->current_column;
12751 }
12752
12753 function get_current_byte()
12754 {
12755 return $this->current_byte;
12756 }
12757
12758 function get_data()
12759 {
12760 return $this->data;
12761 }
12762
12763 function tag_open($parser, $tag, $attributes)
12764 {
12765 if ($this->feed === 0)
12766 {
12767 return;
12768 }
12769 elseif ($this->feed == false)
12770 {
12771 if (in_array($tag, array(
12772 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
12773 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
12774 'rss',
12775 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
12776 )))
12777 {
12778 $this->feed = 1;
12779 }
12780 }
12781 else
12782 {
12783 $this->feed++;
12784 }
12785
12786 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
12787
12788 $attribs = array();
12789 foreach ($attributes as $name => $value)
12790 {
12791 list($attrib_namespace, $attribute) = $this->split_ns($name);
12792 $attribs[$attrib_namespace][$attribute] = $value;
12793 }
12794
12795 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
12796 {
12797 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
12798 $this->xml_base_explicit[] = true;
12799 }
12800 else
12801 {
12802 $this->xml_base[] = end($this->xml_base);
12803 $this->xml_base_explicit[] = end($this->xml_base_explicit);
12804 }
12805
12806 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
12807 {
12808 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
12809 }
12810 else
12811 {
12812 $this->xml_lang[] = end($this->xml_lang);
12813 }
12814
12815 if ($this->current_xhtml_construct >= 0)
12816 {
12817 $this->current_xhtml_construct++;
12818 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
12819 {
12820 $this->data['data'] .= '<' . end($this->element);
12821 if (isset($attribs['']))
12822 {
12823 foreach ($attribs[''] as $name => $value)
12824 {
12825 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
12826 }
12827 }
12828 $this->data['data'] .= '>';
12829 }
12830 }
12831 else
12832 {
12833 $this->datas[] =& $this->data;
12834 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
12835 $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));
12836 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')
12837 || (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'))
12838 {
12839 $this->current_xhtml_construct = 0;
12840 }
12841 }
12842 }
12843
12844 function cdata($parser, $cdata)
12845 {
12846 if ($this->current_xhtml_construct >= 0)
12847 {
12848 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
12849 }
12850 elseif ($this->feed > 1)
12851 {
12852 $this->data['data'] .= $cdata;
12853 }
12854 }
12855
12856 function tag_close($parser, $tag)
12857 {
12858 if (!$this->feed)
12859 {
12860 return;
12861 }
12862
12863 if ($this->current_xhtml_construct >= 0)
12864 {
12865 $this->current_xhtml_construct--;
12866 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')))
12867 {
12868 $this->data['data'] .= '</' . end($this->element) . '>';
12869 }
12870 }
12871 if ($this->current_xhtml_construct == -1)
12872 {
12873 $this->data =& $this->datas[$this->feed];
12874 array_pop($this->datas);
12875 }
12876
12877 array_pop($this->element);
12878 array_pop($this->namespace);
12879 array_pop($this->xml_base);
12880 array_pop($this->xml_base_explicit);
12881 array_pop($this->xml_lang);
12882 $this->feed--;
12883 }
12884
12885 function split_ns($string)
12886 {
12887 static $cache = array();
12888 if (!isset($cache[$string]))
12889 {
12890 if ($pos = strpos($string, $this->separator))
12891 {
12892 static $separator_length;
12893 if (!$separator_length)
12894 {
12895 $separator_length = strlen($this->separator);
12896 }
12897 $namespace = substr($string, 0, $pos);
12898 $local_name = substr($string, $pos + $separator_length);
12899 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
12900 {
12901 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
12902 }
12903 $cache[$string] = array($namespace, $local_name);
12904 }
12905 else
12906 {
12907 $cache[$string] = array('', $string);
12908 }
12909 }
12910 return $cache[$string];
12911 }
12912 }
12913
12914 /**
12915 * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shortern a string while preserving HTML tags
12916 */
12917 class SimplePie_Sanitize
12918 {
12919 // Private vars
12920 var $base;
12921
12922 // Options
12923 var $remove_div = true;
12924 var $image_handler = '';
12925 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
12926 var $encode_instead_of_strip = false;
12927 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
12928 var $strip_comments = false;
12929 var $output_encoding = 'UTF-8';
12930 var $enable_cache = true;
12931 var $cache_location = './cache';
12932 var $cache_name_function = 'md5';
12933 var $cache_class = 'SimplePie_Cache';
12934 var $file_class = 'SimplePie_File';
12935 var $timeout = 10;
12936 var $useragent = '';
12937 var $force_fsockopen = false;
12938
12939 var $replace_url_attributes = array(
12940 'a' => 'href',
12941 'area' => 'href',
12942 'blockquote' => 'cite',
12943 'del' => 'cite',
12944 'form' => 'action',
12945 'img' => array('longdesc', 'src'),
12946 'input' => 'src',
12947 'ins' => 'cite',
12948 'q' => 'cite'
12949 );
12950
12951 function remove_div($enable = true)
12952 {
12953 $this->remove_div = (bool) $enable;
12954 }
12955
12956 function set_image_handler($page = false)
12957 {
12958 if ($page)
12959 {
12960 $this->image_handler = (string) $page;
12961 }
12962 else
12963 {
12964 $this->image_handler = false;
12965 }
12966 }
12967
12968 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
12969 {
12970 if (isset($enable_cache))
12971 {
12972 $this->enable_cache = (bool) $enable_cache;
12973 }
12974
12975 if ($cache_location)
12976 {
12977 $this->cache_location = (string) $cache_location;
12978 }
12979
12980 if ($cache_name_function)
12981 {
12982 $this->cache_name_function = (string) $cache_name_function;
12983 }
12984
12985 if ($cache_class)
12986 {
12987 $this->cache_class = (string) $cache_class;
12988 }
12989 }
12990
12991 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
12992 {
12993 if ($file_class)
12994 {
12995 $this->file_class = (string) $file_class;
12996 }
12997
12998 if ($timeout)
12999 {
13000 $this->timeout = (string) $timeout;
13001 }
13002
13003 if ($useragent)
13004 {
13005 $this->useragent = (string) $useragent;
13006 }
13007
13008 if ($force_fsockopen)
13009 {
13010 $this->force_fsockopen = (string) $force_fsockopen;
13011 }
13012 }
13013
13014 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13015 {
13016 if ($tags)
13017 {
13018 if (is_array($tags))
13019 {
13020 $this->strip_htmltags = $tags;
13021 }
13022 else
13023 {
13024 $this->strip_htmltags = explode(',', $tags);
13025 }
13026 }
13027 else
13028 {
13029 $this->strip_htmltags = false;
13030 }
13031 }
13032
13033 function encode_instead_of_strip($encode = false)
13034 {
13035 $this->encode_instead_of_strip = (bool) $encode;
13036 }
13037
13038 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13039 {
13040 if ($attribs)
13041 {
13042 if (is_array($attribs))
13043 {
13044 $this->strip_attributes = $attribs;
13045 }
13046 else
13047 {
13048 $this->strip_attributes = explode(',', $attribs);
13049 }
13050 }
13051 else
13052 {
13053 $this->strip_attributes = false;
13054 }
13055 }
13056
13057 function strip_comments($strip = false)
13058 {
13059 $this->strip_comments = (bool) $strip;
13060 }
13061
13062 function set_output_encoding($encoding = 'UTF-8')
13063 {
13064 $this->output_encoding = (string) $encoding;
13065 }
13066
13067 /**
13068 * Set element/attribute key/value pairs of HTML attributes
13069 * containing URLs that need to be resolved relative to the feed
13070 *
13071 * @access public
13072 * @since 1.0
13073 * @param array $element_attribute Element/attribute key/value pairs
13074 */
13075 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'))
13076 {
13077 $this->replace_url_attributes = (array) $element_attribute;
13078 }
13079
13080 function sanitize($data, $type, $base = '')
13081 {
13082 $data = trim($data);
13083 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13084 {
13085 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13086 {
13087 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))
13088 {
13089 $type |= SIMPLEPIE_CONSTRUCT_HTML;
13090 }
13091 else
13092 {
13093 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
13094 }
13095 }
13096
13097 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13098 {
13099 $data = base64_decode($data);
13100 }
13101
13102 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13103 {
13104 if ($this->remove_div)
13105 {
13106 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13107 $data = preg_replace('/<\/div>$/', '', $data);
13108 }
13109 else
13110 {
13111 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13112 }
13113 }
13114
13115 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13116 {
13117 // Strip comments
13118 if ($this->strip_comments)
13119 {
13120 $data = SimplePie_Misc::strip_comments($data);
13121 }
13122
13123 // Strip out HTML tags and attributes that might cause various security problems.
13124 // Based on recommendations by Mark Pilgrim at:
13125 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13126 if ($this->strip_htmltags)
13127 {
13128 foreach ($this->strip_htmltags as $tag)
13129 {
13130 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13131 while (preg_match($pcre, $data))
13132 {
13133 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13134 }
13135 }
13136 }
13137
13138 if ($this->strip_attributes)
13139 {
13140 foreach ($this->strip_attributes as $attrib)
13141 {
13142 $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);
13143 }
13144 }
13145
13146 // Replace relative URLs
13147 $this->base = $base;
13148 foreach ($this->replace_url_attributes as $element => $attributes)
13149 {
13150 $data = $this->replace_urls($data, $element, $attributes);
13151 }
13152
13153 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13154 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13155 {
13156 $images = SimplePie_Misc::get_element('img', $data);
13157 foreach ($images as $img)
13158 {
13159 if (isset($img['attribs']['src']['data']))
13160 {
13161 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13162 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
13163
13164 if ($cache->load())
13165 {
13166 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13167 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13168 }
13169 else
13170 {
13171 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
13172 $headers = $file->headers;
13173
13174 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13175 {
13176 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13177 {
13178 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13179 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13180 }
13181 else
13182 {
13183 trigger_error("$cache->name is not writeable", E_USER_WARNING);
13184 }
13185 }
13186 }
13187 }
13188 }
13189 }
13190
13191 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13192 $data = trim($data);
13193 }
13194
13195 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13196 {
13197 $data = SimplePie_Misc::absolutize_url($data, $base);
13198 }
13199
13200 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13201 {
13202 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13203 }
13204
13205 if ($this->output_encoding != 'UTF-8')
13206 {
13207 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13208 }
13209 }
13210 return $data;
13211 }
13212
13213 function replace_urls($data, $tag, $attributes)
13214 {
13215 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13216 {
13217 $elements = SimplePie_Misc::get_element($tag, $data);
13218 foreach ($elements as $element)
13219 {
13220 if (is_array($attributes))
13221 {
13222 foreach ($attributes as $attribute)
13223 {
13224 if (isset($element['attribs'][$attribute]['data']))
13225 {
13226 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
13227 $new_element = SimplePie_Misc::element_implode($element);
13228 $data = str_replace($element['full'], $new_element, $data);
13229 $element['full'] = $new_element;
13230 }
13231 }
13232 }
13233 elseif (isset($element['attribs'][$attributes]['data']))
13234 {
13235 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13236 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13237 }
13238 }
13239 }
13240 return $data;
13241 }
13242
13243 function do_strip_htmltags($match)
13244 {
13245 if ($this->encode_instead_of_strip)
13246 {
13247 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13248 {
13249 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13250 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13251 return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
13252 }
13253 else
13254 {
13255 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13256 }
13257 }
13258 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13259 {
13260 return $match[4];
13261 }
13262 else
13263 {
13264 return '';
13265 }
13266 }
13267 }
13268
13269 ?>