]> git.wh0rd.org - tt-rss.git/blame - simplepie/simplepie.inc
disable application/xml content-type for op=view zoom mode
[tt-rss.git] / simplepie / simplepie.inc
CommitLineData
f2f7b699
AD
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 *
3cae90e1 8 * Copyright (c) 2004-2008, Ryan Parman and Geoffrey Sneddon
f2f7b699
AD
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
3cae90e1
AD
36 * @version 1.1.1
37 * @copyright 2004-2008 Ryan Parman, Geoffrey Sneddon
f2f7b699
AD
38 * @author Ryan Parman
39 * @author Geoffrey Sneddon
40 * @link http://simplepie.org/ SimplePie
41 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43 * @todo phpDoc comments
44 */
45
46/**
47 * SimplePie Name
48 */
49define('SIMPLEPIE_NAME', 'SimplePie');
50
51/**
52 * SimplePie Version
53 */
3cae90e1 54define('SIMPLEPIE_VERSION', '1.1.1');
f2f7b699
AD
55
56/**
57 * SimplePie Build
3cae90e1 58 * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::parse_date() only every load of simplepie.inc)
f2f7b699 59 */
3cae90e1
AD
60define('SIMPLEPIE_BUILD', 20080315205903);
61//define('SIMPLEPIE_BUILD', gmdate('YmdHis', SimplePie_Misc::parse_date(substr('$Date: 2008-03-15 15:28:23 -0700 (Sat, 15 Mar 2008) $', 7, 25)) ? SimplePie_Misc::parse_date(substr('$Date: 2008-03-15 15:28:23 -0700 (Sat, 15 Mar 2008) $', 7, 25)) : filemtime(__FILE__)));
f2f7b699
AD
62
63/**
64 * SimplePie Website URL
65 */
6d7d21a0 66define('SIMPLEPIE_URL', 'http://simplepie.org');
f2f7b699
AD
67
68/**
69 * SimplePie Useragent
70 * @see SimplePie::set_useragent()
71 */
72define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
73
74/**
75 * SimplePie Linkback
76 */
77define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
78
79/**
80 * No Autodiscovery
81 * @see SimplePie::set_autodiscovery_level()
82 */
83define('SIMPLEPIE_LOCATOR_NONE', 0);
84
85/**
86 * Feed Link Element Autodiscovery
87 * @see SimplePie::set_autodiscovery_level()
88 */
89define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
90
91/**
92 * Local Feed Extension Autodiscovery
93 * @see SimplePie::set_autodiscovery_level()
94 */
95define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
96
97/**
98 * Local Feed Body Autodiscovery
99 * @see SimplePie::set_autodiscovery_level()
100 */
101define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
102
103/**
104 * Remote Feed Extension Autodiscovery
105 * @see SimplePie::set_autodiscovery_level()
106 */
107define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
108
109/**
110 * Remote Feed Body Autodiscovery
111 * @see SimplePie::set_autodiscovery_level()
112 */
113define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
114
115/**
116 * All Feed Autodiscovery
117 * @see SimplePie::set_autodiscovery_level()
118 */
119define('SIMPLEPIE_LOCATOR_ALL', 31);
120
121/**
122 * No known feed type
123 */
124define('SIMPLEPIE_TYPE_NONE', 0);
125
126/**
127 * RSS 0.90
128 */
129define('SIMPLEPIE_TYPE_RSS_090', 1);
130
131/**
132 * RSS 0.91 (Netscape)
133 */
134define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
135
136/**
137 * RSS 0.91 (Userland)
138 */
139define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
140
141/**
142 * RSS 0.91 (both Netscape and Userland)
143 */
144define('SIMPLEPIE_TYPE_RSS_091', 6);
145
146/**
147 * RSS 0.92
148 */
149define('SIMPLEPIE_TYPE_RSS_092', 8);
150
151/**
152 * RSS 0.93
153 */
154define('SIMPLEPIE_TYPE_RSS_093', 16);
155
156/**
157 * RSS 0.94
158 */
159define('SIMPLEPIE_TYPE_RSS_094', 32);
160
161/**
162 * RSS 1.0
163 */
164define('SIMPLEPIE_TYPE_RSS_10', 64);
165
166/**
167 * RSS 2.0
168 */
169define('SIMPLEPIE_TYPE_RSS_20', 128);
170
171/**
172 * RDF-based RSS
173 */
174define('SIMPLEPIE_TYPE_RSS_RDF', 65);
175
176/**
177 * Non-RDF-based RSS (truly intended as syndication format)
178 */
179define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
180
181/**
182 * All RSS
183 */
184define('SIMPLEPIE_TYPE_RSS_ALL', 255);
185
186/**
187 * Atom 0.3
188 */
189define('SIMPLEPIE_TYPE_ATOM_03', 256);
190
191/**
192 * Atom 1.0
193 */
194define('SIMPLEPIE_TYPE_ATOM_10', 512);
195
196/**
197 * All Atom
198 */
199define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
200
201/**
202 * All feed types
203 */
204define('SIMPLEPIE_TYPE_ALL', 1023);
205
206/**
207 * No construct
208 */
209define('SIMPLEPIE_CONSTRUCT_NONE', 0);
210
211/**
212 * Text construct
213 */
214define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
215
216/**
217 * HTML construct
218 */
219define('SIMPLEPIE_CONSTRUCT_HTML', 2);
220
221/**
222 * XHTML construct
223 */
224define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
225
226/**
227 * base64-encoded construct
228 */
229define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
230
231/**
232 * IRI construct
233 */
234define('SIMPLEPIE_CONSTRUCT_IRI', 16);
235
236/**
237 * A construct that might be HTML
238 */
239define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
240
241/**
242 * All constructs
243 */
244define('SIMPLEPIE_CONSTRUCT_ALL', 63);
245
246/**
247 * PCRE for HTML attributes
248 */
6d7d21a0 249define('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]*');
f2f7b699
AD
250
251/**
252 * PCRE for XML attributes
253 */
254define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
255
256/**
257 * XML Namespace
258 */
259define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
260
261/**
262 * Atom 1.0 Namespace
263 */
264define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
265
266/**
267 * Atom 0.3 Namespace
268 */
269define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
270
271/**
272 * RDF Namespace
273 */
274define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
275
276/**
277 * RSS 0.90 Namespace
278 */
279define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
280
281/**
282 * RSS 1.0 Namespace
283 */
284define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
285
286/**
287 * RSS 1.0 Content Module Namespace
288 */
289define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
290
291/**
292 * DC 1.0 Namespace
293 */
294define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
295
296/**
297 * DC 1.1 Namespace
298 */
299define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
300
301/**
302 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
303 */
304define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
305
306/**
307 * GeoRSS Namespace
308 */
309define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
310
311/**
312 * Media RSS Namespace
313 */
314define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
315
3cae90e1
AD
316/**
317 * Wrong Media RSS Namespace
318 */
319define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
320
f2f7b699
AD
321/**
322 * iTunes RSS Namespace
323 */
324define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
325
326/**
327 * XHTML Namespace
328 */
329define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
330
331/**
332 * IANA Link Relations Registry
333 */
334define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
335
336/**
337 * Whether we're running on PHP5
338 */
339define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
340
6d7d21a0
AD
341/**
342 * No file source
343 */
344define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
345
346/**
347 * Remote file source
348 */
349define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
350
351/**
352 * Local file source
353 */
354define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
355
356/**
357 * fsockopen() file source
358 */
359define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
360
361/**
362 * cURL file source
363 */
364define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
365
366/**
367 * file_get_contents() file source
368 */
369define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
370
f2f7b699
AD
371/**
372 * SimplePie
373 *
374 * @package SimplePie
375 * @version "Razzleberry"
376 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
377 * @author Ryan Parman
378 * @author Geoffrey Sneddon
379 * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
380 */
381class SimplePie
382{
383 /**
384 * @var array Raw data
385 * @access private
386 */
387 var $data = array();
388
389 /**
390 * @var mixed Error string
391 * @access private
392 */
393 var $error;
394
395 /**
396 * @var object Instance of SimplePie_Sanitize (or other class)
397 * @see SimplePie::set_sanitize_class()
398 * @access private
399 */
400 var $sanitize;
401
402 /**
403 * @var string SimplePie Useragent
404 * @see SimplePie::set_useragent()
405 * @access private
406 */
407 var $useragent = SIMPLEPIE_USERAGENT;
408
409 /**
410 * @var string Feed URL
411 * @see SimplePie::set_feed_url()
412 * @access private
413 */
414 var $feed_url;
415
416 /**
417 * @var object Instance of SimplePie_File to use as a feed
418 * @see SimplePie::set_file()
419 * @access private
420 */
421 var $file;
422
423 /**
424 * @var string Raw feed data
425 * @see SimplePie::set_raw_data()
426 * @access private
427 */
428 var $raw_data;
429
430 /**
431 * @var int Timeout for fetching remote files
432 * @see SimplePie::set_timeout()
433 * @access private
434 */
435 var $timeout = 10;
436
437 /**
438 * @var bool Forces fsockopen() to be used for remote files instead
439 * of cURL, even if a new enough version is installed
440 * @see SimplePie::force_fsockopen()
441 * @access private
442 */
443 var $force_fsockopen = false;
444
6d7d21a0
AD
445 /**
446 * @var bool Force the given data/URL to be treated as a feed no matter what
447 * it appears like
448 * @see SimplePie::force_feed()
449 * @access private
450 */
451 var $force_feed = false;
452
f2f7b699
AD
453 /**
454 * @var bool Enable/Disable XML dump
455 * @see SimplePie::enable_xml_dump()
456 * @access private
457 */
458 var $xml_dump = false;
459
460 /**
461 * @var bool Enable/Disable Caching
462 * @see SimplePie::enable_cache()
463 * @access private
464 */
465 var $cache = true;
466
467 /**
468 * @var int Cache duration (in seconds)
469 * @see SimplePie::set_cache_duration()
470 * @access private
471 */
472 var $cache_duration = 3600;
473
474 /**
475 * @var int Auto-discovery cache duration (in seconds)
476 * @see SimplePie::set_autodiscovery_cache_duration()
477 * @access private
478 */
479 var $autodiscovery_cache_duration = 604800; // 7 Days.
480
481 /**
482 * @var string Cache location (relative to executing script)
483 * @see SimplePie::set_cache_location()
484 * @access private
485 */
486 var $cache_location = './cache';
487
488 /**
489 * @var string Function that creates the cache filename
490 * @see SimplePie::set_cache_name_function()
491 * @access private
492 */
493 var $cache_name_function = 'md5';
494
495 /**
496 * @var bool Reorder feed by date descending
497 * @see SimplePie::enable_order_by_date()
498 * @access private
499 */
500 var $order_by_date = true;
501
502 /**
503 * @var mixed Force input encoding to be set to the follow value
504 * (false, or anything type-cast to false, disables this feature)
505 * @see SimplePie::set_input_encoding()
506 * @access private
507 */
508 var $input_encoding = false;
509
510 /**
511 * @var int Feed Autodiscovery Level
512 * @see SimplePie::set_autodiscovery_level()
513 * @access private
514 */
515 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
516
517 /**
518 * @var string Class used for caching feeds
519 * @see SimplePie::set_cache_class()
520 * @access private
521 */
522 var $cache_class = 'SimplePie_Cache';
523
524 /**
525 * @var string Class used for locating feeds
526 * @see SimplePie::set_locator_class()
527 * @access private
528 */
529 var $locator_class = 'SimplePie_Locator';
530
531 /**
532 * @var string Class used for parsing feeds
533 * @see SimplePie::set_parser_class()
534 * @access private
535 */
536 var $parser_class = 'SimplePie_Parser';
537
538 /**
539 * @var string Class used for fetching feeds
540 * @see SimplePie::set_file_class()
541 * @access private
542 */
543 var $file_class = 'SimplePie_File';
544
545 /**
546 * @var string Class used for items
547 * @see SimplePie::set_item_class()
548 * @access private
549 */
550 var $item_class = 'SimplePie_Item';
551
552 /**
553 * @var string Class used for authors
554 * @see SimplePie::set_author_class()
555 * @access private
556 */
557 var $author_class = 'SimplePie_Author';
558
559 /**
560 * @var string Class used for categories
561 * @see SimplePie::set_category_class()
562 * @access private
563 */
564 var $category_class = 'SimplePie_Category';
565
566 /**
567 * @var string Class used for enclosures
568 * @see SimplePie::set_enclosures_class()
569 * @access private
570 */
571 var $enclosure_class = 'SimplePie_Enclosure';
572
573 /**
574 * @var string Class used for Media RSS <media:text> captions
575 * @see SimplePie::set_caption_class()
576 * @access private
577 */
578 var $caption_class = 'SimplePie_Caption';
579
580 /**
581 * @var string Class used for Media RSS <media:copyright>
582 * @see SimplePie::set_copyright_class()
583 * @access private
584 */
585 var $copyright_class = 'SimplePie_Copyright';
586
587 /**
588 * @var string Class used for Media RSS <media:credit>
589 * @see SimplePie::set_credit_class()
590 * @access private
591 */
592 var $credit_class = 'SimplePie_Credit';
593
594 /**
595 * @var string Class used for Media RSS <media:rating>
596 * @see SimplePie::set_rating_class()
597 * @access private
598 */
599 var $rating_class = 'SimplePie_Rating';
600
601 /**
602 * @var string Class used for Media RSS <media:restriction>
603 * @see SimplePie::set_restriction_class()
604 * @access private
605 */
606 var $restriction_class = 'SimplePie_Restriction';
607
6d7d21a0
AD
608 /**
609 * @var string Class used for content-type sniffing
610 * @see SimplePie::set_content_type_sniffer_class()
611 * @access private
612 */
613 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
614
615 /**
616 * @var string Class used for item sources.
617 * @see SimplePie::set_source_class()
618 * @access private
619 */
620 var $source_class = 'SimplePie_Source';
621
f2f7b699
AD
622 /**
623 * @var mixed Set javascript query string parameter (false, or
624 * anything type-cast to false, disables this feature)
625 * @see SimplePie::set_javascript()
626 * @access private
627 */
628 var $javascript = 'js';
629
630 /**
631 * @var int Maximum number of feeds to check with autodiscovery
632 * @see SimplePie::set_max_checked_feeds()
633 * @access private
634 */
635 var $max_checked_feeds = 10;
636
637 /**
638 * @var string Web-accessible path to the handler_favicon.php file.
639 * @see SimplePie::set_favicon_handler()
640 * @access private
641 */
642 var $favicon_handler = '';
643
644 /**
645 * @var string Web-accessible path to the handler_image.php file.
646 * @see SimplePie::set_image_handler()
647 * @access private
648 */
649 var $image_handler = '';
650
651 /**
652 * @var array Stores the URLs when multiple feeds are being initialized.
653 * @see SimplePie::set_feed_url()
654 * @access private
655 */
656 var $multifeed_url = array();
657
658 /**
659 * @var array Stores SimplePie objects when multiple feeds initialized.
660 * @access private
661 */
662 var $multifeed_objects = array();
663
664 /**
665 * @var array Stores the get_object_vars() array for use with multifeeds.
666 * @see SimplePie::set_feed_url()
667 * @access private
668 */
669 var $config_settings = null;
670
6d7d21a0
AD
671 /**
672 * @var integer Stores the number of items to return per-feed with multifeeds.
673 * @see SimplePie::set_item_limit()
674 * @access private
675 */
676 var $item_limit = 0;
677
f2f7b699
AD
678 /**
679 * @var array Stores the default attributes to be stripped by strip_attributes().
680 * @see SimplePie::strip_attributes()
681 * @access private
682 */
683 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
684
685 /**
686 * @var array Stores the default tags to be stripped by strip_htmltags().
687 * @see SimplePie::strip_htmltags()
688 * @access private
689 */
690 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
691
692 /**
693 * The SimplePie class contains feed level data and options
694 *
695 * There are two ways that you can create a new SimplePie object. The first
696 * is by passing a feed URL as a parameter to the SimplePie constructor
697 * (as well as optionally setting the cache location and cache expiry). This
698 * will initialise the whole feed with all of the default settings, and you
699 * can begin accessing methods and properties immediately.
700 *
701 * The second way is to create the SimplePie object with no parameters
702 * at all. This will enable you to set configuration options. After setting
703 * them, you must initialise the feed using $feed->init(). At that point the
704 * object's methods and properties will be available to you. This format is
705 * what is used throughout this documentation.
706 *
707 * @access public
708 * @since 1.0 Preview Release
709 * @param string $feed_url This is the URL you want to parse.
710 * @param string $cache_location This is where you want the cache to be stored.
711 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
712 */
713 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
714 {
715 // Other objects, instances created here so we can set options on them
716 $this->sanitize =& new SimplePie_Sanitize;
717
718 // Set options if they're passed to the constructor
719 if ($cache_location !== null)
720 {
721 $this->set_cache_location($cache_location);
722 }
723
724 if ($cache_duration !== null)
725 {
726 $this->set_cache_duration($cache_duration);
727 }
728
729 // Only init the script if we're passed a feed URL
730 if ($feed_url !== null)
731 {
732 $this->set_feed_url($feed_url);
733 $this->init();
734 }
735 }
736
737 /**
738 * Used for converting object to a string
739 */
740 function __toString()
741 {
742 return md5(serialize($this->data));
743 }
6d7d21a0
AD
744
745 /**
746 * Remove items that link back to this before destroying this object
747 */
748 function __destruct()
749 {
750 if (!empty($this->data['items']))
751 {
752 foreach ($this->data['items'] as $item)
753 {
754 $item->__destruct();
755 }
756 unset($this->data['items']);
757 }
758 if (!empty($this->data['ordered_items']))
759 {
760 foreach ($this->data['ordered_items'] as $item)
761 {
762 $item->__destruct();
763 }
764 unset($this->data['ordered_items']);
765 }
766 }
767
768 /**
769 * Force the given data/URL to be treated as a feed no matter what it
770 * appears like
771 *
772 * @access public
773 * @since 1.1
774 * @param bool $enable Force the given data/URL to be treated as a feed
775 */
776 function force_feed($enable = false)
777 {
778 $this->force_feed = (bool) $enable;
779 }
f2f7b699
AD
780
781 /**
782 * This is the URL of the feed you want to parse.
783 *
784 * This allows you to enter the URL of the feed you want to parse, or the
785 * website you want to try to use auto-discovery on. This takes priority
786 * over any set raw data.
787 *
788 * You can set multiple feeds to mash together by passing an array instead
789 * of a string for the $url. Remember that with each additional feed comes
790 * additional processing and resources.
791 *
792 * @access public
793 * @since 1.0 Preview Release
794 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
795 * @see SimplePie::set_raw_data()
796 */
797 function set_feed_url($url)
798 {
799 if (is_array($url))
800 {
801 $this->multifeed_url = array();
802 foreach ($url as $value)
803 {
804 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
805 }
806 }
807 else
808 {
809 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
810 }
811 }
812
813 /**
814 * Provides an instance of SimplePie_File to use as a feed
815 *
816 * @access public
817 * @param object &$file Instance of SimplePie_File (or subclass)
818 * @return bool True on success, false on failure
819 */
820 function set_file(&$file)
821 {
6d7d21a0 822 if (is_a($file, 'SimplePie_File'))
f2f7b699
AD
823 {
824 $this->feed_url = $file->url;
825 $this->file =& $file;
826 return true;
827 }
828 return false;
829 }
830
831 /**
832 * Allows you to use a string of RSS/Atom data instead of a remote feed.
833 *
834 * If you have a feed available as a string in PHP, you can tell SimplePie
835 * to parse that data string instead of a remote feed. Any set feed URL
836 * takes precedence.
837 *
838 * @access public
839 * @since 1.0 Beta 3
840 * @param string $data RSS or Atom data as a string.
841 * @see SimplePie::set_feed_url()
842 */
843 function set_raw_data($data)
844 {
3cae90e1 845 $this->raw_data = $data;
f2f7b699
AD
846 }
847
848 /**
849 * Allows you to override the default timeout for fetching remote feeds.
850 *
851 * This allows you to change the maximum time the feed's server to respond
852 * and send the feed back.
853 *
854 * @access public
855 * @since 1.0 Beta 3
856 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
857 */
858 function set_timeout($timeout = 10)
859 {
860 $this->timeout = (int) $timeout;
861 }
862
863 /**
864 * Forces SimplePie to use fsockopen() instead of the preferred cURL
865 * functions.
866 *
867 * @access public
868 * @since 1.0 Beta 3
869 * @param bool $enable Force fsockopen() to be used
870 */
871 function force_fsockopen($enable = false)
872 {
873 $this->force_fsockopen = (bool) $enable;
874 }
875
876 /**
877 * Outputs the raw XML content of the feed, after it has gone through
878 * SimplePie's filters.
879 *
880 * Used only for debugging, this function will output the XML content as
881 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
882 * before trying to parse it. Many parts of the feed are re-written in
883 * memory, and in the end, you have a parsable feed. XML dump shows you the
884 * actual XML that SimplePie tries to parse, which may or may not be very
885 * different from the original feed.
886 *
887 * @access public
888 * @since 1.0 Preview Release
889 * @param bool $enable Enable XML dump
890 */
891 function enable_xml_dump($enable = false)
892 {
893 $this->xml_dump = (bool) $enable;
894 }
895
896 /**
897 * Enables/disables caching in SimplePie.
898 *
899 * This option allows you to disable caching all-together in SimplePie.
900 * However, disabling the cache can lead to longer load times.
901 *
902 * @access public
903 * @since 1.0 Preview Release
904 * @param bool $enable Enable caching
905 */
906 function enable_cache($enable = true)
907 {
908 $this->cache = (bool) $enable;
909 }
910
911 /**
912 * Set the length of time (in seconds) that the contents of a feed
913 * will be cached.
914 *
915 * @access public
916 * @param int $seconds The feed content cache duration.
917 */
918 function set_cache_duration($seconds = 3600)
919 {
920 $this->cache_duration = (int) $seconds;
921 }
922
923 /**
924 * Set the length of time (in seconds) that the autodiscovered feed
925 * URL will be cached.
926 *
927 * @access public
928 * @param int $seconds The autodiscovered feed URL cache duration.
929 */
930 function set_autodiscovery_cache_duration($seconds = 604800)
931 {
932 $this->autodiscovery_cache_duration = (int) $seconds;
933 }
934
935 /**
936 * Set the file system location where the cached files should be stored.
937 *
938 * @access public
939 * @param string $location The file system location.
940 */
941 function set_cache_location($location = './cache')
942 {
943 $this->cache_location = (string) $location;
944 }
945
946 /**
947 * Determines whether feed items should be sorted into reverse chronological order.
948 *
949 * @access public
950 * @param bool $enable Sort as reverse chronological order.
951 */
952 function enable_order_by_date($enable = true)
953 {
954 $this->order_by_date = (bool) $enable;
955 }
956
957 /**
958 * Allows you to override the character encoding reported by the feed.
959 *
960 * @access public
961 * @param string $encoding Character encoding.
962 */
963 function set_input_encoding($encoding = false)
964 {
965 if ($encoding)
966 {
967 $this->input_encoding = (string) $encoding;
968 }
969 else
970 {
971 $this->input_encoding = false;
972 }
973 }
974
975 /**
976 * Set how much feed autodiscovery to do
977 *
978 * @access public
979 * @see SIMPLEPIE_LOCATOR_NONE
980 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
981 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
982 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
983 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
984 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
985 * @see SIMPLEPIE_LOCATOR_ALL
986 * @param int $level Feed Autodiscovery Level (level can be a
987 * combination of the above constants, see bitwise OR operator)
988 */
989 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
990 {
991 $this->autodiscovery = (int) $level;
992 }
993
994 /**
995 * Allows you to change which class SimplePie uses for caching.
996 * Useful when you are overloading or extending SimplePie's default classes.
997 *
998 * @access public
999 * @param string $class Name of custom class.
1000 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1001 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1002 */
1003 function set_cache_class($class = 'SimplePie_Cache')
1004 {
1005 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1006 {
1007 $this->cache_class = $class;
1008 return true;
1009 }
1010 return false;
1011 }
1012
1013 /**
1014 * Allows you to change which class SimplePie uses for auto-discovery.
1015 * Useful when you are overloading or extending SimplePie's default classes.
1016 *
1017 * @access public
1018 * @param string $class Name of custom class.
1019 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1020 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1021 */
1022 function set_locator_class($class = 'SimplePie_Locator')
1023 {
1024 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1025 {
1026 $this->locator_class = $class;
1027 return true;
1028 }
1029 return false;
1030 }
1031
1032 /**
1033 * Allows you to change which class SimplePie uses for XML parsing.
1034 * Useful when you are overloading or extending SimplePie's default classes.
1035 *
1036 * @access public
1037 * @param string $class Name of custom class.
1038 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1039 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1040 */
1041 function set_parser_class($class = 'SimplePie_Parser')
1042 {
1043 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1044 {
1045 $this->parser_class = $class;
1046 return true;
1047 }
1048 return false;
1049 }
1050
1051 /**
1052 * Allows you to change which class SimplePie uses for remote file fetching.
1053 * Useful when you are overloading or extending SimplePie's default classes.
1054 *
1055 * @access public
1056 * @param string $class Name of custom class.
1057 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1058 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1059 */
1060 function set_file_class($class = 'SimplePie_File')
1061 {
1062 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1063 {
1064 $this->file_class = $class;
1065 return true;
1066 }
1067 return false;
1068 }
1069
1070 /**
1071 * Allows you to change which class SimplePie uses for data sanitization.
1072 * Useful when you are overloading or extending SimplePie's default classes.
1073 *
1074 * @access public
1075 * @param string $class Name of custom class.
1076 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1077 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1078 */
1079 function set_sanitize_class($class = 'SimplePie_Sanitize')
1080 {
1081 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1082 {
1083 $this->sanitize =& new $class;
1084 return true;
1085 }
1086 return false;
1087 }
1088
1089 /**
1090 * Allows you to change which class SimplePie uses for handling feed items.
1091 * Useful when you are overloading or extending SimplePie's default classes.
1092 *
1093 * @access public
1094 * @param string $class Name of custom class.
1095 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1096 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1097 */
1098 function set_item_class($class = 'SimplePie_Item')
1099 {
1100 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1101 {
1102 $this->item_class = $class;
1103 return true;
1104 }
1105 return false;
1106 }
1107
1108 /**
1109 * Allows you to change which class SimplePie uses for handling author data.
1110 * Useful when you are overloading or extending SimplePie's default classes.
1111 *
1112 * @access public
1113 * @param string $class Name of custom class.
1114 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1115 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1116 */
1117 function set_author_class($class = 'SimplePie_Author')
1118 {
1119 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1120 {
1121 $this->author_class = $class;
1122 return true;
1123 }
1124 return false;
1125 }
1126
1127 /**
1128 * Allows you to change which class SimplePie uses for handling category data.
1129 * Useful when you are overloading or extending SimplePie's default classes.
1130 *
1131 * @access public
1132 * @param string $class Name of custom class.
1133 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1134 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1135 */
1136 function set_category_class($class = 'SimplePie_Category')
1137 {
1138 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1139 {
1140 $this->category_class = $class;
1141 return true;
1142 }
1143 return false;
1144 }
1145
1146 /**
1147 * Allows you to change which class SimplePie uses for feed enclosures.
1148 * Useful when you are overloading or extending SimplePie's default classes.
1149 *
1150 * @access public
1151 * @param string $class Name of custom class.
1152 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1153 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1154 */
1155 function set_enclosure_class($class = 'SimplePie_Enclosure')
1156 {
1157 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1158 {
1159 $this->enclosure_class = $class;
1160 return true;
1161 }
1162 return false;
1163 }
1164
1165 /**
1166 * Allows you to change which class SimplePie uses for <media:text> captions
1167 * Useful when you are overloading or extending SimplePie's default classes.
1168 *
1169 * @access public
1170 * @param string $class Name of custom class.
1171 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1172 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1173 */
1174 function set_caption_class($class = 'SimplePie_Caption')
1175 {
1176 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1177 {
1178 $this->caption_class = $class;
1179 return true;
1180 }
1181 return false;
1182 }
1183
1184 /**
1185 * Allows you to change which class SimplePie uses for <media:copyright>
1186 * Useful when you are overloading or extending SimplePie's default classes.
1187 *
1188 * @access public
1189 * @param string $class Name of custom class.
1190 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1191 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1192 */
1193 function set_copyright_class($class = 'SimplePie_Copyright')
1194 {
1195 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1196 {
1197 $this->copyright_class = $class;
1198 return true;
1199 }
1200 return false;
1201 }
1202
1203 /**
1204 * Allows you to change which class SimplePie uses for <media:credit>
1205 * Useful when you are overloading or extending SimplePie's default classes.
1206 *
1207 * @access public
1208 * @param string $class Name of custom class.
1209 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1210 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1211 */
1212 function set_credit_class($class = 'SimplePie_Credit')
1213 {
1214 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1215 {
1216 $this->credit_class = $class;
1217 return true;
1218 }
1219 return false;
1220 }
1221
1222 /**
1223 * Allows you to change which class SimplePie uses for <media:rating>
1224 * Useful when you are overloading or extending SimplePie's default classes.
1225 *
1226 * @access public
1227 * @param string $class Name of custom class.
1228 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1229 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1230 */
1231 function set_rating_class($class = 'SimplePie_Rating')
1232 {
1233 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1234 {
1235 $this->rating_class = $class;
1236 return true;
1237 }
1238 return false;
1239 }
1240
1241 /**
1242 * Allows you to change which class SimplePie uses for <media:restriction>
1243 * Useful when you are overloading or extending SimplePie's default classes.
1244 *
1245 * @access public
1246 * @param string $class Name of custom class.
1247 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1248 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1249 */
1250 function set_restriction_class($class = 'SimplePie_Restriction')
1251 {
1252 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1253 {
1254 $this->restriction_class = $class;
1255 return true;
1256 }
1257 return false;
1258 }
1259
6d7d21a0
AD
1260 /**
1261 * Allows you to change which class SimplePie uses for content-type sniffing.
1262 * Useful when you are overloading or extending SimplePie's default classes.
1263 *
1264 * @access public
1265 * @param string $class Name of custom class.
1266 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1267 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1268 */
1269 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1270 {
1271 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1272 {
1273 $this->content_type_sniffer_class = $class;
1274 return true;
1275 }
1276 return false;
1277 }
1278
1279 /**
1280 * Allows you to change which class SimplePie uses item sources.
1281 * Useful when you are overloading or extending SimplePie's default classes.
1282 *
1283 * @access public
1284 * @param string $class Name of custom class.
1285 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1286 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1287 */
1288 function set_source_class($class = 'SimplePie_Source')
1289 {
1290 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1291 {
1292 $this->source_class = $class;
1293 return true;
1294 }
1295 return false;
1296 }
1297
f2f7b699
AD
1298 /**
1299 * Allows you to override the default user agent string.
1300 *
1301 * @access public
1302 * @param string $ua New user agent string.
1303 */
1304 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1305 {
1306 $this->useragent = (string) $ua;
1307 }
1308
1309 /**
1310 * Set callback function to create cache filename with
1311 *
1312 * @access public
1313 * @param mixed $function Callback function
1314 */
1315 function set_cache_name_function($function = 'md5')
1316 {
1317 if (is_callable($function))
1318 {
1319 $this->cache_name_function = $function;
1320 }
1321 }
1322
1323 /**
1324 * Set javascript query string parameter
1325 *
1326 * @access public
1327 * @param mixed $get Javascript query string parameter
1328 */
1329 function set_javascript($get = 'js')
1330 {
1331 if ($get)
1332 {
1333 $this->javascript = (string) $get;
1334 }
1335 else
1336 {
1337 $this->javascript = false;
1338 }
1339 }
1340
1341 /**
1342 * Set options to make SP as fast as possible. Forgoes a
1343 * substantial amount of data sanitization in favor of speed.
1344 *
1345 * @access public
1346 * @param bool $set Whether to set them or not
1347 */
1348 function set_stupidly_fast($set = false)
1349 {
1350 if ($set)
1351 {
1352 $this->enable_order_by_date(false);
1353 $this->remove_div(false);
1354 $this->strip_comments(false);
1355 $this->strip_htmltags(false);
1356 $this->strip_attributes(false);
1357 $this->set_image_handler(false);
1358 }
1359 }
1360
1361 /**
1362 * Set maximum number of feeds to check with autodiscovery
1363 *
1364 * @access public
1365 * @param int $max Maximum number of feeds to check
1366 */
1367 function set_max_checked_feeds($max = 10)
1368 {
1369 $this->max_checked_feeds = (int) $max;
1370 }
1371
1372 function remove_div($enable = true)
1373 {
1374 $this->sanitize->remove_div($enable);
1375 }
1376
1377 function strip_htmltags($tags = '', $encode = null)
1378 {
1379 if ($tags === '')
1380 {
1381 $tags = $this->strip_htmltags;
1382 }
1383 $this->sanitize->strip_htmltags($tags);
1384 if ($encode !== null)
1385 {
1386 $this->sanitize->encode_instead_of_strip($tags);
1387 }
1388 }
1389
1390 function encode_instead_of_strip($enable = true)
1391 {
1392 $this->sanitize->encode_instead_of_strip($enable);
1393 }
1394
1395 function strip_attributes($attribs = '')
1396 {
1397 if ($attribs === '')
1398 {
1399 $attribs = $this->strip_attributes;
1400 }
1401 $this->sanitize->strip_attributes($attribs);
1402 }
1403
1404 function set_output_encoding($encoding = 'UTF-8')
1405 {
1406 $this->sanitize->set_output_encoding($encoding);
1407 }
1408
1409 function strip_comments($strip = false)
1410 {
1411 $this->sanitize->strip_comments($strip);
1412 }
1413
1414 /**
1415 * Set element/attribute key/value pairs of HTML attributes
1416 * containing URLs that need to be resolved relative to the feed
1417 *
1418 * @access public
1419 * @since 1.0
1420 * @param array $element_attribute Element/attribute key/value pairs
1421 */
1422 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'))
1423 {
1424 $this->sanitize->set_url_replacements($element_attribute);
1425 }
1426
1427 /**
1428 * Set the handler to enable the display of cached favicons.
1429 *
1430 * @access public
1431 * @param str $page Web-accessible path to the handler_favicon.php file.
1432 * @param str $qs The query string that the value should be passed to.
1433 */
1434 function set_favicon_handler($page = false, $qs = 'i')
1435 {
1436 if ($page != false)
1437 {
1438 $this->favicon_handler = $page . '?' . $qs . '=';
1439 }
1440 else
1441 {
1442 $this->favicon_handler = '';
1443 }
1444 }
1445
1446 /**
1447 * Set the handler to enable the display of cached images.
1448 *
1449 * @access public
1450 * @param str $page Web-accessible path to the handler_image.php file.
1451 * @param str $qs The query string that the value should be passed to.
1452 */
1453 function set_image_handler($page = false, $qs = 'i')
1454 {
1455 if ($page != false)
1456 {
1457 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1458 }
1459 else
1460 {
1461 $this->image_handler = '';
1462 }
1463 }
1464
6d7d21a0
AD
1465 /**
1466 * Set the limit for items returned per-feed with multifeeds.
1467 *
1468 * @access public
1469 * @param integer $limit The maximum number of items to return.
1470 */
1471 function set_item_limit($limit = 0)
1472 {
1473 $this->item_limit = (int) $limit;
1474 }
1475
f2f7b699
AD
1476 function init()
1477 {
6d7d21a0 1478 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
f2f7b699
AD
1479 {
1480 return false;
1481 }
1482 if (isset($_GET[$this->javascript]))
1483 {
1484 if (function_exists('ob_gzhandler'))
1485 {
1486 ob_start('ob_gzhandler');
1487 }
1488 header('Content-type: text/javascript; charset: UTF-8');
1489 header('Cache-Control: must-revalidate');
1490 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1491 ?>
1492function embed_odeo(link) {
1493 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>');
1494}
1495
1496function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1497 if (placeholder != '') {
1498 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>');
1499 }
1500 else {
1501 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>');
1502 }
1503}
1504
1505function embed_flash(bgcolor, width, height, link, loop, type) {
1506 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>');
1507}
1508
1509function embed_flv(width, height, link, placeholder, loop, player) {
1510 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>');
1511}
1512
1513function embed_wmedia(width, height, link) {
1514 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1515}
1516 <?php
1517 exit;
1518 }
1519
1520 // Pass whatever was set with config options over to the sanitizer.
1521 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1522 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1523
1524 if ($this->feed_url !== null || $this->raw_data !== null)
1525 {
1526 $this->data = array();
1527 $this->multifeed_objects = array();
1528 $cache = false;
1529
1530 if ($this->feed_url !== null)
1531 {
1532 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1533 // Decide whether to enable caching
1534 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1535 {
6d7d21a0 1536 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
f2f7b699
AD
1537 }
1538 // If it's enabled and we don't want an XML dump, use the cache
1539 if ($cache && !$this->xml_dump)
1540 {
1541 // Load the Cache
1542 $this->data = $cache->load();
1543 if (!empty($this->data))
1544 {
1545 // If the cache is for an outdated build of SimplePie
1546 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1547 {
1548 $cache->unlink();
1549 $this->data = array();
1550 }
1551 // If we've hit a collision just rerun it with caching disabled
1552 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1553 {
1554 $cache = false;
1555 $this->data = array();
1556 }
1557 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1558 elseif (isset($this->data['feed_url']))
1559 {
1560 // If the autodiscovery cache is still valid use it.
1561 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1562 {
1563 // Do not need to do feed autodiscovery yet.
1564 if ($this->data['feed_url'] == $this->data['url'])
1565 {
1566 $cache->unlink();
1567 $this->data = array();
1568 }
1569 else
1570 {
1571 $this->set_feed_url($this->data['feed_url']);
1572 return $this->init();
1573 }
1574 }
1575 }
1576 // Check if the cache has been updated
1577 elseif ($cache->mtime() + $this->cache_duration < time())
1578 {
1579 // If we have last-modified and/or etag set
1580 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1581 {
1582 $headers = array();
1583 if (isset($this->data['headers']['last-modified']))
1584 {
1585 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1586 }
1587 if (isset($this->data['headers']['etag']))
1588 {
6d7d21a0 1589 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
f2f7b699
AD
1590 }
1591 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1592 if ($file->success)
1593 {
1594 if ($file->status_code == 304)
1595 {
1596 $cache->touch();
1597 return true;
1598 }
1599 else
1600 {
1601 $headers = $file->headers;
1602 }
1603 }
1604 else
1605 {
1606 unset($file);
1607 }
1608 }
1609 }
1610 // If the cache is still valid, just return true
1611 else
1612 {
1613 return true;
1614 }
1615 }
1616 // If the cache is empty, delete it
1617 else
1618 {
1619 $cache->unlink();
1620 $this->data = array();
1621 }
1622 }
1623 // 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.
1624 if (!isset($file))
1625 {
6d7d21a0 1626 if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
f2f7b699
AD
1627 {
1628 $file =& $this->file;
1629 }
1630 else
1631 {
1632 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1633 }
1634 }
1635 // If the file connection has an error, set SimplePie::error to that and quit
1636 if (!$file->success)
1637 {
1638 $this->error = $file->error;
1639 if (!empty($this->data))
1640 {
1641 return true;
1642 }
1643 else
1644 {
1645 return false;
1646 }
1647 }
1648
6d7d21a0 1649 if (!$this->force_feed)
f2f7b699 1650 {
6d7d21a0
AD
1651 // Check if the supplied URL is a feed, if it isn't, look for it.
1652 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1653 if (!$locate->is_feed($file))
f2f7b699 1654 {
6d7d21a0
AD
1655 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1656 unset($file);
1657 if ($file = $locate->find($this->autodiscovery))
f2f7b699 1658 {
6d7d21a0 1659 if ($cache)
f2f7b699 1660 {
6d7d21a0
AD
1661 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1662 if (!$cache->save($this))
1663 {
1664 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1665 }
1666 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
f2f7b699 1667 }
6d7d21a0
AD
1668 $this->feed_url = $file->url;
1669 }
1670 else
1671 {
1672 $this->error = "A feed could not be found at $this->feed_url";
1673 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1674 return false;
f2f7b699 1675 }
f2f7b699 1676 }
6d7d21a0 1677 $locate = null;
f2f7b699 1678 }
f2f7b699
AD
1679
1680 $headers = $file->headers;
6d7d21a0
AD
1681 $data = $file->body;
1682 $sniffer = new $this->content_type_sniffer_class($file);
1683 $sniffed = $sniffer->get_type();
f2f7b699
AD
1684 }
1685 else
1686 {
1687 $data = $this->raw_data;
1688 }
6d7d21a0
AD
1689
1690 // Set up array of possible encodings
1691 $encodings = array();
f2f7b699
AD
1692
1693 // First check to see if input has been overridden.
1694 if ($this->input_encoding !== false)
1695 {
6d7d21a0 1696 $encodings[] = $this->input_encoding;
f2f7b699 1697 }
6d7d21a0
AD
1698
1699 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1700 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1701
1702 // RFC 3023 (only applies to sniffed content)
1703 if (isset($sniffed))
f2f7b699 1704 {
6d7d21a0
AD
1705 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1706 {
1707 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1708 {
1709 $encodings[] = strtoupper($charset[1]);
1710 }
1711 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1712 $encodings[] = 'UTF-8';
1713 }
1714 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1715 {
1716 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1717 {
1718 $encodings[] = $charset[1];
1719 }
1720 $encodings[] = 'US-ASCII';
1721 }
1722 // Text MIME-type default
1723 elseif (substr($sniffed, 0, 5) === 'text/')
1724 {
1725 $encodings[] = 'US-ASCII';
1726 }
f2f7b699 1727 }
6d7d21a0
AD
1728
1729 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1730 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1731 $encodings[] = 'UTF-8';
1732 $encodings[] = 'ISO-8859-1';
1733
1734 // There's no point in trying an encoding twice
1735 $encodings = array_unique($encodings);
1736
1737 // If we want the XML, just output that with the most likely encoding and quit
f2f7b699
AD
1738 if ($this->xml_dump)
1739 {
6d7d21a0 1740 header('Content-type: text/xml; charset=' . $encodings[0]);
f2f7b699
AD
1741 echo $data;
1742 exit;
1743 }
6d7d21a0
AD
1744
1745 // Loop through each possible encoding, till we return something, or run out of possibilities
1746 foreach ($encodings as $encoding)
f2f7b699 1747 {
6d7d21a0
AD
1748 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1749 $utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8');
1750
1751 // Create new parser
1752 $parser =& new $this->parser_class();
1753
1754 // If it's parsed fine
1755 if ($parser->parse($utf8_data, 'UTF-8'))
f2f7b699 1756 {
6d7d21a0
AD
1757 $this->data = $parser->get_data();
1758 if (isset($this->data['child']))
f2f7b699 1759 {
6d7d21a0
AD
1760 if (isset($headers))
1761 {
1762 $this->data['headers'] = $headers;
1763 }
1764 $this->data['build'] = SIMPLEPIE_BUILD;
1765
1766 // Cache the file if caching is enabled
1767 if ($cache && !$cache->save($this))
1768 {
1769 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1770 }
1771 return true;
f2f7b699 1772 }
6d7d21a0 1773 else
f2f7b699 1774 {
6d7d21a0
AD
1775 $this->error = "A feed could not be found at $this->feed_url";
1776 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1777 return false;
f2f7b699 1778 }
f2f7b699
AD
1779 }
1780 }
6d7d21a0
AD
1781 // We have an error, just set SimplePie::error to it and quit
1782 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1783 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1784 return false;
f2f7b699
AD
1785 }
1786 elseif (!empty($this->multifeed_url))
1787 {
1788 $i = 0;
1789 $success = 0;
1790 $this->multifeed_objects = array();
1791 foreach ($this->multifeed_url as $url)
1792 {
1793 if (SIMPLEPIE_PHP5)
1794 {
1795 // This keyword needs to defy coding standards for PHP4 compatibility
1796 $this->multifeed_objects[$i] = clone($this);
1797 }
1798 else
1799 {
1800 $this->multifeed_objects[$i] = $this;
1801 }
1802 $this->multifeed_objects[$i]->set_feed_url($url);
1803 $success |= $this->multifeed_objects[$i]->init();
1804 $i++;
1805 }
1806 return (bool) $success;
1807 }
1808 else
1809 {
1810 return false;
1811 }
1812 }
1813
1814 /**
1815 * Return the error message for the occured error
1816 *
1817 * @access public
1818 * @return string Error message
1819 */
1820 function error()
1821 {
1822 return $this->error;
1823 }
1824
1825 function get_encoding()
1826 {
1827 return $this->sanitize->output_encoding;
1828 }
1829
1830 function handle_content_type($mime = 'text/html')
1831 {
1832 if (!headers_sent())
1833 {
1834 $header = "Content-type: $mime;";
1835 if ($this->get_encoding())
1836 {
1837 $header .= ' charset=' . $this->get_encoding();
1838 }
1839 else
1840 {
1841 $header .= ' charset=UTF-8';
1842 }
1843 header($header);
1844 }
1845 }
1846
1847 function get_type()
1848 {
1849 if (!isset($this->data['type']))
1850 {
1851 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1852 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1853 {
1854 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1855 }
1856 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1857 {
1858 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1859 }
1860 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1861 {
1862 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1863 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1864 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1865 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1866 {
1867 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1868 }
1869 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1870 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1871 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1872 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1873 {
1874 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1875 }
1876 }
1877 elseif (isset($this->data['child']['']['rss']))
1878 {
1879 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1880 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1881 {
1882 switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1883 {
1884 case '0.91':
1885 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1886 if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1887 {
1888 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1889 {
1890 case '0':
1891 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1892 break;
1893
1894 case '24':
1895 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1896 break;
1897 }
1898 }
1899 break;
1900
1901 case '0.92':
1902 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1903 break;
1904
1905 case '0.93':
1906 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1907 break;
1908
1909 case '0.94':
1910 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1911 break;
1912
1913 case '2.0':
1914 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1915 break;
1916 }
1917 }
1918 }
1919 else
1920 {
1921 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1922 }
1923 }
1924 return $this->data['type'];
1925 }
1926
1927 /**
1928 * Returns the URL for the favicon of the feed's website.
1929 *
6d7d21a0 1930 * @todo Cache atom:icon
f2f7b699
AD
1931 * @access public
1932 * @since 1.0
1933 */
1934 function get_favicon()
1935 {
1936 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1937 {
1938 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1939 }
1940 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1941 {
1942 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1943
1944 if ($this->cache && $this->favicon_handler)
1945 {
6d7d21a0
AD
1946 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1947 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
f2f7b699
AD
1948
1949 if ($cache->load())
1950 {
6d7d21a0 1951 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
f2f7b699
AD
1952 }
1953 else
1954 {
1955 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1956
1957 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1958 {
6d7d21a0
AD
1959 $sniffer = new $this->content_type_sniffer_class($file);
1960 if (substr($sniffer->get_type(), 0, 6) === 'image/')
f2f7b699 1961 {
6d7d21a0
AD
1962 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1963 {
1964 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1965 }
1966 else
1967 {
1968 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1969 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1970 }
f2f7b699
AD
1971 }
1972 }
1973 }
1974 }
1975 else
1976 {
1977 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1978 }
1979 }
1980 return false;
1981 }
1982
1983 /**
1984 * @todo If we have a perm redirect we should return the new URL
1985 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1986 * @todo Also, |atom:link|@rel=self
1987 */
1988 function subscribe_url()
1989 {
1990 if ($this->feed_url !== null)
1991 {
1992 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1993 }
1994 else
1995 {
1996 return null;
1997 }
1998 }
1999
2000 function subscribe_feed()
2001 {
2002 if ($this->feed_url !== null)
2003 {
2004 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2005 }
2006 else
2007 {
2008 return null;
2009 }
2010 }
2011
2012 function subscribe_outlook()
2013 {
2014 if ($this->feed_url !== null)
2015 {
2016 return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2017 }
2018 else
2019 {
2020 return null;
2021 }
2022 }
2023
2024 function subscribe_podcast()
2025 {
2026 if ($this->feed_url !== null)
2027 {
2028 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2029 }
2030 else
2031 {
2032 return null;
2033 }
2034 }
2035
2036 function subscribe_itunes()
2037 {
2038 if ($this->feed_url !== null)
2039 {
2040 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2041 }
2042 else
2043 {
2044 return null;
2045 }
2046 }
2047
2048 /**
2049 * Creates the subscribe_* methods' return data
2050 *
2051 * @access private
2052 * @param string $feed_url String to prefix to the feed URL
2053 * @param string $site_url String to prefix to the site URL (and
2054 * suffix to the feed URL)
2055 * @return mixed URL if feed exists, false otherwise
2056 */
2057 function subscribe_service($feed_url, $site_url = null)
2058 {
2059 if ($this->subscribe_url())
2060 {
6d7d21a0 2061 $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
f2f7b699
AD
2062 if ($site_url !== null && $this->get_link() !== null)
2063 {
2064 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2065 }
2066 return $return;
2067 }
2068 else
2069 {
2070 return null;
2071 }
2072 }
2073
2074 function subscribe_aol()
2075 {
2076 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2077 }
2078
2079 function subscribe_bloglines()
2080 {
2081 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2082 }
2083
2084 function subscribe_eskobo()
2085 {
2086 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2087 }
2088
2089 function subscribe_feedfeeds()
2090 {
2091 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2092 }
2093
2094 function subscribe_feedster()
2095 {
2096 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2097 }
2098
2099 function subscribe_google()
2100 {
2101 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2102 }
2103
2104 function subscribe_gritwire()
2105 {
2106 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2107 }
2108
2109 function subscribe_msn()
2110 {
2111 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2112 }
2113
2114 function subscribe_netvibes()
2115 {
2116 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2117 }
2118
2119 function subscribe_newsburst()
2120 {
2121 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2122 }
2123
2124 function subscribe_newsgator()
2125 {
2126 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2127 }
2128
2129 function subscribe_odeo()
2130 {
2131 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2132 }
2133
2134 function subscribe_podnova()
2135 {
2136 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2137 }
2138
2139 function subscribe_rojo()
2140 {
2141 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2142 }
2143
2144 function subscribe_yahoo()
2145 {
2146 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2147 }
2148
2149 function get_feed_tags($namespace, $tag)
2150 {
2151 $type = $this->get_type();
2152 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2153 {
2154 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2155 {
2156 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2157 }
2158 }
2159 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2160 {
2161 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2162 {
2163 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2164 }
2165 }
2166 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2167 {
2168 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2169 {
2170 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2171 }
2172 }
2173 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2174 {
2175 if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2176 {
2177 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2178 }
2179 }
2180 return null;
2181 }
2182
2183 function get_channel_tags($namespace, $tag)
2184 {
2185 $type = $this->get_type();
2186 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2187 {
2188 if ($return = $this->get_feed_tags($namespace, $tag))
2189 {
2190 return $return;
2191 }
2192 }
2193 if ($type & SIMPLEPIE_TYPE_RSS_10)
2194 {
2195 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2196 {
2197 if (isset($channel[0]['child'][$namespace][$tag]))
2198 {
2199 return $channel[0]['child'][$namespace][$tag];
2200 }
2201 }
2202 }
2203 if ($type & SIMPLEPIE_TYPE_RSS_090)
2204 {
2205 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2206 {
2207 if (isset($channel[0]['child'][$namespace][$tag]))
2208 {
2209 return $channel[0]['child'][$namespace][$tag];
2210 }
2211 }
2212 }
2213 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2214 {
2215 if ($channel = $this->get_feed_tags('', 'channel'))
2216 {
2217 if (isset($channel[0]['child'][$namespace][$tag]))
2218 {
2219 return $channel[0]['child'][$namespace][$tag];
2220 }
2221 }
2222 }
2223 return null;
2224 }
2225
2226 function get_image_tags($namespace, $tag)
2227 {
2228 $type = $this->get_type();
2229 if ($type & SIMPLEPIE_TYPE_RSS_10)
2230 {
2231 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2232 {
2233 if (isset($image[0]['child'][$namespace][$tag]))
2234 {
2235 return $image[0]['child'][$namespace][$tag];
2236 }
2237 }
2238 }
2239 if ($type & SIMPLEPIE_TYPE_RSS_090)
2240 {
2241 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2242 {
2243 if (isset($image[0]['child'][$namespace][$tag]))
2244 {
2245 return $image[0]['child'][$namespace][$tag];
2246 }
2247 }
2248 }
2249 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2250 {
2251 if ($image = $this->get_channel_tags('', 'image'))
2252 {
2253 if (isset($image[0]['child'][$namespace][$tag]))
2254 {
2255 return $image[0]['child'][$namespace][$tag];
2256 }
2257 }
2258 }
2259 return null;
2260 }
2261
2262 function get_base($element = array())
2263 {
2264 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2265 {
2266 return $element['xml_base'];
2267 }
2268 elseif ($this->get_link() !== null)
2269 {
2270 return $this->get_link();
2271 }
f2f7b699
AD
2272 else
2273 {
2274 return $this->subscribe_url();
2275 }
2276 }
2277
2278 function sanitize($data, $type, $base = '')
2279 {
2280 return $this->sanitize->sanitize($data, $type, $base);
2281 }
2282
2283 function get_title()
2284 {
2285 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2286 {
2287 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2288 }
2289 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2290 {
2291 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2292 }
2293 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2294 {
2295 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2296 }
2297 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2298 {
2299 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2300 }
2301 elseif ($return = $this->get_channel_tags('', 'title'))
2302 {
2303 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2304 }
2305 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2306 {
2307 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2308 }
2309 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2310 {
2311 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2312 }
2313 else
2314 {
2315 return null;
2316 }
2317 }
2318
6d7d21a0 2319 function get_category($key = 0)
f2f7b699 2320 {
6d7d21a0
AD
2321 $categories = $this->get_categories();
2322 if (isset($categories[$key]))
f2f7b699 2323 {
6d7d21a0 2324 return $categories[$key];
f2f7b699
AD
2325 }
2326 else
2327 {
2328 return null;
2329 }
2330 }
2331
6d7d21a0 2332 function get_categories()
f2f7b699 2333 {
6d7d21a0 2334 $categories = array();
f2f7b699 2335
6d7d21a0 2336 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
f2f7b699 2337 {
6d7d21a0
AD
2338 $term = null;
2339 $scheme = null;
2340 $label = null;
2341 if (isset($category['attribs']['']['term']))
f2f7b699 2342 {
6d7d21a0 2343 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
f2f7b699 2344 }
6d7d21a0 2345 if (isset($category['attribs']['']['scheme']))
f2f7b699 2346 {
6d7d21a0 2347 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
f2f7b699 2348 }
6d7d21a0 2349 if (isset($category['attribs']['']['label']))
f2f7b699 2350 {
6d7d21a0 2351 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
f2f7b699 2352 }
6d7d21a0 2353 $categories[] =& new $this->category_class($term, $scheme, $label);
f2f7b699 2354 }
6d7d21a0 2355 foreach ((array) $this->get_channel_tags('', 'category') as $category)
f2f7b699 2356 {
6d7d21a0 2357 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
f2f7b699 2358 }
6d7d21a0 2359 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
f2f7b699 2360 {
6d7d21a0
AD
2361 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2362 }
2363 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2364 {
2365 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2366 }
2367
2368 if (!empty($categories))
2369 {
2370 return SimplePie_Misc::array_unique($categories);
2371 }
2372 else
2373 {
2374 return null;
2375 }
2376 }
2377
2378 function get_author($key = 0)
2379 {
2380 $authors = $this->get_authors();
2381 if (isset($authors[$key]))
2382 {
2383 return $authors[$key];
2384 }
2385 else
2386 {
2387 return null;
2388 }
2389 }
2390
2391 function get_authors()
2392 {
2393 $authors = array();
2394 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2395 {
2396 $name = null;
2397 $uri = null;
2398 $email = null;
2399 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2400 {
2401 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2402 }
2403 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2404 {
2405 $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]));
2406 }
2407 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2408 {
2409 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2410 }
2411 if ($name !== null || $email !== null || $uri !== null)
2412 {
2413 $authors[] =& new $this->author_class($name, $uri, $email);
2414 }
2415 }
2416 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2417 {
2418 $name = null;
2419 $url = null;
2420 $email = null;
2421 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2422 {
2423 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2424 }
2425 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2426 {
2427 $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]));
2428 }
2429 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2430 {
2431 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2432 }
2433 if ($name !== null || $email !== null || $url !== null)
2434 {
2435 $authors[] =& new $this->author_class($name, $url, $email);
2436 }
2437 }
2438 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2439 {
2440 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2441 }
2442 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2443 {
2444 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2445 }
2446 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2447 {
2448 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2449 }
2450
2451 if (!empty($authors))
2452 {
2453 return SimplePie_Misc::array_unique($authors);
2454 }
2455 else
2456 {
2457 return null;
2458 }
2459 }
2460
2461 function get_contributor($key = 0)
2462 {
2463 $contributors = $this->get_contributors();
2464 if (isset($contributors[$key]))
2465 {
2466 return $contributors[$key];
2467 }
2468 else
2469 {
2470 return null;
2471 }
2472 }
2473
2474 function get_contributors()
2475 {
2476 $contributors = array();
2477 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2478 {
2479 $name = null;
2480 $uri = null;
2481 $email = null;
2482 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2483 {
2484 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2485 }
2486 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2487 {
2488 $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]));
2489 }
2490 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2491 {
2492 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2493 }
2494 if ($name !== null || $email !== null || $uri !== null)
2495 {
2496 $contributors[] =& new $this->author_class($name, $uri, $email);
2497 }
2498 }
2499 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2500 {
2501 $name = null;
2502 $url = null;
2503 $email = null;
2504 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2505 {
2506 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2507 }
2508 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2509 {
2510 $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]));
2511 }
2512 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2513 {
2514 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2515 }
2516 if ($name !== null || $email !== null || $url !== null)
2517 {
2518 $contributors[] =& new $this->author_class($name, $url, $email);
2519 }
2520 }
2521
2522 if (!empty($contributors))
2523 {
2524 return SimplePie_Misc::array_unique($contributors);
2525 }
2526 else
2527 {
2528 return null;
2529 }
2530 }
2531
2532 function get_link($key = 0, $rel = 'alternate')
2533 {
2534 $links = $this->get_links($rel);
2535 if (isset($links[$key]))
2536 {
2537 return $links[$key];
2538 }
2539 else
2540 {
2541 return null;
2542 }
2543 }
2544
2545 /**
2546 * Added for parity between the parent-level and the item/entry-level.
2547 */
2548 function get_permalink()
2549 {
2550 return $this->get_link(0);
2551 }
2552
2553 function get_links($rel = 'alternate')
2554 {
2555 if (!isset($this->data['links']))
2556 {
2557 $this->data['links'] = array();
2558 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2559 {
2560 foreach ($links as $link)
2561 {
2562 if (isset($link['attribs']['']['href']))
2563 {
2564 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2565 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2566 }
2567 }
2568 }
2569 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2570 {
2571 foreach ($links as $link)
2572 {
2573 if (isset($link['attribs']['']['href']))
2574 {
2575 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2576 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2577
2578 }
2579 }
2580 }
2581 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2582 {
2583 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2584 }
2585 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2586 {
2587 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2588 }
2589 if ($links = $this->get_channel_tags('', 'link'))
2590 {
2591 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2592 }
2593
2594 $keys = array_keys($this->data['links']);
2595 foreach ($keys as $key)
2596 {
2597 if (SimplePie_Misc::is_isegment_nz_nc($key))
2598 {
2599 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2600 {
2601 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2602 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2603 }
2604 else
2605 {
2606 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2607 }
2608 }
2609 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2610 {
2611 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2612 }
2613 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2614 }
2615 }
2616
2617 if (isset($this->data['links'][$rel]))
2618 {
2619 return $this->data['links'][$rel];
2620 }
2621 else
2622 {
2623 return null;
f2f7b699
AD
2624 }
2625 }
2626
2627 function get_description()
2628 {
2629 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2630 {
2631 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2632 }
2633 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2634 {
2635 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2636 }
2637 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2638 {
2639 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2640 }
2641 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2642 {
2643 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2644 }
2645 elseif ($return = $this->get_channel_tags('', 'description'))
2646 {
2647 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2648 }
2649 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2650 {
2651 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2652 }
2653 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2654 {
2655 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2656 }
2657 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2658 {
2659 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2660 }
2661 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2662 {
2663 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2664 }
2665 else
2666 {
2667 return null;
2668 }
2669 }
2670
2671 function get_copyright()
2672 {
2673 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2674 {
2675 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2676 }
6d7d21a0
AD
2677 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2678 {
2679 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2680 }
f2f7b699
AD
2681 elseif ($return = $this->get_channel_tags('', 'copyright'))
2682 {
2683 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2684 }
2685 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2686 {
2687 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2688 }
2689 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2690 {
2691 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2692 }
2693 else
2694 {
2695 return null;
2696 }
2697 }
2698
2699 function get_language()
2700 {
2701 if ($return = $this->get_channel_tags('', 'language'))
2702 {
2703 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2704 }
2705 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2706 {
2707 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2708 }
2709 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2710 {
2711 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2712 }
2713 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2714 {
2715 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2716 }
2717 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2718 {
2719 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2720 }
2721 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2722 {
2723 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2724 }
2725 elseif (isset($this->data['headers']['content-language']))
2726 {
2727 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2728 }
2729 else
2730 {
2731 return null;
2732 }
2733 }
2734
2735 function get_latitude()
2736 {
2737 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2738 {
2739 return (float) $return[0]['data'];
2740 }
2741 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2742 {
2743 return (float) $match[1];
2744 }
2745 else
2746 {
2747 return null;
2748 }
2749 }
2750
2751 function get_longitude()
2752 {
2753 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2754 {
2755 return (float) $return[0]['data'];
2756 }
2757 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2758 {
2759 return (float) $return[0]['data'];
2760 }
2761 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2762 {
2763 return (float) $match[2];
2764 }
2765 else
2766 {
2767 return null;
2768 }
2769 }
2770
2771 function get_image_title()
2772 {
2773 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2774 {
2775 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2776 }
2777 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2778 {
2779 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2780 }
2781 elseif ($return = $this->get_image_tags('', 'title'))
2782 {
2783 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2784 }
2785 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2786 {
2787 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2788 }
2789 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2790 {
2791 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2792 }
2793 else
2794 {
2795 return null;
2796 }
2797 }
2798
2799 function get_image_url()
2800 {
2801 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2802 {
2803 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2804 }
2805 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2806 {
2807 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2808 }
2809 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2810 {
2811 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2812 }
2813 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2814 {
2815 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2816 }
2817 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2818 {
2819 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2820 }
2821 elseif ($return = $this->get_image_tags('', 'url'))
2822 {
2823 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2824 }
2825 else
2826 {
2827 return null;
2828 }
2829 }
2830
2831 function get_image_link()
2832 {
2833 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2834 {
2835 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2836 }
2837 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2838 {
2839 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2840 }
2841 elseif ($return = $this->get_image_tags('', 'link'))
2842 {
2843 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2844 }
2845 else
2846 {
2847 return null;
2848 }
2849 }
2850
2851 function get_image_width()
2852 {
2853 if ($return = $this->get_image_tags('', 'width'))
2854 {
2855 return round($return[0]['data']);
2856 }
2857 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2858 {
2859 return 88.0;
2860 }
2861 else
2862 {
2863 return null;
2864 }
2865 }
2866
2867 function get_image_height()
2868 {
2869 if ($return = $this->get_image_tags('', 'height'))
2870 {
2871 return round($return[0]['data']);
2872 }
2873 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2874 {
2875 return 31.0;
2876 }
2877 else
2878 {
2879 return null;
2880 }
2881 }
2882
2883 function get_item_quantity($max = 0)
2884 {
2885 $qty = count($this->get_items());
2886 if ($max == 0)
2887 {
2888 return $qty;
2889 }
2890 else
2891 {
2892 return ($qty > $max) ? $max : $qty;
2893 }
2894 }
2895
2896 function get_item($key = 0)
2897 {
2898 $items = $this->get_items();
2899 if (isset($items[$key]))
2900 {
2901 return $items[$key];
2902 }
2903 else
2904 {
2905 return null;
2906 }
2907 }
2908
2909 function get_items($start = 0, $end = 0)
2910 {
2911 if (!empty($this->multifeed_objects))
2912 {
6d7d21a0 2913 return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
f2f7b699
AD
2914 }
2915 elseif (!isset($this->data['items']))
2916 {
2917 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2918 {
2919 $keys = array_keys($items);
2920 foreach ($keys as $key)
2921 {
2922 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2923 }
2924 }
2925 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2926 {
2927 $keys = array_keys($items);
2928 foreach ($keys as $key)
2929 {
2930 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2931 }
2932 }
2933 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2934 {
2935 $keys = array_keys($items);
2936 foreach ($keys as $key)
2937 {
2938 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2939 }
2940 }
2941 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2942 {
2943 $keys = array_keys($items);
2944 foreach ($keys as $key)
2945 {
2946 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2947 }
2948 }
2949 if ($items = $this->get_channel_tags('', 'item'))
2950 {
2951 $keys = array_keys($items);
2952 foreach ($keys as $key)
2953 {
2954 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2955 }
2956 }
2957 }
2958
2959 if (!empty($this->data['items']))
2960 {
2961 // If we want to order it by date, check if all items have a date, and then sort it
2962 if ($this->order_by_date)
2963 {
2964 if (!isset($this->data['ordered_items']))
2965 {
2966 $do_sort = true;
2967 foreach ($this->data['items'] as $item)
2968 {
2969 if (!$item->get_date('U'))
2970 {
2971 $do_sort = false;
2972 break;
2973 }
2974 }
2975 $item = null;
2976 $this->data['ordered_items'] = $this->data['items'];
2977 if ($do_sort)
2978 {
2979 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2980 }
2981 }
2982 $items = $this->data['ordered_items'];
2983 }
2984 else
2985 {
2986 $items = $this->data['items'];
2987 }
2988
2989 // Slice the data as desired
2990 if ($end == 0)
2991 {
2992 return array_slice($items, $start);
2993 }
2994 else
2995 {
2996 return array_slice($items, $start, $end);
2997 }
2998 }
2999 else
3000 {
3001 return array();
3002 }
3003 }
3004
3005 function sort_items($a, $b)
3006 {
3007 return $a->get_date('U') <= $b->get_date('U');
3008 }
3009
6d7d21a0 3010 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
f2f7b699
AD
3011 {
3012 if (is_array($urls) && sizeof($urls) > 0)
3013 {
3014 $items = array();
3015 foreach ($urls as $arg)
3016 {
6d7d21a0 3017 if (is_a($arg, 'SimplePie'))
f2f7b699 3018 {
6d7d21a0 3019 $items = array_merge($items, $arg->get_items(0, $limit));
f2f7b699
AD
3020 }
3021 else
3022 {
3023 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3024 }
3025 }
3026
3027 $do_sort = true;
3028 foreach ($items as $item)
3029 {
3030 if (!$item->get_date('U'))
3031 {
3032 $do_sort = false;
3033 break;
3034 }
3035 }
3036 $item = null;
3037 if ($do_sort)
3038 {
3039 usort($items, array('SimplePie', 'sort_items'));
3040 }
3041
3042 if ($end == 0)
3043 {
3044 return array_slice($items, $start);
3045 }
3046 else
3047 {
3048 return array_slice($items, $start, $end);
3049 }
3050 }
3051 else
3052 {
3053 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3054 return array();
3055 }
3056 }
3057}
3058
3059class SimplePie_Item
3060{
3061 var $feed;
3062 var $data = array();
3063
3064 function SimplePie_Item($feed, $data)
3065 {
3066 $this->feed = $feed;
3067 $this->data = $data;
3068 }
3069
3070 function __toString()
3071 {
3072 return md5(serialize($this->data));
3073 }
6d7d21a0
AD
3074
3075 /**
3076 * Remove items that link back to this before destroying this object
3077 */
3078 function __destruct()
3079 {
3080 unset($this->feed);
3081 }
f2f7b699
AD
3082
3083 function get_item_tags($namespace, $tag)
3084 {
3085 if (isset($this->data['child'][$namespace][$tag]))
3086 {
3087 return $this->data['child'][$namespace][$tag];
3088 }
3089 else
3090 {
3091 return null;
3092 }
3093 }
3094
3095 function get_base($element = array())
3096 {
3097 return $this->feed->get_base($element);
3098 }
3099
3100 function sanitize($data, $type, $base = '')
3101 {
3102 return $this->feed->sanitize($data, $type, $base);
3103 }
3104
3105 function get_feed()
3106 {
3107 return $this->feed;
3108 }
3109
3110 function get_id($hash = false)
3111 {
6d7d21a0 3112 if (!$hash)
f2f7b699 3113 {
6d7d21a0
AD
3114 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3115 {
3116 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3117 }
3118 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3119 {
3120 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3121 }
3122 elseif ($return = $this->get_item_tags('', 'guid'))
3123 {
3124 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3125 }
3126 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3127 {
3128 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3129 }
3130 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3131 {
3132 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3133 }
3134 elseif (($return = $this->get_permalink()) !== null)
3135 {
3136 return $return;
3137 }
3138 elseif (($return = $this->get_title()) !== null)
3139 {
3140 return $return;
3141 }
f2f7b699 3142 }
6d7d21a0 3143 if ($this->get_permalink() !== null || $this->get_title() !== null)
f2f7b699 3144 {
6d7d21a0 3145 return md5($this->get_permalink() . $this->get_title());
f2f7b699 3146 }
6d7d21a0 3147 else
f2f7b699 3148 {
6d7d21a0 3149 return md5(serialize($this->data));
f2f7b699 3150 }
6d7d21a0
AD
3151 }
3152
3153 function get_title()
3154 {
3155 if (!isset($this->data['title']))
f2f7b699 3156 {
6d7d21a0
AD
3157 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3158 {
3159 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3160 }
3161 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3162 {
3163 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3164 }
3165 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3166 {
3167 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3168 }
3169 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3170 {
3171 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3172 }
3173 elseif ($return = $this->get_item_tags('', 'title'))
3174 {
3175 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3176 }
3177 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3178 {
3179 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3180 }
3181 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3182 {
3183 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3184 }
3185 else
3186 {
3187 $this->data['title'] = null;
3188 }
f2f7b699 3189 }
6d7d21a0 3190 return $this->data['title'];
f2f7b699
AD
3191 }
3192
3193 function get_description($description_only = false)
3194 {
3195 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3196 {
3197 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3198 }
3199 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3200 {
3201 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3202 }
3203 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3204 {
3205 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3206 }
3207 elseif ($return = $this->get_item_tags('', 'description'))
3208 {
3209 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3210 }
3211 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3212 {
3213 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3214 }
3215 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3216 {
3217 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3218 }
3219 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3220 {
3221 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3222 }
3223 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3224 {
3225 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3226 }
3227 elseif (!$description_only)
3228 {
3229 return $this->get_content(true);
3230 }
3231 else
3232 {
3233 return null;
3234 }
3235 }
3236
3237 function get_content($content_only = false)
3238 {
3239 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3240 {
3241 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3242 }
3243 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3244 {
3245 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3246 }
3247 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3248 {
3249 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3250 }
3251 elseif (!$content_only)
3252 {
3253 return $this->get_description(true);
3254 }
3255 else
3256 {
3257 return null;
3258 }
3259 }
3260
3261 function get_category($key = 0)
3262 {
3263 $categories = $this->get_categories();
3264 if (isset($categories[$key]))
3265 {
3266 return $categories[$key];
3267 }
3268 else
3269 {
3270 return null;
3271 }
3272 }
3273
3274 function get_categories()
3275 {
3276 $categories = array();
3277
3278 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3279 {
3280 $term = null;
3281 $scheme = null;
3282 $label = null;
3283 if (isset($category['attribs']['']['term']))
3284 {
3285 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3286 }
3287 if (isset($category['attribs']['']['scheme']))
3288 {
3289 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3290 }
3291 if (isset($category['attribs']['']['label']))
3292 {
3293 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3294 }
3295 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
3296 }
3297 foreach ((array) $this->get_item_tags('', 'category') as $category)
3298 {
3299 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3300 }
3301 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3302 {
3303 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3304 }
3305 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3306 {
3307 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3308 }
3309
3310 if (!empty($categories))
3311 {
3312 return SimplePie_Misc::array_unique($categories);
3313 }
3314 else
3315 {
3316 return null;
3317 }
3318 }
3319
3320 function get_author($key = 0)
3321 {
3322 $authors = $this->get_authors();
3323 if (isset($authors[$key]))
3324 {
3325 return $authors[$key];
3326 }
3327 else
3328 {
3329 return null;
3330 }
3331 }
3332
6d7d21a0
AD
3333 function get_contributor($key = 0)
3334 {
3335 $contributors = $this->get_contributors();
3336 if (isset($contributors[$key]))
3337 {
3338 return $contributors[$key];
3339 }
3340 else
3341 {
3342 return null;
3343 }
3344 }
3345
3346 function get_contributors()
3347 {
3348 $contributors = array();
3349 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3350 {
3351 $name = null;
3352 $uri = null;
3353 $email = null;
3354 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3355 {
3356 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3357 }
3358 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3359 {
3360 $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]));
3361 }
3362 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3363 {
3364 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3365 }
3366 if ($name !== null || $email !== null || $uri !== null)
3367 {
3368 $contributors[] =& new $this->feed->author_class($name, $uri, $email);
3369 }
3370 }
3371 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3372 {
3373 $name = null;
3374 $url = null;
3375 $email = null;
3376 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3377 {
3378 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3379 }
3380 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3381 {
3382 $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]));
3383 }
3384 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3385 {
3386 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3387 }
3388 if ($name !== null || $email !== null || $url !== null)
3389 {
3390 $contributors[] =& new $this->feed->author_class($name, $url, $email);
3391 }
3392 }
3393
3394 if (!empty($contributors))
3395 {
3396 return SimplePie_Misc::array_unique($contributors);
3397 }
3398 else
3399 {
3400 return null;
3401 }
3402 }
3403
f2f7b699
AD
3404 /**
3405 * @todo Atom inheritance (item author, source author, feed author)
3406 */
3407 function get_authors()
3408 {
3409 $authors = array();
3410 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3411 {
3412 $name = null;
3413 $uri = null;
3414 $email = null;
3415 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3416 {
3417 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3418 }
3419 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3420 {
3421 $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]));
3422 }
3423 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3424 {
3425 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3426 }
3427 if ($name !== null || $email !== null || $uri !== null)
3428 {
3429 $authors[] =& new $this->feed->author_class($name, $uri, $email);
3430 }
3431 }
3432 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3433 {
3434 $name = null;
3435 $url = null;
3436 $email = null;
3437 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3438 {
3439 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3440 }
3441 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3442 {
6d7d21a0 3443 $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]));
f2f7b699
AD
3444 }
3445 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3446 {
3447 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3448 }
6d7d21a0 3449 if ($name !== null || $email !== null || $url !== null)
f2f7b699
AD
3450 {
3451 $authors[] =& new $this->feed->author_class($name, $url, $email);
3452 }
3453 }
3454 if ($author = $this->get_item_tags('', 'author'))
3455 {
3456 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3457 }
3458 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3459 {
3460 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3461 }
3462 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3463 {
3464 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3465 }
3466 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3467 {
3468 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3469 }
3470
3471 if (!empty($authors))
3472 {
3473 return SimplePie_Misc::array_unique($authors);
3474 }
6d7d21a0
AD
3475 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3476 {
3477 return $authors;
3478 }
3479 elseif ($authors = $this->feed->get_authors())
3480 {
3481 return $authors;
3482 }
3483 else
3484 {
3485 return null;
3486 }
3487 }
3488
3489 function get_copyright()
3490 {
3491 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3492 {
3493 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3494 }
3495 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3496 {
3497 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3498 }
3499 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3500 {
3501 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3502 }
f2f7b699
AD
3503 else
3504 {
3505 return null;
3506 }
3507 }
3508
3509 function get_date($date_format = 'j F Y, g:i a')
3510 {
3511 if (!isset($this->data['date']))
3512 {
3513 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3514 {
3515 $this->data['date']['raw'] = $return[0]['data'];
3516 }
3517 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3518 {
3519 $this->data['date']['raw'] = $return[0]['data'];
3520 }
3521 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3522 {
3523 $this->data['date']['raw'] = $return[0]['data'];
3524 }
3525 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3526 {
3527 $this->data['date']['raw'] = $return[0]['data'];
3528 }
3529 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3530 {
3531 $this->data['date']['raw'] = $return[0]['data'];
3532 }
3533 elseif ($return = $this->get_item_tags('', 'pubDate'))
3534 {
3535 $this->data['date']['raw'] = $return[0]['data'];
3536 }
3537 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3538 {
3539 $this->data['date']['raw'] = $return[0]['data'];
3540 }
3541 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3542 {
3543 $this->data['date']['raw'] = $return[0]['data'];
3544 }
3545
3546 if (!empty($this->data['date']['raw']))
3547 {
6d7d21a0
AD
3548 $parser = SimplePie_Parse_Date::get();
3549 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
f2f7b699
AD
3550 }
3551 else
3552 {
3553 $this->data['date'] = null;
3554 }
3555 }
3556 if ($this->data['date'])
3557 {
3558 $date_format = (string) $date_format;
3559 switch ($date_format)
3560 {
3561 case '':
3562 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3563
3564 case 'U':
3565 return $this->data['date']['parsed'];
3566
3567 default:
3568 return date($date_format, $this->data['date']['parsed']);
3569 }
3570 }
3571 else
3572 {
3573 return null;
3574 }
3575 }
3576
3577 function get_local_date($date_format = '%c')
3578 {
3579 if (!$date_format)
3580 {
3581 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3582 }
3583 elseif (($date = $this->get_date('U')) !== null)
3584 {
3585 return strftime($date_format, $date);
3586 }
3587 else
3588 {
3589 return null;
3590 }
3591 }
3592
3593 function get_permalink()
3594 {
3595 $link = $this->get_link();
3596 $enclosure = $this->get_enclosure(0);
3597 if ($link !== null)
3598 {
3599 return $link;
3600 }
3601 elseif ($enclosure !== null)
3602 {
3603 return $enclosure->get_link();
3604 }
3605 else
3606 {
3607 return null;
3608 }
3609 }
3610
3611 function get_link($key = 0, $rel = 'alternate')
3612 {
3613 $links = $this->get_links($rel);
3614 if ($links[$key] !== null)
3615 {
3616 return $links[$key];
3617 }
3618 else
3619 {
3620 return null;
3621 }
3622 }
3623
3624 function get_links($rel = 'alternate')
3625 {
3626 if (!isset($this->data['links']))
3627 {
3628 $this->data['links'] = array();
3629 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3630 {
3631 if (isset($link['attribs']['']['href']))
3632 {
3633 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3634 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3635
3636 }
3637 }
3638 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3639 {
3640 if (isset($link['attribs']['']['href']))
3641 {
3642 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3643 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3644 }
3645 }
3646 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3647 {
3648 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3649 }
3650 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3651 {
3652 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3653 }
3654 if ($links = $this->get_item_tags('', 'link'))
3655 {
3656 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3657 }
3658 if ($links = $this->get_item_tags('', 'guid'))
3659 {
3660 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3661 {
3662 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3663 }
3664 }
3665
3666 $keys = array_keys($this->data['links']);
3667 foreach ($keys as $key)
3668 {
3669 if (SimplePie_Misc::is_isegment_nz_nc($key))
3670 {
3671 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3672 {
3673 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3674 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3675 }
3676 else
3677 {
3678 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3679 }
3680 }
3681 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3682 {
3683 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3684 }
3685 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3686 }
3687 }
3688 if (isset($this->data['links'][$rel]))
3689 {
3690 return $this->data['links'][$rel];
3691 }
3692 else
3693 {
3694 return null;
3695 }
3696 }
3697
3698 /**
3699 * @todo Add ability to prefer one type of content over another (in a media group).
3700 */
3701 function get_enclosure($key = 0, $prefer = null)
3702 {
3703 $enclosures = $this->get_enclosures();
3704 if (isset($enclosures[$key]))
3705 {
3706 return $enclosures[$key];
3707 }
3708 else
3709 {
3710 return null;
3711 }
3712 }
3713
3714 /**
3715 * Grabs all available enclosures (podcasts, etc.)
3716 *
3717 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3718 *
3719 * 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.
3720 *
3721 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
f2f7b699
AD
3722 * @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).
3723 */
3724 function get_enclosures()
3725 {
3726 if (!isset($this->data['enclosures']))
3727 {
3728 $this->data['enclosures'] = array();
3729
3730 // Elements
3731 $captions_parent = null;
3732 $categories_parent = null;
3733 $copyrights_parent = null;
3734 $credits_parent = null;
3735 $description_parent = null;
3736 $duration_parent = null;
3737 $hashes_parent = null;
3738 $keywords_parent = null;
3739 $player_parent = null;
3740 $ratings_parent = null;
3741 $restrictions_parent = null;
3742 $thumbnails_parent = null;
3743 $title_parent = null;
3744
3745 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3746 $parent = $this->get_feed();
3747
3748 // CAPTIONS
3749 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3750 {
3751 foreach ($captions as $caption)
3752 {
3753 $caption_type = null;
3754 $caption_lang = null;
3755 $caption_startTime = null;
3756 $caption_endTime = null;
3757 $caption_text = null;
3758 if (isset($caption['attribs']['']['type']))
3759 {
3760 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3761 }
3762 if (isset($caption['attribs']['']['lang']))
3763 {
3764 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3765 }
3766 if (isset($caption['attribs']['']['start']))
3767 {
3768 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3769 }
3770 if (isset($caption['attribs']['']['end']))
3771 {
3772 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3773 }
3774 if (isset($caption['data']))
3775 {
3776 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3777 }
3778 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3779 }
3780 }
3781 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3782 {
3783 foreach ($captions as $caption)
3784 {
3785 $caption_type = null;
3786 $caption_lang = null;
3787 $caption_startTime = null;
3788 $caption_endTime = null;
3789 $caption_text = null;
3790 if (isset($caption['attribs']['']['type']))
3791 {
3792 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3793 }
3794 if (isset($caption['attribs']['']['lang']))
3795 {
3796 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3797 }
3798 if (isset($caption['attribs']['']['start']))
3799 {
3800 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3801 }
3802 if (isset($caption['attribs']['']['end']))
3803 {
3804 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3805 }
3806 if (isset($caption['data']))
3807 {
3808 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3809 }
3810 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3811 }
3812 }
3813 if (is_array($captions_parent))
3814 {
3815 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3816 }
3817
3818 // CATEGORIES
3819 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3820 {
3821 $term = null;
3822 $scheme = null;
3823 $label = null;
3824 if (isset($category['data']))
3825 {
3826 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3827 }
3828 if (isset($category['attribs']['']['scheme']))
3829 {
3830 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3831 }
3832 else
3833 {
3834 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3835 }
3836 if (isset($category['attribs']['']['label']))
3837 {
3838 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3839 }
3840 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3841 }
3842 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3843 {
3844 $term = null;
3845 $scheme = null;
3846 $label = null;
3847 if (isset($category['data']))
3848 {
3849 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3850 }
3851 if (isset($category['attribs']['']['scheme']))
3852 {
3853 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3854 }
3855 else
3856 {
3857 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3858 }
3859 if (isset($category['attribs']['']['label']))
3860 {
3861 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3862 }
3863 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3864 }
3865 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3866 {
3867 $term = null;
3868 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3869 $label = null;
3870 if (isset($category['attribs']['']['text']))
3871 {
3872 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3873 }
3874 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3875
3876 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3877 {
3878 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3879 {
3880 if (isset($subcategory['attribs']['']['text']))
3881 {
3882 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3883 }
3884 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3885 }
3886 }
3887 }
3888 if (is_array($categories_parent))
3889 {
3890 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3891 }
3892
3893 // COPYRIGHT
3894 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3895 {
3896 $copyright_url = null;
3897 $copyright_label = null;
3898 if (isset($copyright[0]['attribs']['']['url']))
3899 {
3900 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3901 }
3902 if (isset($copyright[0]['data']))
3903 {
3904 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3905 }
3906 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3907 }
3908 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3909 {
3910 $copyright_url = null;
3911 $copyright_label = null;
3912 if (isset($copyright[0]['attribs']['']['url']))
3913 {
3914 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3915 }
3916 if (isset($copyright[0]['data']))
3917 {
3918 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3919 }
3920 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3921 }
3922
3923 // CREDITS
3924 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3925 {
3926 foreach ($credits as $credit)
3927 {
3928 $credit_role = null;
3929 $credit_scheme = null;
3930 $credit_name = null;
3931 if (isset($credit['attribs']['']['role']))
3932 {
3933 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3934 }
3935 if (isset($credit['attribs']['']['scheme']))
3936 {
3937 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3938 }
3939 else
3940 {
3941 $credit_scheme = 'urn:ebu';
3942 }
3943 if (isset($credit['data']))
3944 {
3945 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3946 }
3947 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3948 }
3949 }
3950 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3951 {
3952 foreach ($credits as $credit)
3953 {
3954 $credit_role = null;
3955 $credit_scheme = null;
3956 $credit_name = null;
3957 if (isset($credit['attribs']['']['role']))
3958 {
3959 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3960 }
3961 if (isset($credit['attribs']['']['scheme']))
3962 {
3963 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3964 }
3965 else
3966 {
3967 $credit_scheme = 'urn:ebu';
3968 }
3969 if (isset($credit['data']))
3970 {
3971 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3972 }
3973 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3974 }
3975 }
3976 if (is_array($credits_parent))
3977 {
3978 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3979 }
3980
3981 // DESCRIPTION
3982 if ($description_parent = $this->get_item_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 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3990 {
3991 if (isset($description_parent[0]['data']))
3992 {
3993 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3994 }
3995 }
3996
3997 // DURATION
3998 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
3999 {
4000 $seconds = null;
4001 $minutes = null;
4002 $hours = null;
4003 if (isset($duration_parent[0]['data']))
4004 {
4005 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4006 if (sizeof($temp) > 0)
4007 {
4008 (int) $seconds = array_pop($temp);
4009 }
4010 if (sizeof($temp) > 0)
4011 {
4012 (int) $minutes = array_pop($temp);
4013 $seconds += $minutes * 60;
4014 }
4015 if (sizeof($temp) > 0)
4016 {
4017 (int) $hours = array_pop($temp);
4018 $seconds += $hours * 3600;
4019 }
4020 unset($temp);
4021 $duration_parent = $seconds;
4022 }
4023 }
4024
4025 // HASHES
4026 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4027 {
4028 foreach ($hashes_iterator as $hash)
4029 {
4030 $value = null;
4031 $algo = null;
4032 if (isset($hash['data']))
4033 {
4034 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4035 }
4036 if (isset($hash['attribs']['']['algo']))
4037 {
4038 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4039 }
4040 else
4041 {
4042 $algo = 'md5';
4043 }
4044 $hashes_parent[] = $algo.':'.$value;
4045 }
4046 }
4047 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4048 {
4049 foreach ($hashes_iterator as $hash)
4050 {
4051 $value = null;
4052 $algo = null;
4053 if (isset($hash['data']))
4054 {
4055 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4056 }
4057 if (isset($hash['attribs']['']['algo']))
4058 {
4059 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4060 }
4061 else
4062 {
4063 $algo = 'md5';
4064 }
4065 $hashes_parent[] = $algo.':'.$value;
4066 }
4067 }
4068 if (is_array($hashes_parent))
4069 {
4070 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4071 }
4072
4073 // KEYWORDS
4074 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4075 {
4076 if (isset($keywords[0]['data']))
4077 {
4078 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4079 foreach ($temp as $word)
4080 {
4081 $keywords_parent[] = trim($word);
4082 }
4083 }
4084 unset($temp);
4085 }
4086 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4087 {
4088 if (isset($keywords[0]['data']))
4089 {
4090 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4091 foreach ($temp as $word)
4092 {
4093 $keywords_parent[] = trim($word);
4094 }
4095 }
4096 unset($temp);
4097 }
4098 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4099 {
4100 if (isset($keywords[0]['data']))
4101 {
4102 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4103 foreach ($temp as $word)
4104 {
4105 $keywords_parent[] = trim($word);
4106 }
4107 }
4108 unset($temp);
4109 }
4110 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4111 {
4112 if (isset($keywords[0]['data']))
4113 {
4114 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4115 foreach ($temp as $word)
4116 {
4117 $keywords_parent[] = trim($word);
4118 }
4119 }
4120 unset($temp);
4121 }
4122 if (is_array($keywords_parent))
4123 {
4124 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4125 }
4126
4127 // PLAYER
4128 if ($player_parent = $this->get_item_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 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4136 {
4137 if (isset($player_parent[0]['attribs']['']['url']))
4138 {
4139 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4140 }
4141 }
4142
4143 // RATINGS
4144 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4145 {
4146 foreach ($ratings as $rating)
4147 {
4148 $rating_scheme = null;
4149 $rating_value = null;
4150 if (isset($rating['attribs']['']['scheme']))
4151 {
4152 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4153 }
4154 else
4155 {
4156 $rating_scheme = 'urn:simple';
4157 }
4158 if (isset($rating['data']))
4159 {
4160 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4161 }
4162 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4163 }
4164 }
4165 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4166 {
4167 foreach ($ratings as $rating)
4168 {
4169 $rating_scheme = 'urn:itunes';
4170 $rating_value = null;
4171 if (isset($rating['data']))
4172 {
4173 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4174 }
4175 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4176 }
4177 }
4178 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4179 {
4180 foreach ($ratings as $rating)
4181 {
4182 $rating_scheme = null;
4183 $rating_value = null;
4184 if (isset($rating['attribs']['']['scheme']))
4185 {
4186 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4187 }
4188 else
4189 {
4190 $rating_scheme = 'urn:simple';
4191 }
4192 if (isset($rating['data']))
4193 {
4194 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4195 }
4196 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4197 }
4198 }
4199 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4200 {
4201 foreach ($ratings as $rating)
4202 {
4203 $rating_scheme = 'urn:itunes';
4204 $rating_value = null;
4205 if (isset($rating['data']))
4206 {
4207 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4208 }
4209 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4210 }
4211 }
4212 if (is_array($ratings_parent))
4213 {
4214 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4215 }
4216
4217 // RESTRICTIONS
4218 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4219 {
4220 foreach ($restrictions as $restriction)
4221 {
4222 $restriction_relationship = null;
4223 $restriction_type = null;
4224 $restriction_value = null;
4225 if (isset($restriction['attribs']['']['relationship']))
4226 {
4227 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4228 }
4229 if (isset($restriction['attribs']['']['type']))
4230 {
4231 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4232 }
4233 if (isset($restriction['data']))
4234 {
4235 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4236 }
4237 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4238 }
4239 }
4240 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4241 {
4242 foreach ($restrictions as $restriction)
4243 {
4244 $restriction_relationship = 'allow';
4245 $restriction_type = null;
4246 $restriction_value = 'itunes';
4247 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4248 {
4249 $restriction_relationship = 'deny';
4250 }
4251 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4252 }
4253 }
4254 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4255 {
4256 foreach ($restrictions as $restriction)
4257 {
4258 $restriction_relationship = null;
4259 $restriction_type = null;
4260 $restriction_value = null;
4261 if (isset($restriction['attribs']['']['relationship']))
4262 {
4263 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4264 }
4265 if (isset($restriction['attribs']['']['type']))
4266 {
4267 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4268 }
4269 if (isset($restriction['data']))
4270 {
4271 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4272 }
4273 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4274 }
4275 }
4276 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4277 {
4278 foreach ($restrictions as $restriction)
4279 {
4280 $restriction_relationship = 'allow';
4281 $restriction_type = null;
4282 $restriction_value = 'itunes';
4283 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4284 {
4285 $restriction_relationship = 'deny';
4286 }
4287 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4288 }
4289 }
4290 if (is_array($restrictions_parent))
4291 {
4292 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4293 }
4294
4295 // THUMBNAILS
4296 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4297 {
4298 foreach ($thumbnails as $thumbnail)
4299 {
4300 if (isset($thumbnail['attribs']['']['url']))
4301 {
4302 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4303 }
4304 }
4305 }
4306 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4307 {
4308 foreach ($thumbnails as $thumbnail)
4309 {
4310 if (isset($thumbnail['attribs']['']['url']))
4311 {
4312 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4313 }
4314 }
4315 }
4316
4317 // TITLES
4318 if ($title_parent = $this->get_item_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 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4326 {
4327 if (isset($title_parent[0]['data']))
4328 {
4329 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4330 }
4331 }
4332
4333 // Clear the memory
4334 unset($parent);
4335
3cae90e1
AD
4336 // Attributes
4337 $bitrate = null;
4338 $channels = null;
4339 $duration = null;
4340 $expression = null;
4341 $framerate = null;
4342 $height = null;
4343 $javascript = null;
4344 $lang = null;
4345 $length = null;
4346 $medium = null;
4347 $samplingrate = null;
4348 $type = null;
4349 $url = null;
4350 $width = null;
4351
4352 // Elements
4353 $captions = null;
4354 $categories = null;
4355 $copyrights = null;
4356 $credits = null;
4357 $description = null;
4358 $hashes = null;
4359 $keywords = null;
4360 $player = null;
4361 $ratings = null;
4362 $restrictions = null;
4363 $thumbnails = null;
4364 $title = null;
4365
f2f7b699
AD
4366 // If we have media:group tags, loop through them.
4367 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4368 {
4369 // If we have media:content tags, loop through them.
4370 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4371 {
4372 if (isset($content['attribs']['']['url']))
4373 {
4374 // Attributes
4375 $bitrate = null;
4376 $channels = null;
4377 $duration = null;
4378 $expression = null;
4379 $framerate = null;
4380 $height = null;
4381 $javascript = null;
4382 $lang = null;
4383 $length = null;
4384 $medium = null;
4385 $samplingrate = null;
4386 $type = null;
4387 $url = null;
4388 $width = null;
4389
4390 // Elements
4391 $captions = null;
4392 $categories = null;
4393 $copyrights = null;
4394 $credits = null;
4395 $description = null;
4396 $hashes = null;
4397 $keywords = null;
4398 $player = null;
4399 $ratings = null;
4400 $restrictions = null;
4401 $thumbnails = null;
4402 $title = null;
4403
4404 // Start checking the attributes of media:content
4405 if (isset($content['attribs']['']['bitrate']))
4406 {
4407 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4408 }
4409 if (isset($content['attribs']['']['channels']))
4410 {
4411 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4412 }
4413 if (isset($content['attribs']['']['duration']))
4414 {
4415 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4416 }
4417 else
4418 {
4419 $duration = $duration_parent;
4420 }
4421 if (isset($content['attribs']['']['expression']))
4422 {
4423 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4424 }
4425 if (isset($content['attribs']['']['framerate']))
4426 {
4427 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4428 }
4429 if (isset($content['attribs']['']['height']))
4430 {
4431 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4432 }
4433 if (isset($content['attribs']['']['lang']))
4434 {
4435 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4436 }
4437 if (isset($content['attribs']['']['fileSize']))
4438 {
4439 $length = ceil($content['attribs']['']['fileSize']);
4440 }
4441 if (isset($content['attribs']['']['medium']))
4442 {
4443 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4444 }
4445 if (isset($content['attribs']['']['samplingrate']))
4446 {
4447 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4448 }
4449 if (isset($content['attribs']['']['type']))
4450 {
4451 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4452 }
4453 if (isset($content['attribs']['']['width']))
4454 {
4455 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4456 }
4457 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4458
4459 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4460
4461 // CAPTIONS
4462 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4463 {
4464 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4465 {
4466 $caption_type = null;
4467 $caption_lang = null;
4468 $caption_startTime = null;
4469 $caption_endTime = null;
4470 $caption_text = null;
4471 if (isset($caption['attribs']['']['type']))
4472 {
4473 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4474 }
4475 if (isset($caption['attribs']['']['lang']))
4476 {
4477 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4478 }
4479 if (isset($caption['attribs']['']['start']))
4480 {
4481 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4482 }
4483 if (isset($caption['attribs']['']['end']))
4484 {
4485 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4486 }
4487 if (isset($caption['data']))
4488 {
4489 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4490 }
4491 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4492 }
4493 if (is_array($captions))
4494 {
4495 $captions = array_values(SimplePie_Misc::array_unique($captions));
4496 }
4497 }
4498 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4499 {
4500 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4501 {
4502 $caption_type = null;
4503 $caption_lang = null;
4504 $caption_startTime = null;
4505 $caption_endTime = null;
4506 $caption_text = null;
4507 if (isset($caption['attribs']['']['type']))
4508 {
4509 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4510 }
4511 if (isset($caption['attribs']['']['lang']))
4512 {
4513 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4514 }
4515 if (isset($caption['attribs']['']['start']))
4516 {
4517 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4518 }
4519 if (isset($caption['attribs']['']['end']))
4520 {
4521 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4522 }
4523 if (isset($caption['data']))
4524 {
4525 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4526 }
4527 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4528 }
4529 if (is_array($captions))
4530 {
4531 $captions = array_values(SimplePie_Misc::array_unique($captions));
4532 }
4533 }
4534 else
4535 {
4536 $captions = $captions_parent;
4537 }
4538
4539 // CATEGORIES
4540 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4541 {
4542 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4543 {
4544 $term = null;
4545 $scheme = null;
4546 $label = null;
4547 if (isset($category['data']))
4548 {
4549 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4550 }
4551 if (isset($category['attribs']['']['scheme']))
4552 {
4553 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4554 }
4555 else
4556 {
4557 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4558 }
4559 if (isset($category['attribs']['']['label']))
4560 {
4561 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4562 }
4563 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4564 }
4565 }
4566 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4567 {
4568 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4569 {
4570 $term = null;
4571 $scheme = null;
4572 $label = null;
4573 if (isset($category['data']))
4574 {
4575 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4576 }
4577 if (isset($category['attribs']['']['scheme']))
4578 {
4579 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4580 }
4581 else
4582 {
4583 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4584 }
4585 if (isset($category['attribs']['']['label']))
4586 {
4587 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4588 }
4589 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4590 }
4591 }
4592 if (is_array($categories) && is_array($categories_parent))
4593 {
4594 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4595 }
4596 elseif (is_array($categories))
4597 {
4598 $categories = array_values(SimplePie_Misc::array_unique($categories));
4599 }
4600 elseif (is_array($categories_parent))
4601 {
4602 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4603 }
4604
4605 // COPYRIGHTS
4606 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4607 {
4608 $copyright_url = null;
4609 $copyright_label = null;
4610 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4611 {
4612 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4613 }
4614 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4615 {
4616 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4617 }
4618 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4619 }
4620 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4621 {
4622 $copyright_url = null;
4623 $copyright_label = null;
4624 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4625 {
4626 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4627 }
4628 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4629 {
4630 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4631 }
4632 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4633 }
4634 else
4635 {
4636 $copyrights = $copyrights_parent;
4637 }
4638
4639 // CREDITS
4640 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4641 {
4642 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4643 {
4644 $credit_role = null;
4645 $credit_scheme = null;
4646 $credit_name = null;
4647 if (isset($credit['attribs']['']['role']))
4648 {
4649 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4650 }
4651 if (isset($credit['attribs']['']['scheme']))
4652 {
4653 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4654 }
4655 else
4656 {
4657 $credit_scheme = 'urn:ebu';
4658 }
4659 if (isset($credit['data']))
4660 {
4661 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4662 }
4663 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4664 }
4665 if (is_array($credits))
4666 {
4667 $credits = array_values(SimplePie_Misc::array_unique($credits));
4668 }
4669 }
4670 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4671 {
4672 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4673 {
4674 $credit_role = null;
4675 $credit_scheme = null;
4676 $credit_name = null;
4677 if (isset($credit['attribs']['']['role']))
4678 {
4679 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4680 }
4681 if (isset($credit['attribs']['']['scheme']))
4682 {
4683 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4684 }
4685 else
4686 {
4687 $credit_scheme = 'urn:ebu';
4688 }
4689 if (isset($credit['data']))
4690 {
4691 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4692 }
4693 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4694 }
4695 if (is_array($credits))
4696 {
4697 $credits = array_values(SimplePie_Misc::array_unique($credits));
4698 }
4699 }
4700 else
4701 {
4702 $credits = $credits_parent;
4703 }
4704
4705 // DESCRIPTION
4706 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4707 {
4708 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4709 }
4710 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4711 {
4712 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4713 }
4714 else
4715 {
4716 $description = $description_parent;
4717 }
4718
4719 // HASHES
4720 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4721 {
4722 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4723 {
4724 $value = null;
4725 $algo = null;
4726 if (isset($hash['data']))
4727 {
4728 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4729 }
4730 if (isset($hash['attribs']['']['algo']))
4731 {
4732 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4733 }
4734 else
4735 {
4736 $algo = 'md5';
4737 }
4738 $hashes[] = $algo.':'.$value;
4739 }
4740 if (is_array($hashes))
4741 {
4742 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4743 }
4744 }
4745 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4746 {
4747 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4748 {
4749 $value = null;
4750 $algo = null;
4751 if (isset($hash['data']))
4752 {
4753 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4754 }
4755 if (isset($hash['attribs']['']['algo']))
4756 {
4757 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4758 }
4759 else
4760 {
4761 $algo = 'md5';
4762 }
4763 $hashes[] = $algo.':'.$value;
4764 }
4765 if (is_array($hashes))
4766 {
4767 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4768 }
4769 }
4770 else
4771 {
4772 $hashes = $hashes_parent;
4773 }
4774
4775 // KEYWORDS
4776 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4777 {
4778 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4779 {
4780 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4781 foreach ($temp as $word)
4782 {
4783 $keywords[] = trim($word);
4784 }
4785 unset($temp);
4786 }
4787 if (is_array($keywords))
4788 {
4789 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4790 }
4791 }
4792 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4793 {
4794 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4795 {
4796 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4797 foreach ($temp as $word)
4798 {
4799 $keywords[] = trim($word);
4800 }
4801 unset($temp);
4802 }
4803 if (is_array($keywords))
4804 {
4805 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4806 }
4807 }
4808 else
4809 {
4810 $keywords = $keywords_parent;
4811 }
4812
4813 // PLAYER
4814 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4815 {
4816 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4817 }
4818 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4819 {
4820 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4821 }
4822 else
4823 {
4824 $player = $player_parent;
4825 }
4826
4827 // RATINGS
4828 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4829 {
4830 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4831 {
4832 $rating_scheme = null;
4833 $rating_value = null;
4834 if (isset($rating['attribs']['']['scheme']))
4835 {
4836 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4837 }
4838 else
4839 {
4840 $rating_scheme = 'urn:simple';
4841 }
4842 if (isset($rating['data']))
4843 {
4844 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4845 }
4846 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4847 }
4848 if (is_array($ratings))
4849 {
4850 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4851 }
4852 }
4853 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4854 {
4855 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4856 {
4857 $rating_scheme = null;
4858 $rating_value = null;
4859 if (isset($rating['attribs']['']['scheme']))
4860 {
4861 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4862 }
4863 else
4864 {
4865 $rating_scheme = 'urn:simple';
4866 }
4867 if (isset($rating['data']))
4868 {
4869 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4870 }
4871 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4872 }
4873 if (is_array($ratings))
4874 {
4875 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4876 }
4877 }
4878 else
4879 {
4880 $ratings = $ratings_parent;
4881 }
4882
4883 // RESTRICTIONS
4884 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4885 {
4886 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4887 {
4888 $restriction_relationship = null;
4889 $restriction_type = null;
4890 $restriction_value = null;
4891 if (isset($restriction['attribs']['']['relationship']))
4892 {
4893 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4894 }
4895 if (isset($restriction['attribs']['']['type']))
4896 {
4897 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4898 }
4899 if (isset($restriction['data']))
4900 {
4901 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4902 }
4903 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4904 }
4905 if (is_array($restrictions))
4906 {
4907 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4908 }
4909 }
4910 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4911 {
4912 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4913 {
4914 $restriction_relationship = null;
4915 $restriction_type = null;
4916 $restriction_value = null;
4917 if (isset($restriction['attribs']['']['relationship']))
4918 {
4919 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4920 }
4921 if (isset($restriction['attribs']['']['type']))
4922 {
4923 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4924 }
4925 if (isset($restriction['data']))
4926 {
4927 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4928 }
4929 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4930 }
4931 if (is_array($restrictions))
4932 {
4933 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4934 }
4935 }
4936 else
4937 {
4938 $restrictions = $restrictions_parent;
4939 }
4940
4941 // THUMBNAILS
4942 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4943 {
4944 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4945 {
4946 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4947 }
4948 if (is_array($thumbnails))
4949 {
4950 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4951 }
4952 }
4953 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4954 {
4955 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4956 {
4957 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4958 }
4959 if (is_array($thumbnails))
4960 {
4961 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4962 }
4963 }
4964 else
4965 {
4966 $thumbnails = $thumbnails_parent;
4967 }
4968
4969 // TITLES
4970 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4971 {
4972 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4973 }
4974 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4975 {
4976 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4977 }
4978 else
4979 {
4980 $title = $title_parent;
4981 }
4982
4983 $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);
4984 }
4985 }
4986 }
4987
4988 // If we have standalone media:content tags, loop through them.
4989 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4990 {
4991 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4992 {
4993 if (isset($content['attribs']['']['url']))
4994 {
4995 // Attributes
4996 $bitrate = null;
4997 $channels = null;
4998 $duration = null;
4999 $expression = null;
5000 $framerate = null;
5001 $height = null;
5002 $javascript = null;
5003 $lang = null;
5004 $length = null;
5005 $medium = null;
5006 $samplingrate = null;
5007 $type = null;
5008 $url = null;
5009 $width = null;
5010
5011 // Elements
5012 $captions = null;
5013 $categories = null;
5014 $copyrights = null;
5015 $credits = null;
5016 $description = null;
5017 $hashes = null;
5018 $keywords = null;
5019 $player = null;
5020 $ratings = null;
5021 $restrictions = null;
5022 $thumbnails = null;
5023 $title = null;
5024
5025 // Start checking the attributes of media:content
5026 if (isset($content['attribs']['']['bitrate']))
5027 {
5028 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5029 }
5030 if (isset($content['attribs']['']['channels']))
5031 {
5032 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5033 }
5034 if (isset($content['attribs']['']['duration']))
5035 {
5036 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5037 }
5038 else
5039 {
5040 $duration = $duration_parent;
5041 }
5042 if (isset($content['attribs']['']['expression']))
5043 {
5044 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5045 }
5046 if (isset($content['attribs']['']['framerate']))
5047 {
5048 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5049 }
5050 if (isset($content['attribs']['']['height']))
5051 {
5052 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5053 }
5054 if (isset($content['attribs']['']['lang']))
5055 {
5056 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5057 }
5058 if (isset($content['attribs']['']['fileSize']))
5059 {
5060 $length = ceil($content['attribs']['']['fileSize']);
5061 }
5062 if (isset($content['attribs']['']['medium']))
5063 {
5064 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5065 }
5066 if (isset($content['attribs']['']['samplingrate']))
5067 {
5068 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5069 }
5070 if (isset($content['attribs']['']['type']))
5071 {
5072 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5073 }
5074 if (isset($content['attribs']['']['width']))
5075 {
5076 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5077 }
5078 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5079
5080 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5081
5082 // CAPTIONS
5083 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5084 {
5085 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5086 {
5087 $caption_type = null;
5088 $caption_lang = null;
5089 $caption_startTime = null;
5090 $caption_endTime = null;
5091 $caption_text = null;
5092 if (isset($caption['attribs']['']['type']))
5093 {
5094 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5095 }
5096 if (isset($caption['attribs']['']['lang']))
5097 {
5098 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5099 }
5100 if (isset($caption['attribs']['']['start']))
5101 {
5102 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5103 }
5104 if (isset($caption['attribs']['']['end']))
5105 {
5106 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5107 }
5108 if (isset($caption['data']))
5109 {
5110 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5111 }
5112 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5113 }
5114 if (is_array($captions))
5115 {
5116 $captions = array_values(SimplePie_Misc::array_unique($captions));
5117 }
5118 }
5119 else
5120 {
5121 $captions = $captions_parent;
5122 }
5123
5124 // CATEGORIES
5125 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5126 {
5127 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5128 {
5129 $term = null;
5130 $scheme = null;
5131 $label = null;
5132 if (isset($category['data']))
5133 {
5134 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5135 }
5136 if (isset($category['attribs']['']['scheme']))
5137 {
5138 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5139 }
5140 else
5141 {
5142 $scheme = 'http://search.yahoo.com/mrss/category_schema';
5143 }
5144 if (isset($category['attribs']['']['label']))
5145 {
5146 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5147 }
5148 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
5149 }
5150 }
5151 if (is_array($categories) && is_array($categories_parent))
5152 {
5153 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5154 }
5155 elseif (is_array($categories))
5156 {
5157 $categories = array_values(SimplePie_Misc::array_unique($categories));
5158 }
5159 elseif (is_array($categories_parent))
5160 {
5161 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5162 }
5163 else
5164 {
5165 $categories = null;
5166 }
5167
5168 // COPYRIGHTS
5169 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5170 {
5171 $copyright_url = null;
5172 $copyright_label = null;
5173 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5174 {
5175 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5176 }
5177 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5178 {
5179 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5180 }
5181 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
5182 }
5183 else
5184 {
5185 $copyrights = $copyrights_parent;
5186 }
5187
5188 // CREDITS
5189 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5190 {
5191 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5192 {
5193 $credit_role = null;
5194 $credit_scheme = null;
5195 $credit_name = null;
5196 if (isset($credit['attribs']['']['role']))
5197 {
5198 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5199 }
5200 if (isset($credit['attribs']['']['scheme']))
5201 {
5202 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5203 }
5204 else
5205 {
5206 $credit_scheme = 'urn:ebu';
5207 }
5208 if (isset($credit['data']))
5209 {
5210 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5211 }
5212 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5213 }
5214 if (is_array($credits))
5215 {
5216 $credits = array_values(SimplePie_Misc::array_unique($credits));
5217 }
5218 }
5219 else
5220 {
5221 $credits = $credits_parent;
5222 }
5223
5224 // DESCRIPTION
5225 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5226 {
5227 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5228 }
5229 else
5230 {
5231 $description = $description_parent;
5232 }
5233
5234 // HASHES
5235 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5236 {
5237 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5238 {
5239 $value = null;
5240 $algo = null;
5241 if (isset($hash['data']))
5242 {
5243 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5244 }
5245 if (isset($hash['attribs']['']['algo']))
5246 {
5247 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5248 }
5249 else
5250 {
5251 $algo = 'md5';
5252 }
5253 $hashes[] = $algo.':'.$value;
5254 }
5255 if (is_array($hashes))
5256 {
5257 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5258 }
5259 }
5260 else
5261 {
5262 $hashes = $hashes_parent;
5263 }
5264
5265 // KEYWORDS
5266 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5267 {
5268 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5269 {
5270 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5271 foreach ($temp as $word)
5272 {
5273 $keywords[] = trim($word);
5274 }
5275 unset($temp);
5276 }
5277 if (is_array($keywords))
5278 {
5279 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5280 }
5281 }
5282 else
5283 {
5284 $keywords = $keywords_parent;
5285 }
5286
5287 // PLAYER
5288 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5289 {
5290 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5291 }
5292 else
5293 {
5294 $player = $player_parent;
5295 }
5296
5297 // RATINGS
5298 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5299 {
5300 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5301 {
5302 $rating_scheme = null;
5303 $rating_value = null;
5304 if (isset($rating['attribs']['']['scheme']))
5305 {
5306 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5307 }
5308 else
5309 {
5310 $rating_scheme = 'urn:simple';
5311 }
5312 if (isset($rating['data']))
5313 {
5314 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5315 }
5316 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
5317 }
5318 if (is_array($ratings))
5319 {
5320 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5321 }
5322 }
5323 else
5324 {
5325 $ratings = $ratings_parent;
5326 }
5327
5328 // RESTRICTIONS
5329 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5330 {
5331 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5332 {
5333 $restriction_relationship = null;
5334 $restriction_type = null;
5335 $restriction_value = null;
5336 if (isset($restriction['attribs']['']['relationship']))
5337 {
5338 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5339 }
5340 if (isset($restriction['attribs']['']['type']))
5341 {
5342 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5343 }
5344 if (isset($restriction['data']))
5345 {
5346 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5347 }
5348 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5349 }
5350 if (is_array($restrictions))
5351 {
5352 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5353 }
5354 }
5355 else
5356 {
5357 $restrictions = $restrictions_parent;
5358 }
5359
5360 // THUMBNAILS
5361 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5362 {
5363 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5364 {
5365 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5366 }
5367 if (is_array($thumbnails))
5368 {
5369 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5370 }
5371 }
5372 else
5373 {
5374 $thumbnails = $thumbnails_parent;
5375 }
5376
5377 // TITLES
5378 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5379 {
5380 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5381 }
5382 else
5383 {
5384 $title = $title_parent;
5385 }
5386
5387 $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);
5388 }
5389 }
5390 }
5391
5392 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5393 {
5394 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5395 {
5396 // Attributes
5397 $bitrate = null;
5398 $channels = null;
5399 $duration = null;
5400 $expression = null;
5401 $framerate = null;
5402 $height = null;
5403 $javascript = null;
5404 $lang = null;
5405 $length = null;
5406 $medium = null;
5407 $samplingrate = null;
5408 $type = null;
5409 $url = null;
5410 $width = null;
5411
5412 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5413 if (isset($link['attribs']['']['type']))
5414 {
5415 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5416 }
5417 if (isset($link['attribs']['']['length']))
5418 {
5419 $length = ceil($link['attribs']['']['length']);
5420 }
5421
5422 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5423 $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);
5424 }
5425 }
5426
5427 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5428 {
5429 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5430 {
5431 // Attributes
5432 $bitrate = null;
5433 $channels = null;
5434 $duration = null;
5435 $expression = null;
5436 $framerate = null;
5437 $height = null;
5438 $javascript = null;
5439 $lang = null;
5440 $length = null;
5441 $medium = null;
5442 $samplingrate = null;
5443 $type = null;
5444 $url = null;
5445 $width = null;
5446
5447 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5448 if (isset($link['attribs']['']['type']))
5449 {
5450 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5451 }
5452 if (isset($link['attribs']['']['length']))
5453 {
5454 $length = ceil($link['attribs']['']['length']);
5455 }
5456
5457 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5458 $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);
5459 }
5460 }
5461
5462 if ($enclosure = $this->get_item_tags('', 'enclosure'))
5463 {
5464 if (isset($enclosure[0]['attribs']['']['url']))
5465 {
5466 // Attributes
5467 $bitrate = null;
5468 $channels = null;
5469 $duration = null;
5470 $expression = null;
5471 $framerate = null;
5472 $height = null;
5473 $javascript = null;
5474 $lang = null;
5475 $length = null;
5476 $medium = null;
5477 $samplingrate = null;
5478 $type = null;
5479 $url = null;
5480 $width = null;
5481
5482 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5483 if (isset($enclosure[0]['attribs']['']['type']))
5484 {
5485 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5486 }
5487 if (isset($enclosure[0]['attribs']['']['length']))
5488 {
5489 $length = ceil($enclosure[0]['attribs']['']['length']);
5490 }
5491
5492 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5493 $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);
5494 }
5495 }
6d7d21a0 5496
3cae90e1 5497 if (sizeof($this->data['enclosures']) == 0 && ($url || $type || $length || $bitrate || $captions_parent || $categories_parent || $channels || $copyrights_parent || $credits_parent || $description_parent || $duration_parent || $expression || $framerate || $hashes_parent || $height || $keywords_parent || $lang || $medium || $player_parent || $ratings_parent || $restrictions_parent || $samplingrate || $thumbnails_parent || $title_parent || $width))
6d7d21a0
AD
5498 {
5499 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5500 $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);
5501 }
5502
f2f7b699
AD
5503 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5504 }
5505 if (!empty($this->data['enclosures']))
5506 {
5507 return $this->data['enclosures'];
5508 }
5509 else
5510 {
5511 return null;
5512 }
5513 }
5514
5515 function get_latitude()
5516 {
5517 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5518 {
5519 return (float) $return[0]['data'];
5520 }
5521 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5522 {
5523 return (float) $match[1];
5524 }
5525 else
5526 {
5527 return null;
5528 }
5529 }
5530
5531 function get_longitude()
5532 {
5533 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5534 {
5535 return (float) $return[0]['data'];
5536 }
5537 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5538 {
5539 return (float) $return[0]['data'];
5540 }
5541 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5542 {
5543 return (float) $match[2];
5544 }
5545 else
5546 {
5547 return null;
5548 }
5549 }
6d7d21a0
AD
5550
5551 function get_source()
5552 {
5553 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5554 {
5555 return new $this->feed->source_class($this, $return[0]);
5556 }
5557 else
5558 {
5559 return null;
5560 }
5561 }
f2f7b699
AD
5562
5563 /**
5564 * Creates the add_to_* methods' return data
5565 *
5566 * @access private
5567 * @param string $item_url String to prefix to the item permalink
5568 * @param string $title_url String to prefix to the item title
5569 * (and suffix to the item permalink)
5570 * @return mixed URL if feed exists, false otherwise
5571 */
3cae90e1 5572 function add_to_service($item_url, $title_url = null, $summary_url = null)
f2f7b699
AD
5573 {
5574 if ($this->get_permalink() !== null)
5575 {
5576 $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5577 if ($title_url !== null && $this->get_title() !== null)
5578 {
5579 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5580 }
3cae90e1
AD
5581 if ($summary_url !== null && $this->get_description() !== null)
5582 {
5583 $return .= $this->sanitize($summary_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_description());
5584 }
f2f7b699
AD
5585 return $return;
5586 }
5587 else
5588 {
5589 return null;
5590 }
5591 }
5592
5593 function add_to_blinklist()
5594 {
5595 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5596 }
5597
5598 function add_to_blogmarks()
5599 {
5600 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5601 }
5602
5603 function add_to_delicious()
5604 {
6d7d21a0 5605 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
f2f7b699
AD
5606 }
5607
5608 function add_to_digg()
5609 {
3cae90e1 5610 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
f2f7b699
AD
5611 }
5612
5613 function add_to_furl()
5614 {
5615 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5616 }
5617
5618 function add_to_magnolia()
5619 {
5620 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5621 }
5622
5623 function add_to_myweb20()
5624 {
5625 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5626 }
5627
5628 function add_to_newsvine()
5629 {
5630 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5631 }
5632
5633 function add_to_reddit()
5634 {
5635 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5636 }
5637
5638 function add_to_segnalo()
5639 {
5640 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5641 }
5642
5643 function add_to_simpy()
5644 {
5645 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5646 }
5647
5648 function add_to_spurl()
5649 {
5650 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5651 }
5652
5653 function add_to_wists()
5654 {
5655 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5656 }
5657
5658 function search_technorati()
5659 {
5660 return $this->add_to_service('http://www.technorati.com/search/');
5661 }
5662}
5663
6d7d21a0 5664class SimplePie_Source
f2f7b699 5665{
6d7d21a0
AD
5666 var $item;
5667 var $data = array();
f2f7b699 5668
6d7d21a0 5669 function SimplePie_Source($item, $data)
f2f7b699 5670 {
6d7d21a0
AD
5671 $this->item = $item;
5672 $this->data = $data;
f2f7b699
AD
5673 }
5674
5675 function __toString()
5676 {
6d7d21a0 5677 return md5(serialize($this->data));
f2f7b699 5678 }
6d7d21a0
AD
5679
5680 /**
5681 * Remove items that link back to this before destroying this object
5682 */
5683 function __destruct()
f2f7b699 5684 {
6d7d21a0 5685 unset($this->item);
f2f7b699
AD
5686 }
5687
6d7d21a0 5688 function get_source_tags($namespace, $tag)
f2f7b699 5689 {
6d7d21a0 5690 if (isset($this->data['child'][$namespace][$tag]))
f2f7b699 5691 {
6d7d21a0 5692 return $this->data['child'][$namespace][$tag];
f2f7b699
AD
5693 }
5694 else
5695 {
5696 return null;
5697 }
5698 }
5699
6d7d21a0 5700 function get_base($element = array())
f2f7b699 5701 {
6d7d21a0 5702 return $this->item->get_base($element);
f2f7b699 5703 }
f2f7b699 5704
6d7d21a0 5705 function sanitize($data, $type, $base = '')
f2f7b699 5706 {
6d7d21a0 5707 return $this->item->sanitize($data, $type, $base);
f2f7b699
AD
5708 }
5709
6d7d21a0 5710 function get_item()
f2f7b699 5711 {
6d7d21a0 5712 return $this->item;
f2f7b699
AD
5713 }
5714
6d7d21a0 5715 function get_title()
f2f7b699 5716 {
6d7d21a0 5717 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
f2f7b699 5718 {
6d7d21a0
AD
5719 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5720 }
5721 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5722 {
5723 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5724 }
5725 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5726 {
5727 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5728 }
5729 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5730 {
5731 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5732 }
5733 elseif ($return = $this->get_source_tags('', 'title'))
5734 {
5735 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5736 }
5737 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5738 {
5739 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5740 }
5741 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5742 {
5743 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
f2f7b699
AD
5744 }
5745 else
5746 {
5747 return null;
5748 }
5749 }
5750
6d7d21a0 5751 function get_category($key = 0)
f2f7b699 5752 {
6d7d21a0
AD
5753 $categories = $this->get_categories();
5754 if (isset($categories[$key]))
f2f7b699 5755 {
6d7d21a0 5756 return $categories[$key];
f2f7b699
AD
5757 }
5758 else
5759 {
5760 return null;
5761 }
5762 }
5763
6d7d21a0 5764 function get_categories()
f2f7b699 5765 {
6d7d21a0
AD
5766 $categories = array();
5767
5768 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
f2f7b699 5769 {
6d7d21a0
AD
5770 $term = null;
5771 $scheme = null;
5772 $label = null;
5773 if (isset($category['attribs']['']['term']))
5774 {
5775 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5776 }
5777 if (isset($category['attribs']['']['scheme']))
5778 {
5779 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5780 }
5781 if (isset($category['attribs']['']['label']))
5782 {
5783 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5784 }
5785 $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
f2f7b699 5786 }
6d7d21a0 5787 foreach ((array) $this->get_source_tags('', 'category') as $category)
f2f7b699 5788 {
6d7d21a0
AD
5789 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5790 }
5791 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5792 {
5793 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5794 }
5795 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5796 {
5797 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
f2f7b699 5798 }
f2f7b699 5799
6d7d21a0 5800 if (!empty($categories))
f2f7b699 5801 {
6d7d21a0 5802 return SimplePie_Misc::array_unique($categories);
f2f7b699
AD
5803 }
5804 else
5805 {
5806 return null;
5807 }
5808 }
5809
6d7d21a0 5810 function get_author($key = 0)
f2f7b699 5811 {
6d7d21a0
AD
5812 $authors = $this->get_authors();
5813 if (isset($authors[$key]))
f2f7b699 5814 {
6d7d21a0 5815 return $authors[$key];
f2f7b699
AD
5816 }
5817 else
5818 {
5819 return null;
5820 }
5821 }
5822
6d7d21a0 5823 function get_authors()
f2f7b699 5824 {
6d7d21a0
AD
5825 $authors = array();
5826 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
f2f7b699 5827 {
6d7d21a0
AD
5828 $name = null;
5829 $uri = null;
5830 $email = null;
5831 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5832 {
5833 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5834 }
5835 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5836 {
5837 $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]));
5838 }
5839 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5840 {
5841 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5842 }
5843 if ($name !== null || $email !== null || $uri !== null)
5844 {
5845 $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
5846 }
f2f7b699 5847 }
6d7d21a0 5848 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
f2f7b699 5849 {
6d7d21a0
AD
5850 $name = null;
5851 $url = null;
5852 $email = null;
5853 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5854 {
5855 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5856 }
5857 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5858 {
5859 $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]));
5860 }
5861 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5862 {
5863 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5864 }
5865 if ($name !== null || $email !== null || $url !== null)
5866 {
5867 $authors[] =& new $this->item->feed->author_class($name, $url, $email);
5868 }
f2f7b699 5869 }
6d7d21a0 5870 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
f2f7b699 5871 {
6d7d21a0 5872 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
f2f7b699 5873 }
6d7d21a0 5874 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
f2f7b699 5875 {
6d7d21a0
AD
5876 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5877 }
5878 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5879 {
5880 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
f2f7b699 5881 }
f2f7b699 5882
6d7d21a0 5883 if (!empty($authors))
f2f7b699 5884 {
6d7d21a0 5885 return SimplePie_Misc::array_unique($authors);
f2f7b699
AD
5886 }
5887 else
5888 {
5889 return null;
5890 }
5891 }
5892
6d7d21a0 5893 function get_contributor($key = 0)
f2f7b699 5894 {
6d7d21a0
AD
5895 $contributors = $this->get_contributors();
5896 if (isset($contributors[$key]))
f2f7b699 5897 {
6d7d21a0 5898 return $contributors[$key];
f2f7b699
AD
5899 }
5900 else
5901 {
5902 return null;
5903 }
5904 }
5905
6d7d21a0 5906 function get_contributors()
f2f7b699 5907 {
6d7d21a0
AD
5908 $contributors = array();
5909 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
f2f7b699 5910 {
6d7d21a0
AD
5911 $name = null;
5912 $uri = null;
5913 $email = null;
5914 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5915 {
5916 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5917 }
5918 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5919 {
5920 $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]));
5921 }
5922 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5923 {
5924 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5925 }
5926 if ($name !== null || $email !== null || $uri !== null)
5927 {
5928 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
5929 }
f2f7b699 5930 }
6d7d21a0 5931 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
f2f7b699 5932 {
6d7d21a0
AD
5933 $name = null;
5934 $url = null;
5935 $email = null;
5936 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5937 {
5938 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5939 }
5940 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5941 {
5942 $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]));
5943 }
5944 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5945 {
5946 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5947 }
5948 if ($name !== null || $email !== null || $url !== null)
5949 {
5950 $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
5951 }
f2f7b699 5952 }
f2f7b699 5953
6d7d21a0 5954 if (!empty($contributors))
f2f7b699 5955 {
6d7d21a0 5956 return SimplePie_Misc::array_unique($contributors);
f2f7b699
AD
5957 }
5958 else
5959 {
5960 return null;
5961 }
5962 }
5963
6d7d21a0 5964 function get_link($key = 0, $rel = 'alternate')
f2f7b699 5965 {
6d7d21a0
AD
5966 $links = $this->get_links($rel);
5967 if (isset($links[$key]))
f2f7b699 5968 {
6d7d21a0 5969 return $links[$key];
f2f7b699
AD
5970 }
5971 else
5972 {
5973 return null;
5974 }
5975 }
5976
6d7d21a0
AD
5977 /**
5978 * Added for parity between the parent-level and the item/entry-level.
5979 */
5980 function get_permalink()
f2f7b699 5981 {
6d7d21a0 5982 return $this->get_link(0);
f2f7b699
AD
5983 }
5984
6d7d21a0 5985 function get_links($rel = 'alternate')
f2f7b699 5986 {
6d7d21a0 5987 if (!isset($this->data['links']))
f2f7b699 5988 {
6d7d21a0
AD
5989 $this->data['links'] = array();
5990 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
f2f7b699 5991 {
6d7d21a0
AD
5992 foreach ($links as $link)
5993 {
5994 if (isset($link['attribs']['']['href']))
5995 {
5996 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
5997 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5998 }
5999 }
f2f7b699 6000 }
6d7d21a0 6001 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
f2f7b699 6002 {
6d7d21a0
AD
6003 foreach ($links as $link)
6004 {
6005 if (isset($link['attribs']['']['href']))
6006 {
6007 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6008 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
f2f7b699 6009
6d7d21a0
AD
6010 }
6011 }
6012 }
6013 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
f2f7b699 6014 {
6d7d21a0
AD
6015 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6016 }
6017 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6018 {
6019 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6020 }
6021 if ($links = $this->get_source_tags('', 'link'))
6022 {
6023 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6024 }
6025
6026 $keys = array_keys($this->data['links']);
6027 foreach ($keys as $key)
6028 {
6029 if (SimplePie_Misc::is_isegment_nz_nc($key))
6030 {
6031 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6032 {
6033 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6034 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6035 }
6036 else
6037 {
6038 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6039 }
6040 }
6041 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6042 {
6043 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6044 }
6045 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
f2f7b699
AD
6046 }
6047 }
f2f7b699 6048
6d7d21a0 6049 if (isset($this->data['links'][$rel]))
f2f7b699 6050 {
6d7d21a0 6051 return $this->data['links'][$rel];
f2f7b699
AD
6052 }
6053 else
6054 {
6055 return null;
6056 }
6057 }
6058
6d7d21a0 6059 function get_description()
f2f7b699 6060 {
6d7d21a0 6061 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
f2f7b699 6062 {
6d7d21a0 6063 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
f2f7b699 6064 }
6d7d21a0 6065 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
f2f7b699 6066 {
6d7d21a0 6067 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
f2f7b699 6068 }
6d7d21a0 6069 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
f2f7b699 6070 {
6d7d21a0 6071 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
f2f7b699 6072 }
6d7d21a0 6073 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
f2f7b699 6074 {
6d7d21a0 6075 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
f2f7b699 6076 }
6d7d21a0 6077 elseif ($return = $this->get_source_tags('', 'description'))
f2f7b699 6078 {
6d7d21a0 6079 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
f2f7b699 6080 }
6d7d21a0 6081 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
f2f7b699 6082 {
6d7d21a0 6083 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
f2f7b699 6084 }
6d7d21a0 6085 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
f2f7b699 6086 {
6d7d21a0 6087 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
f2f7b699 6088 }
6d7d21a0 6089 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
f2f7b699 6090 {
6d7d21a0 6091 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
f2f7b699 6092 }
6d7d21a0 6093 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
f2f7b699 6094 {
6d7d21a0 6095 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
f2f7b699
AD
6096 }
6097 else
6098 {
6099 return null;
6100 }
6101 }
6102
6d7d21a0 6103 function get_copyright()
f2f7b699 6104 {
6d7d21a0 6105 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
f2f7b699 6106 {
6d7d21a0 6107 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
f2f7b699 6108 }
6d7d21a0 6109 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
f2f7b699 6110 {
6d7d21a0 6111 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
f2f7b699 6112 }
6d7d21a0 6113 elseif ($return = $this->get_source_tags('', 'copyright'))
f2f7b699 6114 {
6d7d21a0 6115 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
f2f7b699 6116 }
6d7d21a0 6117 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
f2f7b699 6118 {
6d7d21a0 6119 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
f2f7b699 6120 }
6d7d21a0 6121 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
f2f7b699 6122 {
6d7d21a0 6123 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
f2f7b699
AD
6124 }
6125 else
6126 {
6127 return null;
6128 }
6129 }
6130
6d7d21a0 6131 function get_language()
f2f7b699 6132 {
6d7d21a0 6133 if ($return = $this->get_source_tags('', 'language'))
f2f7b699 6134 {
6d7d21a0 6135 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
f2f7b699 6136 }
6d7d21a0 6137 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
f2f7b699 6138 {
6d7d21a0 6139 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
f2f7b699 6140 }
6d7d21a0 6141 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
f2f7b699 6142 {
6d7d21a0
AD
6143 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6144 }
6145 elseif (isset($this->data['xml_lang']))
6146 {
6147 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
f2f7b699
AD
6148 }
6149 else
6150 {
6151 return null;
6152 }
6153 }
6154
6d7d21a0 6155 function get_latitude()
f2f7b699 6156 {
6d7d21a0 6157 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
f2f7b699 6158 {
6d7d21a0
AD
6159 return (float) $return[0]['data'];
6160 }
6161 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6162 {
6163 return (float) $match[1];
f2f7b699
AD
6164 }
6165 else
6166 {
6167 return null;
6168 }
6169 }
6170
6d7d21a0 6171 function get_longitude()
f2f7b699 6172 {
6d7d21a0 6173 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
f2f7b699 6174 {
6d7d21a0 6175 return (float) $return[0]['data'];
f2f7b699 6176 }
6d7d21a0 6177 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
f2f7b699 6178 {
6d7d21a0 6179 return (float) $return[0]['data'];
f2f7b699 6180 }
6d7d21a0 6181 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
f2f7b699 6182 {
6d7d21a0 6183 return (float) $match[2];
f2f7b699
AD
6184 }
6185 else
6186 {
6187 return null;
6188 }
6189 }
6190
6d7d21a0 6191 function get_image_url()
f2f7b699 6192 {
6d7d21a0 6193 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
f2f7b699 6194 {
6d7d21a0 6195 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
f2f7b699 6196 }
6d7d21a0 6197 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
f2f7b699 6198 {
6d7d21a0 6199 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
f2f7b699 6200 }
6d7d21a0 6201 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
f2f7b699 6202 {
6d7d21a0 6203 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
f2f7b699
AD
6204 }
6205 else
6206 {
6207 return null;
6208 }
6209 }
6d7d21a0 6210}
f2f7b699 6211
6d7d21a0
AD
6212class SimplePie_Author
6213{
6214 var $name;
6215 var $link;
6216 var $email;
6217
6218 // Constructor, used to input the data
6219 function SimplePie_Author($name = null, $link = null, $email = null)
f2f7b699 6220 {
6d7d21a0
AD
6221 $this->name = $name;
6222 $this->link = $link;
6223 $this->email = $email;
6224 }
6225
6226 function __toString()
6227 {
6228 // There is no $this->data here
6229 return md5(serialize($this));
6230 }
6231
6232 function get_name()
6233 {
6234 if ($this->name !== null)
f2f7b699 6235 {
6d7d21a0 6236 return $this->name;
f2f7b699
AD
6237 }
6238 else
6239 {
6240 return null;
6241 }
6242 }
6243
6d7d21a0 6244 function get_link()
f2f7b699 6245 {
6d7d21a0 6246 if ($this->link !== null)
f2f7b699 6247 {
6d7d21a0 6248 return $this->link;
f2f7b699
AD
6249 }
6250 else
6251 {
6252 return null;
6253 }
6254 }
6255
6d7d21a0 6256 function get_email()
f2f7b699 6257 {
6d7d21a0 6258 if ($this->email !== null)
f2f7b699 6259 {
6d7d21a0 6260 return $this->email;
f2f7b699
AD
6261 }
6262 else
6263 {
6264 return null;
6265 }
6266 }
6d7d21a0 6267}
f2f7b699 6268
6d7d21a0
AD
6269class SimplePie_Category
6270{
6271 var $term;
6272 var $scheme;
6273 var $label;
6274
6275 // Constructor, used to input the data
6276 function SimplePie_Category($term = null, $scheme = null, $label = null)
f2f7b699 6277 {
6d7d21a0
AD
6278 $this->term = $term;
6279 $this->scheme = $scheme;
6280 $this->label = $label;
6281 }
6282
6283 function __toString()
6284 {
6285 // There is no $this->data here
6286 return md5(serialize($this));
6287 }
6288
6289 function get_term()
6290 {
6291 if ($this->term !== null)
f2f7b699 6292 {
6d7d21a0 6293 return $this->term;
f2f7b699
AD
6294 }
6295 else
6296 {
6297 return null;
6298 }
6299 }
6300
6d7d21a0 6301 function get_scheme()
f2f7b699 6302 {
6d7d21a0 6303 if ($this->scheme !== null)
f2f7b699 6304 {
6d7d21a0 6305 return $this->scheme;
f2f7b699
AD
6306 }
6307 else
6308 {
6309 return null;
6310 }
6311 }
6312
6d7d21a0 6313 function get_label()
f2f7b699 6314 {
6d7d21a0 6315 if ($this->label !== null)
f2f7b699 6316 {
6d7d21a0 6317 return $this->label;
f2f7b699
AD
6318 }
6319 else
6320 {
6d7d21a0 6321 return $this->get_term();
f2f7b699
AD
6322 }
6323 }
6d7d21a0 6324}
f2f7b699 6325
6d7d21a0
AD
6326class SimplePie_Enclosure
6327{
6328 var $bitrate;
6329 var $captions;
6330 var $categories;
6331 var $channels;
6332 var $copyright;
6333 var $credits;
6334 var $description;
6335 var $duration;
6336 var $expression;
6337 var $framerate;
6338 var $handler;
6339 var $hashes;
6340 var $height;
6341 var $javascript;
6342 var $keywords;
6343 var $lang;
6344 var $length;
6345 var $link;
6346 var $medium;
6347 var $player;
6348 var $ratings;
6349 var $restrictions;
6350 var $samplingrate;
6351 var $thumbnails;
6352 var $title;
6353 var $type;
6354 var $width;
6355
6356 // Constructor, used to input the data
6357 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)
f2f7b699 6358 {
6d7d21a0
AD
6359 $this->bitrate = $bitrate;
6360 $this->captions = $captions;
6361 $this->categories = $categories;
6362 $this->channels = $channels;
6363 $this->copyright = $copyright;
6364 $this->credits = $credits;
6365 $this->description = $description;
6366 $this->duration = $duration;
6367 $this->expression = $expression;
6368 $this->framerate = $framerate;
6369 $this->hashes = $hashes;
6370 $this->height = $height;
6371 $this->javascript = $javascript;
6372 $this->keywords = $keywords;
6373 $this->lang = $lang;
6374 $this->length = $length;
6375 $this->link = $link;
6376 $this->medium = $medium;
6377 $this->player = $player;
6378 $this->ratings = $ratings;
6379 $this->restrictions = $restrictions;
6380 $this->samplingrate = $samplingrate;
6381 $this->thumbnails = $thumbnails;
6382 $this->title = $title;
6383 $this->type = $type;
6384 $this->width = $width;
6385 if (class_exists('idna_convert'))
6386 {
6387 $idn =& new idna_convert;
6388 $parsed = SimplePie_Misc::parse_url($link);
6389 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6390 }
6391 $this->handler = $this->get_handler(); // Needs to load last
f2f7b699
AD
6392 }
6393
6d7d21a0 6394 function __toString()
f2f7b699 6395 {
6d7d21a0
AD
6396 // There is no $this->data here
6397 return md5(serialize($this));
6398 }
f2f7b699 6399
6d7d21a0
AD
6400 function get_bitrate()
6401 {
6402 if ($this->bitrate !== null)
f2f7b699 6403 {
6d7d21a0 6404 return $this->bitrate;
f2f7b699
AD
6405 }
6406 else
6407 {
6d7d21a0 6408 return null;
f2f7b699 6409 }
6d7d21a0 6410 }
f2f7b699 6411
6d7d21a0
AD
6412 function get_caption($key = 0)
6413 {
6414 $captions = $this->get_captions();
6415 if (isset($captions[$key]))
f2f7b699 6416 {
6d7d21a0
AD
6417 return $captions[$key];
6418 }
6419 else
6420 {
6421 return null;
f2f7b699 6422 }
6d7d21a0 6423 }
f2f7b699 6424
6d7d21a0
AD
6425 function get_captions()
6426 {
6427 if ($this->captions !== null)
f2f7b699 6428 {
6d7d21a0 6429 return $this->captions;
f2f7b699 6430 }
6d7d21a0 6431 else
f2f7b699 6432 {
6d7d21a0 6433 return null;
f2f7b699 6434 }
6d7d21a0 6435 }
f2f7b699 6436
6d7d21a0
AD
6437 function get_category($key = 0)
6438 {
6439 $categories = $this->get_categories();
6440 if (isset($categories[$key]))
f2f7b699 6441 {
6d7d21a0 6442 return $categories[$key];
f2f7b699 6443 }
6d7d21a0 6444 else
f2f7b699 6445 {
6d7d21a0 6446 return null;
f2f7b699 6447 }
6d7d21a0 6448 }
f2f7b699 6449
6d7d21a0
AD
6450 function get_categories()
6451 {
6452 if ($this->categories !== null)
f2f7b699 6453 {
6d7d21a0 6454 return $this->categories;
f2f7b699 6455 }
6d7d21a0 6456 else
f2f7b699 6457 {
6d7d21a0 6458 return null;
f2f7b699 6459 }
6d7d21a0 6460 }
f2f7b699 6461
6d7d21a0
AD
6462 function get_channels()
6463 {
6464 if ($this->channels !== null)
f2f7b699 6465 {
6d7d21a0
AD
6466 return $this->channels;
6467 }
6468 else
6469 {
6470 return null;
f2f7b699 6471 }
6d7d21a0 6472 }
f2f7b699 6473
6d7d21a0
AD
6474 function get_copyright()
6475 {
6476 if ($this->copyright !== null)
f2f7b699 6477 {
6d7d21a0
AD
6478 return $this->copyright;
6479 }
6480 else
6481 {
6482 return null;
f2f7b699 6483 }
6d7d21a0 6484 }
f2f7b699 6485
6d7d21a0
AD
6486 function get_credit($key = 0)
6487 {
6488 $credits = $this->get_credits();
6489 if (isset($credits[$key]))
f2f7b699 6490 {
6d7d21a0
AD
6491 return $credits[$key];
6492 }
6493 else
6494 {
6495 return null;
f2f7b699 6496 }
6d7d21a0 6497 }
f2f7b699 6498
6d7d21a0
AD
6499 function get_credits()
6500 {
6501 if ($this->credits !== null)
f2f7b699 6502 {
6d7d21a0
AD
6503 return $this->credits;
6504 }
6505 else
6506 {
6507 return null;
6508 }
6509 }
6510
6511 function get_description()
6512 {
6513 if ($this->description !== null)
6514 {
6515 return $this->description;
6516 }
6517 else
6518 {
6519 return null;
6520 }
6521 }
6522
6523 function get_duration($convert = false)
6524 {
6525 if ($this->duration !== null)
6526 {
6527 if ($convert)
f2f7b699 6528 {
6d7d21a0
AD
6529 $time = SimplePie_Misc::time_hms($this->duration);
6530 return $time;
f2f7b699
AD
6531 }
6532 else
6533 {
6d7d21a0 6534 return $this->duration;
f2f7b699
AD
6535 }
6536 }
6d7d21a0
AD
6537 else
6538 {
6539 return null;
6540 }
6541 }
f2f7b699 6542
6d7d21a0
AD
6543 function get_expression()
6544 {
6545 if ($this->expression !== null)
6546 {
6547 return $this->expression;
6548 }
6549 else
6550 {
6551 return 'full';
6552 }
6553 }
f2f7b699 6554
6d7d21a0
AD
6555 function get_extension()
6556 {
6557 if ($this->link !== null)
6558 {
6559 $url = SimplePie_Misc::parse_url($this->link);
6560 if ($url['path'] !== '')
6561 {
6562 return pathinfo($url['path'], PATHINFO_EXTENSION);
6563 }
6564 }
6565 return null;
f2f7b699
AD
6566 }
6567
6d7d21a0 6568 function get_framerate()
f2f7b699 6569 {
6d7d21a0 6570 if ($this->framerate !== null)
f2f7b699 6571 {
6d7d21a0
AD
6572 return $this->framerate;
6573 }
6574 else
6575 {
6576 return null;
f2f7b699 6577 }
6d7d21a0 6578 }
f2f7b699 6579
6d7d21a0
AD
6580 function get_handler()
6581 {
6582 return $this->get_real_type(true);
6583 }
f2f7b699 6584
6d7d21a0
AD
6585 function get_hash($key = 0)
6586 {
6587 $hashes = $this->get_hashes();
6588 if (isset($hashes[$key]))
f2f7b699 6589 {
6d7d21a0 6590 return $hashes[$key];
f2f7b699
AD
6591 }
6592 else
6593 {
6d7d21a0 6594 return null;
f2f7b699 6595 }
6d7d21a0 6596 }
f2f7b699 6597
6d7d21a0
AD
6598 function get_hashes()
6599 {
6600 if ($this->hashes !== null)
f2f7b699 6601 {
6d7d21a0
AD
6602 return $this->hashes;
6603 }
6604 else
6605 {
6606 return null;
6607 }
6608 }
f2f7b699 6609
6d7d21a0
AD
6610 function get_height()
6611 {
6612 if ($this->height !== null)
6613 {
6614 return $this->height;
6615 }
6616 else
6617 {
6618 return null;
6619 }
6620 }
f2f7b699 6621
6d7d21a0
AD
6622 function get_language()
6623 {
6624 if ($this->lang !== null)
6625 {
6626 return $this->lang;
6627 }
6628 else
6629 {
6630 return null;
6631 }
6632 }
f2f7b699 6633
6d7d21a0
AD
6634 function get_keyword($key = 0)
6635 {
6636 $keywords = $this->get_keywords();
6637 if (isset($keywords[$key]))
6638 {
6639 return $keywords[$key];
6640 }
6641 else
6642 {
6643 return null;
6644 }
6645 }
f2f7b699 6646
6d7d21a0
AD
6647 function get_keywords()
6648 {
6649 if ($this->keywords !== null)
6650 {
6651 return $this->keywords;
6652 }
6653 else
6654 {
6655 return null;
6656 }
6657 }
f2f7b699 6658
6d7d21a0
AD
6659 function get_length()
6660 {
6661 if ($this->length !== null)
f2f7b699 6662 {
6d7d21a0 6663 return $this->length;
f2f7b699
AD
6664 }
6665 else
6666 {
6d7d21a0 6667 return null;
f2f7b699
AD
6668 }
6669 }
f2f7b699 6670
6d7d21a0 6671 function get_link()
f2f7b699 6672 {
6d7d21a0 6673 if ($this->link !== null)
f2f7b699 6674 {
6d7d21a0 6675 return urldecode($this->link);
f2f7b699
AD
6676 }
6677 else
6678 {
6679 return null;
6680 }
6681 }
6682
6d7d21a0 6683 function get_medium()
f2f7b699 6684 {
6d7d21a0 6685 if ($this->medium !== null)
f2f7b699 6686 {
6d7d21a0 6687 return $this->medium;
f2f7b699
AD
6688 }
6689 else
6690 {
6691 return null;
6692 }
6693 }
6694
6d7d21a0 6695 function get_player()
f2f7b699 6696 {
6d7d21a0 6697 if ($this->player !== null)
f2f7b699 6698 {
6d7d21a0 6699 return $this->player;
f2f7b699
AD
6700 }
6701 else
6702 {
6703 return null;
6704 }
6705 }
6706
6d7d21a0 6707 function get_rating($key = 0)
f2f7b699 6708 {
6d7d21a0
AD
6709 $ratings = $this->get_ratings();
6710 if (isset($ratings[$key]))
f2f7b699 6711 {
6d7d21a0 6712 return $ratings[$key];
f2f7b699
AD
6713 }
6714 else
6715 {
6716 return null;
6717 }
6718 }
6719
6d7d21a0 6720 function get_ratings()
f2f7b699 6721 {
6d7d21a0 6722 if ($this->ratings !== null)
f2f7b699 6723 {
6d7d21a0 6724 return $this->ratings;
f2f7b699
AD
6725 }
6726 else
6727 {
6728 return null;
6729 }
6730 }
f2f7b699 6731
6d7d21a0 6732 function get_restriction($key = 0)
f2f7b699 6733 {
6d7d21a0
AD
6734 $restrictions = $this->get_restrictions();
6735 if (isset($restrictions[$key]))
f2f7b699 6736 {
6d7d21a0 6737 return $restrictions[$key];
f2f7b699
AD
6738 }
6739 else
6740 {
6741 return null;
6742 }
6743 }
6744
6d7d21a0 6745 function get_restrictions()
f2f7b699 6746 {
6d7d21a0 6747 if ($this->restrictions !== null)
f2f7b699 6748 {
6d7d21a0 6749 return $this->restrictions;
f2f7b699
AD
6750 }
6751 else
6752 {
6753 return null;
6754 }
6755 }
6756
6d7d21a0 6757 function get_sampling_rate()
f2f7b699 6758 {
6d7d21a0 6759 if ($this->samplingrate !== null)
f2f7b699 6760 {
6d7d21a0 6761 return $this->samplingrate;
f2f7b699
AD
6762 }
6763 else
6764 {
6765 return null;
6766 }
6767 }
f2f7b699 6768
6d7d21a0 6769 function get_size()
f2f7b699 6770 {
6d7d21a0
AD
6771 $length = $this->get_length();
6772 if ($length !== null)
6773 {
6774 return round($length/1048576, 2);
6775 }
6776 else
6777 {
6778 return null;
6779 }
f2f7b699
AD
6780 }
6781
6d7d21a0 6782 function get_thumbnail($key = 0)
f2f7b699 6783 {
6d7d21a0
AD
6784 $thumbnails = $this->get_thumbnails();
6785 if (isset($thumbnails[$key]))
f2f7b699 6786 {
6d7d21a0 6787 return $thumbnails[$key];
f2f7b699
AD
6788 }
6789 else
6790 {
6791 return null;
6792 }
6793 }
6794
6d7d21a0 6795 function get_thumbnails()
f2f7b699 6796 {
6d7d21a0 6797 if ($this->thumbnails !== null)
f2f7b699 6798 {
6d7d21a0 6799 return $this->thumbnails;
f2f7b699
AD
6800 }
6801 else
6802 {
6803 return null;
6804 }
6805 }
f2f7b699 6806
6d7d21a0 6807 function get_title()
f2f7b699 6808 {
6d7d21a0 6809 if ($this->title !== null)
f2f7b699 6810 {
6d7d21a0 6811 return $this->title;
f2f7b699
AD
6812 }
6813 else
6814 {
6815 return null;
6816 }
6817 }
6818
6d7d21a0 6819 function get_type()
f2f7b699 6820 {
6d7d21a0 6821 if ($this->type !== null)
f2f7b699 6822 {
6d7d21a0 6823 return $this->type;
f2f7b699
AD
6824 }
6825 else
6826 {
6827 return null;
6828 }
6829 }
f2f7b699 6830
6d7d21a0 6831 function get_width()
f2f7b699 6832 {
6d7d21a0 6833 if ($this->width !== null)
f2f7b699 6834 {
6d7d21a0 6835 return $this->width;
f2f7b699
AD
6836 }
6837 else
6838 {
6839 return null;
6840 }
6841 }
6842
6d7d21a0 6843 function native_embed($options='')
f2f7b699 6844 {
6d7d21a0 6845 return $this->embed($options, true);
f2f7b699
AD
6846 }
6847
6d7d21a0
AD
6848 /**
6849 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6850 */
6851 function embed($options = '', $native = false)
f2f7b699 6852 {
6d7d21a0
AD
6853 // Set up defaults
6854 $audio = '';
6855 $video = '';
6856 $alt = '';
6857 $altclass = '';
6858 $loop = 'false';
6859 $width = 'auto';
6860 $height = 'auto';
6861 $bgcolor = '#ffffff';
6862 $mediaplayer = '';
6863 $widescreen = false;
6864 $handler = $this->get_handler();
6865 $type = $this->get_real_type();
6866
6867 // Process options and reassign values as necessary
6868 if (is_array($options))
f2f7b699 6869 {
6d7d21a0 6870 extract($options);
f2f7b699
AD
6871 }
6872 else
6873 {
6d7d21a0
AD
6874 $options = explode(',', $options);
6875 foreach($options as $option)
6876 {
6877 $opt = explode(':', $option, 2);
6878 if (isset($opt[0], $opt[1]))
6879 {
6880 $opt[0] = trim($opt[0]);
6881 $opt[1] = trim($opt[1]);
6882 switch ($opt[0])
6883 {
6884 case 'audio':
6885 $audio = $opt[1];
6886 break;
f2f7b699 6887
6d7d21a0
AD
6888 case 'video':
6889 $video = $opt[1];
6890 break;
f2f7b699 6891
6d7d21a0
AD
6892 case 'alt':
6893 $alt = $opt[1];
6894 break;
6895
6896 case 'altclass':
6897 $altclass = $opt[1];
6898 break;
6899
6900 case 'loop':
6901 $loop = $opt[1];
6902 break;
6903
6904 case 'width':
6905 $width = $opt[1];
6906 break;
6907
6908 case 'height':
6909 $height = $opt[1];
6910 break;
6911
6912 case 'bgcolor':
6913 $bgcolor = $opt[1];
6914 break;
6915
6916 case 'mediaplayer':
6917 $mediaplayer = $opt[1];
6918 break;
6919
6920 case 'widescreen':
6921 $widescreen = $opt[1];
6922 break;
6923 }
6924 }
6925 }
f2f7b699 6926 }
6d7d21a0
AD
6927
6928 $mime = explode('/', $type, 2);
6929 $mime = $mime[0];
6930
6931 // Process values for 'auto'
6932 if ($width == 'auto')
f2f7b699 6933 {
6d7d21a0 6934 if ($mime == 'video')
f2f7b699 6935 {
6d7d21a0 6936 if ($height == 'auto')
f2f7b699 6937 {
6d7d21a0 6938 $width = 480;
f2f7b699 6939 }
6d7d21a0 6940 elseif ($widescreen)
f2f7b699 6941 {
6d7d21a0 6942 $width = round((intval($height)/9)*16);
f2f7b699 6943 }
6d7d21a0 6944 else
f2f7b699 6945 {
6d7d21a0 6946 $width = round((intval($height)/3)*4);
f2f7b699 6947 }
6d7d21a0
AD
6948 }
6949 else
6950 {
6951 $width = '100%';
6952 }
6953 }
f2f7b699 6954
6d7d21a0
AD
6955 if ($height == 'auto')
6956 {
6957 if ($mime == 'audio')
6958 {
6959 $height = 0;
6960 }
6961 elseif ($mime == 'video')
6962 {
6963 if ($width == 'auto')
f2f7b699 6964 {
6d7d21a0
AD
6965 if ($widescreen)
6966 {
6967 $height = 270;
6968 }
6969 else
6970 {
6971 $height = 360;
6972 }
f2f7b699 6973 }
6d7d21a0 6974 elseif ($widescreen)
f2f7b699 6975 {
6d7d21a0 6976 $height = round((intval($width)/16)*9);
f2f7b699
AD
6977 }
6978 else
6979 {
6d7d21a0 6980 $height = round((intval($width)/4)*3);
f2f7b699
AD
6981 }
6982 }
6983 else
6984 {
6d7d21a0
AD
6985 $height = 376;
6986 }
6987 }
6988 elseif ($mime == 'audio')
6989 {
6990 $height = 0;
6991 }
f2f7b699 6992
6d7d21a0
AD
6993 // Set proper placeholder value
6994 if ($mime == 'audio')
6995 {
6996 $placeholder = $audio;
6997 }
6998 elseif ($mime == 'video')
6999 {
7000 $placeholder = $video;
7001 }
f2f7b699 7002
6d7d21a0 7003 $embed = '';
f2f7b699 7004
6d7d21a0
AD
7005 // Make sure the JS library is included
7006 if (!$native)
7007 {
7008 static $javascript_outputted = null;
7009 if (!$javascript_outputted && $this->javascript)
7010 {
7011 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7012 $javascript_outputted = true;
f2f7b699
AD
7013 }
7014 }
6d7d21a0
AD
7015
7016 // Odeo Feed MP3's
7017 if ($handler == 'odeo')
f2f7b699 7018 {
6d7d21a0 7019 if ($native)
f2f7b699 7020 {
6d7d21a0
AD
7021 $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>';
7022 }
7023 else
7024 {
7025 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
f2f7b699
AD
7026 }
7027 }
6d7d21a0
AD
7028
7029 // Flash
7030 elseif ($handler == 'flash')
f2f7b699 7031 {
6d7d21a0 7032 if ($native)
f2f7b699 7033 {
6d7d21a0 7034 $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>";
f2f7b699
AD
7035 }
7036 else
7037 {
6d7d21a0 7038 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
f2f7b699
AD
7039 }
7040 }
f2f7b699 7041
6d7d21a0
AD
7042 // Flash Media Player file types.
7043 // Preferred handler for MP3 file types.
7044 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7045 {
7046 $height += 20;
7047 if ($native)
7048 {
7049 $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>";
7050 }
7051 else
7052 {
7053 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7054 }
7055 }
f2f7b699 7056
6d7d21a0
AD
7057 // QuickTime 7 file types. Need to test with QuickTime 6.
7058 // Only handle MP3's if the Flash Media Player is not present.
7059 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7060 {
7061 $height += 16;
7062 if ($native)
7063 {
7064 if ($placeholder != ""){
7065 $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>";
7066 }
7067 else {
7068 $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>";
7069 }
7070 }
7071 else
7072 {
7073 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7074 }
7075 }
f2f7b699 7076
6d7d21a0
AD
7077 // Windows Media
7078 elseif ($handler == 'wmedia')
7079 {
7080 $height += 45;
7081 if ($native)
7082 {
7083 $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>";
7084 }
7085 else
7086 {
7087 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7088 }
7089 }
f2f7b699 7090
6d7d21a0
AD
7091 // Everything else
7092 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
f2f7b699 7093
6d7d21a0
AD
7094 return $embed;
7095 }
f2f7b699 7096
6d7d21a0 7097 function get_real_type($find_handler = false)
f2f7b699 7098 {
6d7d21a0
AD
7099 // If it's Odeo, let's get it out of the way.
7100 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
f2f7b699 7101 {
6d7d21a0 7102 return 'odeo';
f2f7b699 7103 }
f2f7b699 7104
6d7d21a0
AD
7105 // Mime-types by handler.
7106 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7107 $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
7108 $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
7109 $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
7110 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
f2f7b699 7111
6d7d21a0 7112 if ($this->get_type() !== null)
f2f7b699 7113 {
6d7d21a0 7114 $type = strtolower($this->type);
f2f7b699
AD
7115 }
7116 else
7117 {
6d7d21a0 7118 $type = null;
f2f7b699 7119 }
f2f7b699 7120
6d7d21a0
AD
7121 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7122 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
f2f7b699 7123 {
6d7d21a0 7124 switch (strtolower($this->get_extension()))
f2f7b699 7125 {
6d7d21a0
AD
7126 // Audio mime-types
7127 case 'aac':
7128 case 'adts':
7129 $type = 'audio/acc';
7130 break;
f2f7b699 7131
6d7d21a0
AD
7132 case 'aif':
7133 case 'aifc':
7134 case 'aiff':
7135 case 'cdda':
7136 $type = 'audio/aiff';
7137 break;
f2f7b699 7138
6d7d21a0
AD
7139 case 'bwf':
7140 $type = 'audio/wav';
7141 break;
f2f7b699 7142
6d7d21a0
AD
7143 case 'kar':
7144 case 'mid':
7145 case 'midi':
7146 case 'smf':
7147 $type = 'audio/midi';
7148 break;
f2f7b699 7149
6d7d21a0
AD
7150 case 'm4a':
7151 $type = 'audio/x-m4a';
7152 break;
f2f7b699 7153
6d7d21a0
AD
7154 case 'mp3':
7155 case 'swa':
7156 $type = 'audio/mp3';
7157 break;
f2f7b699 7158
6d7d21a0
AD
7159 case 'wav':
7160 $type = 'audio/wav';
7161 break;
f2f7b699 7162
6d7d21a0
AD
7163 case 'wax':
7164 $type = 'audio/x-ms-wax';
7165 break;
f2f7b699 7166
6d7d21a0
AD
7167 case 'wma':
7168 $type = 'audio/x-ms-wma';
7169 break;
f2f7b699 7170
6d7d21a0
AD
7171 // Video mime-types
7172 case '3gp':
7173 case '3gpp':
7174 $type = 'video/3gpp';
f2f7b699
AD
7175 break;
7176
6d7d21a0
AD
7177 case '3g2':
7178 case '3gp2':
7179 $type = 'video/3gpp2';
f2f7b699
AD
7180 break;
7181
6d7d21a0
AD
7182 case 'asf':
7183 $type = 'video/x-ms-asf';
f2f7b699 7184 break;
f2f7b699 7185
6d7d21a0
AD
7186 case 'flv':
7187 $type = 'video/x-flv';
7188 break;
f2f7b699 7189
6d7d21a0
AD
7190 case 'm1a':
7191 case 'm1s':
7192 case 'm1v':
7193 case 'm15':
7194 case 'm75':
7195 case 'mp2':
7196 case 'mpa':
7197 case 'mpeg':
7198 case 'mpg':
7199 case 'mpm':
7200 case 'mpv':
7201 $type = 'video/mpeg';
7202 break;
f2f7b699 7203
6d7d21a0
AD
7204 case 'm4v':
7205 $type = 'video/x-m4v';
7206 break;
f2f7b699 7207
6d7d21a0
AD
7208 case 'mov':
7209 case 'qt':
7210 $type = 'video/quicktime';
7211 break;
f2f7b699 7212
6d7d21a0
AD
7213 case 'mp4':
7214 case 'mpg4':
7215 $type = 'video/mp4';
7216 break;
7217
7218 case 'sdv':
7219 $type = 'video/sd-video';
7220 break;
7221
7222 case 'wm':
7223 $type = 'video/x-ms-wm';
7224 break;
7225
7226 case 'wmv':
7227 $type = 'video/x-ms-wmv';
7228 break;
7229
7230 case 'wvx':
7231 $type = 'video/x-ms-wvx';
7232 break;
7233
7234 // Flash mime-types
7235 case 'spl':
7236 $type = 'application/futuresplash';
7237 break;
7238
7239 case 'swf':
7240 $type = 'application/x-shockwave-flash';
7241 break;
7242 }
f2f7b699 7243 }
6d7d21a0
AD
7244
7245 if ($find_handler)
f2f7b699 7246 {
6d7d21a0
AD
7247 if (in_array($type, $types_flash))
7248 {
7249 return 'flash';
7250 }
7251 elseif (in_array($type, $types_fmedia))
7252 {
7253 return 'fmedia';
7254 }
7255 elseif (in_array($type, $types_quicktime))
7256 {
7257 return 'quicktime';
7258 }
7259 elseif (in_array($type, $types_wmedia))
7260 {
7261 return 'wmedia';
7262 }
7263 elseif (in_array($type, $types_mp3))
7264 {
7265 return 'mp3';
7266 }
7267 else
7268 {
7269 return null;
7270 }
f2f7b699
AD
7271 }
7272 else
7273 {
6d7d21a0 7274 return $type;
f2f7b699
AD
7275 }
7276 }
7277}
7278
6d7d21a0 7279class SimplePie_Caption
f2f7b699 7280{
6d7d21a0
AD
7281 var $type;
7282 var $lang;
7283 var $startTime;
7284 var $endTime;
7285 var $text;
f2f7b699 7286
6d7d21a0
AD
7287 // Constructor, used to input the data
7288 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
f2f7b699 7289 {
6d7d21a0
AD
7290 $this->type = $type;
7291 $this->lang = $lang;
7292 $this->startTime = $startTime;
7293 $this->endTime = $endTime;
7294 $this->text = $text;
f2f7b699
AD
7295 }
7296
6d7d21a0 7297 function __toString()
f2f7b699 7298 {
6d7d21a0
AD
7299 // There is no $this->data here
7300 return md5(serialize($this));
f2f7b699
AD
7301 }
7302
6d7d21a0 7303 function get_endtime()
f2f7b699 7304 {
6d7d21a0 7305 if ($this->endTime !== null)
f2f7b699 7306 {
6d7d21a0
AD
7307 return $this->endTime;
7308 }
7309 else
7310 {
7311 return null;
f2f7b699 7312 }
f2f7b699
AD
7313 }
7314
6d7d21a0 7315 function get_language()
f2f7b699 7316 {
6d7d21a0 7317 if ($this->lang !== null)
f2f7b699 7318 {
6d7d21a0
AD
7319 return $this->lang;
7320 }
7321 else
7322 {
7323 return null;
f2f7b699 7324 }
f2f7b699
AD
7325 }
7326
6d7d21a0 7327 function get_starttime()
f2f7b699 7328 {
6d7d21a0 7329 if ($this->startTime !== null)
f2f7b699 7330 {
6d7d21a0
AD
7331 return $this->startTime;
7332 }
7333 else
7334 {
7335 return null;
f2f7b699 7336 }
f2f7b699
AD
7337 }
7338
6d7d21a0 7339 function get_text()
f2f7b699 7340 {
6d7d21a0 7341 if ($this->text !== null)
f2f7b699 7342 {
6d7d21a0
AD
7343 return $this->text;
7344 }
7345 else
7346 {
7347 return null;
f2f7b699 7348 }
f2f7b699 7349 }
f2f7b699 7350
6d7d21a0 7351 function get_type()
f2f7b699 7352 {
6d7d21a0 7353 if ($this->type !== null)
f2f7b699 7354 {
6d7d21a0 7355 return $this->type;
f2f7b699 7356 }
6d7d21a0 7357 else
f2f7b699 7358 {
6d7d21a0 7359 return null;
f2f7b699 7360 }
6d7d21a0
AD
7361 }
7362}
f2f7b699 7363
6d7d21a0
AD
7364class SimplePie_Credit
7365{
7366 var $role;
7367 var $scheme;
7368 var $name;
f2f7b699 7369
6d7d21a0
AD
7370 // Constructor, used to input the data
7371 function SimplePie_Credit($role = null, $scheme = null, $name = null)
7372 {
7373 $this->role = $role;
7374 $this->scheme = $scheme;
7375 $this->name = $name;
f2f7b699
AD
7376 }
7377
6d7d21a0 7378 function __toString()
f2f7b699 7379 {
6d7d21a0
AD
7380 // There is no $this->data here
7381 return md5(serialize($this));
7382 }
7383
7384 function get_role()
7385 {
7386 if ($this->role !== null)
f2f7b699 7387 {
6d7d21a0 7388 return $this->role;
f2f7b699
AD
7389 }
7390 else
7391 {
6d7d21a0 7392 return null;
f2f7b699 7393 }
f2f7b699
AD
7394 }
7395
6d7d21a0 7396 function get_scheme()
f2f7b699 7397 {
6d7d21a0 7398 if ($this->scheme !== null)
f2f7b699 7399 {
6d7d21a0
AD
7400 return $this->scheme;
7401 }
7402 else
7403 {
7404 return null;
f2f7b699 7405 }
f2f7b699
AD
7406 }
7407
6d7d21a0 7408 function get_name()
f2f7b699 7409 {
6d7d21a0 7410 if ($this->name !== null)
f2f7b699 7411 {
6d7d21a0
AD
7412 return $this->name;
7413 }
7414 else
7415 {
7416 return null;
f2f7b699 7417 }
f2f7b699 7418 }
6d7d21a0 7419}
f2f7b699 7420
6d7d21a0
AD
7421class SimplePie_Copyright
7422{
7423 var $url;
7424 var $label;
7425
7426 // Constructor, used to input the data
7427 function SimplePie_Copyright($url = null, $label = null)
f2f7b699 7428 {
6d7d21a0
AD
7429 $this->url = $url;
7430 $this->label = $label;
7431 }
7432
7433 function __toString()
7434 {
7435 // There is no $this->data here
7436 return md5(serialize($this));
7437 }
7438
7439 function get_url()
7440 {
7441 if ($this->url !== null)
f2f7b699 7442 {
6d7d21a0 7443 return $this->url;
f2f7b699
AD
7444 }
7445 else
7446 {
6d7d21a0 7447 return null;
f2f7b699 7448 }
f2f7b699
AD
7449 }
7450
6d7d21a0 7451 function get_attribution()
f2f7b699 7452 {
6d7d21a0 7453 if ($this->label !== null)
f2f7b699 7454 {
6d7d21a0 7455 return $this->label;
f2f7b699 7456 }
6d7d21a0 7457 else
f2f7b699 7458 {
6d7d21a0 7459 return null;
f2f7b699 7460 }
6d7d21a0
AD
7461 }
7462}
f2f7b699 7463
6d7d21a0
AD
7464class SimplePie_Rating
7465{
7466 var $scheme;
7467 var $value;
7468
7469 // Constructor, used to input the data
7470 function SimplePie_Rating($scheme = null, $value = null)
7471 {
7472 $this->scheme = $scheme;
7473 $this->value = $value;
f2f7b699
AD
7474 }
7475
6d7d21a0 7476 function __toString()
f2f7b699 7477 {
6d7d21a0
AD
7478 // There is no $this->data here
7479 return md5(serialize($this));
7480 }
f2f7b699 7481
6d7d21a0
AD
7482 function get_scheme()
7483 {
7484 if ($this->scheme !== null)
f2f7b699 7485 {
6d7d21a0 7486 return $this->scheme;
f2f7b699
AD
7487 }
7488 else
7489 {
6d7d21a0 7490 return null;
f2f7b699
AD
7491 }
7492 }
7493
6d7d21a0 7494 function get_value()
f2f7b699 7495 {
6d7d21a0 7496 if ($this->value !== null)
f2f7b699 7497 {
6d7d21a0 7498 return $this->value;
f2f7b699
AD
7499 }
7500 else
7501 {
6d7d21a0 7502 return null;
f2f7b699
AD
7503 }
7504 }
6d7d21a0 7505}
f2f7b699 7506
6d7d21a0
AD
7507class SimplePie_Restriction
7508{
7509 var $relationship;
7510 var $type;
7511 var $value;
7512
7513 // Constructor, used to input the data
7514 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
f2f7b699 7515 {
6d7d21a0
AD
7516 $this->relationship = $relationship;
7517 $this->type = $type;
7518 $this->value = $value;
f2f7b699
AD
7519 }
7520
6d7d21a0 7521 function __toString()
f2f7b699 7522 {
6d7d21a0
AD
7523 // There is no $this->data here
7524 return md5(serialize($this));
f2f7b699
AD
7525 }
7526
6d7d21a0 7527 function get_relationship()
f2f7b699 7528 {
6d7d21a0 7529 if ($this->relationship !== null)
f2f7b699 7530 {
6d7d21a0 7531 return $this->relationship;
f2f7b699
AD
7532 }
7533 else
7534 {
6d7d21a0 7535 return null;
f2f7b699
AD
7536 }
7537 }
7538
6d7d21a0 7539 function get_type()
f2f7b699 7540 {
6d7d21a0 7541 if ($this->type !== null)
f2f7b699 7542 {
6d7d21a0 7543 return $this->type;
f2f7b699
AD
7544 }
7545 else
7546 {
6d7d21a0 7547 return null;
f2f7b699
AD
7548 }
7549 }
7550
6d7d21a0 7551 function get_value()
f2f7b699 7552 {
6d7d21a0 7553 if ($this->value !== null)
f2f7b699 7554 {
6d7d21a0 7555 return $this->value;
f2f7b699 7556 }
6d7d21a0 7557 else
f2f7b699 7558 {
6d7d21a0 7559 return null;
f2f7b699 7560 }
f2f7b699 7561 }
6d7d21a0 7562}
f2f7b699 7563
6d7d21a0
AD
7564/**
7565 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7566 */
7567class SimplePie_File
7568{
7569 var $url;
7570 var $useragent;
7571 var $success = true;
7572 var $headers = array();
7573 var $body;
7574 var $status_code;
7575 var $redirects = 0;
7576 var $error;
7577 var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7578
7579 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
f2f7b699 7580 {
6d7d21a0 7581 if (class_exists('idna_convert'))
f2f7b699 7582 {
6d7d21a0
AD
7583 $idn =& new idna_convert;
7584 $parsed = SimplePie_Misc::parse_url($url);
7585 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7586 }
7587 $this->url = $url;
7588 $this->useragent = $useragent;
7589 if (preg_match('/^http(s)?:\/\//i', $url))
7590 {
7591 if ($useragent === null)
7592 {
7593 $useragent = ini_get('user_agent');
7594 $this->useragent = $useragent;
7595 }
7596 if (!is_array($headers))
7597 {
7598 $headers = array();
7599 }
7600 if (!$force_fsockopen && function_exists('curl_exec'))
7601 {
7602 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7603 $fp = curl_init();
7604 $headers2 = array();
7605 foreach ($headers as $key => $value)
7606 {
7607 $headers2[] = "$key: $value";
7608 }
7609 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7610 {
7611 curl_setopt($fp, CURLOPT_ENCODING, '');
7612 }
7613 curl_setopt($fp, CURLOPT_URL, $url);
7614 curl_setopt($fp, CURLOPT_HEADER, 1);
7615 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7616 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7617 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7618 curl_setopt($fp, CURLOPT_REFERER, $url);
7619 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7620 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7621 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7622 {
7623 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7624 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7625 }
3cae90e1
AD
7626
7627 /* Enable Digest authentication and SSL -fox */
96841bf3
AD
7628 curl_setopt($fp, CURLOPT_SSL_VERIFYPEER, false);
7629 curl_setopt($fp, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
f2f7b699 7630
6d7d21a0
AD
7631 $this->headers = curl_exec($fp);
7632 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7633 {
7634 curl_setopt($fp, CURLOPT_ENCODING, 'none');
7635 $this->headers = curl_exec($fp);
7636 }
7637 if (curl_errno($fp))
7638 {
7639 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7640 $this->success = false;
7641 }
7642 else
7643 {
7644 $info = curl_getinfo($fp);
7645 curl_close($fp);
7646 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7647 $this->headers = array_pop($this->headers);
7648 $parser =& new SimplePie_HTTP_Parser($this->headers);
7649 if ($parser->parse())
7650 {
7651 $this->headers = $parser->headers;
7652 $this->body = $parser->body;
7653 $this->status_code = $parser->status_code;
7654 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)
7655 {
7656 $this->redirects++;
7657 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7658 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7659 }
7660 }
7661 }
7662 }
7663 else
7664 {
7665 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7666 $url_parts = parse_url($url);
7667 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7668 {
7669 $url_parts['host'] = "ssl://$url_parts[host]";
7670 $url_parts['port'] = 443;
7671 }
7672 if (!isset($url_parts['port']))
7673 {
7674 $url_parts['port'] = 80;
7675 }
7676 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7677 if (!$fp)
7678 {
7679 $this->error = 'fsockopen error: ' . $errstr;
7680 $this->success = false;
7681 }
7682 else
7683 {
7684 stream_set_timeout($fp, $timeout);
7685 if (isset($url_parts['path']))
7686 {
7687 if (isset($url_parts['query']))
7688 {
7689 $get = "$url_parts[path]?$url_parts[query]";
7690 }
7691 else
7692 {
7693 $get = $url_parts['path'];
7694 }
7695 }
7696 else
7697 {
7698 $get = '/';
7699 }
7700 $out = "GET $get HTTP/1.0\r\n";
7701 $out .= "Host: $url_parts[host]\r\n";
7702 $out .= "User-Agent: $useragent\r\n";
7703 if (function_exists('gzinflate'))
7704 {
7705 $out .= "Accept-Encoding: gzip,deflate\r\n";
7706 }
f2f7b699 7707
6d7d21a0
AD
7708 if (isset($url_parts['user']) && isset($url_parts['pass']))
7709 {
7710 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7711 }
7712 foreach ($headers as $key => $value)
7713 {
7714 $out .= "$key: $value\r\n";
7715 }
7716 $out .= "Connection: Close\r\n\r\n";
7717 fwrite($fp, $out);
f2f7b699 7718
6d7d21a0 7719 $info = stream_get_meta_data($fp);
f2f7b699 7720
6d7d21a0
AD
7721 $this->headers = '';
7722 while (!$info['eof'] && !$info['timed_out'])
7723 {
7724 $this->headers .= fread($fp, 1160);
7725 $info = stream_get_meta_data($fp);
7726 }
7727 if (!$info['timed_out'])
7728 {
7729 $parser =& new SimplePie_HTTP_Parser($this->headers);
7730 if ($parser->parse())
7731 {
7732 $this->headers = $parser->headers;
7733 $this->body = $parser->body;
7734 $this->status_code = $parser->status_code;
7735 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)
7736 {
7737 $this->redirects++;
7738 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7739 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7740 }
7741 if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
7742 {
7743 if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
7744 {
7745 $this->body = substr($this->body, 10);
7746 }
7747 $this->body = gzinflate($this->body);
7748 }
7749 }
7750 }
7751 else
7752 {
7753 $this->error = 'fsocket timed out';
7754 $this->success = false;
7755 }
7756 fclose($fp);
7757 }
7758 }
7759 }
7760 else
7761 {
7762 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7763 if (!$this->body = file_get_contents($url))
7764 {
7765 $this->error = 'file_get_contents could not read the file';
7766 $this->success = false;
7767 }
7768 }
7769 }
7770}
f2f7b699 7771
6d7d21a0
AD
7772/**
7773 * HTTP Response Parser
7774 *
7775 * @package SimplePie
7776 */
7777class SimplePie_HTTP_Parser
7778{
7779 /**
7780 * HTTP Version
7781 *
7782 * @access public
7783 * @var float
7784 */
7785 var $http_version = 0.0;
f2f7b699 7786
6d7d21a0
AD
7787 /**
7788 * Status code
7789 *
7790 * @access public
7791 * @var int
7792 */
7793 var $status_code = 0;
f2f7b699 7794
6d7d21a0
AD
7795 /**
7796 * Reason phrase
7797 *
7798 * @access public
7799 * @var string
7800 */
7801 var $reason = '';
f2f7b699 7802
6d7d21a0
AD
7803 /**
7804 * Key/value pairs of the headers
7805 *
7806 * @access public
7807 * @var array
7808 */
7809 var $headers = array();
f2f7b699 7810
6d7d21a0
AD
7811 /**
7812 * Body of the response
7813 *
7814 * @access public
7815 * @var string
7816 */
7817 var $body = '';
f2f7b699 7818
6d7d21a0
AD
7819 /**
7820 * Current state of the state machine
7821 *
7822 * @access private
7823 * @var string
7824 */
7825 var $state = 'http_version';
f2f7b699 7826
6d7d21a0
AD
7827 /**
7828 * Input data
7829 *
7830 * @access private
7831 * @var string
7832 */
7833 var $data = '';
f2f7b699 7834
6d7d21a0
AD
7835 /**
7836 * Input data length (to avoid calling strlen() everytime this is needed)
7837 *
7838 * @access private
7839 * @var int
7840 */
7841 var $data_length = 0;
f2f7b699 7842
6d7d21a0
AD
7843 /**
7844 * Current position of the pointer
7845 *
7846 * @var int
7847 * @access private
7848 */
7849 var $position = 0;
f2f7b699 7850
6d7d21a0
AD
7851 /**
7852 * Name of the hedaer currently being parsed
7853 *
7854 * @access private
7855 * @var string
7856 */
7857 var $name = '';
f2f7b699 7858
6d7d21a0
AD
7859 /**
7860 * Value of the hedaer currently being parsed
7861 *
7862 * @access private
7863 * @var string
7864 */
7865 var $value = '';
f2f7b699 7866
6d7d21a0
AD
7867 /**
7868 * Create an instance of the class with the input data
7869 *
7870 * @access public
7871 * @param string $data Input data
7872 */
7873 function SimplePie_HTTP_Parser($data)
7874 {
7875 $this->data = $data;
7876 $this->data_length = strlen($this->data);
7877 }
f2f7b699 7878
6d7d21a0
AD
7879 /**
7880 * Parse the input data
7881 *
7882 * @access public
7883 * @return bool true on success, false on failure
7884 */
7885 function parse()
7886 {
7887 while ($this->state && $this->state !== 'emit' && $this->has_data())
7888 {
7889 $state = $this->state;
7890 $this->$state();
7891 }
7892 $this->data = '';
3cae90e1 7893 if ($this->state === 'emit' || $this->state === 'body')
6d7d21a0
AD
7894 {
7895 return true;
7896 }
7897 else
7898 {
7899 $this->http_version = '';
7900 $this->status_code = '';
7901 $this->reason = '';
7902 $this->headers = array();
7903 $this->body = '';
7904 return false;
7905 }
7906 }
f2f7b699 7907
6d7d21a0
AD
7908 /**
7909 * Check whether there is data beyond the pointer
7910 *
7911 * @access private
7912 * @return bool true if there is further data, false if not
7913 */
7914 function has_data()
7915 {
7916 return (bool) ($this->position < $this->data_length);
7917 }
f2f7b699 7918
6d7d21a0
AD
7919 /**
7920 * See if the next character is LWS
7921 *
7922 * @access private
7923 * @return bool true if the next character is LWS, false if not
7924 */
7925 function is_linear_whitespace()
7926 {
7927 return (bool) ($this->data[$this->position] === "\x09"
7928 || $this->data[$this->position] === "\x20"
7929 || ($this->data[$this->position] === "\x0A"
7930 && isset($this->data[$this->position + 1])
7931 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
7932 }
f2f7b699 7933
6d7d21a0
AD
7934 /**
7935 * Parse the HTTP version
7936 *
7937 * @access private
7938 */
7939 function http_version()
7940 {
7941 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
7942 {
7943 $len = strspn($this->data, '0123456789.', 5);
7944 $this->http_version = substr($this->data, 5, $len);
7945 $this->position += 5 + $len;
7946 if (substr_count($this->http_version, '.') <= 1)
7947 {
7948 $this->http_version = (float) $this->http_version;
7949 $this->position += strspn($this->data, "\x09\x20", $this->position);
7950 $this->state = 'status';
7951 }
7952 else
7953 {
7954 $this->state = false;
7955 }
7956 }
7957 else
7958 {
7959 $this->state = false;
7960 }
7961 }
f2f7b699 7962
6d7d21a0
AD
7963 /**
7964 * Parse the status code
7965 *
7966 * @access private
7967 */
7968 function status()
7969 {
7970 if ($len = strspn($this->data, '0123456789', $this->position))
7971 {
7972 $this->status_code = (int) substr($this->data, $this->position, $len);
7973 $this->position += $len;
7974 $this->state = 'reason';
7975 }
7976 else
7977 {
7978 $this->state = false;
7979 }
7980 }
f2f7b699 7981
6d7d21a0
AD
7982 /**
7983 * Parse the reason phrase
7984 *
7985 * @access private
7986 */
7987 function reason()
7988 {
7989 $len = strcspn($this->data, "\x0A", $this->position);
7990 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
7991 $this->position += $len + 1;
7992 $this->state = 'new_line';
7993 }
f2f7b699 7994
6d7d21a0
AD
7995 /**
7996 * Deal with a new line, shifting data around as needed
7997 *
7998 * @access private
7999 */
8000 function new_line()
8001 {
8002 $this->value = trim($this->value, "\x0D\x20");
8003 if ($this->name !== '' && $this->value !== '')
8004 {
8005 $this->name = strtolower($this->name);
8006 if (isset($this->headers[$this->name]))
8007 {
8008 $this->headers[$this->name] .= ', ' . $this->value;
8009 }
8010 else
8011 {
8012 $this->headers[$this->name] = $this->value;
8013 }
8014 }
8015 $this->name = '';
8016 $this->value = '';
8017 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8018 {
8019 $this->position += 2;
8020 $this->state = 'body';
8021 }
8022 elseif ($this->data[$this->position] === "\x0A")
8023 {
8024 $this->position++;
8025 $this->state = 'body';
8026 }
8027 else
8028 {
8029 $this->state = 'name';
8030 }
8031 }
f2f7b699 8032
6d7d21a0
AD
8033 /**
8034 * Parse a header name
8035 *
8036 * @access private
8037 */
8038 function name()
8039 {
8040 $len = strcspn($this->data, "\x0A:", $this->position);
8041 if (isset($this->data[$this->position + $len]))
8042 {
8043 if ($this->data[$this->position + $len] === "\x0A")
8044 {
8045 $this->position += $len;
8046 $this->state = 'new_line';
8047 }
8048 else
8049 {
8050 $this->name = substr($this->data, $this->position, $len);
8051 $this->position += $len + 1;
8052 $this->state = 'value';
8053 }
8054 }
8055 else
8056 {
8057 $this->state = false;
8058 }
8059 }
f2f7b699 8060
6d7d21a0
AD
8061 /**
8062 * Parse LWS, replacing consecutive LWS characters with a single space
8063 *
8064 * @access private
8065 */
8066 function linear_whitespace()
8067 {
8068 do
8069 {
8070 if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8071 {
8072 $this->position += 2;
8073 }
8074 elseif ($this->data[$this->position] === "\x0A")
8075 {
8076 $this->position++;
8077 }
8078 $this->position += strspn($this->data, "\x09\x20", $this->position);
8079 } while ($this->has_data() && $this->is_linear_whitespace());
8080 $this->value .= "\x20";
8081 }
f2f7b699 8082
6d7d21a0
AD
8083 /**
8084 * See what state to move to while within non-quoted header values
8085 *
8086 * @access private
8087 */
8088 function value()
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 = 'quote';
8101 break;
f2f7b699 8102
6d7d21a0
AD
8103 case "\x0A":
8104 $this->position++;
8105 $this->state = 'new_line';
8106 break;
f2f7b699 8107
6d7d21a0
AD
8108 default:
8109 $this->state = 'value_char';
8110 break;
8111 }
8112 }
8113 }
f2f7b699 8114
6d7d21a0
AD
8115 /**
8116 * Parse a header value while outside quotes
8117 *
8118 * @access private
8119 */
8120 function value_char()
8121 {
8122 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8123 $this->value .= substr($this->data, $this->position, $len);
8124 $this->position += $len;
8125 $this->state = 'value';
8126 }
f2f7b699 8127
6d7d21a0
AD
8128 /**
8129 * See what state to move to while within quoted header values
8130 *
8131 * @access private
8132 */
8133 function quote()
8134 {
8135 if ($this->is_linear_whitespace())
8136 {
8137 $this->linear_whitespace();
8138 }
8139 else
8140 {
8141 switch ($this->data[$this->position])
8142 {
8143 case '"':
8144 $this->position++;
8145 $this->state = 'value';
8146 break;
f2f7b699 8147
6d7d21a0
AD
8148 case "\x0A":
8149 $this->position++;
8150 $this->state = 'new_line';
8151 break;
f2f7b699 8152
6d7d21a0
AD
8153 case '\\':
8154 $this->position++;
8155 $this->state = 'quote_escaped';
8156 break;
f2f7b699 8157
6d7d21a0
AD
8158 default:
8159 $this->state = 'quote_char';
8160 break;
8161 }
8162 }
8163 }
f2f7b699 8164
6d7d21a0
AD
8165 /**
8166 * Parse a header value while within quotes
8167 *
8168 * @access private
8169 */
8170 function quote_char()
8171 {
8172 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8173 $this->value .= substr($this->data, $this->position, $len);
8174 $this->position += $len;
8175 $this->state = 'value';
8176 }
f2f7b699 8177
6d7d21a0
AD
8178 /**
8179 * Parse an escaped character within quotes
8180 *
8181 * @access private
8182 */
8183 function quote_escaped()
8184 {
8185 $this->value .= $this->data[$this->position];
8186 $this->position++;
8187 $this->state = 'quote';
8188 }
f2f7b699 8189
6d7d21a0
AD
8190 /**
8191 * Parse the body
8192 *
8193 * @access private
8194 */
8195 function body()
8196 {
8197 $this->body = substr($this->data, $this->position);
8198 $this->state = 'emit';
8199 }
8200}
f2f7b699 8201
6d7d21a0
AD
8202class SimplePie_Cache
8203{
8204 /**
8205 * Don't call the constructor. Please.
8206 *
8207 * @access private
8208 */
8209 function SimplePie_Cache()
8210 {
8211 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8212 }
f2f7b699 8213
6d7d21a0
AD
8214 /**
8215 * Create a new SimplePie_Cache object
8216 *
8217 * @static
8218 * @access public
8219 */
8220 function create($location, $filename, $extension)
8221 {
8222 return new SimplePie_Cache_File($location, $filename, $extension);
8223 }
8224}
f2f7b699 8225
6d7d21a0
AD
8226class SimplePie_Cache_File
8227{
8228 var $location;
8229 var $filename;
8230 var $extension;
8231 var $name;
f2f7b699 8232
6d7d21a0
AD
8233 function SimplePie_Cache_File($location, $filename, $extension)
8234 {
8235 $this->location = $location;
8236 $this->filename = rawurlencode($filename);
8237 $this->extension = rawurlencode($extension);
8238 $this->name = "$location/$this->filename.$this->extension";
8239 }
f2f7b699 8240
6d7d21a0
AD
8241 function save($data)
8242 {
8243 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8244 {
8245 if (is_a($data, 'SimplePie'))
8246 {
8247 $data = $data->data;
8248 }
f2f7b699 8249
6d7d21a0 8250 $data = serialize($data);
f2f7b699 8251
6d7d21a0
AD
8252 if (function_exists('file_put_contents'))
8253 {
8254 return (bool) file_put_contents($this->name, $data);
8255 }
8256 else
8257 {
8258 $fp = fopen($this->name, 'wb');
8259 if ($fp)
8260 {
8261 fwrite($fp, $data);
8262 fclose($fp);
8263 return true;
8264 }
8265 }
8266 }
8267 return false;
8268 }
f2f7b699 8269
6d7d21a0
AD
8270 function load()
8271 {
8272 if (file_exists($this->name) && is_readable($this->name))
8273 {
8274 return unserialize(file_get_contents($this->name));
8275 }
8276 return false;
8277 }
f2f7b699 8278
6d7d21a0
AD
8279 function mtime()
8280 {
8281 if (file_exists($this->name))
8282 {
8283 return filemtime($this->name);
8284 }
8285 return false;
8286 }
f2f7b699 8287
6d7d21a0
AD
8288 function touch()
8289 {
8290 if (file_exists($this->name))
8291 {
8292 return touch($this->name);
8293 }
8294 return false;
8295 }
f2f7b699 8296
6d7d21a0
AD
8297 function unlink()
8298 {
8299 if (file_exists($this->name))
8300 {
8301 return unlink($this->name);
8302 }
8303 return false;
8304 }
8305}
f2f7b699 8306
6d7d21a0
AD
8307class SimplePie_Misc
8308{
8309 function time_hms($seconds)
8310 {
8311 $time = '';
f2f7b699 8312
6d7d21a0
AD
8313 $hours = floor($seconds / 3600);
8314 $remainder = $seconds % 3600;
8315 if ($hours > 0)
8316 {
8317 $time .= $hours.':';
8318 }
f2f7b699 8319
6d7d21a0
AD
8320 $minutes = floor($remainder / 60);
8321 $seconds = $remainder % 60;
8322 if ($minutes < 10 && $hours > 0)
8323 {
8324 $minutes = '0' . $minutes;
8325 }
8326 if ($seconds < 10)
8327 {
8328 $seconds = '0' . $seconds;
8329 }
f2f7b699 8330
6d7d21a0
AD
8331 $time .= $minutes.':';
8332 $time .= $seconds;
f2f7b699 8333
6d7d21a0
AD
8334 return $time;
8335 }
f2f7b699 8336
6d7d21a0
AD
8337 function absolutize_url($relative, $base)
8338 {
8339 if ($relative !== '')
8340 {
8341 $relative = SimplePie_Misc::parse_url($relative);
8342 if ($relative['scheme'] !== '')
8343 {
8344 $target = $relative;
8345 }
8346 elseif ($base !== '')
8347 {
8348 $base = SimplePie_Misc::parse_url($base);
8349 $target = SimplePie_Misc::parse_url('');
8350 if ($relative['authority'] !== '')
8351 {
8352 $target = $relative;
8353 $target['scheme'] = $base['scheme'];
8354 }
8355 else
8356 {
8357 $target['scheme'] = $base['scheme'];
8358 $target['authority'] = $base['authority'];
8359 if ($relative['path'] !== '')
8360 {
8361 if (strpos($relative['path'], '/') === 0)
8362 {
8363 $target['path'] = $relative['path'];
8364 }
8365 elseif ($base['authority'] !== '' && $base['path'] === '')
8366 {
8367 $target['path'] = '/' . $relative['path'];
8368 }
8369 elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8370 {
8371 $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8372 }
8373 else
8374 {
8375 $target['path'] = $relative['path'];
8376 }
8377 $target['query'] = $relative['query'];
8378 }
8379 else
8380 {
8381 $target['path'] = $base['path'];
8382 if ($relative['query'] !== '')
8383 {
8384 $target['query'] = $relative['query'];
8385 }
8386 elseif ($base['query'] !== '')
8387 {
8388 $target['query'] = $base['query'];
8389 }
8390 }
8391 }
8392 $target['fragment'] = $relative['fragment'];
8393 }
8394 else
8395 {
8396 // No base URL, just return the relative URL
8397 $target = $relative;
8398 }
8399 $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8400 }
8401 else
8402 {
8403 $return = $base;
8404 }
8405 $return = SimplePie_Misc::normalize_url($return);
8406 return $return;
8407 }
f2f7b699 8408
6d7d21a0
AD
8409 function remove_dot_segments($input)
8410 {
8411 $output = '';
8412 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8413 {
8414 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8415 if (strpos($input, '../') === 0)
8416 {
8417 $input = substr($input, 3);
8418 }
8419 elseif (strpos($input, './') === 0)
8420 {
8421 $input = substr($input, 2);
8422 }
8423 // 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,
8424 elseif (strpos($input, '/./') === 0)
8425 {
8426 $input = substr_replace($input, '/', 0, 3);
8427 }
8428 elseif ($input == '/.')
8429 {
8430 $input = '/';
8431 }
8432 // 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,
8433 elseif (strpos($input, '/../') === 0)
8434 {
8435 $input = substr_replace($input, '/', 0, 4);
8436 $output = substr_replace($output, '', strrpos($output, '/'));
8437 }
8438 elseif ($input == '/..')
8439 {
8440 $input = '/';
8441 $output = substr_replace($output, '', strrpos($output, '/'));
8442 }
8443 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8444 elseif ($input == '.' || $input == '..')
8445 {
8446 $input = '';
8447 }
8448 // 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
8449 elseif (($pos = strpos($input, '/', 1)) !== false)
8450 {
8451 $output .= substr($input, 0, $pos);
8452 $input = substr_replace($input, '', 0, $pos);
8453 }
8454 else
8455 {
8456 $output .= $input;
8457 $input = '';
8458 }
8459 }
8460 return $output . $input;
8461 }
f2f7b699 8462
6d7d21a0
AD
8463 function get_element($realname, $string)
8464 {
8465 $return = array();
8466 $name = preg_quote($realname, '/');
8467 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8468 {
8469 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8470 {
8471 $return[$i]['tag'] = $realname;
8472 $return[$i]['full'] = $matches[$i][0][0];
8473 $return[$i]['offset'] = $matches[$i][0][1];
8474 if (strlen($matches[$i][3][0]) <= 2)
8475 {
8476 $return[$i]['self_closing'] = true;
8477 }
8478 else
8479 {
8480 $return[$i]['self_closing'] = false;
8481 $return[$i]['content'] = $matches[$i][4][0];
8482 }
8483 $return[$i]['attribs'] = array();
8484 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))
8485 {
8486 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8487 {
8488 if (count($attribs[$j]) == 2)
8489 {
8490 $attribs[$j][2] = $attribs[$j][1];
8491 }
8492 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8493 }
8494 }
8495 }
8496 }
8497 return $return;
8498 }
f2f7b699 8499
6d7d21a0
AD
8500 function element_implode($element)
8501 {
8502 $full = "<$element[tag]";
8503 foreach ($element['attribs'] as $key => $value)
8504 {
8505 $key = strtolower($key);
8506 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8507 }
8508 if ($element['self_closing'])
8509 {
8510 $full .= ' />';
8511 }
8512 else
8513 {
8514 $full .= ">$element[content]</$element[tag]>";
8515 }
8516 return $full;
8517 }
f2f7b699 8518
6d7d21a0
AD
8519 function error($message, $level, $file, $line)
8520 {
8521 switch ($level)
8522 {
8523 case E_USER_ERROR:
8524 $note = 'PHP Error';
8525 break;
8526 case E_USER_WARNING:
8527 $note = 'PHP Warning';
8528 break;
8529 case E_USER_NOTICE:
8530 $note = 'PHP Notice';
8531 break;
8532 default:
8533 $note = 'Unknown Error';
8534 break;
8535 }
8536 error_log("$note: $message in $file on line $line", 0);
8537 return $message;
8538 }
f2f7b699 8539
6d7d21a0
AD
8540 /**
8541 * If a file has been cached, retrieve and display it.
8542 *
8543 * This is most useful for caching images (get_favicon(), etc.),
8544 * however it works for all cached files. This WILL NOT display ANY
8545 * file/image/page/whatever, but rather only display what has already
8546 * been cached by SimplePie.
8547 *
8548 * @access public
8549 * @see SimplePie::get_favicon()
8550 * @param str $identifier_url URL that is used to identify the content.
8551 * This may or may not be the actual URL of the live content.
8552 * @param str $cache_location Location of SimplePie's cache. Defaults
8553 * to './cache'.
8554 * @param str $cache_extension The file extension that the file was
8555 * cached with. Defaults to 'spc'.
8556 * @param str $cache_class Name of the cache-handling class being used
8557 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
8558 * as-is unless you've overloaded the class.
8559 * @param str $cache_name_function Obsolete. Exists for backwards
8560 * compatibility reasons only.
8561 */
8562 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8563 {
8564 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
f2f7b699 8565
6d7d21a0
AD
8566 if ($file = $cache->load())
8567 {
8568 if (isset($file['headers']['content-type']))
8569 {
8570 header('Content-type:' . $file['headers']['content-type']);
8571 }
8572 else
8573 {
8574 header('Content-type: application/octet-stream');
8575 }
8576 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8577 echo $file['body'];
8578 exit;
8579 }
f2f7b699 8580
6d7d21a0
AD
8581 die('Cached file for ' . $identifier_url . ' cannot be found.');
8582 }
f2f7b699 8583
6d7d21a0
AD
8584 function fix_protocol($url, $http = 1)
8585 {
8586 $url = SimplePie_Misc::normalize_url($url);
8587 $parsed = SimplePie_Misc::parse_url($url);
8588 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8589 {
8590 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8591 }
f2f7b699 8592
6d7d21a0
AD
8593 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8594 {
8595 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8596 }
f2f7b699 8597
6d7d21a0
AD
8598 if ($http == 2 && $parsed['scheme'] !== '')
8599 {
8600 return "feed:$url";
8601 }
8602 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
8603 {
8604 return substr_replace($url, 'podcast', 0, 4);
8605 }
8606 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
8607 {
8608 return substr_replace($url, 'itpc', 0, 4);
8609 }
8610 else
8611 {
8612 return $url;
8613 }
8614 }
f2f7b699 8615
6d7d21a0
AD
8616 function parse_url($url)
8617 {
8618 static $cache = array();
8619 if (isset($cache[$url]))
8620 {
8621 return $cache[$url];
8622 }
8623 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
8624 {
8625 for ($i = count($match); $i <= 9; $i++)
8626 {
8627 $match[$i] = '';
8628 }
8629 return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
8630 }
8631 else
8632 {
8633 return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
8634 }
8635 }
f2f7b699 8636
6d7d21a0
AD
8637 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
8638 {
8639 $return = '';
8640 if ($scheme !== '')
8641 {
8642 $return .= "$scheme:";
8643 }
8644 if ($authority !== '')
8645 {
8646 $return .= "//$authority";
8647 }
8648 if ($path !== '')
8649 {
8650 $return .= $path;
8651 }
8652 if ($query !== '')
8653 {
8654 $return .= "?$query";
8655 }
8656 if ($fragment !== '')
8657 {
8658 $return .= "#$fragment";
8659 }
8660 return $return;
8661 }
f2f7b699 8662
6d7d21a0
AD
8663 function normalize_url($url)
8664 {
8665 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
8666 $url = SimplePie_Misc::parse_url($url);
8667 $url['scheme'] = strtolower($url['scheme']);
8668 if ($url['authority'] !== '')
8669 {
8670 $url['authority'] = strtolower($url['authority']);
8671 $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
8672 }
8673 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
8674 }
f2f7b699 8675
6d7d21a0
AD
8676 function percent_encoding_normalization($match)
8677 {
8678 $integer = hexdec($match[1]);
8679 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
8680 {
8681 return chr($integer);
8682 }
8683 else
8684 {
8685 return strtoupper($match[0]);
8686 }
8687 }
f2f7b699 8688
6d7d21a0
AD
8689 /**
8690 * Remove bad UTF-8 bytes
8691 *
8692 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
8693 * FAQ: Multilingual Forms (modified to include full ASCII range)
8694 *
8695 * @author Geoffrey Sneddon
8696 * @see http://www.w3.org/International/questions/qa-forms-utf-8
8697 * @param string $str String to remove bad UTF-8 bytes from
8698 * @return string UTF-8 string
8699 */
8700 function utf8_bad_replace($str)
8701 {
8702 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
8703 {
8704 return $return;
8705 }
8706 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
8707 {
8708 return $return;
8709 }
8710 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))
8711 {
8712 return implode("\xEF\xBF\xBD", $matches[0]);
8713 }
8714 elseif ($str !== '')
8715 {
8716 return "\xEF\xBF\xBD";
8717 }
8718 else
8719 {
8720 return '';
8721 }
8722 }
8723
8724 /**
8725 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
8726 *
8727 * @static
8728 * @access public
8729 * @param string $string Windows-1252 encoded string
8730 * @return string UTF-8 encoded string
8731 */
8732 function windows_1252_to_utf8($string)
8733 {
8734 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");
8735
8736 return strtr($string, $convert_table);
8737 }
f2f7b699 8738
6d7d21a0
AD
8739 function change_encoding($data, $input, $output)
8740 {
8741 $input = SimplePie_Misc::encoding($input);
8742 $output = SimplePie_Misc::encoding($output);
8743
8744 // We fail to fail on non US-ASCII bytes
8745 if ($input === 'US-ASCII')
8746 {
8747 static $non_ascii_octects = '';
8748 if (!$non_ascii_octects)
8749 {
8750 for ($i = 0x80; $i <= 0xFF; $i++)
8751 {
8752 $non_ascii_octects .= chr($i);
8753 }
8754 }
8755 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
8756 }
f2f7b699 8757
6d7d21a0
AD
8758 if (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
8759 {
8760 return $return;
8761 }
8762 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
8763 {
8764 return $return;
8765 }
8766 elseif ($input == 'windows-1252' && $output == 'UTF-8')
8767 {
8768 return SimplePie_Misc::windows_1252_to_utf8($data);
8769 }
8770 elseif ($input == 'UTF-8' && $output == 'windows-1252')
8771 {
8772 return utf8_decode($data);
8773 }
8774 return $data;
8775 }
f2f7b699 8776
6d7d21a0
AD
8777 function encoding($encoding)
8778 {
8779 // Character sets are case-insensitive (though we'll return them in the form given in their registration)
8780 switch (strtoupper($encoding))
8781 {
8782 case 'ANSI_X3.110-1983':
8783 case 'CSA_T500-1983':
8784 case 'CSISO99NAPLPS':
8785 case 'ISO-IR-99':
8786 case 'NAPLPS':
8787 return 'ANSI_X3.110-1983';
8788
8789 case 'ARABIC7':
8790 case 'ASMO_449':
8791 case 'CSISO89ASMO449':
8792 case 'ISO-IR-89':
8793 case 'ISO_9036':
8794 return 'ASMO_449';
8795
8796 case 'ADOBE-STANDARD-ENCODING':
8797 case 'CSADOBESTANDARDENCODING':
8798 return 'Adobe-Standard-Encoding';
8799
8800 case 'ADOBE-SYMBOL-ENCODING':
8801 case 'CSHPPSMATH':
8802 return 'Adobe-Symbol-Encoding';
8803
8804 case 'AMI-1251':
8805 case 'AMI1251':
8806 case 'AMIGA-1251':
8807 case 'AMIGA1251':
8808 return 'Amiga-1251';
8809
8810 case 'BOCU-1':
8811 case 'CSBOCU-1':
8812 return 'BOCU-1';
8813
8814 case 'BRF':
8815 case 'CSBRF':
8816 return 'BRF';
8817
8818 case 'BS_4730':
8819 case 'CSISO4UNITEDKINGDOM':
8820 case 'GB':
8821 case 'ISO-IR-4':
8822 case 'ISO646-GB':
8823 case 'UK':
8824 return 'BS_4730';
8825
8826 case 'BS_VIEWDATA':
8827 case 'CSISO47BSVIEWDATA':
8828 case 'ISO-IR-47':
8829 return 'BS_viewdata';
8830
8831 case 'BIG5':
8832 case 'CSBIG5':
8833 return 'Big5';
8834
8835 case 'BIG5-HKSCS':
8836 return 'Big5-HKSCS';
8837
8838 case 'CESU-8':
8839 case 'CSCESU-8':
8840 return 'CESU-8';
8841
8842 case 'CA':
8843 case 'CSA7-1':
8844 case 'CSA_Z243.4-1985-1':
8845 case 'CSISO121CANADIAN1':
8846 case 'ISO-IR-121':
8847 case 'ISO646-CA':
8848 return 'CSA_Z243.4-1985-1';
8849
8850 case 'CSA7-2':
8851 case 'CSA_Z243.4-1985-2':
8852 case 'CSISO122CANADIAN2':
8853 case 'ISO-IR-122':
8854 case 'ISO646-CA2':
8855 return 'CSA_Z243.4-1985-2';
8856
8857 case 'CSA_Z243.4-1985-GR':
8858 case 'CSISO123CSAZ24341985GR':
8859 case 'ISO-IR-123':
8860 return 'CSA_Z243.4-1985-gr';
8861
8862 case 'CSISO139CSN369103':
f2f7b699
AD
8863 case 'CSN_369103':
8864 case 'ISO-IR-139':
f2f7b699 8865 return 'CSN_369103';
6d7d21a0
AD
8866
8867 case 'CSDECMCS':
8868 case 'DEC':
8869 case 'DEC-MCS':
8870 return 'DEC-MCS';
8871
8872 case 'CSISO21GERMAN':
8873 case 'DE':
8874 case 'DIN_66003':
8875 case 'ISO-IR-21':
8876 case 'ISO646-DE':
8877 return 'DIN_66003';
8878
8879 case 'CSISO646DANISH':
8880 case 'DK':
8881 case 'DS2089':
8882 case 'DS_2089':
8883 case 'ISO646-DK':
8884 return 'DS_2089';
8885
8886 case 'CSIBMEBCDICATDE':
8887 case 'EBCDIC-AT-DE':
8888 return 'EBCDIC-AT-DE';
8889
8890 case 'CSEBCDICATDEA':
8891 case 'EBCDIC-AT-DE-A':
8892 return 'EBCDIC-AT-DE-A';
8893
8894 case 'CSEBCDICCAFR':
8895 case 'EBCDIC-CA-FR':
8896 return 'EBCDIC-CA-FR';
8897
8898 case 'CSEBCDICDKNO':
8899 case 'EBCDIC-DK-NO':
8900 return 'EBCDIC-DK-NO';
8901
8902 case 'CSEBCDICDKNOA':
8903 case 'EBCDIC-DK-NO-A':
8904 return 'EBCDIC-DK-NO-A';
8905
8906 case 'CSEBCDICES':
8907 case 'EBCDIC-ES':
8908 return 'EBCDIC-ES';
8909
8910 case 'CSEBCDICESA':
8911 case 'EBCDIC-ES-A':
8912 return 'EBCDIC-ES-A';
8913
8914 case 'CSEBCDICESS':
8915 case 'EBCDIC-ES-S':
8916 return 'EBCDIC-ES-S';
8917
8918 case 'CSEBCDICFISE':
8919 case 'EBCDIC-FI-SE':
8920 return 'EBCDIC-FI-SE';
8921
8922 case 'CSEBCDICFISEA':
8923 case 'EBCDIC-FI-SE-A':
8924 return 'EBCDIC-FI-SE-A';
8925
8926 case 'CSEBCDICFR':
8927 case 'EBCDIC-FR':
8928 return 'EBCDIC-FR';
8929
8930 case 'CSEBCDICIT':
8931 case 'EBCDIC-IT':
8932 return 'EBCDIC-IT';
8933
8934 case 'CSEBCDICPT':
8935 case 'EBCDIC-PT':
8936 return 'EBCDIC-PT';
8937
8938 case 'CSEBCDICUK':
8939 case 'EBCDIC-UK':
8940 return 'EBCDIC-UK';
8941
8942 case 'CSEBCDICUS':
8943 case 'EBCDIC-US':
8944 return 'EBCDIC-US';
8945
8946 case 'CSISO111ECMACYRILLIC':
8947 case 'ECMA-CYRILLIC':
8948 case 'ISO-IR-111':
8949 case 'KOI8-E':
8950 return 'ECMA-cyrillic';
8951
8952 case 'CSISO17SPANISH':
8953 case 'ES':
8954 case 'ISO-IR-17':
8955 case 'ISO646-ES':
8956 return 'ES';
8957
8958 case 'CSISO85SPANISH2':
8959 case 'ES2':
8960 case 'ISO-IR-85':
8961 case 'ISO646-ES2':
8962 return 'ES2';
8963
8964 case 'CSEUCPKDFMTJAPANESE':
8965 case 'EUC-JP':
8966 case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
8967 return 'EUC-JP';
8968
8969 case 'CSEUCKR':
8970 case 'EUC-KR':
8971 return 'EUC-KR';
8972
8973 case 'CSEUCFIXWIDJAPANESE':
8974 case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
8975 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
8976
8977 case 'GB18030':
8978 return 'GB18030';
8979
8980 case 'CSGB2312':
8981 case 'GB2312':
8982 return 'GB2312';
8983
f2f7b699 8984 case 'CP936':
6d7d21a0 8985 case 'GBK':
f2f7b699
AD
8986 case 'MS936':
8987 case 'WINDOWS-936':
8988 return 'GBK';
6d7d21a0
AD
8989
8990 case 'CN':
8991 case 'CSISO57GB1988':
8992 case 'GB_1988-80':
8993 case 'ISO-IR-57':
8994 case 'ISO646-CN':
8995 return 'GB_1988-80';
8996
8997 case 'CHINESE':
8998 case 'CSISO58GB231280':
8999 case 'GB_2312-80':
9000 case 'ISO-IR-58':
9001 return 'GB_2312-80';
9002
9003 case 'CSISO153GOST1976874':
9004 case 'GOST_19768-74':
9005 case 'ISO-IR-153':
9006 case 'ST_SEV_358-88':
9007 return 'GOST_19768-74';
9008
9009 case 'CSHPDESKTOP':
9010 case 'HP-DESKTOP':
9011 return 'HP-DeskTop';
9012
f2f7b699 9013 case 'CSHPLEGAL':
6d7d21a0 9014 case 'HP-LEGAL':
f2f7b699 9015 return 'HP-Legal';
6d7d21a0 9016
f2f7b699 9017 case 'CSHPMATH8':
6d7d21a0 9018 case 'HP-MATH8':
f2f7b699 9019 return 'HP-Math8';
6d7d21a0
AD
9020
9021 case 'CSHPPIFONT':
9022 case 'HP-PI-FONT':
9023 return 'HP-Pi-font';
9024
9025 case 'HZ-GB-2312':
9026 return 'HZ-GB-2312';
9027
9028 case 'CSIBMSYMBOLS':
9029 case 'IBM-SYMBOLS':
9030 return 'IBM-Symbols';
9031
9032 case 'CSIBMTHAI':
9033 case 'IBM-THAI':
9034 return 'IBM-Thai';
9035
9036 case 'CCSID00858':
9037 case 'CP00858':
9038 case 'IBM00858':
9039 case 'PC-MULTILINGUAL-850+EURO':
9040 return 'IBM00858';
9041
9042 case 'CCSID00924':
9043 case 'CP00924':
9044 case 'EBCDIC-LATIN9--EURO':
9045 case 'IBM00924':
9046 return 'IBM00924';
9047
9048 case 'CCSID01140':
9049 case 'CP01140':
9050 case 'EBCDIC-US-37+EURO':
9051 case 'IBM01140':
9052 return 'IBM01140';
9053
9054 case 'CCSID01141':
9055 case 'CP01141':
9056 case 'EBCDIC-DE-273+EURO':
9057 case 'IBM01141':
9058 return 'IBM01141';
9059
9060 case 'CCSID01142':
9061 case 'CP01142':
9062 case 'EBCDIC-DK-277+EURO':
9063 case 'EBCDIC-NO-277+EURO':
9064 case 'IBM01142':
9065 return 'IBM01142';
9066
9067 case 'CCSID01143':
9068 case 'CP01143':
9069 case 'EBCDIC-FI-278+EURO':
9070 case 'EBCDIC-SE-278+EURO':
9071 case 'IBM01143':
9072 return 'IBM01143';
9073
9074 case 'CCSID01144':
9075 case 'CP01144':
9076 case 'EBCDIC-IT-280+EURO':
9077 case 'IBM01144':
9078 return 'IBM01144';
9079
9080 case 'CCSID01145':
9081 case 'CP01145':
9082 case 'EBCDIC-ES-284+EURO':
9083 case 'IBM01145':
9084 return 'IBM01145';
9085
9086 case 'CCSID01146':
9087 case 'CP01146':
9088 case 'EBCDIC-GB-285+EURO':
9089 case 'IBM01146':
9090 return 'IBM01146';
9091
9092 case 'CCSID01147':
9093 case 'CP01147':
9094 case 'EBCDIC-FR-297+EURO':
9095 case 'IBM01147':
9096 return 'IBM01147';
9097
9098 case 'CCSID01148':
9099 case 'CP01148':
9100 case 'EBCDIC-INTERNATIONAL-500+EURO':
9101 case 'IBM01148':
9102 return 'IBM01148';
9103
9104 case 'CCSID01149':
9105 case 'CP01149':
9106 case 'EBCDIC-IS-871+EURO':
9107 case 'IBM01149':
9108 return 'IBM01149';
9109
f2f7b699 9110 case 'CP037':
6d7d21a0 9111 case 'CSIBM037':
f2f7b699 9112 case 'EBCDIC-CP-CA':
f2f7b699 9113 case 'EBCDIC-CP-NL':
6d7d21a0
AD
9114 case 'EBCDIC-CP-US':
9115 case 'EBCDIC-CP-WT':
9116 case 'IBM037':
f2f7b699 9117 return 'IBM037';
6d7d21a0 9118
f2f7b699
AD
9119 case 'CP038':
9120 case 'CSIBM038':
6d7d21a0
AD
9121 case 'EBCDIC-INT':
9122 case 'IBM038':
f2f7b699 9123 return 'IBM038';
6d7d21a0
AD
9124
9125 case 'CP1026':
9126 case 'CSIBM1026':
9127 case 'IBM1026':
9128 return 'IBM1026';
9129
9130 case 'IBM-1047':
9131 case 'IBM1047':
9132 return 'IBM1047';
9133
f2f7b699
AD
9134 case 'CP273':
9135 case 'CSIBM273':
6d7d21a0 9136 case 'IBM273':
f2f7b699 9137 return 'IBM273';
6d7d21a0 9138
f2f7b699
AD
9139 case 'CP274':
9140 case 'CSIBM274':
6d7d21a0
AD
9141 case 'EBCDIC-BE':
9142 case 'IBM274':
f2f7b699 9143 return 'IBM274';
6d7d21a0 9144
f2f7b699
AD
9145 case 'CP275':
9146 case 'CSIBM275':
6d7d21a0
AD
9147 case 'EBCDIC-BR':
9148 case 'IBM275':
f2f7b699 9149 return 'IBM275';
6d7d21a0
AD
9150
9151 case 'CSIBM277':
f2f7b699
AD
9152 case 'EBCDIC-CP-DK':
9153 case 'EBCDIC-CP-NO':
6d7d21a0 9154 case 'IBM277':
f2f7b699 9155 return 'IBM277';
6d7d21a0 9156
f2f7b699 9157 case 'CP278':
6d7d21a0 9158 case 'CSIBM278':
f2f7b699
AD
9159 case 'EBCDIC-CP-FI':
9160 case 'EBCDIC-CP-SE':
6d7d21a0 9161 case 'IBM278':
f2f7b699 9162 return 'IBM278';
6d7d21a0 9163
f2f7b699 9164 case 'CP280':
f2f7b699 9165 case 'CSIBM280':
6d7d21a0
AD
9166 case 'EBCDIC-CP-IT':
9167 case 'IBM280':
f2f7b699 9168 return 'IBM280';
6d7d21a0 9169
f2f7b699
AD
9170 case 'CP281':
9171 case 'CSIBM281':
6d7d21a0
AD
9172 case 'EBCDIC-JP-E':
9173 case 'IBM281':
f2f7b699 9174 return 'IBM281';
6d7d21a0 9175
f2f7b699 9176 case 'CP284':
f2f7b699 9177 case 'CSIBM284':
6d7d21a0
AD
9178 case 'EBCDIC-CP-ES':
9179 case 'IBM284':
f2f7b699 9180 return 'IBM284';
6d7d21a0 9181
f2f7b699 9182 case 'CP285':
f2f7b699 9183 case 'CSIBM285':
6d7d21a0
AD
9184 case 'EBCDIC-CP-GB':
9185 case 'IBM285':
f2f7b699 9186 return 'IBM285';
6d7d21a0 9187
f2f7b699 9188 case 'CP290':
f2f7b699 9189 case 'CSIBM290':
6d7d21a0
AD
9190 case 'EBCDIC-JP-KANA':
9191 case 'IBM290':
9192 return 'IBM290';
9193
f2f7b699 9194 case 'CP297':
f2f7b699 9195 case 'CSIBM297':
6d7d21a0
AD
9196 case 'EBCDIC-CP-FR':
9197 case 'IBM297':
f2f7b699 9198 return 'IBM297';
6d7d21a0 9199
f2f7b699 9200 case 'CP420':
f2f7b699 9201 case 'CSIBM420':
6d7d21a0
AD
9202 case 'EBCDIC-CP-AR1':
9203 case 'IBM420':
f2f7b699 9204 return 'IBM420';
6d7d21a0 9205
f2f7b699 9206 case 'CP423':
f2f7b699 9207 case 'CSIBM423':
6d7d21a0
AD
9208 case 'EBCDIC-CP-GR':
9209 case 'IBM423':
f2f7b699 9210 return 'IBM423';
6d7d21a0 9211
f2f7b699 9212 case 'CP424':
f2f7b699 9213 case 'CSIBM424':
6d7d21a0
AD
9214 case 'EBCDIC-CP-HE':
9215 case 'IBM424':
f2f7b699 9216 return 'IBM424';
6d7d21a0 9217
f2f7b699 9218 case '437':
6d7d21a0 9219 case 'CP437':
f2f7b699 9220 case 'CSPC8CODEPAGE437':
6d7d21a0 9221 case 'IBM437':
f2f7b699 9222 return 'IBM437';
6d7d21a0 9223
f2f7b699 9224 case 'CP500':
6d7d21a0 9225 case 'CSIBM500':
f2f7b699
AD
9226 case 'EBCDIC-CP-BE':
9227 case 'EBCDIC-CP-CH':
6d7d21a0 9228 case 'IBM500':
f2f7b699 9229 return 'IBM500';
6d7d21a0
AD
9230
9231 case 'CP775':
9232 case 'CSPC775BALTIC':
9233 case 'IBM775':
9234 return 'IBM775';
9235
9236 case '850':
9237 case 'CP850':
9238 case 'CSPC850MULTILINGUAL':
9239 case 'IBM850':
9240 return 'IBM850';
9241
f2f7b699 9242 case '851':
6d7d21a0 9243 case 'CP851':
f2f7b699 9244 case 'CSIBM851':
6d7d21a0 9245 case 'IBM851':
f2f7b699 9246 return 'IBM851';
6d7d21a0 9247
f2f7b699 9248 case '852':
6d7d21a0 9249 case 'CP852':
f2f7b699 9250 case 'CSPCP852':
6d7d21a0 9251 case 'IBM852':
f2f7b699 9252 return 'IBM852';
6d7d21a0 9253
f2f7b699 9254 case '855':
6d7d21a0 9255 case 'CP855':
f2f7b699 9256 case 'CSIBM855':
6d7d21a0 9257 case 'IBM855':
f2f7b699 9258 return 'IBM855';
6d7d21a0 9259
f2f7b699 9260 case '857':
6d7d21a0 9261 case 'CP857':
f2f7b699 9262 case 'CSIBM857':
6d7d21a0 9263 case 'IBM857':
f2f7b699 9264 return 'IBM857';
6d7d21a0 9265
f2f7b699 9266 case '860':
6d7d21a0 9267 case 'CP860':
f2f7b699 9268 case 'CSIBM860':
6d7d21a0 9269 case 'IBM860':
f2f7b699 9270 return 'IBM860';
6d7d21a0 9271
f2f7b699
AD
9272 case '861':
9273 case 'CP-IS':
6d7d21a0 9274 case 'CP861':
f2f7b699 9275 case 'CSIBM861':
6d7d21a0 9276 case 'IBM861':
f2f7b699 9277 return 'IBM861';
6d7d21a0
AD
9278
9279 case '862':
9280 case 'CP862':
9281 case 'CSPC862LATINHEBREW':
9282 case 'IBM862':
9283 return 'IBM862';
9284
f2f7b699 9285 case '863':
6d7d21a0 9286 case 'CP863':
f2f7b699 9287 case 'CSIBM863':
6d7d21a0 9288 case 'IBM863':
f2f7b699 9289 return 'IBM863';
6d7d21a0 9290
f2f7b699
AD
9291 case 'CP864':
9292 case 'CSIBM864':
6d7d21a0 9293 case 'IBM864':
f2f7b699 9294 return 'IBM864';
6d7d21a0 9295
f2f7b699 9296 case '865':
6d7d21a0 9297 case 'CP865':
f2f7b699 9298 case 'CSIBM865':
6d7d21a0 9299 case 'IBM865':
f2f7b699 9300 return 'IBM865';
6d7d21a0
AD
9301
9302 case '866':
9303 case 'CP866':
9304 case 'CSIBM866':
9305 case 'IBM866':
9306 return 'IBM866';
9307
f2f7b699 9308 case 'CP-AR':
6d7d21a0 9309 case 'CP868':
f2f7b699 9310 case 'CSIBM868':
6d7d21a0 9311 case 'IBM868':
f2f7b699 9312 return 'IBM868';
6d7d21a0 9313
f2f7b699
AD
9314 case '869':
9315 case 'CP-GR':
6d7d21a0 9316 case 'CP869':
f2f7b699 9317 case 'CSIBM869':
6d7d21a0 9318 case 'IBM869':
f2f7b699 9319 return 'IBM869';
6d7d21a0 9320
f2f7b699 9321 case 'CP870':
6d7d21a0 9322 case 'CSIBM870':
f2f7b699
AD
9323 case 'EBCDIC-CP-ROECE':
9324 case 'EBCDIC-CP-YU':
6d7d21a0 9325 case 'IBM870':
f2f7b699 9326 return 'IBM870';
6d7d21a0 9327
f2f7b699 9328 case 'CP871':
f2f7b699 9329 case 'CSIBM871':
6d7d21a0
AD
9330 case 'EBCDIC-CP-IS':
9331 case 'IBM871':
f2f7b699 9332 return 'IBM871';
6d7d21a0 9333
f2f7b699 9334 case 'CP880':
f2f7b699 9335 case 'CSIBM880':
6d7d21a0
AD
9336 case 'EBCDIC-CYRILLIC':
9337 case 'IBM880':
f2f7b699 9338 return 'IBM880';
6d7d21a0 9339
f2f7b699
AD
9340 case 'CP891':
9341 case 'CSIBM891':
6d7d21a0 9342 case 'IBM891':
f2f7b699 9343 return 'IBM891';
6d7d21a0 9344
f2f7b699
AD
9345 case 'CP903':
9346 case 'CSIBM903':
6d7d21a0 9347 case 'IBM903':
f2f7b699 9348 return 'IBM903';
6d7d21a0 9349
f2f7b699 9350 case '904':
6d7d21a0 9351 case 'CP904':
f2f7b699 9352 case 'CSIBBM904':
6d7d21a0 9353 case 'IBM904':
f2f7b699 9354 return 'IBM904';
6d7d21a0 9355
f2f7b699 9356 case 'CP905':
f2f7b699 9357 case 'CSIBM905':
6d7d21a0
AD
9358 case 'EBCDIC-CP-TR':
9359 case 'IBM905':
f2f7b699 9360 return 'IBM905';
6d7d21a0 9361
f2f7b699 9362 case 'CP918':
f2f7b699 9363 case 'CSIBM918':
6d7d21a0
AD
9364 case 'EBCDIC-CP-AR2':
9365 case 'IBM918':
f2f7b699 9366 return 'IBM918';
6d7d21a0
AD
9367
9368 case 'CSISO143IECP271':
9369 case 'IEC_P27-1':
9370 case 'ISO-IR-143':
9371 return 'IEC_P27-1';
9372
9373 case 'CSISO49INIS':
9374 case 'INIS':
9375 case 'ISO-IR-49':
9376 return 'INIS';
9377
9378 case 'CSISO50INIS8':
9379 case 'INIS-8':
9380 case 'ISO-IR-50':
9381 return 'INIS-8';
9382
9383 case 'CSISO51INISCYRILLIC':
9384 case 'INIS-CYRILLIC':
9385 case 'ISO-IR-51':
9386 return 'INIS-cyrillic';
9387
9388 case 'CSINVARIANT':
9389 case 'INVARIANT':
9390 return 'INVARIANT';
9391
9392 case 'ISO-10646-J-1':
9393 return 'ISO-10646-J-1';
9394
9395 case 'CSUNICODE':
9396 case 'ISO-10646-UCS-2':
9397 return 'ISO-10646-UCS-2';
9398
9399 case 'CSUCS4':
9400 case 'ISO-10646-UCS-4':
9401 return 'ISO-10646-UCS-4';
9402
9403 case 'CSUNICODEASCII':
9404 case 'ISO-10646-UCS-BASIC':
9405 return 'ISO-10646-UCS-Basic';
9406
9407 case 'CSISO10646UTF1':
9408 case 'ISO-10646-UTF-1':
9409 return 'ISO-10646-UTF-1';
9410
9411 case 'CSUNICODELATIN1':
9412 case 'ISO-10646':
9413 case 'ISO-10646-UNICODE-LATIN1':
9414 return 'ISO-10646-Unicode-Latin1';
9415
9416 case 'CSISO115481':
9417 case 'ISO-11548-1':
9418 case 'ISO_11548-1':
9419 case 'ISO_TR_11548-1':
9420 return 'ISO-11548-1';
9421
9422 case 'ISO-2022-CN':
9423 return 'ISO-2022-CN';
9424
9425 case 'ISO-2022-CN-EXT':
9426 return 'ISO-2022-CN-EXT';
9427
9428 case 'CSISO2022JP':
9429 case 'ISO-2022-JP':
9430 return 'ISO-2022-JP';
9431
9432 case 'CSISO2022JP2':
9433 case 'ISO-2022-JP-2':
9434 return 'ISO-2022-JP-2';
9435
9436 case 'CSISO2022KR':
9437 case 'ISO-2022-KR':
9438 return 'ISO-2022-KR';
9439
9440 case 'CSWINDOWS30LATIN1':
9441 case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
9442 return 'ISO-8859-1-Windows-3.0-Latin-1';
9443
9444 case 'CSWINDOWS31LATIN1':
9445 case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
9446 return 'ISO-8859-1-Windows-3.1-Latin-1';
9447
9448 case 'CSISOLATIN6':
9449 case 'ISO-8859-10':
9450 case 'ISO-IR-157':
9451 case 'ISO_8859-10:1992':
9452 case 'L6':
9453 case 'LATIN6':
9454 return 'ISO-8859-10';
9455
9456 case 'ISO-8859-13':
9457 return 'ISO-8859-13';
9458
9459 case 'ISO-8859-14':
9460 case 'ISO-CELTIC':
9461 case 'ISO-IR-199':
9462 case 'ISO_8859-14':
9463 case 'ISO_8859-14:1998':
9464 case 'L8':
9465 case 'LATIN8':
9466 return 'ISO-8859-14';
9467
9468 case 'ISO-8859-15':
9469 case 'ISO_8859-15':
9470 case 'LATIN-9':
9471 return 'ISO-8859-15';
9472
9473 case 'ISO-8859-16':
9474 case 'ISO-IR-226':
9475 case 'ISO_8859-16':
9476 case 'ISO_8859-16:2001':
9477 case 'L10':
9478 case 'LATIN10':
9479 return 'ISO-8859-16';
9480
9481 case 'CSISOLATIN2':
9482 case 'ISO-8859-2':
9483 case 'ISO-IR-101':
9484 case 'ISO_8859-2':
9485 case 'ISO_8859-2:1987':
9486 case 'L2':
9487 case 'LATIN2':
9488 return 'ISO-8859-2';
9489
9490 case 'CSWINDOWS31LATIN2':
9491 case 'ISO-8859-2-WINDOWS-LATIN-2':
9492 return 'ISO-8859-2-Windows-Latin-2';
9493
9494 case 'CSISOLATIN3':
9495 case 'ISO-8859-3':
9496 case 'ISO-IR-109':
9497 case 'ISO_8859-3':
9498 case 'ISO_8859-3:1988':
9499 case 'L3':
9500 case 'LATIN3':
9501 return 'ISO-8859-3';
9502
9503 case 'CSISOLATIN4':
9504 case 'ISO-8859-4':
9505 case 'ISO-IR-110':
9506 case 'ISO_8859-4':
9507 case 'ISO_8859-4:1988':
9508 case 'L4':
9509 case 'LATIN4':
9510 return 'ISO-8859-4';
9511
9512 case 'CSISOLATINCYRILLIC':
9513 case 'CYRILLIC':
9514 case 'ISO-8859-5':
9515 case 'ISO-IR-144':
9516 case 'ISO_8859-5':
9517 case 'ISO_8859-5:1988':
9518 return 'ISO-8859-5';
9519
9520 case 'ARABIC':
9521 case 'ASMO-708':
9522 case 'CSISOLATINARABIC':
9523 case 'ECMA-114':
9524 case 'ISO-8859-6':
9525 case 'ISO-IR-127':
9526 case 'ISO_8859-6':
9527 case 'ISO_8859-6:1987':
9528 return 'ISO-8859-6';
9529
9530 case 'CSISO88596E':
9531 case 'ISO-8859-6-E':
9532 case 'ISO_8859-6-E':
9533 return 'ISO-8859-6-E';
9534
9535 case 'CSISO88596I':
9536 case 'ISO-8859-6-I':
9537 case 'ISO_8859-6-I':
9538 return 'ISO-8859-6-I';
9539
9540 case 'CSISOLATINGREEK':
9541 case 'ECMA-118':
9542 case 'ELOT_928':
9543 case 'GREEK':
9544 case 'GREEK8':
9545 case 'ISO-8859-7':
9546 case 'ISO-IR-126':
9547 case 'ISO_8859-7':
9548 case 'ISO_8859-7:1987':
9549 return 'ISO-8859-7';
9550
9551 case 'CSISOLATINHEBREW':
9552 case 'HEBREW':
9553 case 'ISO-8859-8':
9554 case 'ISO-IR-138':
9555 case 'ISO_8859-8':
9556 case 'ISO_8859-8:1988':
9557 return 'ISO-8859-8';
9558
9559 case 'CSISO88598E':
9560 case 'ISO-8859-8-E':
9561 case 'ISO_8859-8-E':
9562 return 'ISO-8859-8-E';
9563
9564 case 'CSISO88598I':
9565 case 'ISO-8859-8-I':
9566 case 'ISO_8859-8-I':
9567 return 'ISO-8859-8-I';
9568
9569 case 'CSISOLATIN5':
9570 case 'ISO-8859-9':
9571 case 'ISO-IR-148':
9572 case 'ISO_8859-9':
9573 case 'ISO_8859-9:1989':
9574 case 'L5':
9575 case 'LATIN5':
9576 return 'ISO-8859-9';
9577
9578 case 'CSWINDOWS31LATIN5':
9579 case 'ISO-8859-9-WINDOWS-LATIN-5':
9580 return 'ISO-8859-9-Windows-Latin-5';
9581
9582 case 'CSUNICODEIBM1261':
9583 case 'ISO-UNICODE-IBM-1261':
9584 return 'ISO-Unicode-IBM-1261';
9585
9586 case 'CSUNICODEIBM1264':
9587 case 'ISO-UNICODE-IBM-1264':
9588 return 'ISO-Unicode-IBM-1264';
9589
9590 case 'CSUNICODEIBM1265':
9591 case 'ISO-UNICODE-IBM-1265':
9592 return 'ISO-Unicode-IBM-1265';
9593
9594 case 'CSUNICODEIBM1268':
9595 case 'ISO-UNICODE-IBM-1268':
9596 return 'ISO-Unicode-IBM-1268';
9597
9598 case 'CSUNICODEIBM1276':
9599 case 'ISO-UNICODE-IBM-1276':
9600 return 'ISO-Unicode-IBM-1276';
9601
9602 case 'CSISO10367BOX':
9603 case 'ISO-IR-155':
9604 case 'ISO_10367-BOX':
9605 return 'ISO_10367-box';
9606
9607 case 'CSISO2033':
9608 case 'E13B':
9609 case 'ISO-IR-98':
9610 case 'ISO_2033-1983':
9611 return 'ISO_2033-1983';
9612
9613 case 'CSISO5427CYRILLIC':
9614 case 'ISO-IR-37':
9615 case 'ISO_5427':
9616 return 'ISO_5427';
9617
9618 case 'ISO-IR-54':
9619 case 'ISO5427CYRILLIC1981':
9620 case 'ISO_5427:1981':
9621 return 'ISO_5427:1981';
9622
9623 case 'CSISO5428GREEK':
9624 case 'ISO-IR-55':
9625 case 'ISO_5428:1980':
9626 return 'ISO_5428:1980';
9627
9628 case 'CSISO646BASIC1983':
9629 case 'ISO_646.BASIC:1983':
9630 case 'REF':
9631 return 'ISO_646.basic:1983';
9632
9633 case 'CSISO2INTLREFVERSION':
9634 case 'IRV':
9635 case 'ISO-IR-2':
9636 case 'ISO_646.IRV:1983':
9637 return 'ISO_646.irv:1983';
9638
9639 case 'CSISO6937ADD':
9640 case 'ISO-IR-152':
9641 case 'ISO_6937-2-25':
9642 return 'ISO_6937-2-25';
9643
9644 case 'CSISOTEXTCOMM':
9645 case 'ISO-IR-142':
9646 case 'ISO_6937-2-ADD':
9647 return 'ISO_6937-2-add';
9648
9649 case 'CSISO8859SUPP':
9650 case 'ISO-IR-154':
9651 case 'ISO_8859-SUPP':
9652 case 'LATIN1-2-5':
9653 return 'ISO_8859-supp';
9654
9655 case 'CSISO15ITALIAN':
9656 case 'ISO-IR-15':
9657 case 'ISO646-IT':
9658 case 'IT':
9659 return 'IT';
9660
9661 case 'CSISO13JISC6220JP':
9662 case 'ISO-IR-13':
9663 case 'JIS_C6220-1969':
9664 case 'JIS_C6220-1969-JP':
9665 case 'KATAKANA':
9666 case 'X0201-7':
9667 return 'JIS_C6220-1969-jp';
9668
9669 case 'CSISO14JISC6220RO':
9670 case 'ISO-IR-14':
9671 case 'ISO646-JP':
9672 case 'JIS_C6220-1969-RO':
9673 case 'JP':
9674 return 'JIS_C6220-1969-ro';
9675
9676 case 'CSISO42JISC62261978':
9677 case 'ISO-IR-42':
9678 case 'JIS_C6226-1978':
9679 return 'JIS_C6226-1978';
9680
9681 case 'CSISO87JISX0208':
9682 case 'ISO-IR-87':
9683 case 'JIS_C6226-1983':
9684 case 'JIS_X0208-1983':
9685 case 'X0208':
9686 return 'JIS_C6226-1983';
9687
9688 case 'CSISO91JISC62291984A':
9689 case 'ISO-IR-91':
9690 case 'JIS_C6229-1984-A':
9691 case 'JP-OCR-A':
9692 return 'JIS_C6229-1984-a';
9693
9694 case 'CSISO92JISC62991984B':
9695 case 'ISO-IR-92':
9696 case 'ISO646-JP-OCR-B':
9697 case 'JIS_C6229-1984-B':
9698 case 'JP-OCR-B':
9699 return 'JIS_C6229-1984-b';
9700
9701 case 'CSISO93JIS62291984BADD':
9702 case 'ISO-IR-93':
9703 case 'JIS_C6229-1984-B-ADD':
9704 case 'JP-OCR-B-ADD':
9705 return 'JIS_C6229-1984-b-add';
9706
9707 case 'CSISO94JIS62291984HAND':
9708 case 'ISO-IR-94':
9709 case 'JIS_C6229-1984-HAND':
9710 case 'JP-OCR-HAND':
9711 return 'JIS_C6229-1984-hand';
9712
9713 case 'CSISO95JIS62291984HANDADD':
9714 case 'ISO-IR-95':
9715 case 'JIS_C6229-1984-HAND-ADD':
9716 case 'JP-OCR-HAND-ADD':
9717 return 'JIS_C6229-1984-hand-add';
9718
9719 case 'CSISO96JISC62291984KANA':
9720 case 'ISO-IR-96':
9721 case 'JIS_C6229-1984-KANA':
9722 return 'JIS_C6229-1984-kana';
9723
9724 case 'CSJISENCODING':
9725 case 'JIS_ENCODING':
9726 return 'JIS_Encoding';
9727
9728 case 'CSHALFWIDTHKATAKANA':
9729 case 'JIS_X0201':
9730 case 'X0201':
9731 return 'JIS_X0201';
9732
9733 case 'CSISO159JISX02121990':
9734 case 'ISO-IR-159':
9735 case 'JIS_X0212-1990':
9736 case 'X0212':
9737 return 'JIS_X0212-1990';
9738
9739 case 'CSISO141JUSIB1002':
9740 case 'ISO-IR-141':
9741 case 'ISO646-YU':
9742 case 'JS':
9743 case 'JUS_I.B1.002':
9744 case 'YU':
9745 return 'JUS_I.B1.002';
9746
9747 case 'CSISO147MACEDONIAN':
9748 case 'ISO-IR-147':
9749 case 'JUS_I.B1.003-MAC':
9750 case 'MACEDONIAN':
9751 return 'JUS_I.B1.003-mac';
9752
9753 case 'CSISO146SERBIAN':
9754 case 'ISO-IR-146':
9755 case 'JUS_I.B1.003-SERB':
9756 case 'SERBIAN':
9757 return 'JUS_I.B1.003-serb';
9758
9759 case 'KOI7-SWITCHED':
9760 return 'KOI7-switched';
9761
9762 case 'CSKOI8R':
9763 case 'KOI8-R':
9764 return 'KOI8-R';
9765
9766 case 'KOI8-U':
9767 return 'KOI8-U';
9768
9769 case 'CSKSC5636':
9770 case 'ISO646-KR':
9771 case 'KSC5636':
9772 return 'KSC5636';
9773
9774 case 'CSKSC56011987':
9775 case 'ISO-IR-149':
9776 case 'KOREAN':
9777 case 'KSC_5601':
9778 case 'KS_C_5601-1987':
9779 case 'KS_C_5601-1989':
9780 return 'KS_C_5601-1987';
9781
9782 case 'CSKZ1048':
9783 case 'KZ-1048':
9784 case 'RK1048':
9785 case 'STRK1048-2002':
9786 return 'KZ-1048';
9787
9788 case 'CSISO27LATINGREEK1':
9789 case 'ISO-IR-27':
9790 case 'LATIN-GREEK-1':
9791 return 'Latin-greek-1';
9792
9793 case 'CSMNEM':
9794 case 'MNEM':
9795 return 'MNEM';
9796
9797 case 'CSMNEMONIC':
9798 case 'MNEMONIC':
9799 return 'MNEMONIC';
9800
9801 case 'CSISO86HUNGARIAN':
9802 case 'HU':
9803 case 'ISO-IR-86':
9804 case 'ISO646-HU':
9805 case 'MSZ_7795.3':
9806 return 'MSZ_7795.3';
9807
9808 case 'CSMICROSOFTPUBLISHING':
9809 case 'MICROSOFT-PUBLISHING':
9810 return 'Microsoft-Publishing';
9811
9812 case 'CSNATSDANO':
9813 case 'ISO-IR-9-1':
9814 case 'NATS-DANO':
9815 return 'NATS-DANO';
9816
9817 case 'CSNATSDANOADD':
9818 case 'ISO-IR-9-2':
9819 case 'NATS-DANO-ADD':
9820 return 'NATS-DANO-ADD';
9821
9822 case 'CSNATSSEFI':
9823 case 'ISO-IR-8-1':
9824 case 'NATS-SEFI':
9825 return 'NATS-SEFI';
9826
9827 case 'CSNATSSEFIADD':
9828 case 'ISO-IR-8-2':
9829 case 'NATS-SEFI-ADD':
9830 return 'NATS-SEFI-ADD';
9831
9832 case 'CSISO151CUBA':
9833 case 'CUBA':
9834 case 'ISO-IR-151':
9835 case 'ISO646-CU':
9836 case 'NC_NC00-10:81':
9837 return 'NC_NC00-10:81';
9838
9839 case 'CSISO69FRENCH':
9840 case 'FR':
9841 case 'ISO-IR-69':
9842 case 'ISO646-FR':
9843 case 'NF_Z_62-010':
9844 return 'NF_Z_62-010';
9845
9846 case 'CSISO25FRENCH':
9847 case 'ISO-IR-25':
9848 case 'ISO646-FR1':
9849 case 'NF_Z_62-010_(1973)':
9850 return 'NF_Z_62-010_(1973)';
9851
9852 case 'CSISO60DANISHNORWEGIAN':
9853 case 'CSISO60NORWEGIAN1':
9854 case 'ISO-IR-60':
9855 case 'ISO646-NO':
9856 case 'NO':
9857 case 'NS_4551-1':
9858 return 'NS_4551-1';
9859
9860 case 'CSISO61NORWEGIAN2':
9861 case 'ISO-IR-61':
9862 case 'ISO646-NO2':
9863 case 'NO2':
9864 case 'NS_4551-2':
9865 return 'NS_4551-2';
9866
9867 case 'OSD_EBCDIC_DF03_IRV':
9868 return 'OSD_EBCDIC_DF03_IRV';
9869
9870 case 'OSD_EBCDIC_DF04_1':
9871 return 'OSD_EBCDIC_DF04_1';
9872
9873 case 'OSD_EBCDIC_DF04_15':
9874 return 'OSD_EBCDIC_DF04_15';
9875
9876 case 'CSPC8DANISHNORWEGIAN':
9877 case 'PC8-DANISH-NORWEGIAN':
9878 return 'PC8-Danish-Norwegian';
9879
9880 case 'CSPC8TURKISH':
9881 case 'PC8-TURKISH':
9882 return 'PC8-Turkish';
9883
9884 case 'CSISO16PORTUGUESE':
9885 case 'ISO-IR-16':
9886 case 'ISO646-PT':
9887 case 'PT':
9888 return 'PT';
9889
9890 case 'CSISO84PORTUGUESE2':
9891 case 'ISO-IR-84':
9892 case 'ISO646-PT2':
9893 case 'PT2':
9894 return 'PT2';
9895
9896 case 'CP154':
9897 case 'CSPTCP154':
9898 case 'CYRILLIC-ASIAN':
9899 case 'PT154':
9900 case 'PTCP154':
9901 return 'PTCP154';
9902
9903 case 'SCSU':
9904 return 'SCSU';
9905
9906 case 'CSISO10SWEDISH':
9907 case 'FI':
9908 case 'ISO-IR-10':
9909 case 'ISO646-FI':
9910 case 'ISO646-SE':
9911 case 'SE':
9912 case 'SEN_850200_B':
9913 return 'SEN_850200_B';
9914
9915 case 'CSISO11SWEDISHFORNAMES':
9916 case 'ISO-IR-11':
9917 case 'ISO646-SE2':
9918 case 'SE2':
9919 case 'SEN_850200_C':
9920 return 'SEN_850200_C';
9921
9922 case 'CSSHIFTJIS':
9923 case 'MS_KANJI':
9924 case 'SHIFT_JIS':
9925 return 'Shift_JIS';
9926
9927 case 'CSISO128T101G2':
9928 case 'ISO-IR-128':
9929 case 'T.101-G2':
9930 return 'T.101-G2';
9931
9932 case 'CSISO102T617BIT':
9933 case 'ISO-IR-102':
9934 case 'T.61-7BIT':
9935 return 'T.61-7bit';
9936
9937 case 'CSISO103T618BIT':
9938 case 'ISO-IR-103':
9939 case 'T.61':
9940 case 'T.61-8BIT':
9941 return 'T.61-8bit';
9942
9943 case 'CSTSCII':
9944 case 'TSCII':
9945 return 'TSCII';
9946
9947 case 'CSUNICODE11':
9948 case 'UNICODE-1-1':
9949 return 'UNICODE-1-1';
9950
9951 case 'CSUNICODE11UTF7':
9952 case 'UNICODE-1-1-UTF-7':
9953 return 'UNICODE-1-1-UTF-7';
9954
9955 case 'CSUNKNOWN8BIT':
9956 case 'UNKNOWN-8BIT':
9957 return 'UNKNOWN-8BIT';
9958
9959 case 'ANSI':
9960 case 'ANSI_X3.4-1968':
9961 case 'ANSI_X3.4-1986':
9962 case 'ASCII':
9963 case 'CP367':
9964 case 'CSASCII':
9965 case 'IBM367':
9966 case 'ISO-IR-6':
9967 case 'ISO646-US':
9968 case 'ISO_646.IRV:1991':
9969 case 'US':
9970 case 'US-ASCII':
9971 return 'US-ASCII';
9972
9973 case 'UTF-16':
9974 return 'UTF-16';
9975
9976 case 'UTF-16BE':
9977 return 'UTF-16BE';
9978
9979 case 'UTF-16LE':
9980 return 'UTF-16LE';
9981
9982 case 'UTF-32':
9983 return 'UTF-32';
9984
9985 case 'UTF-32BE':
9986 return 'UTF-32BE';
9987
9988 case 'UTF-32LE':
9989 return 'UTF-32LE';
9990
9991 case 'UTF-7':
9992 return 'UTF-7';
9993
9994 case 'UTF-8':
9995 return 'UTF-8';
9996
f2f7b699 9997 case 'CSVIQR':
6d7d21a0 9998 case 'VIQR':
f2f7b699 9999 return 'VIQR';
6d7d21a0
AD
10000
10001 case 'CSVISCII':
10002 case 'VISCII':
10003 return 'VISCII';
10004
10005 case 'CSVENTURAINTERNATIONAL':
10006 case 'VENTURA-INTERNATIONAL':
10007 return 'Ventura-International';
10008
10009 case 'CSVENTURAMATH':
10010 case 'VENTURA-MATH':
10011 return 'Ventura-Math';
10012
10013 case 'CSVENTURAUS':
10014 case 'VENTURA-US':
10015 return 'Ventura-US';
10016
10017 case 'CSWINDOWS31J':
10018 case 'WINDOWS-31J':
10019 return 'Windows-31J';
10020
10021 case 'CSDKUS':
10022 case 'DK-US':
10023 return 'dk-us';
10024
10025 case 'CSISO150':
10026 case 'CSISO150GREEKCCITT':
10027 case 'GREEK-CCITT':
10028 case 'ISO-IR-150':
10029 return 'greek-ccitt';
10030
10031 case 'CSISO88GREEK7':
10032 case 'GREEK7':
10033 case 'ISO-IR-88':
10034 return 'greek7';
10035
10036 case 'CSISO18GREEK7OLD':
10037 case 'GREEK7-OLD':
10038 case 'ISO-IR-18':
10039 return 'greek7-old';
10040
10041 case 'CSHPROMAN8':
10042 case 'HP-ROMAN8':
10043 case 'R8':
10044 case 'ROMAN8':
10045 return 'hp-roman8';
10046
10047 case 'CSISO90':
10048 case 'ISO-IR-90':
10049 return 'iso-ir-90';
10050
10051 case 'CSISO19LATINGREEK':
10052 case 'ISO-IR-19':
10053 case 'LATIN-GREEK':
10054 return 'latin-greek';
10055
10056 case 'CSISO158LAP':
10057 case 'ISO-IR-158':
10058 case 'LAP':
10059 case 'LATIN-LAP':
10060 return 'latin-lap';
10061
10062 case 'CSMACINTOSH':
10063 case 'MAC':
10064 case 'MACINTOSH':
10065 return 'macintosh';
10066
10067 case 'CSUSDK':
10068 case 'US-DK':
10069 return 'us-dk';
10070
10071 case 'CSISO70VIDEOTEXSUPP1':
10072 case 'ISO-IR-70':
10073 case 'VIDEOTEX-SUPPL':
10074 return 'videotex-suppl';
10075
10076 case 'WINDOWS-1250':
10077 return 'windows-1250';
10078
10079 case 'WINDOWS-1251':
10080 return 'windows-1251';
10081
10082 case 'CP819':
10083 case 'CSISOLATIN1':
10084 case 'IBM819':
10085 case 'ISO-8859-1':
10086 case 'ISO-IR-100':
10087 case 'ISO_8859-1':
10088 case 'ISO_8859-1:1987':
10089 case 'L1':
10090 case 'LATIN1':
10091 case 'WINDOWS-1252':
10092 return 'windows-1252';
10093
10094 case 'WINDOWS-1253':
10095 return 'windows-1253';
10096
10097 case 'WINDOWS-1254':
10098 return 'windows-1254';
10099
10100 case 'WINDOWS-1255':
10101 return 'windows-1255';
10102
10103 case 'WINDOWS-1256':
10104 return 'windows-1256';
10105
10106 case 'WINDOWS-1257':
10107 return 'windows-1257';
10108
10109 case 'WINDOWS-1258':
10110 return 'windows-1258';
10111
10112 default:
10113 return $encoding;
10114 }
10115 }
f2f7b699 10116
6d7d21a0
AD
10117 function get_curl_version()
10118 {
10119 if (is_array($curl = curl_version()))
10120 {
10121 $curl = $curl['version'];
10122 }
10123 elseif (substr($curl, 0, 5) == 'curl/')
10124 {
10125 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10126 }
10127 elseif (substr($curl, 0, 8) == 'libcurl/')
10128 {
10129 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10130 }
10131 else
10132 {
10133 $curl = 0;
10134 }
10135 return $curl;
10136 }
f2f7b699 10137
6d7d21a0
AD
10138 function is_subclass_of($class1, $class2)
10139 {
10140 if (func_num_args() != 2)
10141 {
10142 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10143 }
10144 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10145 {
10146 return is_subclass_of($class1, $class2);
10147 }
10148 elseif (is_string($class1) && is_string($class2))
10149 {
10150 if (class_exists($class1))
10151 {
10152 if (class_exists($class2))
10153 {
10154 $class2 = strtolower($class2);
10155 while ($class1 = strtolower(get_parent_class($class1)))
10156 {
10157 if ($class1 == $class2)
10158 {
10159 return true;
10160 }
10161 }
10162 }
10163 }
10164 else
10165 {
10166 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10167 }
10168 }
10169 return false;
10170 }
f2f7b699 10171
6d7d21a0
AD
10172 /**
10173 * Strip HTML comments
10174 *
10175 * @access public
10176 * @param string $data Data to strip comments from
10177 * @return string Comment stripped string
10178 */
10179 function strip_comments($data)
10180 {
10181 $output = '';
10182 while (($start = strpos($data, '<!--')) !== false)
10183 {
10184 $output .= substr($data, 0, $start);
10185 if (($end = strpos($data, '-->', $start)) !== false)
10186 {
10187 $data = substr_replace($data, '', 0, $end + 3);
10188 }
10189 else
10190 {
10191 $data = '';
10192 }
10193 }
10194 return $output . $data;
10195 }
f2f7b699 10196
6d7d21a0
AD
10197 function parse_date($dt)
10198 {
10199 $parser = SimplePie_Parse_Date::get();
10200 return $parser->parse($dt);
10201 }
f2f7b699 10202
6d7d21a0
AD
10203 /**
10204 * Decode HTML entities
10205 *
10206 * @static
10207 * @access public
10208 * @param string $data Input data
10209 * @return string Output data
10210 */
10211 function entities_decode($data)
10212 {
10213 $decoder = new SimplePie_Decode_HTML_Entities($data);
10214 return $decoder->parse();
10215 }
f2f7b699 10216
6d7d21a0
AD
10217 /**
10218 * Remove RFC822 comments
10219 *
10220 * @access public
10221 * @param string $data Data to strip comments from
10222 * @return string Comment stripped string
10223 */
10224 function uncomment_rfc822($string)
10225 {
10226 $string = (string) $string;
10227 $position = 0;
10228 $length = strlen($string);
10229 $depth = 0;
10230
10231 $output = '';
10232
10233 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10234 {
10235 $output .= substr($string, $position, $pos - $position);
10236 $position = $pos + 1;
10237 if ($string[$pos - 1] !== '\\')
10238 {
10239 $depth++;
10240 while ($depth && $position < $length)
10241 {
10242 $position += strcspn($string, '()', $position);
10243 if ($string[$position - 1] === '\\')
10244 {
10245 $position++;
10246 continue;
10247 }
10248 elseif (isset($string[$position]))
10249 {
10250 switch ($string[$position])
10251 {
10252 case '(':
10253 $depth++;
10254 break;
10255
10256 case ')':
10257 $depth--;
10258 break;
10259 }
10260 $position++;
10261 }
10262 else
10263 {
10264 break;
10265 }
10266 }
10267 }
10268 else
10269 {
10270 $output .= '(';
10271 }
10272 }
10273 $output .= substr($string, $position);
10274
10275 return $output;
10276 }
f2f7b699 10277
6d7d21a0
AD
10278 function parse_mime($mime)
10279 {
10280 if (($pos = strpos($mime, ';')) === false)
10281 {
10282 return trim($mime);
10283 }
10284 else
10285 {
10286 return trim(substr($mime, 0, $pos));
10287 }
10288 }
f2f7b699 10289
6d7d21a0
AD
10290 function htmlspecialchars_decode($string, $quote_style)
10291 {
10292 if (function_exists('htmlspecialchars_decode'))
10293 {
10294 return htmlspecialchars_decode($string, $quote_style);
10295 }
10296 else
10297 {
10298 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10299 }
10300 }
f2f7b699 10301
6d7d21a0
AD
10302 function atom_03_construct_type($attribs)
10303 {
10304 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10305 {
10306 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10307 }
10308 else
10309 {
10310 $mode = SIMPLEPIE_CONSTRUCT_NONE;
10311 }
10312 if (isset($attribs['']['type']))
10313 {
10314 switch (strtolower(trim($attribs['']['type'])))
10315 {
10316 case 'text':
10317 case 'text/plain':
10318 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
f2f7b699 10319
6d7d21a0
AD
10320 case 'html':
10321 case 'text/html':
10322 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
f2f7b699 10323
6d7d21a0
AD
10324 case 'xhtml':
10325 case 'application/xhtml+xml':
10326 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
f2f7b699 10327
6d7d21a0
AD
10328 default:
10329 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10330 }
10331 }
10332 else
10333 {
10334 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10335 }
10336 }
f2f7b699 10337
6d7d21a0
AD
10338 function atom_10_construct_type($attribs)
10339 {
10340 if (isset($attribs['']['type']))
10341 {
10342 switch (strtolower(trim($attribs['']['type'])))
10343 {
10344 case 'text':
10345 return SIMPLEPIE_CONSTRUCT_TEXT;
f2f7b699 10346
6d7d21a0
AD
10347 case 'html':
10348 return SIMPLEPIE_CONSTRUCT_HTML;
f2f7b699 10349
6d7d21a0
AD
10350 case 'xhtml':
10351 return SIMPLEPIE_CONSTRUCT_XHTML;
f2f7b699 10352
6d7d21a0
AD
10353 default:
10354 return SIMPLEPIE_CONSTRUCT_NONE;
10355 }
10356 }
10357 return SIMPLEPIE_CONSTRUCT_TEXT;
10358 }
f2f7b699 10359
6d7d21a0
AD
10360 function atom_10_content_construct_type($attribs)
10361 {
10362 if (isset($attribs['']['type']))
10363 {
10364 $type = strtolower(trim($attribs['']['type']));
10365 switch ($type)
10366 {
10367 case 'text':
10368 return SIMPLEPIE_CONSTRUCT_TEXT;
f2f7b699 10369
6d7d21a0
AD
10370 case 'html':
10371 return SIMPLEPIE_CONSTRUCT_HTML;
f2f7b699 10372
6d7d21a0
AD
10373 case 'xhtml':
10374 return SIMPLEPIE_CONSTRUCT_XHTML;
10375 }
10376 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10377 {
10378 return SIMPLEPIE_CONSTRUCT_NONE;
10379 }
10380 else
10381 {
10382 return SIMPLEPIE_CONSTRUCT_BASE64;
10383 }
10384 }
10385 else
10386 {
10387 return SIMPLEPIE_CONSTRUCT_TEXT;
10388 }
10389 }
f2f7b699 10390
6d7d21a0
AD
10391 function is_isegment_nz_nc($string)
10392 {
10393 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);
10394 }
f2f7b699 10395
6d7d21a0
AD
10396 function space_seperated_tokens($string)
10397 {
10398 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10399 $string_length = strlen($string);
f2f7b699 10400
6d7d21a0
AD
10401 $position = strspn($string, $space_characters);
10402 $tokens = array();
f2f7b699 10403
6d7d21a0
AD
10404 while ($position < $string_length)
10405 {
10406 $len = strcspn($string, $space_characters, $position);
10407 $tokens[] = substr($string, $position, $len);
10408 $position += $len;
10409 $position += strspn($string, $space_characters, $position);
10410 }
f2f7b699 10411
6d7d21a0
AD
10412 return $tokens;
10413 }
f2f7b699 10414
6d7d21a0
AD
10415 function array_unique($array)
10416 {
10417 if (version_compare(PHP_VERSION, '5.2', '>='))
10418 {
10419 return array_unique($array);
10420 }
10421 else
10422 {
10423 $array = (array) $array;
10424 $new_array = array();
10425 $new_array_strings = array();
10426 foreach ($array as $key => $value)
10427 {
10428 if (is_object($value))
10429 {
10430 if (method_exists($value, '__toString'))
10431 {
10432 $cmp = $value->__toString();
10433 }
10434 else
10435 {
10436 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10437 }
10438 }
10439 elseif (is_array($value))
10440 {
10441 $cmp = (string) reset($value);
10442 }
10443 else
10444 {
10445 $cmp = (string) $value;
10446 }
10447 if (!in_array($cmp, $new_array_strings))
10448 {
10449 $new_array[$key] = $value;
10450 $new_array_strings[] = $cmp;
10451 }
10452 }
10453 return $new_array;
f2f7b699
AD
10454 }
10455 }
10456
6d7d21a0
AD
10457 /**
10458 * Converts a unicode codepoint to a UTF-8 character
10459 *
10460 * @static
10461 * @access public
10462 * @param int $codepoint Unicode codepoint
10463 * @return string UTF-8 character
10464 */
10465 function codepoint_to_utf8($codepoint)
f2f7b699 10466 {
6d7d21a0
AD
10467 static $cache = array();
10468 $codepoint = (int) $codepoint;
10469 if (isset($cache[$codepoint]))
f2f7b699 10470 {
6d7d21a0 10471 return $cache[$codepoint];
f2f7b699 10472 }
6d7d21a0 10473 elseif ($codepoint < 0)
f2f7b699 10474 {
6d7d21a0 10475 return $cache[$codepoint] = false;
f2f7b699 10476 }
6d7d21a0 10477 else if ($codepoint <= 0x7f)
f2f7b699 10478 {
6d7d21a0
AD
10479 return $cache[$codepoint] = chr($codepoint);
10480 }
10481 else if ($codepoint <= 0x7ff)
10482 {
10483 return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10484 }
10485 else if ($codepoint <= 0xffff)
10486 {
10487 return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10488 }
10489 else if ($codepoint <= 0x10ffff)
10490 {
10491 return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
f2f7b699
AD
10492 }
10493 else
10494 {
6d7d21a0
AD
10495 // U+FFFD REPLACEMENT CHARACTER
10496 return $cache[$codepoint] = "\xEF\xBF\xBD";
f2f7b699 10497 }
f2f7b699
AD
10498 }
10499
6d7d21a0
AD
10500 /**
10501 * Re-implementation of PHP 5's stripos()
10502 *
10503 * Returns the numeric position of the first occurrence of needle in the
10504 * haystack string.
10505 *
10506 * @static
10507 * @access string
10508 * @param object $haystack
10509 * @param string $needle Note that the needle may be a string of one or more
10510 * characters. If needle is not a string, it is converted to an integer
10511 * and applied as the ordinal value of a character.
10512 * @param int $offset The optional offset parameter allows you to specify which
10513 * character in haystack to start searching. The position returned is still
10514 * relative to the beginning of haystack.
10515 * @return bool If needle is not found, stripos() will return boolean false.
10516 */
10517 function stripos($haystack, $needle, $offset = 0)
f2f7b699 10518 {
6d7d21a0 10519 if (function_exists('stripos'))
f2f7b699 10520 {
6d7d21a0 10521 return stripos($haystack, $needle, $offset);
f2f7b699 10522 }
6d7d21a0 10523 else
f2f7b699 10524 {
6d7d21a0
AD
10525 if (is_string($needle))
10526 {
10527 $needle = strtolower($needle);
10528 }
10529 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10530 {
10531 $needle = strtolower(chr($needle));
10532 }
10533 else
10534 {
10535 trigger_error('needle is not a string or an integer', E_USER_WARNING);
10536 return false;
10537 }
10538
10539 return strpos(strtolower($haystack), $needle, $offset);
f2f7b699 10540 }
6d7d21a0
AD
10541 }
10542
10543 /**
10544 * Similar to parse_str()
10545 *
10546 * Returns an associative array of name/value pairs, where the value is an
10547 * array of values that have used the same name
10548 *
10549 * @static
10550 * @access string
10551 * @param string $str The input string.
10552 * @return array
10553 */
10554 function parse_str($str)
10555 {
10556 $return = array();
10557 $str = explode('&', $str);
10558
10559 foreach ($str as $section)
f2f7b699 10560 {
6d7d21a0 10561 if (strpos($section, '=') !== false)
f2f7b699 10562 {
6d7d21a0
AD
10563 list($name, $value) = explode('=', $section, 2);
10564 $return[urldecode($name)][] = urldecode($value);
10565 }
10566 else
10567 {
10568 $return[urldecode($section)][] = null;
10569 }
10570 }
10571
10572 return $return;
10573 }
10574
10575 /**
10576 * Detect XML encoding, as per XML 1.0 Appendix F.1
10577 *
10578 * @todo Add support for EBCDIC
10579 * @param string $data XML data
10580 * @return array Possible encodings
10581 */
10582 function xml_encoding($data)
10583 {
10584 // UTF-32 Big Endian BOM
10585 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10586 {
10587 $encoding[] = 'UTF-32BE';
10588 }
10589 // UTF-32 Little Endian BOM
10590 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10591 {
10592 $encoding[] = 'UTF-32LE';
10593 }
10594 // UTF-16 Big Endian BOM
10595 elseif (substr($data, 0, 2) === "\xFE\xFF")
10596 {
10597 $encoding[] = 'UTF-16BE';
10598 }
10599 // UTF-16 Little Endian BOM
10600 elseif (substr($data, 0, 2) === "\xFF\xFE")
10601 {
10602 $encoding[] = 'UTF-16LE';
10603 }
10604 // UTF-8 BOM
10605 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10606 {
10607 $encoding[] = 'UTF-8';
10608 }
10609 // UTF-32 Big Endian Without BOM
10610 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")
10611 {
10612 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
10613 {
10614 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
10615 if ($parser->parse())
f2f7b699 10616 {
6d7d21a0 10617 $encoding[] = $parser->encoding;
f2f7b699
AD
10618 }
10619 }
6d7d21a0
AD
10620 $encoding[] = 'UTF-32BE';
10621 }
10622 // UTF-32 Little Endian Without BOM
10623 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")
10624 {
10625 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
f2f7b699 10626 {
6d7d21a0
AD
10627 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
10628 if ($parser->parse())
10629 {
10630 $encoding[] = $parser->encoding;
10631 }
10632 }
10633 $encoding[] = 'UTF-32LE';
10634 }
10635 // UTF-16 Big Endian Without BOM
10636 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
10637 {
10638 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
10639 {
10640 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
10641 if ($parser->parse())
10642 {
10643 $encoding[] = $parser->encoding;
10644 }
10645 }
10646 $encoding[] = 'UTF-16BE';
10647 }
10648 // UTF-16 Little Endian Without BOM
10649 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
10650 {
10651 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
10652 {
10653 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
10654 if ($parser->parse())
10655 {
10656 $encoding[] = $parser->encoding;
10657 }
10658 }
10659 $encoding[] = 'UTF-16LE';
10660 }
10661 // US-ASCII (or superset)
10662 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
10663 {
10664 if ($pos = strpos($data, "\x3F\x3E"))
10665 {
10666 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
10667 if ($parser->parse())
10668 {
10669 $encoding[] = $parser->encoding;
10670 }
f2f7b699 10671 }
6d7d21a0
AD
10672 $encoding[] = 'UTF-8';
10673 }
10674 // Fallback to UTF-8
10675 else
10676 {
10677 $encoding[] = 'UTF-8';
10678 }
10679 return $encoding;
10680 }
10681}
10682
10683/**
10684 * Decode HTML Entities
10685 *
10686 * This implements HTML5 as of revision 967 (2007-06-28)
10687 *
10688 * @package SimplePie
10689 */
10690class SimplePie_Decode_HTML_Entities
10691{
10692 /**
10693 * Data to be parsed
10694 *
10695 * @access private
10696 * @var string
10697 */
10698 var $data = '';
10699
10700 /**
10701 * Currently consumed bytes
10702 *
10703 * @access private
10704 * @var string
10705 */
10706 var $consumed = '';
10707
10708 /**
10709 * Position of the current byte being parsed
10710 *
10711 * @access private
10712 * @var int
10713 */
10714 var $position = 0;
10715
10716 /**
10717 * Create an instance of the class with the input data
10718 *
10719 * @access public
10720 * @param string $data Input data
10721 */
10722 function SimplePie_Decode_HTML_Entities($data)
10723 {
10724 $this->data = $data;
10725 }
10726
10727 /**
10728 * Parse the input data
10729 *
10730 * @access public
10731 * @return string Output data
10732 */
10733 function parse()
10734 {
10735 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
10736 {
10737 $this->consume();
10738 $this->entity();
10739 $this->consumed = '';
10740 }
10741 return $this->data;
10742 }
10743
10744 /**
10745 * Consume the next byte
10746 *
10747 * @access private
10748 * @return mixed The next byte, or false, if there is no more data
10749 */
10750 function consume()
10751 {
10752 if (isset($this->data[$this->position]))
10753 {
10754 $this->consumed .= $this->data[$this->position];
10755 return $this->data[$this->position++];
10756 }
10757 else
10758 {
10759 $this->consumed = false;
10760 return false;
f2f7b699 10761 }
f2f7b699
AD
10762 }
10763
10764 /**
6d7d21a0 10765 * Consume a range of characters
f2f7b699 10766 *
6d7d21a0
AD
10767 * @access private
10768 * @param string $chars Characters to consume
10769 * @return mixed A series of characters that match the range, or false
f2f7b699 10770 */
6d7d21a0 10771 function consume_range($chars)
f2f7b699 10772 {
6d7d21a0 10773 if ($len = strspn($this->data, $chars, $this->position))
f2f7b699 10774 {
6d7d21a0
AD
10775 $data = substr($this->data, $this->position, $len);
10776 $this->consumed .= $data;
10777 $this->position += $len;
10778 return $data;
10779 }
10780 else
10781 {
10782 $this->consumed = false;
10783 return false;
f2f7b699 10784 }
f2f7b699
AD
10785 }
10786
6d7d21a0
AD
10787 /**
10788 * Unconsume one byte
10789 *
10790 * @access private
10791 */
10792 function unconsume()
f2f7b699 10793 {
6d7d21a0
AD
10794 $this->consumed = substr($this->consumed, 0, -1);
10795 $this->position--;
10796 }
10797
10798 /**
10799 * Decode an entity
10800 *
10801 * @access private
10802 */
10803 function entity()
10804 {
10805 switch ($this->consume())
f2f7b699 10806 {
6d7d21a0
AD
10807 case "\x09":
10808 case "\x0A":
10809 case "\x0B":
10810 case "\x0B":
10811 case "\x0C":
10812 case "\x20":
10813 case "\x3C":
10814 case "\x26":
10815 case false:
10816 break;
10817
10818 case "\x23":
10819 switch ($this->consume())
f2f7b699 10820 {
6d7d21a0
AD
10821 case "\x78":
10822 case "\x58":
10823 $range = '0123456789ABCDEFabcdef';
10824 $hex = true;
10825 break;
10826
10827 default:
10828 $range = '0123456789';
10829 $hex = false;
10830 $this->unconsume();
10831 break;
f2f7b699 10832 }
f2f7b699 10833
6d7d21a0 10834 if ($codepoint = $this->consume_range($range))
f2f7b699 10835 {
6d7d21a0
AD
10836 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");
10837
10838 if ($hex)
f2f7b699 10839 {
6d7d21a0 10840 $codepoint = hexdec($codepoint);
f2f7b699
AD
10841 }
10842 else
10843 {
6d7d21a0 10844 $codepoint = intval($codepoint);
f2f7b699 10845 }
f2f7b699 10846
6d7d21a0
AD
10847 if (isset($windows_1252_specials[$codepoint]))
10848 {
10849 $replacement = $windows_1252_specials[$codepoint];
f2f7b699 10850 }
6d7d21a0 10851 else
f2f7b699 10852 {
6d7d21a0
AD
10853 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
10854 }
f2f7b699 10855
6d7d21a0
AD
10856 if ($this->consume() != ';')
10857 {
10858 $this->unconsume();
10859 }
f2f7b699 10860
6d7d21a0
AD
10861 $consumed_length = strlen($this->consumed);
10862 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
10863 $this->position += strlen($replacement) - $consumed_length;
10864 }
10865 break;
f2f7b699 10866
6d7d21a0
AD
10867 default:
10868 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");
f2f7b699 10869
6d7d21a0
AD
10870 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
10871 {
10872 $consumed = substr($this->consumed, 1);
10873 if (isset($entities[$consumed]))
f2f7b699 10874 {
6d7d21a0 10875 $match = $consumed;
f2f7b699
AD
10876 }
10877 }
f2f7b699 10878
6d7d21a0
AD
10879 if ($match !== null)
10880 {
10881 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
10882 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
10883 }
10884 break;
10885 }
10886 }
10887}
f2f7b699 10888
6d7d21a0
AD
10889/**
10890 * Date Parser
10891 *
10892 * @package SimplePie
10893 */
10894class SimplePie_Parse_Date
10895{
10896 /**
10897 * Input data
10898 *
10899 * @access protected
10900 * @var string
10901 */
10902 var $date;
f2f7b699 10903
6d7d21a0
AD
10904 /**
10905 * List of days, calendar day name => ordinal day number in the week
10906 *
10907 * @access protected
10908 * @var array
10909 */
10910 var $day = array(
10911 // English
10912 'mon' => 1,
10913 'monday' => 1,
10914 'tue' => 2,
10915 'tuesday' => 2,
10916 'wed' => 3,
10917 'wednesday' => 3,
10918 'thu' => 4,
10919 'thursday' => 4,
10920 'fri' => 5,
10921 'friday' => 5,
10922 'sat' => 6,
10923 'saturday' => 6,
10924 'sun' => 7,
10925 'sunday' => 7,
10926 // Dutch
10927 'maandag' => 1,
10928 'dinsdag' => 2,
10929 'woensdag' => 3,
10930 'donderdag' => 4,
10931 'vrijdag' => 5,
10932 'zaterdag' => 6,
10933 'zondag' => 7,
10934 // French
10935 'lundi' => 1,
10936 'mardi' => 2,
10937 'mercredi' => 3,
10938 'jeudi' => 4,
10939 'vendredi' => 5,
10940 'samedi' => 6,
10941 'dimanche' => 7,
10942 // German
10943 'montag' => 1,
10944 'dienstag' => 2,
10945 'mittwoch' => 3,
10946 'donnerstag' => 4,
10947 'freitag' => 5,
10948 'samstag' => 6,
10949 'sonnabend' => 6,
10950 'sonntag' => 7,
10951 // Italian
10952 'lunedì' => 1,
10953 'martedì' => 2,
10954 'mercoledì' => 3,
10955 'giovedì' => 4,
10956 'venerdì' => 5,
10957 'sabato' => 6,
10958 'domenica' => 7,
10959 // Spanish
10960 'lunes' => 1,
10961 'martes' => 2,
10962 'miércoles' => 3,
10963 'jueves' => 4,
10964 'viernes' => 5,
10965 'sábado' => 6,
10966 'domingo' => 7,
10967 // Finnish
10968 'maanantai' => 1,
10969 'tiistai' => 2,
10970 'keskiviikko' => 3,
10971 'torstai' => 4,
10972 'perjantai' => 5,
10973 'lauantai' => 6,
10974 'sunnuntai' => 7,
10975 // Hungarian
10976 'hétfő' => 1,
10977 'kedd' => 2,
10978 'szerda' => 3,
10979 'csütörtok' => 4,
10980 'péntek' => 5,
10981 'szombat' => 6,
10982 'vasárnap' => 7,
10983 // Greek
10984 'Δευ' => 1,
10985 'Τρι' => 2,
10986 'Τετ' => 3,
10987 'Πεμ' => 4,
10988 'Παρ' => 5,
10989 'Σαβ' => 6,
10990 'Κυρ' => 7,
10991 );
f2f7b699 10992
6d7d21a0
AD
10993 /**
10994 * List of months, calendar month name => calendar month number
10995 *
10996 * @access protected
10997 * @var array
10998 */
10999 var $month = array(
11000 // English
11001 'jan' => 1,
11002 'january' => 1,
11003 'feb' => 2,
11004 'february' => 2,
11005 'mar' => 3,
11006 'march' => 3,
11007 'apr' => 4,
11008 'april' => 4,
11009 'may' => 5,
11010 // No long form of May
11011 'jun' => 6,
11012 'june' => 6,
11013 'jul' => 7,
11014 'july' => 7,
11015 'aug' => 8,
11016 'august' => 8,
11017 'sep' => 9,
11018 'september' => 8,
11019 'oct' => 10,
11020 'october' => 10,
11021 'nov' => 11,
11022 'november' => 11,
11023 'dec' => 12,
11024 'december' => 12,
11025 // Dutch
11026 'januari' => 1,
11027 'februari' => 2,
11028 'maart' => 3,
11029 'april' => 4,
11030 'mei' => 5,
11031 'juni' => 6,
11032 'juli' => 7,
11033 'augustus' => 8,
11034 'september' => 9,
11035 'oktober' => 10,
11036 'november' => 11,
11037 'december' => 12,
11038 // French
11039 'janvier' => 1,
11040 'février' => 2,
11041 'mars' => 3,
11042 'avril' => 4,
11043 'mai' => 5,
11044 'juin' => 6,
11045 'juillet' => 7,
11046 'août' => 8,
11047 'septembre' => 9,
11048 'octobre' => 10,
11049 'novembre' => 11,
11050 'décembre' => 12,
11051 // German
11052 'januar' => 1,
11053 'februar' => 2,
11054 'märz' => 3,
11055 'april' => 4,
11056 'mai' => 5,
11057 'juni' => 6,
11058 'juli' => 7,
11059 'august' => 8,
11060 'september' => 9,
11061 'oktober' => 10,
11062 'november' => 11,
11063 'dezember' => 12,
11064 // Italian
11065 'gennaio' => 1,
11066 'febbraio' => 2,
11067 'marzo' => 3,
11068 'aprile' => 4,
11069 'maggio' => 5,
11070 'giugno' => 6,
11071 'luglio' => 7,
11072 'agosto' => 8,
11073 'settembre' => 9,
11074 'ottobre' => 10,
11075 'novembre' => 11,
11076 'dicembre' => 12,
11077 // Spanish
11078 'enero' => 1,
11079 'febrero' => 2,
11080 'marzo' => 3,
11081 'abril' => 4,
11082 'mayo' => 5,
11083 'junio' => 6,
11084 'julio' => 7,
11085 'agosto' => 8,
11086 'septiembre' => 9,
11087 'setiembre' => 9,
11088 'octubre' => 10,
11089 'noviembre' => 11,
11090 'diciembre' => 12,
11091 // Finnish
11092 'tammikuu' => 1,
11093 'helmikuu' => 2,
11094 'maaliskuu' => 3,
11095 'huhtikuu' => 4,
11096 'toukokuu' => 5,
11097 'kesäkuu' => 6,
11098 'heinäkuu' => 7,
11099 'elokuu' => 8,
11100 'suuskuu' => 9,
11101 'lokakuu' => 10,
11102 'marras' => 11,
11103 'joulukuu' => 12,
11104 // Hungarian
11105 'január' => 1,
11106 'február' => 2,
11107 'március' => 3,
11108 'április' => 4,
11109 'május' => 5,
11110 'június' => 6,
11111 'július' => 7,
11112 'augusztus' => 8,
11113 'szeptember' => 9,
11114 'október' => 10,
11115 'november' => 11,
11116 'december' => 12,
11117 // Greek
11118 'Ιαν' => 1,
11119 'Φεβ' => 2,
11120 'Μάώ' => 3,
11121 'Μαώ' => 3,
11122 'Απρ' => 4,
11123 'Μάι' => 5,
11124 'Μαϊ' => 5,
11125 'Μαι' => 5,
11126 'Ιούν' => 6,
11127 'Ιον' => 6,
11128 'Ιούλ' => 7,
11129 'Ιολ' => 7,
11130 'Αύγ' => 8,
11131 'Αυγ' => 8,
11132 'Σεπ' => 9,
11133 'Οκτ' => 10,
11134 'Νοέ' => 11,
11135 'Δεκ' => 12,
11136 );
f2f7b699 11137
6d7d21a0
AD
11138 /**
11139 * List of timezones, abbreviation => offset from UTC
11140 *
11141 * @access protected
11142 * @var array
11143 */
11144 var $timezone = array(
11145 'ACDT' => 37800,
11146 'ACIT' => 28800,
11147 'ACST' => 34200,
11148 'ACT' => -18000,
11149 'ACWDT' => 35100,
11150 'ACWST' => 31500,
11151 'AEDT' => 39600,
11152 'AEST' => 36000,
11153 'AFT' => 16200,
11154 'AKDT' => -28800,
11155 'AKST' => -32400,
11156 'AMDT' => 18000,
11157 'AMT' => -14400,
11158 'ANAST' => 46800,
11159 'ANAT' => 43200,
11160 'ART' => -10800,
11161 'AZOST' => -3600,
11162 'AZST' => 18000,
11163 'AZT' => 14400,
11164 'BIOT' => 21600,
11165 'BIT' => -43200,
11166 'BOT' => -14400,
11167 'BRST' => -7200,
11168 'BRT' => -10800,
11169 'BST' => 3600,
11170 'BTT' => 21600,
11171 'CAST' => 18000,
11172 'CAT' => 7200,
11173 'CCT' => 23400,
11174 'CDT' => -18000,
11175 'CEDT' => 7200,
11176 'CET' => 3600,
11177 'CGST' => -7200,
11178 'CGT' => -10800,
11179 'CHADT' => 49500,
11180 'CHAST' => 45900,
11181 'CIST' => -28800,
11182 'CKT' => -36000,
11183 'CLDT' => -10800,
11184 'CLST' => -14400,
11185 'COT' => -18000,
11186 'CST' => -21600,
11187 'CVT' => -3600,
11188 'CXT' => 25200,
11189 'DAVT' => 25200,
11190 'DTAT' => 36000,
11191 'EADT' => -18000,
11192 'EAST' => -21600,
11193 'EAT' => 10800,
11194 'ECT' => -18000,
11195 'EDT' => -14400,
11196 'EEST' => 10800,
11197 'EET' => 7200,
11198 'EGT' => -3600,
11199 'EKST' => 21600,
11200 'EST' => -18000,
11201 'FJT' => 43200,
11202 'FKDT' => -10800,
11203 'FKST' => -14400,
11204 'FNT' => -7200,
11205 'GALT' => -21600,
11206 'GEDT' => 14400,
11207 'GEST' => 10800,
11208 'GFT' => -10800,
11209 'GILT' => 43200,
11210 'GIT' => -32400,
11211 'GST' => 14400,
11212 'GST' => -7200,
11213 'GYT' => -14400,
11214 'HAA' => -10800,
11215 'HAC' => -18000,
11216 'HADT' => -32400,
11217 'HAE' => -14400,
11218 'HAP' => -25200,
11219 'HAR' => -21600,
11220 'HAST' => -36000,
11221 'HAT' => -9000,
11222 'HAY' => -28800,
11223 'HKST' => 28800,
11224 'HMT' => 18000,
11225 'HNA' => -14400,
11226 'HNC' => -21600,
11227 'HNE' => -18000,
11228 'HNP' => -28800,
11229 'HNR' => -25200,
11230 'HNT' => -12600,
11231 'HNY' => -32400,
11232 'IRDT' => 16200,
11233 'IRKST' => 32400,
11234 'IRKT' => 28800,
11235 'IRST' => 12600,
11236 'JFDT' => -10800,
11237 'JFST' => -14400,
11238 'JST' => 32400,
11239 'KGST' => 21600,
11240 'KGT' => 18000,
11241 'KOST' => 39600,
11242 'KOVST' => 28800,
11243 'KOVT' => 25200,
11244 'KRAST' => 28800,
11245 'KRAT' => 25200,
11246 'KST' => 32400,
11247 'LHDT' => 39600,
11248 'LHST' => 37800,
11249 'LINT' => 50400,
11250 'LKT' => 21600,
11251 'MAGST' => 43200,
11252 'MAGT' => 39600,
11253 'MAWT' => 21600,
11254 'MDT' => -21600,
11255 'MESZ' => 7200,
11256 'MEZ' => 3600,
11257 'MHT' => 43200,
11258 'MIT' => -34200,
11259 'MNST' => 32400,
11260 'MSDT' => 14400,
11261 'MSST' => 10800,
11262 'MST' => -25200,
11263 'MUT' => 14400,
11264 'MVT' => 18000,
11265 'MYT' => 28800,
11266 'NCT' => 39600,
11267 'NDT' => -9000,
11268 'NFT' => 41400,
11269 'NMIT' => 36000,
11270 'NOVST' => 25200,
11271 'NOVT' => 21600,
11272 'NPT' => 20700,
11273 'NRT' => 43200,
11274 'NST' => -12600,
11275 'NUT' => -39600,
11276 'NZDT' => 46800,
11277 'NZST' => 43200,
11278 'OMSST' => 25200,
11279 'OMST' => 21600,
11280 'PDT' => -25200,
11281 'PET' => -18000,
11282 'PETST' => 46800,
11283 'PETT' => 43200,
11284 'PGT' => 36000,
11285 'PHOT' => 46800,
11286 'PHT' => 28800,
11287 'PKT' => 18000,
11288 'PMDT' => -7200,
11289 'PMST' => -10800,
11290 'PONT' => 39600,
11291 'PST' => -28800,
11292 'PWT' => 32400,
11293 'PYST' => -10800,
11294 'PYT' => -14400,
11295 'RET' => 14400,
11296 'ROTT' => -10800,
11297 'SAMST' => 18000,
11298 'SAMT' => 14400,
11299 'SAST' => 7200,
11300 'SBT' => 39600,
11301 'SCDT' => 46800,
11302 'SCST' => 43200,
11303 'SCT' => 14400,
11304 'SEST' => 3600,
11305 'SGT' => 28800,
11306 'SIT' => 28800,
11307 'SRT' => -10800,
11308 'SST' => -39600,
11309 'SYST' => 10800,
11310 'SYT' => 7200,
11311 'TFT' => 18000,
11312 'THAT' => -36000,
11313 'TJT' => 18000,
11314 'TKT' => -36000,
11315 'TMT' => 18000,
11316 'TOT' => 46800,
11317 'TPT' => 32400,
11318 'TRUT' => 36000,
11319 'TVT' => 43200,
11320 'TWT' => 28800,
11321 'UYST' => -7200,
11322 'UYT' => -10800,
11323 'UZT' => 18000,
11324 'VET' => -14400,
11325 'VLAST' => 39600,
11326 'VLAT' => 36000,
11327 'VOST' => 21600,
11328 'VUT' => 39600,
11329 'WAST' => 7200,
11330 'WAT' => 3600,
11331 'WDT' => 32400,
11332 'WEST' => 3600,
11333 'WFT' => 43200,
11334 'WIB' => 25200,
11335 'WIT' => 32400,
11336 'WITA' => 28800,
11337 'WKST' => 18000,
11338 'WST' => 28800,
11339 'YAKST' => 36000,
11340 'YAKT' => 32400,
11341 'YAPT' => 36000,
11342 'YEKST' => 21600,
11343 'YEKT' => 18000,
11344 );
f2f7b699 11345
6d7d21a0
AD
11346 /**
11347 * Cached PCRE for SimplePie_Parse_Date::$day
11348 *
11349 * @access protected
11350 * @var string
11351 */
11352 var $day_pcre;
f2f7b699 11353
6d7d21a0
AD
11354 /**
11355 * Cached PCRE for SimplePie_Parse_Date::$month
11356 *
11357 * @access protected
11358 * @var string
11359 */
11360 var $month_pcre;
f2f7b699 11361
6d7d21a0
AD
11362 /**
11363 * Array of user-added callback methods
11364 *
11365 * @access private
11366 * @var array
11367 */
11368 var $built_in = array();
f2f7b699 11369
6d7d21a0
AD
11370 /**
11371 * Array of user-added callback methods
11372 *
11373 * @access private
11374 * @var array
11375 */
11376 var $user = array();
f2f7b699 11377
6d7d21a0
AD
11378 /**
11379 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11380 * self::month_pcre, and self::built_in
11381 *
11382 * @access private
11383 */
11384 function SimplePie_Parse_Date()
11385 {
11386 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11387 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11388
11389 static $cache;
11390 if (!isset($cache[get_class($this)]))
11391 {
11392 if (extension_loaded('Reflection'))
11393 {
11394 $class = new ReflectionClass(get_class($this));
11395 $methods = $class->getMethods();
11396 $all_methods = array();
11397 foreach ($methods as $method)
f2f7b699 11398 {
6d7d21a0 11399 $all_methods[] = $method->getName();
f2f7b699
AD
11400 }
11401 }
6d7d21a0 11402 else
f2f7b699 11403 {
6d7d21a0 11404 $all_methods = get_class_methods($this);
f2f7b699 11405 }
6d7d21a0
AD
11406
11407 foreach ($all_methods as $method)
f2f7b699 11408 {
6d7d21a0
AD
11409 if (strtolower(substr($method, 0, 5)) === 'date_')
11410 {
11411 $cache[get_class($this)][] = $method;
11412 }
f2f7b699
AD
11413 }
11414 }
6d7d21a0
AD
11415
11416 foreach ($cache[get_class($this)] as $method)
11417 {
11418 $this->built_in[] = $method;
11419 }
f2f7b699 11420 }
6d7d21a0 11421
f2f7b699 11422 /**
6d7d21a0 11423 * Get the object
f2f7b699 11424 *
f2f7b699 11425 * @access public
f2f7b699 11426 */
6d7d21a0 11427 function get()
f2f7b699 11428 {
6d7d21a0
AD
11429 static $object;
11430 if (!$object)
11431 {
11432 $object = new SimplePie_Parse_Date;
11433 }
11434 return $object;
f2f7b699
AD
11435 }
11436
11437 /**
6d7d21a0 11438 * Parse a date
f2f7b699 11439 *
6d7d21a0 11440 * @final
f2f7b699 11441 * @access public
6d7d21a0
AD
11442 * @param string $date Date to parse
11443 * @return int Timestamp corresponding to date string, or false on failure
f2f7b699 11444 */
6d7d21a0 11445 function parse($date)
f2f7b699 11446 {
6d7d21a0 11447 foreach ($this->user as $method)
f2f7b699 11448 {
6d7d21a0
AD
11449 if (($returned = call_user_func($method, $date)) !== false)
11450 {
11451 return $returned;
11452 }
f2f7b699 11453 }
6d7d21a0
AD
11454
11455 foreach ($this->built_in as $method)
f2f7b699 11456 {
6d7d21a0
AD
11457 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11458 {
11459 return $returned;
11460 }
f2f7b699 11461 }
6d7d21a0
AD
11462
11463 return false;
f2f7b699
AD
11464 }
11465
6d7d21a0
AD
11466 /**
11467 * Add a callback method to parse a date
11468 *
11469 * @final
11470 * @access public
11471 * @param callback $callback
11472 */
11473 function add_callback($callback)
f2f7b699 11474 {
6d7d21a0 11475 if (is_callable($callback))
f2f7b699 11476 {
6d7d21a0 11477 $this->user[] = $callback;
f2f7b699
AD
11478 }
11479 else
11480 {
6d7d21a0 11481 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
f2f7b699
AD
11482 }
11483 }
11484
6d7d21a0
AD
11485 /**
11486 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11487 * well as allowing any of upper or lower case "T", horizontal tabs, or
11488 * spaces to be used as the time seperator (including more than one))
11489 *
11490 * @access protected
11491 * @return int Timestamp
11492 */
11493 function date_w3cdtf($date)
f2f7b699 11494 {
6d7d21a0
AD
11495 static $pcre;
11496 if (!$pcre)
f2f7b699 11497 {
6d7d21a0
AD
11498 $year = '([0-9]{4})';
11499 $month = $day = $hour = $minute = $second = '([0-9]{2})';
11500 $decimal = '([0-9]*)';
11501 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11502 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11503 }
11504 if (preg_match($pcre, $date, $match))
11505 {
11506 /*
11507 Capturing subpatterns:
11508 1: Year
11509 2: Month
11510 3: Day
11511 4: Hour
11512 5: Minute
11513 6: Second
11514 7: Decimal fraction of a second
11515 8: Zulu
11516 9: Timezone ±
11517 10: Timezone hours
11518 11: Timezone minutes
11519 */
11520
11521 // Fill in empty matches
11522 for ($i = count($match); $i <= 3; $i++)
11523 {
11524 $match[$i] = '1';
11525 }
11526
11527 for ($i = count($match); $i <= 7; $i++)
11528 {
11529 $match[$i] = '0';
11530 }
11531
11532 // Numeric timezone
11533 if (isset($match[9]) && $match[9] !== '')
11534 {
11535 $timezone = $match[10] * 3600;
11536 $timezone += $match[11] * 60;
11537 if ($match[9] === '-')
11538 {
11539 $timezone = 0 - $timezone;
11540 }
11541 }
11542 else
11543 {
11544 $timezone = 0;
11545 }
11546
11547 // Convert the number of seconds to an integer, taking decimals into account
11548 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11549
11550 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
f2f7b699
AD
11551 }
11552 else
11553 {
6d7d21a0 11554 return false;
f2f7b699
AD
11555 }
11556 }
11557
6d7d21a0
AD
11558 /**
11559 * Remove RFC822 comments
11560 *
11561 * @access protected
11562 * @param string $data Data to strip comments from
11563 * @return string Comment stripped string
11564 */
11565 function remove_rfc2822_comments($string)
f2f7b699 11566 {
6d7d21a0
AD
11567 $string = (string) $string;
11568 $position = 0;
11569 $length = strlen($string);
11570 $depth = 0;
11571
11572 $output = '';
11573
11574 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
f2f7b699 11575 {
6d7d21a0
AD
11576 $output .= substr($string, $position, $pos - $position);
11577 $position = $pos + 1;
11578 if ($string[$pos - 1] !== '\\')
11579 {
11580 $depth++;
11581 while ($depth && $position < $length)
11582 {
11583 $position += strcspn($string, '()', $position);
11584 if ($string[$position - 1] === '\\')
11585 {
11586 $position++;
11587 continue;
11588 }
11589 elseif (isset($string[$position]))
11590 {
11591 switch ($string[$position])
11592 {
11593 case '(':
11594 $depth++;
11595 break;
11596
11597 case ')':
11598 $depth--;
11599 break;
11600 }
11601 $position++;
11602 }
11603 else
11604 {
11605 break;
11606 }
11607 }
11608 }
11609 else
11610 {
11611 $output .= '(';
11612 }
f2f7b699 11613 }
6d7d21a0
AD
11614 $output .= substr($string, $position);
11615
11616 return $output;
11617 }
11618
11619 /**
11620 * Parse RFC2822's date format
11621 *
11622 * @access protected
11623 * @return int Timestamp
11624 */
11625 function date_rfc2822($date)
11626 {
11627 static $pcre;
11628 if (!$pcre)
f2f7b699 11629 {
6d7d21a0
AD
11630 $wsp = '[\x09\x20]';
11631 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
11632 $optional_fws = $fws . '?';
11633 $day_name = $this->day_pcre;
11634 $month = $this->month_pcre;
11635 $day = '([0-9]{1,2})';
11636 $hour = $minute = $second = '([0-9]{2})';
11637 $year = '([0-9]{2,4})';
11638 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
11639 $character_zone = '([A-Z]{1,5})';
11640 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
11641 $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';
f2f7b699 11642 }
6d7d21a0 11643 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
f2f7b699 11644 {
6d7d21a0
AD
11645 /*
11646 Capturing subpatterns:
11647 1: Day name
11648 2: Day
11649 3: Month
11650 4: Year
11651 5: Hour
11652 6: Minute
11653 7: Second
11654 8: Timezone ±
11655 9: Timezone hours
11656 10: Timezone minutes
11657 11: Alphabetic timezone
11658 */
f2f7b699 11659
6d7d21a0
AD
11660 // Find the month number
11661 $month = $this->month[strtolower($match[3])];
f2f7b699 11662
6d7d21a0
AD
11663 // Numeric timezone
11664 if ($match[8] !== '')
11665 {
11666 $timezone = $match[9] * 3600;
11667 $timezone += $match[10] * 60;
11668 if ($match[8] === '-')
11669 {
11670 $timezone = 0 - $timezone;
11671 }
11672 }
11673 // Character timezone
11674 elseif (isset($this->timezone[strtoupper($match[11])]))
11675 {
11676 $timezone = $this->timezone[strtoupper($match[11])];
11677 }
11678 // Assume everything else to be -0000
11679 else
11680 {
11681 $timezone = 0;
11682 }
f2f7b699 11683
6d7d21a0
AD
11684 // Deal with 2/3 digit years
11685 if ($match[4] < 50)
11686 {
11687 $match[4] += 2000;
11688 }
11689 elseif ($match[4] < 1000)
11690 {
11691 $match[4] += 1900;
11692 }
11693
11694 // Second is optional, if it is empty set it to zero
11695 if ($match[7] !== '')
11696 {
11697 $second = $match[7];
11698 }
11699 else
11700 {
11701 $second = 0;
f2f7b699 11702 }
6d7d21a0
AD
11703
11704 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
f2f7b699
AD
11705 }
11706 else
11707 {
6d7d21a0 11708 return false;
f2f7b699
AD
11709 }
11710 }
11711
6d7d21a0
AD
11712 /**
11713 * Parse RFC850's date format
11714 *
11715 * @access protected
11716 * @return int Timestamp
11717 */
11718 function date_rfc850($date)
f2f7b699 11719 {
6d7d21a0
AD
11720 static $pcre;
11721 if (!$pcre)
f2f7b699 11722 {
6d7d21a0
AD
11723 $space = '[\x09\x20]+';
11724 $day_name = $this->day_pcre;
11725 $month = $this->month_pcre;
11726 $day = '([0-9]{1,2})';
11727 $year = $hour = $minute = $second = '([0-9]{2})';
11728 $zone = '([A-Z]{1,5})';
11729 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
f2f7b699 11730 }
6d7d21a0 11731 if (preg_match($pcre, $date, $match))
f2f7b699 11732 {
6d7d21a0
AD
11733 /*
11734 Capturing subpatterns:
11735 1: Day name
11736 2: Day
11737 3: Month
11738 4: Year
11739 5: Hour
11740 6: Minute
11741 7: Second
11742 8: Timezone
11743 */
f2f7b699 11744
6d7d21a0
AD
11745 // Month
11746 $month = $this->month[strtolower($match[3])];
f2f7b699 11747
6d7d21a0
AD
11748 // Character timezone
11749 if (isset($this->timezone[strtoupper($match[8])]))
11750 {
11751 $timezone = $this->timezone[strtoupper($match[8])];
f2f7b699 11752 }
6d7d21a0
AD
11753 // Assume everything else to be -0000
11754 else
f2f7b699 11755 {
6d7d21a0
AD
11756 $timezone = 0;
11757 }
11758
11759 // Deal with 2 digit year
11760 if ($match[4] < 50)
11761 {
11762 $match[4] += 2000;
f2f7b699
AD
11763 }
11764 else
11765 {
6d7d21a0 11766 $match[4] += 1900;
f2f7b699 11767 }
6d7d21a0
AD
11768
11769 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
f2f7b699
AD
11770 }
11771 else
11772 {
6d7d21a0 11773 return false;
f2f7b699
AD
11774 }
11775 }
11776
6d7d21a0
AD
11777 /**
11778 * Parse C99's asctime()'s date format
11779 *
11780 * @access protected
11781 * @return int Timestamp
11782 */
11783 function date_asctime($date)
f2f7b699 11784 {
6d7d21a0
AD
11785 static $pcre;
11786 if (!$pcre)
11787 {
11788 $space = '[\x09\x20]+';
11789 $wday_name = $this->day_pcre;
11790 $mon_name = $this->month_pcre;
11791 $day = '([0-9]{1,2})';
11792 $hour = $sec = $min = '([0-9]{2})';
11793 $year = '([0-9]{4})';
11794 $terminator = '\x0A?\x00?';
11795 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
11796 }
11797 if (preg_match($pcre, $date, $match))
11798 {
11799 /*
11800 Capturing subpatterns:
11801 1: Day name
11802 2: Month
11803 3: Day
11804 4: Hour
11805 5: Minute
11806 6: Second
11807 7: Year
11808 */
11809
11810 $month = $this->month[strtolower($match[2])];
11811 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
11812 }
11813 else
11814 {
11815 return false;
11816 }
f2f7b699
AD
11817 }
11818
6d7d21a0
AD
11819 /**
11820 * Parse dates using strtotime()
11821 *
11822 * @access protected
11823 * @return int Timestamp
11824 */
11825 function date_strtotime($date)
f2f7b699 11826 {
6d7d21a0
AD
11827 $strtotime = strtotime($date);
11828 if ($strtotime === -1 || $strtotime === false)
f2f7b699 11829 {
6d7d21a0
AD
11830 return false;
11831 }
11832 else
11833 {
11834 return $strtotime;
f2f7b699 11835 }
f2f7b699 11836 }
6d7d21a0 11837}
f2f7b699 11838
6d7d21a0
AD
11839/**
11840 * Content-type sniffing
11841 *
11842 * @package SimplePie
11843 */
11844class SimplePie_Content_Type_Sniffer
11845{
11846 /**
11847 * File object
11848 *
11849 * @var SimplePie_File
11850 * @access private
11851 */
11852 var $file;
11853
11854 /**
11855 * Create an instance of the class with the input file
11856 *
11857 * @access public
11858 * @param SimplePie_Content_Type_Sniffer $file Input file
11859 */
11860 function SimplePie_Content_Type_Sniffer($file)
11861 {
11862 $this->file = $file;
11863 }
11864
11865 /**
11866 * Get the Content-Type of the specified file
11867 *
11868 * @access public
11869 * @return string Actual Content-Type
11870 */
11871 function get_type()
f2f7b699 11872 {
6d7d21a0 11873 if (isset($this->file->headers['content-type']))
f2f7b699 11874 {
6d7d21a0
AD
11875 if (!isset($this->file->headers['content-encoding'])
11876 && ($this->file->headers['content-type'] === 'text/plain'
11877 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
11878 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
f2f7b699 11879 {
6d7d21a0
AD
11880 return $this->text_or_binary();
11881 }
11882
11883 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
11884 {
11885 $official = substr($this->file->headers['content-type'], 0, $pos);
11886 }
11887 else
11888 {
11889 $official = $this->file->headers['content-type'];
11890 }
11891 $official = strtolower($official);
11892
11893 if ($official === 'unknown/unknown'
11894 || $official === 'application/unknown')
11895 {
11896 return $this->unknown();
11897 }
11898 elseif (substr($official, -4) === '+xml'
11899 || $official === 'text/xml'
11900 || $official === 'application/xml')
11901 {
11902 return $official;
11903 }
11904 elseif (substr($official, 0, 6) === 'image/')
11905 {
11906 if ($return = $this->image())
f2f7b699 11907 {
6d7d21a0 11908 return $return;
f2f7b699
AD
11909 }
11910 else
11911 {
6d7d21a0 11912 return $official;
f2f7b699
AD
11913 }
11914 }
6d7d21a0
AD
11915 elseif ($official === 'text/html')
11916 {
11917 return $this->feed_or_html();
11918 }
11919 else
11920 {
11921 return $official;
11922 }
11923 }
11924 else
11925 {
11926 return $this->unknown();
f2f7b699
AD
11927 }
11928 }
6d7d21a0 11929
f2f7b699 11930 /**
6d7d21a0 11931 * Sniff text or binary
f2f7b699 11932 *
6d7d21a0
AD
11933 * @access private
11934 * @return string Actual Content-Type
f2f7b699 11935 */
6d7d21a0 11936 function text_or_binary()
f2f7b699 11937 {
6d7d21a0
AD
11938 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
11939 || substr($this->file->body, 0, 2) === "\xFF\xFE"
11940 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
11941 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
f2f7b699 11942 {
6d7d21a0 11943 return 'text/plain';
f2f7b699 11944 }
6d7d21a0 11945 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
f2f7b699 11946 {
6d7d21a0 11947 return 'application/octect-stream';
f2f7b699 11948 }
6d7d21a0 11949 else
f2f7b699 11950 {
6d7d21a0 11951 return 'text/plain';
f2f7b699 11952 }
6d7d21a0
AD
11953 }
11954
11955 /**
11956 * Sniff unknown
11957 *
11958 * @access private
11959 * @return string Actual Content-Type
11960 */
11961 function unknown()
11962 {
11963 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
11964 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
11965 || strtolower(substr($this->file->body, $ws, 5)) === '<html'
11966 || strtolower(substr($this->file->body, $ws, 7)) === '<script')
f2f7b699 11967 {
6d7d21a0 11968 return 'text/html';
f2f7b699 11969 }
6d7d21a0 11970 elseif (substr($this->file->body, 0, 5) === '%PDF-')
f2f7b699 11971 {
6d7d21a0 11972 return 'application/pdf';
f2f7b699 11973 }
6d7d21a0 11974 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
f2f7b699 11975 {
6d7d21a0
AD
11976 return 'application/postscript';
11977 }
11978 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
11979 || substr($this->file->body, 0, 6) === 'GIF89a')
11980 {
11981 return 'image/gif';
11982 }
11983 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
11984 {
11985 return 'image/png';
11986 }
11987 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
11988 {
11989 return 'image/jpeg';
11990 }
11991 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
11992 {
11993 return 'image/bmp';
f2f7b699
AD
11994 }
11995 else
11996 {
6d7d21a0 11997 return $this->text_or_binary();
f2f7b699
AD
11998 }
11999 }
6d7d21a0 12000
f2f7b699 12001 /**
6d7d21a0 12002 * Sniff images
f2f7b699 12003 *
6d7d21a0
AD
12004 * @access private
12005 * @return string Actual Content-Type
12006 */
12007 function image()
12008 {
12009 if (substr($this->file->body, 0, 6) === 'GIF87a'
12010 || substr($this->file->body, 0, 6) === 'GIF89a')
12011 {
12012 return 'image/gif';
12013 }
12014 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12015 {
12016 return 'image/png';
12017 }
12018 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12019 {
12020 return 'image/jpeg';
12021 }
12022 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12023 {
12024 return 'image/bmp';
12025 }
12026 else
12027 {
12028 return false;
12029 }
12030 }
12031
f2f7b699 12032 /**
6d7d21a0 12033 * Sniff HTML
f2f7b699 12034 *
6d7d21a0
AD
12035 * @access private
12036 * @return string Actual Content-Type
f2f7b699 12037 */
6d7d21a0
AD
12038 function feed_or_html()
12039 {
12040 $len = strlen($this->file->body);
12041 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
12042
12043 while ($pos < $len)
12044 {
12045 switch ($this->file->body[$pos])
12046 {
12047 case "\x09":
12048 case "\x0A":
12049 case "\x0D":
12050 case "\x20":
12051 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12052 continue 2;
12053
12054 case '<':
12055 $pos++;
12056 break;
12057
12058 default:
12059 return 'text/html';
12060 }
12061
12062 if (substr($this->file->body, $pos, 3) === '!--')
12063 {
12064 $pos += 3;
12065 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12066 {
12067 $pos += 3;
12068 }
12069 else
12070 {
12071 return 'text/html';
12072 }
12073 }
12074 elseif (substr($this->file->body, $pos, 1) === '!')
12075 {
12076 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12077 {
12078 $pos++;
12079 }
12080 else
12081 {
12082 return 'text/html';
12083 }
12084 }
12085 elseif (substr($this->file->body, $pos, 1) === '?')
12086 {
12087 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12088 {
12089 $pos += 2;
12090 }
12091 else
12092 {
12093 return 'text/html';
12094 }
12095 }
12096 elseif (substr($this->file->body, $pos, 3) === 'rss'
12097 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
12098 {
12099 return 'application/rss+xml';
12100 }
12101 elseif (substr($this->file->body, $pos, 4) === 'feed')
12102 {
12103 return 'application/atom+xml';
12104 }
12105 else
12106 {
12107 return 'text/html';
12108 }
12109 }
12110
12111 return 'text/html';
12112 }
f2f7b699
AD
12113}
12114
12115/**
6d7d21a0 12116 * Parses the XML Declaration
f2f7b699
AD
12117 *
12118 * @package SimplePie
12119 */
6d7d21a0 12120class SimplePie_XML_Declaration_Parser
f2f7b699
AD
12121{
12122 /**
6d7d21a0 12123 * XML Version
f2f7b699 12124 *
6d7d21a0 12125 * @access public
f2f7b699
AD
12126 * @var string
12127 */
6d7d21a0
AD
12128 var $version = '1.0';
12129
12130 /**
12131 * Encoding
12132 *
12133 * @access public
12134 * @var string
12135 */
12136 var $encoding = 'UTF-8';
12137
12138 /**
12139 * Standalone
12140 *
12141 * @access public
12142 * @var bool
12143 */
12144 var $standalone = false;
f2f7b699
AD
12145
12146 /**
6d7d21a0 12147 * Current state of the state machine
f2f7b699
AD
12148 *
12149 * @access private
12150 * @var string
12151 */
6d7d21a0
AD
12152 var $state = 'before_version_name';
12153
12154 /**
12155 * Input data
12156 *
12157 * @access private
12158 * @var string
12159 */
12160 var $data = '';
f2f7b699
AD
12161
12162 /**
6d7d21a0 12163 * Input data length (to avoid calling strlen() everytime this is needed)
f2f7b699
AD
12164 *
12165 * @access private
12166 * @var int
12167 */
6d7d21a0 12168 var $data_length = 0;
f2f7b699 12169
6d7d21a0
AD
12170 /**
12171 * Current position of the pointer
12172 *
12173 * @var int
12174 * @access private
12175 */
12176 var $position = 0;
12177
f2f7b699
AD
12178 /**
12179 * Create an instance of the class with the input data
12180 *
12181 * @access public
12182 * @param string $data Input data
12183 */
6d7d21a0
AD
12184 function SimplePie_XML_Declaration_Parser($data)
12185 {
12186 $this->data = $data;
12187 $this->data_length = strlen($this->data);
12188 }
12189
12190 /**
12191 * Parse the input data
12192 *
12193 * @access public
12194 * @return bool true on success, false on failure
12195 */
12196 function parse()
12197 {
12198 while ($this->state && $this->state !== 'emit' && $this->has_data())
12199 {
12200 $state = $this->state;
12201 $this->$state();
12202 }
12203 $this->data = '';
12204 if ($this->state === 'emit')
12205 {
12206 return true;
12207 }
12208 else
12209 {
12210 $this->version = '';
12211 $this->encoding = '';
12212 $this->standalone = '';
12213 return false;
12214 }
12215 }
12216
12217 /**
12218 * Check whether there is data beyond the pointer
12219 *
12220 * @access private
12221 * @return bool true if there is further data, false if not
12222 */
12223 function has_data()
12224 {
12225 return (bool) ($this->position < $this->data_length);
12226 }
12227
12228 /**
12229 * Advance past any whitespace
12230 *
12231 * @return int Number of whitespace characters passed
12232 */
12233 function skip_whitespace()
12234 {
12235 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12236 $this->position += $whitespace;
12237 return $whitespace;
12238 }
12239
12240 /**
12241 * Read value
12242 */
12243 function get_value()
12244 {
12245 $quote = substr($this->data, $this->position, 1);
12246 if ($quote === '"' || $quote === "'")
12247 {
12248 $this->position++;
12249 $len = strcspn($this->data, $quote, $this->position);
12250 if ($this->has_data())
12251 {
12252 $value = substr($this->data, $this->position, $len);
12253 $this->position += $len + 1;
12254 return $value;
12255 }
12256 }
12257 return false;
12258 }
12259
12260 function before_version_name()
12261 {
12262 if ($this->skip_whitespace())
12263 {
12264 $this->state = 'version_name';
12265 }
12266 else
12267 {
12268 $this->state = false;
12269 }
12270 }
12271
12272 function version_name()
f2f7b699 12273 {
6d7d21a0
AD
12274 if (substr($this->data, $this->position, 7) === 'version')
12275 {
12276 $this->position += 7;
12277 $this->skip_whitespace();
12278 $this->state = 'version_equals';
12279 }
12280 else
12281 {
12282 $this->state = false;
12283 }
f2f7b699 12284 }
6d7d21a0
AD
12285
12286 function version_equals()
f2f7b699 12287 {
6d7d21a0 12288 if (substr($this->data, $this->position, 1) === '=')
f2f7b699 12289 {
6d7d21a0
AD
12290 $this->position++;
12291 $this->skip_whitespace();
12292 $this->state = 'version_value';
12293 }
12294 else
12295 {
12296 $this->state = false;
f2f7b699 12297 }
f2f7b699 12298 }
6d7d21a0
AD
12299
12300 function version_value()
f2f7b699 12301 {
6d7d21a0 12302 if ($this->version = $this->get_value())
f2f7b699 12303 {
6d7d21a0
AD
12304 $this->skip_whitespace();
12305 if ($this->has_data())
12306 {
12307 $this->state = 'encoding_name';
12308 }
12309 else
12310 {
12311 $this->state = 'emit';
12312 }
f2f7b699
AD
12313 }
12314 else
12315 {
6d7d21a0 12316 $this->state = 'standalone_name';
f2f7b699
AD
12317 }
12318 }
6d7d21a0
AD
12319
12320 function encoding_name()
f2f7b699 12321 {
6d7d21a0 12322 if (substr($this->data, $this->position, 8) === 'encoding')
f2f7b699 12323 {
6d7d21a0
AD
12324 $this->position += 8;
12325 $this->skip_whitespace();
12326 $this->state = 'encoding_equals';
f2f7b699
AD
12327 }
12328 else
12329 {
6d7d21a0 12330 $this->state = false;
f2f7b699
AD
12331 }
12332 }
6d7d21a0
AD
12333
12334 function encoding_equals()
f2f7b699 12335 {
6d7d21a0
AD
12336 if (substr($this->data, $this->position, 1) === '=')
12337 {
12338 $this->position++;
12339 $this->skip_whitespace();
12340 $this->state = 'encoding_value';
12341 }
12342 else
12343 {
12344 $this->state = false;
12345 }
f2f7b699 12346 }
6d7d21a0
AD
12347
12348 function encoding_value()
f2f7b699 12349 {
6d7d21a0 12350 if ($this->encoding = $this->get_value())
f2f7b699 12351 {
6d7d21a0
AD
12352 $this->skip_whitespace();
12353 if ($this->has_data())
12354 {
12355 $this->state = 'standalone_name';
12356 }
12357 else
12358 {
12359 $this->state = 'emit';
12360 }
12361 }
12362 else
12363 {
12364 $this->state = false;
12365 }
12366 }
12367
12368 function standalone_name()
12369 {
12370 if (substr($this->data, $this->position, 10) === 'standalone')
12371 {
12372 $this->position += 10;
12373 $this->skip_whitespace();
12374 $this->state = 'standalone_equals';
12375 }
12376 else
12377 {
12378 $this->state = false;
12379 }
12380 }
12381
12382 function standalone_equals()
12383 {
12384 if (substr($this->data, $this->position, 1) === '=')
12385 {
12386 $this->position++;
12387 $this->skip_whitespace();
12388 $this->state = 'standalone_value';
12389 }
12390 else
12391 {
12392 $this->state = false;
12393 }
12394 }
12395
12396 function standalone_value()
12397 {
12398 if ($standalone = $this->get_value())
12399 {
12400 switch ($standalone)
12401 {
12402 case 'yes':
12403 $this->standalone = true;
12404 break;
12405
12406 case 'no':
12407 $this->standalone = false;
12408 break;
12409
12410 default:
12411 $this->state = false;
12412 return;
12413 }
12414
12415 $this->skip_whitespace();
12416 if ($this->has_data())
12417 {
12418 $this->state = false;
12419 }
12420 else
12421 {
12422 $this->state = 'emit';
12423 }
12424 }
12425 else
12426 {
12427 $this->state = false;
f2f7b699
AD
12428 }
12429 }
12430}
12431
12432class SimplePie_Locator
12433{
12434 var $useragent;
12435 var $timeout;
12436 var $file;
12437 var $local = array();
12438 var $elsewhere = array();
12439 var $file_class = 'SimplePie_File';
12440 var $cached_entities = array();
12441 var $http_base;
12442 var $base;
12443 var $base_location = 0;
12444 var $checked_feeds = 0;
12445 var $max_checked_feeds = 10;
6d7d21a0 12446 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
f2f7b699 12447
6d7d21a0 12448 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
f2f7b699
AD
12449 {
12450 $this->file =& $file;
12451 $this->file_class = $file_class;
12452 $this->useragent = $useragent;
12453 $this->timeout = $timeout;
12454 $this->max_checked_feeds = $max_checked_feeds;
3cae90e1 12455 $this->content_type_sniffer_class = $content_type_sniffer_class;
f2f7b699
AD
12456 }
12457
12458 function find($type = SIMPLEPIE_LOCATOR_ALL)
12459 {
12460 if ($this->is_feed($this->file))
12461 {
12462 return $this->file;
12463 }
6d7d21a0
AD
12464
12465 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12466 {
12467 $sniffer = new $this->content_type_sniffer_class($this->file);
12468 if ($sniffer->get_type() !== 'text/html')
12469 {
12470 return null;
12471 }
12472 }
f2f7b699
AD
12473
12474 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12475 {
12476 $this->get_base();
12477 }
12478
12479 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12480 {
12481 return $working;
12482 }
12483
12484 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12485 {
12486 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12487 {
12488 return $working;
12489 }
12490
12491 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12492 {
12493 return $working;
12494 }
12495
12496 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12497 {
12498 return $working;
12499 }
12500
12501 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12502 {
12503 return $working;
12504 }
12505 }
12506 return null;
12507 }
12508
12509 function is_feed(&$file)
12510 {
6d7d21a0 12511 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
f2f7b699 12512 {
6d7d21a0
AD
12513 $sniffer = new $this->content_type_sniffer_class($file);
12514 $sniffed = $sniffer->get_type();
12515 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'application/atom+xml', 'text/xml', 'application/xml', 'text/plain')))
12516 {
12517 return true;
12518 }
12519 else
12520 {
12521 return false;
12522 }
f2f7b699 12523 }
6d7d21a0 12524 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
f2f7b699 12525 {
6d7d21a0 12526 return true;
f2f7b699
AD
12527 }
12528 else
12529 {
6d7d21a0 12530 return false;
f2f7b699 12531 }
6d7d21a0
AD
12532 }
12533
12534 function get_base()
12535 {
12536 $this->http_base = $this->file->url;
f2f7b699
AD
12537 $this->base = $this->http_base;
12538 $elements = SimplePie_Misc::get_element('base', $this->file->body);
12539 foreach ($elements as $element)
12540 {
12541 if ($element['attribs']['href']['data'] !== '')
12542 {
12543 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12544 $this->base_location = $element['offset'];
12545 break;
12546 }
12547 }
12548 }
12549
12550 function autodiscovery()
12551 {
12552 $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));
12553 $done = array();
12554 foreach ($links as $link)
12555 {
12556 if ($this->checked_feeds == $this->max_checked_feeds)
12557 {
12558 break;
12559 }
12560 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12561 {
12562 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12563
12564 if ($this->base_location < $link['offset'])
12565 {
12566 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12567 }
12568 else
12569 {
12570 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12571 }
12572
12573 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'))))
12574 {
12575 $this->checked_feeds++;
12576 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
12577 if ($this->is_feed($feed))
12578 {
12579 return $feed;
12580 }
12581 }
12582 $done[] = $href;
12583 }
12584 }
12585 return null;
12586 }
12587
12588 function get_links()
12589 {
12590 $links = SimplePie_Misc::get_element('a', $this->file->body);
12591 foreach ($links as $link)
12592 {
12593 if (isset($link['attribs']['href']['data']))
12594 {
12595 $href = trim($link['attribs']['href']['data']);
12596 $parsed = SimplePie_Misc::parse_url($href);
12597 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12598 {
12599 if ($this->base_location < $link['offset'])
12600 {
12601 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12602 }
12603 else
12604 {
12605 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12606 }
12607
12608 $current = SimplePie_Misc::parse_url($this->file->url);
12609
12610 if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
12611 {
12612 $this->local[] = $href;
12613 }
12614 else
12615 {
12616 $this->elsewhere[] = $href;
12617 }
12618 }
12619 }
12620 }
12621 $this->local = array_unique($this->local);
12622 $this->elsewhere = array_unique($this->elsewhere);
12623 if (!empty($this->local) || !empty($this->elsewhere))
12624 {
12625 return true;
12626 }
12627 return null;
12628 }
12629
12630 function extension(&$array)
12631 {
12632 foreach ($array as $key => $value)
12633 {
12634 if ($this->checked_feeds == $this->max_checked_feeds)
12635 {
12636 break;
12637 }
12638 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
12639 {
12640 $this->checked_feeds++;
12641 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12642 if ($this->is_feed($feed))
12643 {
12644 return $feed;
12645 }
12646 else
12647 {
12648 unset($array[$key]);
12649 }
12650 }
12651 }
12652 return null;
12653 }
12654
12655 function body(&$array)
12656 {
12657 foreach ($array as $key => $value)
12658 {
12659 if ($this->checked_feeds == $this->max_checked_feeds)
12660 {
12661 break;
12662 }
12663 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
12664 {
12665 $this->checked_feeds++;
12666 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12667 if ($this->is_feed($feed))
12668 {
12669 return $feed;
12670 }
12671 else
12672 {
12673 unset($array[$key]);
12674 }
12675 }
12676 }
12677 return null;
12678 }
12679}
12680
12681class SimplePie_Parser
12682{
f2f7b699
AD
12683 var $error_code;
12684 var $error_string;
12685 var $current_line;
12686 var $current_column;
12687 var $current_byte;
12688 var $separator = ' ';
12689 var $feed = false;
12690 var $namespace = array('');
12691 var $element = array('');
12692 var $xml_base = array('');
12693 var $xml_base_explicit = array(false);
12694 var $xml_lang = array('');
12695 var $data = array();
12696 var $datas = array(array());
12697 var $current_xhtml_construct = -1;
12698 var $encoding;
12699
6d7d21a0 12700 function parse(&$data, $encoding)
f2f7b699
AD
12701 {
12702 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
12703 if (strtoupper($encoding) == 'US-ASCII')
12704 {
12705 $this->encoding = 'UTF-8';
12706 }
12707 else
12708 {
12709 $this->encoding = $encoding;
12710 }
12711
12712 // Strip BOM:
12713 // UTF-32 Big Endian BOM
6d7d21a0 12714 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
f2f7b699
AD
12715 {
12716 $data = substr($data, 4);
12717 }
12718 // UTF-32 Little Endian BOM
6d7d21a0 12719 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
f2f7b699
AD
12720 {
12721 $data = substr($data, 4);
12722 }
12723 // UTF-16 Big Endian BOM
6d7d21a0 12724 elseif (substr($data, 0, 2) === "\xFE\xFF")
f2f7b699
AD
12725 {
12726 $data = substr($data, 2);
12727 }
12728 // UTF-16 Little Endian BOM
6d7d21a0 12729 elseif (substr($data, 0, 2) === "\xFF\xFE")
f2f7b699
AD
12730 {
12731 $data = substr($data, 2);
12732 }
12733 // UTF-8 BOM
6d7d21a0 12734 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
f2f7b699
AD
12735 {
12736 $data = substr($data, 3);
12737 }
6d7d21a0
AD
12738
12739 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
12740 {
12741 $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
12742 if ($declaration->parse())
12743 {
12744 $data = substr($data, $pos + 2);
12745 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
12746 }
12747 else
12748 {
12749 $this->error_string = 'SimplePie bug! Please report this!';
12750 return false;
12751 }
12752 }
12753
f2f7b699
AD
12754 $return = true;
12755
12756 // Create the parser
6d7d21a0
AD
12757 $xml = xml_parser_create_ns($this->encoding, $this->separator);
12758 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
12759 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
12760 xml_set_object($xml, $this);
12761 xml_set_character_data_handler($xml, 'cdata');
12762 xml_set_element_handler($xml, 'tag_open', 'tag_close');
f2f7b699 12763
7cc1e4ae
AD
12764 $data=str_replace("&lt;","&#60;",$data);
12765 $data=str_replace("&gt;","&#62;",$data);
12766 $data=str_replace("&amp;","&#38;",$data);
12767
f2f7b699 12768 // Parse!
6d7d21a0 12769 if (!xml_parse($xml, $data, true))
f2f7b699 12770 {
6d7d21a0 12771 $this->error_code = xml_get_error_code($xml);
f2f7b699
AD
12772 $this->error_string = xml_error_string($this->error_code);
12773 $return = false;
12774 }
6d7d21a0
AD
12775 $this->current_line = xml_get_current_line_number($xml);
12776 $this->current_column = xml_get_current_column_number($xml);
12777 $this->current_byte = xml_get_current_byte_index($xml);
12778 xml_parser_free($xml);
f2f7b699
AD
12779 return $return;
12780 }
12781
12782 function get_error_code()
12783 {
12784 return $this->error_code;
12785 }
12786
12787 function get_error_string()
12788 {
12789 return $this->error_string;
12790 }
12791
12792 function get_current_line()
12793 {
12794 return $this->current_line;
12795 }
12796
12797 function get_current_column()
12798 {
12799 return $this->current_column;
12800 }
12801
12802 function get_current_byte()
12803 {
12804 return $this->current_byte;
12805 }
12806
12807 function get_data()
12808 {
12809 return $this->data;
12810 }
12811
12812 function tag_open($parser, $tag, $attributes)
12813 {
12814 if ($this->feed === 0)
12815 {
12816 return;
12817 }
12818 elseif ($this->feed == false)
12819 {
12820 if (in_array($tag, array(
12821 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
12822 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
12823 'rss',
12824 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
12825 )))
12826 {
12827 $this->feed = 1;
12828 }
12829 }
12830 else
12831 {
12832 $this->feed++;
12833 }
12834
12835 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
12836
12837 $attribs = array();
12838 foreach ($attributes as $name => $value)
12839 {
12840 list($attrib_namespace, $attribute) = $this->split_ns($name);
12841 $attribs[$attrib_namespace][$attribute] = $value;
12842 }
12843
12844 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
12845 {
12846 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
12847 $this->xml_base_explicit[] = true;
12848 }
12849 else
12850 {
12851 $this->xml_base[] = end($this->xml_base);
12852 $this->xml_base_explicit[] = end($this->xml_base_explicit);
12853 }
12854
12855 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
12856 {
12857 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
12858 }
12859 else
12860 {
12861 $this->xml_lang[] = end($this->xml_lang);
12862 }
12863
12864 if ($this->current_xhtml_construct >= 0)
12865 {
12866 $this->current_xhtml_construct++;
12867 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
12868 {
12869 $this->data['data'] .= '<' . end($this->element);
12870 if (isset($attribs['']))
12871 {
12872 foreach ($attribs[''] as $name => $value)
12873 {
12874 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
12875 }
12876 }
12877 $this->data['data'] .= '>';
12878 }
12879 }
12880 else
12881 {
12882 $this->datas[] =& $this->data;
12883 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
12884 $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));
12885 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')
12886 || (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'))
12887 {
12888 $this->current_xhtml_construct = 0;
12889 }
12890 }
12891 }
12892
12893 function cdata($parser, $cdata)
12894 {
12895 if ($this->current_xhtml_construct >= 0)
12896 {
12897 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
12898 }
12899 elseif ($this->feed > 1)
12900 {
12901 $this->data['data'] .= $cdata;
12902 }
12903 }
12904
12905 function tag_close($parser, $tag)
12906 {
12907 if (!$this->feed)
12908 {
12909 return;
12910 }
12911
12912 if ($this->current_xhtml_construct >= 0)
12913 {
12914 $this->current_xhtml_construct--;
12915 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')))
12916 {
12917 $this->data['data'] .= '</' . end($this->element) . '>';
12918 }
12919 }
12920 if ($this->current_xhtml_construct == -1)
12921 {
12922 $this->data =& $this->datas[$this->feed];
12923 array_pop($this->datas);
12924 }
12925
12926 array_pop($this->element);
12927 array_pop($this->namespace);
12928 array_pop($this->xml_base);
12929 array_pop($this->xml_base_explicit);
12930 array_pop($this->xml_lang);
12931 $this->feed--;
12932 }
12933
12934 function split_ns($string)
12935 {
12936 static $cache = array();
12937 if (!isset($cache[$string]))
12938 {
12939 if ($pos = strpos($string, $this->separator))
12940 {
12941 static $separator_length;
12942 if (!$separator_length)
12943 {
12944 $separator_length = strlen($this->separator);
12945 }
6d7d21a0
AD
12946 $namespace = substr($string, 0, $pos);
12947 $local_name = substr($string, $pos + $separator_length);
12948 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
12949 {
12950 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
12951 }
3cae90e1
AD
12952
12953 // Normalize the Media RSS namespaces
12954 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
12955 {
12956 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
12957 }
6d7d21a0 12958 $cache[$string] = array($namespace, $local_name);
f2f7b699
AD
12959 }
12960 else
12961 {
12962 $cache[$string] = array('', $string);
12963 }
12964 }
12965 return $cache[$string];
12966 }
12967}
12968
12969/**
3cae90e1 12970 * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags
f2f7b699
AD
12971 */
12972class SimplePie_Sanitize
12973{
12974 // Private vars
12975 var $base;
12976
12977 // Options
12978 var $remove_div = true;
12979 var $image_handler = '';
12980 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
12981 var $encode_instead_of_strip = false;
12982 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
12983 var $strip_comments = false;
12984 var $output_encoding = 'UTF-8';
12985 var $enable_cache = true;
12986 var $cache_location = './cache';
12987 var $cache_name_function = 'md5';
12988 var $cache_class = 'SimplePie_Cache';
12989 var $file_class = 'SimplePie_File';
12990 var $timeout = 10;
12991 var $useragent = '';
12992 var $force_fsockopen = false;
12993
12994 var $replace_url_attributes = array(
12995 'a' => 'href',
12996 'area' => 'href',
12997 'blockquote' => 'cite',
12998 'del' => 'cite',
12999 'form' => 'action',
13000 'img' => array('longdesc', 'src'),
13001 'input' => 'src',
13002 'ins' => 'cite',
13003 'q' => 'cite'
13004 );
13005
13006 function remove_div($enable = true)
13007 {
13008 $this->remove_div = (bool) $enable;
13009 }
13010
13011 function set_image_handler($page = false)
13012 {
13013 if ($page)
13014 {
13015 $this->image_handler = (string) $page;
13016 }
13017 else
13018 {
13019 $this->image_handler = false;
13020 }
13021 }
13022
13023 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
13024 {
13025 if (isset($enable_cache))
13026 {
13027 $this->enable_cache = (bool) $enable_cache;
13028 }
13029
13030 if ($cache_location)
13031 {
13032 $this->cache_location = (string) $cache_location;
13033 }
13034
13035 if ($cache_name_function)
13036 {
13037 $this->cache_name_function = (string) $cache_name_function;
13038 }
13039
13040 if ($cache_class)
13041 {
13042 $this->cache_class = (string) $cache_class;
13043 }
13044 }
13045
13046 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
13047 {
13048 if ($file_class)
13049 {
13050 $this->file_class = (string) $file_class;
13051 }
13052
13053 if ($timeout)
13054 {
13055 $this->timeout = (string) $timeout;
13056 }
13057
13058 if ($useragent)
13059 {
13060 $this->useragent = (string) $useragent;
13061 }
13062
13063 if ($force_fsockopen)
13064 {
13065 $this->force_fsockopen = (string) $force_fsockopen;
13066 }
13067 }
13068
13069 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13070 {
13071 if ($tags)
13072 {
13073 if (is_array($tags))
13074 {
13075 $this->strip_htmltags = $tags;
13076 }
13077 else
13078 {
13079 $this->strip_htmltags = explode(',', $tags);
13080 }
13081 }
13082 else
13083 {
13084 $this->strip_htmltags = false;
13085 }
13086 }
13087
13088 function encode_instead_of_strip($encode = false)
13089 {
13090 $this->encode_instead_of_strip = (bool) $encode;
13091 }
13092
13093 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13094 {
13095 if ($attribs)
13096 {
13097 if (is_array($attribs))
13098 {
13099 $this->strip_attributes = $attribs;
13100 }
13101 else
13102 {
13103 $this->strip_attributes = explode(',', $attribs);
13104 }
13105 }
13106 else
13107 {
13108 $this->strip_attributes = false;
13109 }
13110 }
13111
13112 function strip_comments($strip = false)
13113 {
13114 $this->strip_comments = (bool) $strip;
13115 }
13116
13117 function set_output_encoding($encoding = 'UTF-8')
13118 {
13119 $this->output_encoding = (string) $encoding;
13120 }
13121
13122 /**
13123 * Set element/attribute key/value pairs of HTML attributes
13124 * containing URLs that need to be resolved relative to the feed
13125 *
13126 * @access public
13127 * @since 1.0
13128 * @param array $element_attribute Element/attribute key/value pairs
13129 */
13130 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'))
13131 {
13132 $this->replace_url_attributes = (array) $element_attribute;
13133 }
13134
13135 function sanitize($data, $type, $base = '')
13136 {
13137 $data = trim($data);
13138 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13139 {
13140 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13141 {
6d7d21a0 13142 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))
f2f7b699
AD
13143 {
13144 $type |= SIMPLEPIE_CONSTRUCT_HTML;
13145 }
13146 else
13147 {
13148 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
13149 }
13150 }
13151
13152 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13153 {
13154 $data = base64_decode($data);
13155 }
13156
13157 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13158 {
13159 if ($this->remove_div)
13160 {
13161 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13162 $data = preg_replace('/<\/div>$/', '', $data);
13163 }
13164 else
13165 {
13166 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13167 }
13168 }
13169
13170 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13171 {
13172 // Strip comments
13173 if ($this->strip_comments)
13174 {
13175 $data = SimplePie_Misc::strip_comments($data);
13176 }
13177
13178 // Strip out HTML tags and attributes that might cause various security problems.
13179 // Based on recommendations by Mark Pilgrim at:
13180 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13181 if ($this->strip_htmltags)
13182 {
13183 foreach ($this->strip_htmltags as $tag)
13184 {
13185 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13186 while (preg_match($pcre, $data))
13187 {
13188 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13189 }
13190 }
13191 }
13192
13193 if ($this->strip_attributes)
13194 {
13195 foreach ($this->strip_attributes as $attrib)
13196 {
6d7d21a0 13197 $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);
f2f7b699
AD
13198 }
13199 }
13200
13201 // Replace relative URLs
13202 $this->base = $base;
13203 foreach ($this->replace_url_attributes as $element => $attributes)
13204 {
13205 $data = $this->replace_urls($data, $element, $attributes);
13206 }
13207
13208 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13209 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13210 {
13211 $images = SimplePie_Misc::get_element('img', $data);
13212 foreach ($images as $img)
13213 {
13214 if (isset($img['attribs']['src']['data']))
13215 {
6d7d21a0
AD
13216 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13217 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
f2f7b699
AD
13218
13219 if ($cache->load())
13220 {
6d7d21a0 13221 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
f2f7b699
AD
13222 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13223 }
13224 else
13225 {
6d7d21a0 13226 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
f2f7b699
AD
13227 $headers = $file->headers;
13228
13229 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13230 {
6d7d21a0
AD
13231 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13232 {
13233 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13234 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13235 }
13236 else
f2f7b699
AD
13237 {
13238 trigger_error("$cache->name is not writeable", E_USER_WARNING);
13239 }
f2f7b699
AD
13240 }
13241 }
13242 }
13243 }
13244 }
13245
13246 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13247 $data = trim($data);
13248 }
13249
13250 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13251 {
13252 $data = SimplePie_Misc::absolutize_url($data, $base);
13253 }
13254
13255 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13256 {
13257 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13258 }
13259
13260 if ($this->output_encoding != 'UTF-8')
13261 {
13262 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13263 }
13264 }
13265 return $data;
13266 }
13267
13268 function replace_urls($data, $tag, $attributes)
13269 {
13270 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13271 {
13272 $elements = SimplePie_Misc::get_element($tag, $data);
13273 foreach ($elements as $element)
13274 {
13275 if (is_array($attributes))
13276 {
13277 foreach ($attributes as $attribute)
13278 {
13279 if (isset($element['attribs'][$attribute]['data']))
13280 {
13281 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
6d7d21a0
AD
13282 $new_element = SimplePie_Misc::element_implode($element);
13283 $data = str_replace($element['full'], $new_element, $data);
13284 $element['full'] = $new_element;
f2f7b699
AD
13285 }
13286 }
13287 }
13288 elseif (isset($element['attribs'][$attributes]['data']))
13289 {
13290 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13291 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13292 }
13293 }
13294 }
13295 return $data;
13296 }
13297
13298 function do_strip_htmltags($match)
13299 {
13300 if ($this->encode_instead_of_strip)
13301 {
13302 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13303 {
13304 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13305 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13306 return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
13307 }
13308 else
13309 {
13310 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13311 }
13312 }
13313 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13314 {
13315 return $match[4];
13316 }
13317 else
13318 {
13319 return '';
13320 }
13321 }
13322}
13323
96841bf3 13324?>