Project

General

Profile

Download (348 KB) Statistics
| Branch: | Tag: | Revision:
1 b2e02eef Scott Ullrich
<?php
2
/**
3
 * SimplePie
4
 *
5
 * A PHP-Based RSS and Atom Feed Framework.
6
 * Takes the hard work out of managing a complete RSS/Atom solution.
7
 *
8
 * Copyright (c) 2004-2008, Ryan Parman and Geoffrey Sneddon
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without modification, are
12
 * permitted provided that the following conditions are met:
13
 *
14
 * 	* Redistributions of source code must retain the above copyright notice, this list of
15
 * 	  conditions and the following disclaimer.
16
 *
17
 * 	* Redistributions in binary form must reproduce the above copyright notice, this list
18
 * 	  of conditions and the following disclaimer in the documentation and/or other materials
19
 * 	  provided with the distribution.
20
 *
21
 * 	* Neither the name of the SimplePie Team nor the names of its contributors may be used
22
 * 	  to endorse or promote products derived from this software without specific prior
23
 * 	  written permission.
24
 *
25
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28
 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
 * POSSIBILITY OF SUCH DAMAGE.
34
 *
35
 * @package SimplePie
36
 * @version 1.1.3
37
 * @copyright 2004-2008 Ryan Parman, Geoffrey Sneddon
38
 * @author Ryan Parman
39
 * @author Geoffrey Sneddon
40
 * @link http://simplepie.org/ SimplePie
41
 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
42
 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43
 * @todo phpDoc comments
44
 */
45
46
/**
47
 * SimplePie Name
48
 */
49
define('SIMPLEPIE_NAME', 'SimplePie');
50
51
/**
52
 * SimplePie Version
53
 */
54
define('SIMPLEPIE_VERSION', '1.1.3');
55
56
/**
57
 * SimplePie Build
58
 */
59
define('SIMPLEPIE_BUILD', 20081219);
60
61
/**
62
 * SimplePie Website URL
63
 */
64
define('SIMPLEPIE_URL', 'http://simplepie.org');
65
66
/**
67
 * SimplePie Useragent
68
 * @see SimplePie::set_useragent()
69
 */
70
define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
71
72
/**
73
 * SimplePie Linkback
74
 */
75
define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
76
77
/**
78
 * No Autodiscovery
79
 * @see SimplePie::set_autodiscovery_level()
80
 */
81
define('SIMPLEPIE_LOCATOR_NONE', 0);
82
83
/**
84
 * Feed Link Element Autodiscovery
85
 * @see SimplePie::set_autodiscovery_level()
86
 */
87
define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
88
89
/**
90
 * Local Feed Extension Autodiscovery
91
 * @see SimplePie::set_autodiscovery_level()
92
 */
93
define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
94
95
/**
96
 * Local Feed Body Autodiscovery
97
 * @see SimplePie::set_autodiscovery_level()
98
 */
99
define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
100
101
/**
102
 * Remote Feed Extension Autodiscovery
103
 * @see SimplePie::set_autodiscovery_level()
104
 */
105
define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
106
107
/**
108
 * Remote Feed Body Autodiscovery
109
 * @see SimplePie::set_autodiscovery_level()
110
 */
111
define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
112
113
/**
114
 * All Feed Autodiscovery
115
 * @see SimplePie::set_autodiscovery_level()
116
 */
117
define('SIMPLEPIE_LOCATOR_ALL', 31);
118
119
/**
120
 * No known feed type
121
 */
122
define('SIMPLEPIE_TYPE_NONE', 0);
123
124
/**
125
 * RSS 0.90
126
 */
127
define('SIMPLEPIE_TYPE_RSS_090', 1);
128
129
/**
130
 * RSS 0.91 (Netscape)
131
 */
132
define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
133
134
/**
135
 * RSS 0.91 (Userland)
136
 */
137
define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
138
139
/**
140
 * RSS 0.91 (both Netscape and Userland)
141
 */
142
define('SIMPLEPIE_TYPE_RSS_091', 6);
143
144
/**
145
 * RSS 0.92
146
 */
147
define('SIMPLEPIE_TYPE_RSS_092', 8);
148
149
/**
150
 * RSS 0.93
151
 */
152
define('SIMPLEPIE_TYPE_RSS_093', 16);
153
154
/**
155
 * RSS 0.94
156
 */
157
define('SIMPLEPIE_TYPE_RSS_094', 32);
158
159
/**
160
 * RSS 1.0
161
 */
162
define('SIMPLEPIE_TYPE_RSS_10', 64);
163
164
/**
165
 * RSS 2.0
166
 */
167
define('SIMPLEPIE_TYPE_RSS_20', 128);
168
169
/**
170
 * RDF-based RSS
171
 */
172
define('SIMPLEPIE_TYPE_RSS_RDF', 65);
173
174
/**
175
 * Non-RDF-based RSS (truly intended as syndication format)
176
 */
177
define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
178
179
/**
180
 * All RSS
181
 */
182
define('SIMPLEPIE_TYPE_RSS_ALL', 255);
183
184
/**
185
 * Atom 0.3
186
 */
187
define('SIMPLEPIE_TYPE_ATOM_03', 256);
188
189
/**
190
 * Atom 1.0
191
 */
192
define('SIMPLEPIE_TYPE_ATOM_10', 512);
193
194
/**
195
 * All Atom
196
 */
197
define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
198
199
/**
200
 * All feed types
201
 */
202
define('SIMPLEPIE_TYPE_ALL', 1023);
203
204
/**
205
 * No construct
206
 */
207
define('SIMPLEPIE_CONSTRUCT_NONE', 0);
208
209
/**
210
 * Text construct
211
 */
212
define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
213
214
/**
215
 * HTML construct
216
 */
217
define('SIMPLEPIE_CONSTRUCT_HTML', 2);
218
219
/**
220
 * XHTML construct
221
 */
222
define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
223
224
/**
225
 * base64-encoded construct
226
 */
227
define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
228
229
/**
230
 * IRI construct
231
 */
232
define('SIMPLEPIE_CONSTRUCT_IRI', 16);
233
234
/**
235
 * A construct that might be HTML
236
 */
237
define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
238
239
/**
240
 * All constructs
241
 */
242
define('SIMPLEPIE_CONSTRUCT_ALL', 63);
243
244
/**
245
 * PCRE for HTML attributes
246
 */
247
define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
248
249
/**
250
 * PCRE for XML attributes
251
 */
252
define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
253
254
/**
255
 * XML Namespace
256
 */
257
define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
258
259
/**
260
 * Atom 1.0 Namespace
261
 */
262
define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
263
264
/**
265
 * Atom 0.3 Namespace
266
 */
267
define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
268
269
/**
270
 * RDF Namespace
271
 */
272
define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
273
274
/**
275
 * RSS 0.90 Namespace
276
 */
277
define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
278
279
/**
280
 * RSS 1.0 Namespace
281
 */
282
define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
283
284
/**
285
 * RSS 1.0 Content Module Namespace
286
 */
287
define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
288
289
/**
290
 * RSS 2.0 Namespace
291
 * (Stupid, I know, but I'm certain it will confuse people less with support.)
292
 */
293
define('SIMPLEPIE_NAMESPACE_RSS_20', '');
294
295
/**
296
 * DC 1.0 Namespace
297
 */
298
define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
299
300
/**
301
 * DC 1.1 Namespace
302
 */
303
define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
304
305
/**
306
 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
307
 */
308
define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
309
310
/**
311
 * GeoRSS Namespace
312
 */
313
define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
314
315
/**
316
 * Media RSS Namespace
317
 */
318
define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
319
320
/**
321
 * Wrong Media RSS Namespace
322
 */
323
define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
324
325
/**
326
 * iTunes RSS Namespace
327
 */
328
define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
329
330
/**
331
 * XHTML Namespace
332
 */
333
define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
334
335
/**
336
 * IANA Link Relations Registry
337
 */
338
define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
339
340
/**
341
 * Whether we're running on PHP5
342
 */
343
define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
344
345
/**
346
 * No file source
347
 */
348
define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
349
350
/**
351
 * Remote file source
352
 */
353
define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
354
355
/**
356
 * Local file source
357
 */
358
define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
359
360
/**
361
 * fsockopen() file source
362
 */
363
define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
364
365
/**
366
 * cURL file source
367
 */
368
define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
369
370
/**
371
 * file_get_contents() file source
372
 */
373
define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
374
375
/**
376
 * SimplePie
377
 *
378
 * @package SimplePie
379
 * @version "Razzleberry"
380
 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
381
 * @author Ryan Parman
382
 * @author Geoffrey Sneddon
383
 * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
384
 */
385
class SimplePie
386
{
387
	/**
388
	 * @var array Raw data
389
	 * @access private
390
	 */
391
	var $data = array();
392
393
	/**
394
	 * @var mixed Error string
395
	 * @access private
396
	 */
397
	var $error;
398
399
	/**
400
	 * @var object Instance of SimplePie_Sanitize (or other class)
401
	 * @see SimplePie::set_sanitize_class()
402
	 * @access private
403
	 */
404
	var $sanitize;
405
406
	/**
407
	 * @var string SimplePie Useragent
408
	 * @see SimplePie::set_useragent()
409
	 * @access private
410
	 */
411
	var $useragent = SIMPLEPIE_USERAGENT;
412
413
	/**
414
	 * @var string Feed URL
415
	 * @see SimplePie::set_feed_url()
416
	 * @access private
417
	 */
418
	var $feed_url;
419
420
	/**
421
	 * @var object Instance of SimplePie_File to use as a feed
422
	 * @see SimplePie::set_file()
423
	 * @access private
424
	 */
425
	var $file;
426
427
	/**
428
	 * @var string Raw feed data
429
	 * @see SimplePie::set_raw_data()
430
	 * @access private
431
	 */
432
	var $raw_data;
433
434
	/**
435
	 * @var int Timeout for fetching remote files
436
	 * @see SimplePie::set_timeout()
437
	 * @access private
438
	 */
439
	var $timeout = 10;
440
441
	/**
442
	 * @var bool Forces fsockopen() to be used for remote files instead
443
	 * of cURL, even if a new enough version is installed
444
	 * @see SimplePie::force_fsockopen()
445
	 * @access private
446
	 */
447
	var $force_fsockopen = false;
448
449
	/**
450
	 * @var bool Force the given data/URL to be treated as a feed no matter what
451
	 * it appears like
452
	 * @see SimplePie::force_feed()
453
	 * @access private
454
	 */
455
	var $force_feed = false;
456
457
	/**
458
	 * @var bool Enable/Disable XML dump
459
	 * @see SimplePie::enable_xml_dump()
460
	 * @access private
461
	 */
462
	var $xml_dump = false;
463
464
	/**
465
	 * @var bool Enable/Disable Caching
466
	 * @see SimplePie::enable_cache()
467
	 * @access private
468
	 */
469
	var $cache = true;
470
471
	/**
472
	 * @var int Cache duration (in seconds)
473
	 * @see SimplePie::set_cache_duration()
474
	 * @access private
475
	 */
476
	var $cache_duration = 3600;
477
478
	/**
479
	 * @var int Auto-discovery cache duration (in seconds)
480
	 * @see SimplePie::set_autodiscovery_cache_duration()
481
	 * @access private
482
	 */
483
	var $autodiscovery_cache_duration = 604800; // 7 Days.
484
485
	/**
486
	 * @var string Cache location (relative to executing script)
487
	 * @see SimplePie::set_cache_location()
488
	 * @access private
489
	 */
490
	var $cache_location = './cache';
491
492
	/**
493
	 * @var string Function that creates the cache filename
494
	 * @see SimplePie::set_cache_name_function()
495
	 * @access private
496
	 */
497
	var $cache_name_function = 'md5';
498
499
	/**
500
	 * @var bool Reorder feed by date descending
501
	 * @see SimplePie::enable_order_by_date()
502
	 * @access private
503
	 */
504
	var $order_by_date = true;
505
506
	/**
507
	 * @var mixed Force input encoding to be set to the follow value
508
	 * (false, or anything type-cast to false, disables this feature)
509
	 * @see SimplePie::set_input_encoding()
510
	 * @access private
511
	 */
512
	var $input_encoding = false;
513
514
	/**
515
	 * @var int Feed Autodiscovery Level
516
	 * @see SimplePie::set_autodiscovery_level()
517
	 * @access private
518
	 */
519
	var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
520
521
	/**
522
	 * @var string Class used for caching feeds
523
	 * @see SimplePie::set_cache_class()
524
	 * @access private
525
	 */
526
	var $cache_class = 'SimplePie_Cache';
527
528
	/**
529
	 * @var string Class used for locating feeds
530
	 * @see SimplePie::set_locator_class()
531
	 * @access private
532
	 */
533
	var $locator_class = 'SimplePie_Locator';
534
535
	/**
536
	 * @var string Class used for parsing feeds
537
	 * @see SimplePie::set_parser_class()
538
	 * @access private
539
	 */
540
	var $parser_class = 'SimplePie_Parser';
541
542
	/**
543
	 * @var string Class used for fetching feeds
544
	 * @see SimplePie::set_file_class()
545
	 * @access private
546
	 */
547
	var $file_class = 'SimplePie_File';
548
549
	/**
550
	 * @var string Class used for items
551
	 * @see SimplePie::set_item_class()
552
	 * @access private
553
	 */
554
	var $item_class = 'SimplePie_Item';
555
556
	/**
557
	 * @var string Class used for authors
558
	 * @see SimplePie::set_author_class()
559
	 * @access private
560
	 */
561
	var $author_class = 'SimplePie_Author';
562
563
	/**
564
	 * @var string Class used for categories
565
	 * @see SimplePie::set_category_class()
566
	 * @access private
567
	 */
568
	var $category_class = 'SimplePie_Category';
569
570
	/**
571
	 * @var string Class used for enclosures
572
	 * @see SimplePie::set_enclosures_class()
573
	 * @access private
574
	 */
575
	var $enclosure_class = 'SimplePie_Enclosure';
576
577
	/**
578
	 * @var string Class used for Media RSS <media:text> captions
579
	 * @see SimplePie::set_caption_class()
580
	 * @access private
581
	 */
582
	var $caption_class = 'SimplePie_Caption';
583
584
	/**
585
	 * @var string Class used for Media RSS <media:copyright>
586
	 * @see SimplePie::set_copyright_class()
587
	 * @access private
588
	 */
589
	var $copyright_class = 'SimplePie_Copyright';
590
591
	/**
592
	 * @var string Class used for Media RSS <media:credit>
593
	 * @see SimplePie::set_credit_class()
594
	 * @access private
595
	 */
596
	var $credit_class = 'SimplePie_Credit';
597
598
	/**
599
	 * @var string Class used for Media RSS <media:rating>
600
	 * @see SimplePie::set_rating_class()
601
	 * @access private
602
	 */
603
	var $rating_class = 'SimplePie_Rating';
604
605
	/**
606
	 * @var string Class used for Media RSS <media:restriction>
607
	 * @see SimplePie::set_restriction_class()
608
	 * @access private
609
	 */
610
	var $restriction_class = 'SimplePie_Restriction';
611
612
	/**
613
	 * @var string Class used for content-type sniffing
614
	 * @see SimplePie::set_content_type_sniffer_class()
615
	 * @access private
616
	 */
617
	var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
618
619
	/**
620
	 * @var string Class used for item sources.
621
	 * @see SimplePie::set_source_class()
622
	 * @access private
623
	 */
624
	var $source_class = 'SimplePie_Source';
625
626
	/**
627
	 * @var mixed Set javascript query string parameter (false, or
628
	 * anything type-cast to false, disables this feature)
629
	 * @see SimplePie::set_javascript()
630
	 * @access private
631
	 */
632
	var $javascript = 'js';
633
634
	/**
635
	 * @var int Maximum number of feeds to check with autodiscovery
636
	 * @see SimplePie::set_max_checked_feeds()
637
	 * @access private
638
	 */
639
	var $max_checked_feeds = 10;
640
641
	/**
642
	 * @var string Web-accessible path to the handler_favicon.php file.
643
	 * @see SimplePie::set_favicon_handler()
644
	 * @access private
645
	 */
646
	var $favicon_handler = '';
647
648
	/**
649
	 * @var string Web-accessible path to the handler_image.php file.
650
	 * @see SimplePie::set_image_handler()
651
	 * @access private
652
	 */
653
	var $image_handler = '';
654
655
	/**
656
	 * @var array Stores the URLs when multiple feeds are being initialized.
657
	 * @see SimplePie::set_feed_url()
658
	 * @access private
659
	 */
660
	var $multifeed_url = array();
661
662
	/**
663
	 * @var array Stores SimplePie objects when multiple feeds initialized.
664
	 * @access private
665
	 */
666
	var $multifeed_objects = array();
667
668
	/**
669
	 * @var array Stores the get_object_vars() array for use with multifeeds.
670
	 * @see SimplePie::set_feed_url()
671
	 * @access private
672
	 */
673
	var $config_settings = null;
674
675
	/**
676
	 * @var integer Stores the number of items to return per-feed with multifeeds.
677
	 * @see SimplePie::set_item_limit()
678
	 * @access private
679
	 */
680
	var $item_limit = 0;
681
682
	/**
683
	 * @var array Stores the default attributes to be stripped by strip_attributes().
684
	 * @see SimplePie::strip_attributes()
685
	 * @access private
686
	 */
687
	var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
688
689
	/**
690
	 * @var array Stores the default tags to be stripped by strip_htmltags().
691
	 * @see SimplePie::strip_htmltags()
692
	 * @access private
693
	 */
694
	var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
695
696
	/**
697
	 * The SimplePie class contains feed level data and options
698
	 *
699
	 * There are two ways that you can create a new SimplePie object. The first
700
	 * is by passing a feed URL as a parameter to the SimplePie constructor
701
	 * (as well as optionally setting the cache location and cache expiry). This
702
	 * will initialise the whole feed with all of the default settings, and you
703
	 * can begin accessing methods and properties immediately.
704
	 *
705
	 * The second way is to create the SimplePie object with no parameters
706
	 * at all. This will enable you to set configuration options. After setting
707
	 * them, you must initialise the feed using $feed->init(). At that point the
708
	 * object's methods and properties will be available to you. This format is
709
	 * what is used throughout this documentation.
710
	 *
711
	 * @access public
712
	 * @since 1.0 Preview Release
713
	 * @param string $feed_url This is the URL you want to parse.
714
	 * @param string $cache_location This is where you want the cache to be stored.
715
	 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
716
	 */
717
	function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
718
	{
719
		// Other objects, instances created here so we can set options on them
720 23ca5695 Chris Buechler
		$this->sanitize =& new SimplePie_Sanitize;
721 b2e02eef Scott Ullrich
722
		// Set options if they're passed to the constructor
723
		if ($cache_location !== null)
724
		{
725
			$this->set_cache_location($cache_location);
726
		}
727
728
		if ($cache_duration !== null)
729
		{
730
			$this->set_cache_duration($cache_duration);
731
		}
732
733
		// Only init the script if we're passed a feed URL
734
		if ($feed_url !== null)
735
		{
736
			$this->set_feed_url($feed_url);
737
			$this->init();
738
		}
739
	}
740
741
	/**
742
	 * Used for converting object to a string
743
	 */
744
	function __toString()
745
	{
746
		return md5(serialize($this->data));
747
	}
748
749
	/**
750
	 * Remove items that link back to this before destroying this object
751
	 */
752
	function __destruct()
753
	{
754
		if (!empty($this->data['items']))
755
		{
756
			foreach ($this->data['items'] as $item)
757
			{
758
				$item->__destruct();
759
			}
760
			unset($this->data['items']);
761
		}
762
		if (!empty($this->data['ordered_items']))
763
		{
764
			foreach ($this->data['ordered_items'] as $item)
765
			{
766
				$item->__destruct();
767
			}
768
			unset($this->data['ordered_items']);
769
		}
770
	}
771
772
	/**
773
	 * Force the given data/URL to be treated as a feed no matter what it
774
	 * appears like
775
	 *
776
	 * @access public
777
	 * @since 1.1
778
	 * @param bool $enable Force the given data/URL to be treated as a feed
779
	 */
780
	function force_feed($enable = false)
781
	{
782
		$this->force_feed = (bool) $enable;
783
	}
784
785
	/**
786
	 * This is the URL of the feed you want to parse.
787
	 *
788
	 * This allows you to enter the URL of the feed you want to parse, or the
789
	 * website you want to try to use auto-discovery on. This takes priority
790
	 * over any set raw data.
791
	 *
792
	 * You can set multiple feeds to mash together by passing an array instead
793
	 * of a string for the $url. Remember that with each additional feed comes
794
	 * additional processing and resources.
795
	 *
796
	 * @access public
797
	 * @since 1.0 Preview Release
798
	 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
799
	 * @see SimplePie::set_raw_data()
800
	 */
801
	function set_feed_url($url)
802
	{
803
		if (is_array($url))
804
		{
805
			$this->multifeed_url = array();
806
			foreach ($url as $value)
807
			{
808
				$this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
809
			}
810
		}
811
		else
812
		{
813
			$this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
814
		}
815
	}
816
817
	/**
818
	 * Provides an instance of SimplePie_File to use as a feed
819
	 *
820
	 * @access public
821
	 * @param object &$file Instance of SimplePie_File (or subclass)
822
	 * @return bool True on success, false on failure
823
	 */
824
	function set_file(&$file)
825
	{
826
		if (is_a($file, 'SimplePie_File'))
827
		{
828
			$this->feed_url = $file->url;
829
			$this->file =& $file;
830
			return true;
831
		}
832
		return false;
833
	}
834
835
	/**
836
	 * Allows you to use a string of RSS/Atom data instead of a remote feed.
837
	 *
838
	 * If you have a feed available as a string in PHP, you can tell SimplePie
839
	 * to parse that data string instead of a remote feed. Any set feed URL
840
	 * takes precedence.
841
	 *
842
	 * @access public
843
	 * @since 1.0 Beta 3
844
	 * @param string $data RSS or Atom data as a string.
845
	 * @see SimplePie::set_feed_url()
846
	 */
847
	function set_raw_data($data)
848
	{
849
		$this->raw_data = $data;
850
	}
851
852
	/**
853
	 * Allows you to override the default timeout for fetching remote feeds.
854
	 *
855
	 * This allows you to change the maximum time the feed's server to respond
856
	 * and send the feed back.
857
	 *
858
	 * @access public
859
	 * @since 1.0 Beta 3
860
	 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
861
	 */
862
	function set_timeout($timeout = 10)
863
	{
864
		$this->timeout = (int) $timeout;
865
	}
866
867
	/**
868
	 * Forces SimplePie to use fsockopen() instead of the preferred cURL
869
	 * functions.
870
	 *
871
	 * @access public
872
	 * @since 1.0 Beta 3
873
	 * @param bool $enable Force fsockopen() to be used
874
	 */
875
	function force_fsockopen($enable = false)
876
	{
877
		$this->force_fsockopen = (bool) $enable;
878
	}
879
880
	/**
881
	 * Outputs the raw XML content of the feed, after it has gone through
882
	 * SimplePie's filters.
883
	 *
884
	 * Used only for debugging, this function will output the XML content as
885
	 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
886
	 * before trying to parse it. Many parts of the feed are re-written in
887
	 * memory, and in the end, you have a parsable feed. XML dump shows you the
888
	 * actual XML that SimplePie tries to parse, which may or may not be very
889
	 * different from the original feed.
890
	 *
891
	 * @access public
892
	 * @since 1.0 Preview Release
893
	 * @param bool $enable Enable XML dump
894
	 */
895
	function enable_xml_dump($enable = false)
896
	{
897
		$this->xml_dump = (bool) $enable;
898
	}
899
900
	/**
901
	 * Enables/disables caching in SimplePie.
902
	 *
903
	 * This option allows you to disable caching all-together in SimplePie.
904
	 * However, disabling the cache can lead to longer load times.
905
	 *
906
	 * @access public
907
	 * @since 1.0 Preview Release
908
	 * @param bool $enable Enable caching
909
	 */
910
	function enable_cache($enable = true)
911
	{
912
		$this->cache = (bool) $enable;
913
	}
914
915
	/**
916
	 * Set the length of time (in seconds) that the contents of a feed
917
	 * will be cached.
918
	 *
919
	 * @access public
920
	 * @param int $seconds The feed content cache duration.
921
	 */
922
	function set_cache_duration($seconds = 3600)
923
	{
924
		$this->cache_duration = (int) $seconds;
925
	}
926
927
	/**
928
	 * Set the length of time (in seconds) that the autodiscovered feed
929
	 * URL will be cached.
930
	 *
931
	 * @access public
932
	 * @param int $seconds The autodiscovered feed URL cache duration.
933
	 */
934
	function set_autodiscovery_cache_duration($seconds = 604800)
935
	{
936
		$this->autodiscovery_cache_duration = (int) $seconds;
937
	}
938
939
	/**
940
	 * Set the file system location where the cached files should be stored.
941
	 *
942
	 * @access public
943
	 * @param string $location The file system location.
944
	 */
945
	function set_cache_location($location = './cache')
946
	{
947
		$this->cache_location = (string) $location;
948
	}
949
950
	/**
951
	 * Determines whether feed items should be sorted into reverse chronological order.
952
	 *
953
	 * @access public
954
	 * @param bool $enable Sort as reverse chronological order.
955
	 */
956
	function enable_order_by_date($enable = true)
957
	{
958
		$this->order_by_date = (bool) $enable;
959
	}
960
961
	/**
962
	 * Allows you to override the character encoding reported by the feed.
963
	 *
964
	 * @access public
965
	 * @param string $encoding Character encoding.
966
	 */
967
	function set_input_encoding($encoding = false)
968
	{
969
		if ($encoding)
970
		{
971
			$this->input_encoding = (string) $encoding;
972
		}
973
		else
974
		{
975
			$this->input_encoding = false;
976
		}
977
	}
978
979
	/**
980
	 * Set how much feed autodiscovery to do
981
	 *
982
	 * @access public
983
	 * @see SIMPLEPIE_LOCATOR_NONE
984
	 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
985
	 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
986
	 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
987
	 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
988
	 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
989
	 * @see SIMPLEPIE_LOCATOR_ALL
990
	 * @param int $level Feed Autodiscovery Level (level can be a
991
	 * combination of the above constants, see bitwise OR operator)
992
	 */
993
	function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
994
	{
995
		$this->autodiscovery = (int) $level;
996
	}
997
998
	/**
999
	 * Allows you to change which class SimplePie uses for caching.
1000
	 * Useful when you are overloading or extending SimplePie's default classes.
1001
	 *
1002
	 * @access public
1003
	 * @param string $class Name of custom class.
1004
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1005
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1006
	 */
1007
	function set_cache_class($class = 'SimplePie_Cache')
1008
	{
1009
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1010
		{
1011
			$this->cache_class = $class;
1012
			return true;
1013
		}
1014
		return false;
1015
	}
1016
1017
	/**
1018
	 * Allows you to change which class SimplePie uses for auto-discovery.
1019
	 * Useful when you are overloading or extending SimplePie's default classes.
1020
	 *
1021
	 * @access public
1022
	 * @param string $class Name of custom class.
1023
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1024
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1025
	 */
1026
	function set_locator_class($class = 'SimplePie_Locator')
1027
	{
1028
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1029
		{
1030
			$this->locator_class = $class;
1031
			return true;
1032
		}
1033
		return false;
1034
	}
1035
1036
	/**
1037
	 * Allows you to change which class SimplePie uses for XML parsing.
1038
	 * Useful when you are overloading or extending SimplePie's default classes.
1039
	 *
1040
	 * @access public
1041
	 * @param string $class Name of custom class.
1042
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1043
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1044
	 */
1045
	function set_parser_class($class = 'SimplePie_Parser')
1046
	{
1047
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1048
		{
1049
			$this->parser_class = $class;
1050
			return true;
1051
		}
1052
		return false;
1053
	}
1054
1055
	/**
1056
	 * Allows you to change which class SimplePie uses for remote file fetching.
1057
	 * Useful when you are overloading or extending SimplePie's default classes.
1058
	 *
1059
	 * @access public
1060
	 * @param string $class Name of custom class.
1061
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1062
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1063
	 */
1064
	function set_file_class($class = 'SimplePie_File')
1065
	{
1066
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1067
		{
1068
			$this->file_class = $class;
1069
			return true;
1070
		}
1071
		return false;
1072
	}
1073
1074
	/**
1075
	 * Allows you to change which class SimplePie uses for data sanitization.
1076
	 * Useful when you are overloading or extending SimplePie's default classes.
1077
	 *
1078
	 * @access public
1079
	 * @param string $class Name of custom class.
1080
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1081
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1082
	 */
1083
	function set_sanitize_class($class = 'SimplePie_Sanitize')
1084
	{
1085
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1086
		{
1087 23ca5695 Chris Buechler
			$this->sanitize =& new $class;
1088 b2e02eef Scott Ullrich
			return true;
1089
		}
1090
		return false;
1091
	}
1092
1093
	/**
1094
	 * Allows you to change which class SimplePie uses for handling feed items.
1095
	 * Useful when you are overloading or extending SimplePie's default classes.
1096
	 *
1097
	 * @access public
1098
	 * @param string $class Name of custom class.
1099
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1100
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1101
	 */
1102
	function set_item_class($class = 'SimplePie_Item')
1103
	{
1104
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1105
		{
1106
			$this->item_class = $class;
1107
			return true;
1108
		}
1109
		return false;
1110
	}
1111
1112
	/**
1113
	 * Allows you to change which class SimplePie uses for handling author data.
1114
	 * Useful when you are overloading or extending SimplePie's default classes.
1115
	 *
1116
	 * @access public
1117
	 * @param string $class Name of custom class.
1118
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1119
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1120
	 */
1121
	function set_author_class($class = 'SimplePie_Author')
1122
	{
1123
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1124
		{
1125
			$this->author_class = $class;
1126
			return true;
1127
		}
1128
		return false;
1129
	}
1130
1131
	/**
1132
	 * Allows you to change which class SimplePie uses for handling category data.
1133
	 * Useful when you are overloading or extending SimplePie's default classes.
1134
	 *
1135
	 * @access public
1136
	 * @param string $class Name of custom class.
1137
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1138
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1139
	 */
1140
	function set_category_class($class = 'SimplePie_Category')
1141
	{
1142
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1143
		{
1144
			$this->category_class = $class;
1145
			return true;
1146
		}
1147
		return false;
1148
	}
1149
1150
	/**
1151
	 * Allows you to change which class SimplePie uses for feed enclosures.
1152
	 * Useful when you are overloading or extending SimplePie's default classes.
1153
	 *
1154
	 * @access public
1155
	 * @param string $class Name of custom class.
1156
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1157
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1158
	 */
1159
	function set_enclosure_class($class = 'SimplePie_Enclosure')
1160
	{
1161
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1162
		{
1163
			$this->enclosure_class = $class;
1164
			return true;
1165
		}
1166
		return false;
1167
	}
1168
1169
	/**
1170
	 * Allows you to change which class SimplePie uses for <media:text> captions
1171
	 * Useful when you are overloading or extending SimplePie's default classes.
1172
	 *
1173
	 * @access public
1174
	 * @param string $class Name of custom class.
1175
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1176
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1177
	 */
1178
	function set_caption_class($class = 'SimplePie_Caption')
1179
	{
1180
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1181
		{
1182
			$this->caption_class = $class;
1183
			return true;
1184
		}
1185
		return false;
1186
	}
1187
1188
	/**
1189
	 * Allows you to change which class SimplePie uses for <media:copyright>
1190
	 * Useful when you are overloading or extending SimplePie's default classes.
1191
	 *
1192
	 * @access public
1193
	 * @param string $class Name of custom class.
1194
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1195
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1196
	 */
1197
	function set_copyright_class($class = 'SimplePie_Copyright')
1198
	{
1199
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1200
		{
1201
			$this->copyright_class = $class;
1202
			return true;
1203
		}
1204
		return false;
1205
	}
1206
1207
	/**
1208
	 * Allows you to change which class SimplePie uses for <media:credit>
1209
	 * Useful when you are overloading or extending SimplePie's default classes.
1210
	 *
1211
	 * @access public
1212
	 * @param string $class Name of custom class.
1213
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1214
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1215
	 */
1216
	function set_credit_class($class = 'SimplePie_Credit')
1217
	{
1218
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1219
		{
1220
			$this->credit_class = $class;
1221
			return true;
1222
		}
1223
		return false;
1224
	}
1225
1226
	/**
1227
	 * Allows you to change which class SimplePie uses for <media:rating>
1228
	 * Useful when you are overloading or extending SimplePie's default classes.
1229
	 *
1230
	 * @access public
1231
	 * @param string $class Name of custom class.
1232
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1233
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1234
	 */
1235
	function set_rating_class($class = 'SimplePie_Rating')
1236
	{
1237
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1238
		{
1239
			$this->rating_class = $class;
1240
			return true;
1241
		}
1242
		return false;
1243
	}
1244
1245
	/**
1246
	 * Allows you to change which class SimplePie uses for <media:restriction>
1247
	 * Useful when you are overloading or extending SimplePie's default classes.
1248
	 *
1249
	 * @access public
1250
	 * @param string $class Name of custom class.
1251
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1252
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1253
	 */
1254
	function set_restriction_class($class = 'SimplePie_Restriction')
1255
	{
1256
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1257
		{
1258
			$this->restriction_class = $class;
1259
			return true;
1260
		}
1261
		return false;
1262
	}
1263
1264
	/**
1265
	 * Allows you to change which class SimplePie uses for content-type sniffing.
1266
	 * Useful when you are overloading or extending SimplePie's default classes.
1267
	 *
1268
	 * @access public
1269
	 * @param string $class Name of custom class.
1270
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1271
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1272
	 */
1273
	function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1274
	{
1275
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1276
		{
1277
			$this->content_type_sniffer_class = $class;
1278
			return true;
1279
		}
1280
		return false;
1281
	}
1282
1283
	/**
1284
	 * Allows you to change which class SimplePie uses item sources.
1285
	 * Useful when you are overloading or extending SimplePie's default classes.
1286
	 *
1287
	 * @access public
1288
	 * @param string $class Name of custom class.
1289
	 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1290
	 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1291
	 */
1292
	function set_source_class($class = 'SimplePie_Source')
1293
	{
1294
		if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1295
		{
1296
			$this->source_class = $class;
1297
			return true;
1298
		}
1299
		return false;
1300
	}
1301
1302
	/**
1303
	 * Allows you to override the default user agent string.
1304
	 *
1305
	 * @access public
1306
	 * @param string $ua New user agent string.
1307
	 */
1308
	function set_useragent($ua = SIMPLEPIE_USERAGENT)
1309
	{
1310
		$this->useragent = (string) $ua;
1311
	}
1312
1313
	/**
1314
	 * Set callback function to create cache filename with
1315
	 *
1316
	 * @access public
1317
	 * @param mixed $function Callback function
1318
	 */
1319
	function set_cache_name_function($function = 'md5')
1320
	{
1321
		if (is_callable($function))
1322
		{
1323
			$this->cache_name_function = $function;
1324
		}
1325
	}
1326
1327
	/**
1328
	 * Set javascript query string parameter
1329
	 *
1330
	 * @access public
1331
	 * @param mixed $get Javascript query string parameter
1332
	 */
1333
	function set_javascript($get = 'js')
1334
	{
1335
		if ($get)
1336
		{
1337
			$this->javascript = (string) $get;
1338
		}
1339
		else
1340
		{
1341
			$this->javascript = false;
1342
		}
1343
	}
1344
1345
	/**
1346
	 * Set options to make SP as fast as possible.  Forgoes a
1347
	 * substantial amount of data sanitization in favor of speed.
1348
	 *
1349
	 * @access public
1350
	 * @param bool $set Whether to set them or not
1351
	 */
1352
	function set_stupidly_fast($set = false)
1353
	{
1354
		if ($set)
1355
		{
1356
			$this->enable_order_by_date(false);
1357
			$this->remove_div(false);
1358
			$this->strip_comments(false);
1359
			$this->strip_htmltags(false);
1360
			$this->strip_attributes(false);
1361
			$this->set_image_handler(false);
1362
		}
1363
	}
1364
1365
	/**
1366
	 * Set maximum number of feeds to check with autodiscovery
1367
	 *
1368
	 * @access public
1369
	 * @param int $max Maximum number of feeds to check
1370
	 */
1371
	function set_max_checked_feeds($max = 10)
1372
	{
1373
		$this->max_checked_feeds = (int) $max;
1374
	}
1375
1376
	function remove_div($enable = true)
1377
	{
1378
		$this->sanitize->remove_div($enable);
1379
	}
1380
1381
	function strip_htmltags($tags = '', $encode = null)
1382
	{
1383
		if ($tags === '')
1384
		{
1385
			$tags = $this->strip_htmltags;
1386
		}
1387
		$this->sanitize->strip_htmltags($tags);
1388
		if ($encode !== null)
1389
		{
1390
			$this->sanitize->encode_instead_of_strip($tags);
1391
		}
1392
	}
1393
1394
	function encode_instead_of_strip($enable = true)
1395
	{
1396
		$this->sanitize->encode_instead_of_strip($enable);
1397
	}
1398
1399
	function strip_attributes($attribs = '')
1400
	{
1401
		if ($attribs === '')
1402
		{
1403
			$attribs = $this->strip_attributes;
1404
		}
1405
		$this->sanitize->strip_attributes($attribs);
1406
	}
1407
1408
	function set_output_encoding($encoding = 'UTF-8')
1409
	{
1410
		$this->sanitize->set_output_encoding($encoding);
1411
	}
1412
1413
	function strip_comments($strip = false)
1414
	{
1415
		$this->sanitize->strip_comments($strip);
1416
	}
1417
1418
	/**
1419
	 * Set element/attribute key/value pairs of HTML attributes
1420
	 * containing URLs that need to be resolved relative to the feed
1421
	 *
1422
	 * @access public
1423
	 * @since 1.0
1424
	 * @param array $element_attribute Element/attribute key/value pairs
1425
	 */
1426
	function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
1427
	{
1428
		$this->sanitize->set_url_replacements($element_attribute);
1429
	}
1430
1431
	/**
1432
	 * Set the handler to enable the display of cached favicons.
1433
	 *
1434
	 * @access public
1435
	 * @param str $page Web-accessible path to the handler_favicon.php file.
1436
	 * @param str $qs The query string that the value should be passed to.
1437
	 */
1438
	function set_favicon_handler($page = false, $qs = 'i')
1439
	{
1440
		if ($page != false)
1441
		{
1442
			$this->favicon_handler = $page . '?' . $qs . '=';
1443
		}
1444
		else
1445
		{
1446
			$this->favicon_handler = '';
1447
		}
1448
	}
1449
1450
	/**
1451
	 * Set the handler to enable the display of cached images.
1452
	 *
1453
	 * @access public
1454
	 * @param str $page Web-accessible path to the handler_image.php file.
1455
	 * @param str $qs The query string that the value should be passed to.
1456
	 */
1457
	function set_image_handler($page = false, $qs = 'i')
1458
	{
1459
		if ($page != false)
1460
		{
1461
			$this->sanitize->set_image_handler($page . '?' . $qs . '=');
1462
		}
1463
		else
1464
		{
1465
			$this->image_handler = '';
1466
		}
1467
	}
1468
1469
	/**
1470
	 * Set the limit for items returned per-feed with multifeeds.
1471
	 *
1472
	 * @access public
1473
	 * @param integer $limit The maximum number of items to return.
1474
	 */
1475
	function set_item_limit($limit = 0)
1476
	{
1477
		$this->item_limit = (int) $limit;
1478
	}
1479
1480
	function init()
1481
	{
1482
		if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1483
		{
1484
			return false;
1485
		}
1486
		if (isset($_GET[$this->javascript]))
1487
		{
1488
			if (function_exists('ob_gzhandler'))
1489
			{
1490
				ob_start('ob_gzhandler');
1491
			}
1492
			header('Content-type: text/javascript; charset: UTF-8');
1493
			header('Cache-Control: must-revalidate');
1494
			header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1495
			?>
1496
function embed_odeo(link) {
1497
	document.writeln('<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url='+link+'"></embed>');
1498
}
1499
1500
function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1501
	if (placeholder != '') {
1502
		document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1503
	}
1504
	else {
1505
		document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1506
	}
1507
}
1508
1509
function embed_flash(bgcolor, width, height, link, loop, type) {
1510
	document.writeln('<embed src="'+link+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="'+type+'" quality="high" width="'+width+'" height="'+height+'" bgcolor="'+bgcolor+'" loop="'+loop+'"></embed>');
1511
}
1512
1513
function embed_flv(width, height, link, placeholder, loop, player) {
1514
	document.writeln('<embed src="'+player+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="'+width+'" height="'+height+'" wmode="transparent" flashvars="file='+link+'&autostart=false&repeat='+loop+'&showdigits=true&showfsbutton=false"></embed>');
1515
}
1516
1517
function embed_wmedia(width, height, link) {
1518
	document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1519
}
1520
			<?php
1521
			exit;
1522
		}
1523
1524
		// Pass whatever was set with config options over to the sanitizer.
1525
		$this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1526
		$this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1527
1528
		if ($this->feed_url !== null || $this->raw_data !== null)
1529
		{
1530
			$this->data = array();
1531
			$this->multifeed_objects = array();
1532
			$cache = false;
1533
1534
			if ($this->feed_url !== null)
1535
			{
1536
				$parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1537
				// Decide whether to enable caching
1538
				if ($this->cache && $parsed_feed_url['scheme'] !== '')
1539
				{
1540
					$cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1541
				}
1542
				// If it's enabled and we don't want an XML dump, use the cache
1543
				if ($cache && !$this->xml_dump)
1544
				{
1545
					// Load the Cache
1546
					$this->data = $cache->load();
1547
					if (!empty($this->data))
1548
					{
1549
						// If the cache is for an outdated build of SimplePie
1550
						if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1551
						{
1552
							$cache->unlink();
1553
							$this->data = array();
1554
						}
1555
						// If we've hit a collision just rerun it with caching disabled
1556
						elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1557
						{
1558
							$cache = false;
1559
							$this->data = array();
1560
						}
1561
						// If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1562
						elseif (isset($this->data['feed_url']))
1563
						{
1564
							// If the autodiscovery cache is still valid use it.
1565
							if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1566
							{
1567
								// Do not need to do feed autodiscovery yet.
1568
								if ($this->data['feed_url'] == $this->data['url'])
1569
								{
1570
									$cache->unlink();
1571
									$this->data = array();
1572
								}
1573
								else
1574
								{
1575
									$this->set_feed_url($this->data['feed_url']);
1576
									return $this->init();
1577
								}
1578
							}
1579
						}
1580
						// Check if the cache has been updated
1581
						elseif ($cache->mtime() + $this->cache_duration < time())
1582
						{
1583
							// If we have last-modified and/or etag set
1584
							if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1585
							{
1586
								$headers = array();
1587
								if (isset($this->data['headers']['last-modified']))
1588
								{
1589
									$headers['if-modified-since'] = $this->data['headers']['last-modified'];
1590
								}
1591
								if (isset($this->data['headers']['etag']))
1592
								{
1593
									$headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1594
								}
1595 23ca5695 Chris Buechler
								$file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1596 b2e02eef Scott Ullrich
								if ($file->success)
1597
								{
1598
									if ($file->status_code == 304)
1599
									{
1600
										$cache->touch();
1601
										return true;
1602
									}
1603
									else
1604
									{
1605
										$headers = $file->headers;
1606
									}
1607
								}
1608
								else
1609
								{
1610
									unset($file);
1611
								}
1612
							}
1613
						}
1614
						// If the cache is still valid, just return true
1615
						else
1616
						{
1617
							return true;
1618
						}
1619
					}
1620
					// If the cache is empty, delete it
1621
					else
1622
					{
1623
						$cache->unlink();
1624
						$this->data = array();
1625
					}
1626
				}
1627
				// If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
1628
				if (!isset($file))
1629
				{
1630
					if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1631
					{
1632
						$file =& $this->file;
1633
					}
1634
					else
1635
					{
1636 23ca5695 Chris Buechler
						$file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1637 b2e02eef Scott Ullrich
					}
1638
				}
1639
				// If the file connection has an error, set SimplePie::error to that and quit
1640
				if (!$file->success)
1641
				{
1642
					$this->error = $file->error;
1643
					if (!empty($this->data))
1644
					{
1645
						return true;
1646
					}
1647
					else
1648
					{
1649
						return false;
1650
					}
1651
				}
1652
1653
				if (!$this->force_feed)
1654
				{
1655
					// Check if the supplied URL is a feed, if it isn't, look for it.
1656 23ca5695 Chris Buechler
					$locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1657 b2e02eef Scott Ullrich
					if (!$locate->is_feed($file))
1658
					{
1659
						// We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1660
						unset($file);
1661
						if ($file = $locate->find($this->autodiscovery))
1662
						{
1663
							if ($cache)
1664
							{
1665
								$this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1666
								if (!$cache->save($this))
1667
								{
1668
									trigger_error("$cache->name is not writeable", E_USER_WARNING);
1669
								}
1670
								$cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1671
							}
1672
							$this->feed_url = $file->url;
1673
						}
1674
						else
1675
						{
1676
							$this->error = "A feed could not be found at $this->feed_url";
1677
							SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1678
							return false;
1679
						}
1680
					}
1681
					$locate = null;
1682
				}
1683
1684
				$headers = $file->headers;
1685
				$data = $file->body;
1686
				$sniffer = new $this->content_type_sniffer_class($file);
1687
				$sniffed = $sniffer->get_type();
1688
			}
1689
			else
1690
			{
1691
				$data = $this->raw_data;
1692
			}
1693
1694
			// Set up array of possible encodings
1695
			$encodings = array();
1696
1697
			// First check to see if input has been overridden.
1698
			if ($this->input_encoding !== false)
1699
			{
1700
				$encodings[] = $this->input_encoding;
1701
			}
1702
1703
			$application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1704
			$text_types = array('text/xml', 'text/xml-external-parsed-entity');
1705
1706
			// RFC 3023 (only applies to sniffed content)
1707
			if (isset($sniffed))
1708
			{
1709
				if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1710
				{
1711
					if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1712
					{
1713
						$encodings[] = strtoupper($charset[1]);
1714
					}
1715
					$encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1716
					$encodings[] = 'UTF-8';
1717
				}
1718
				elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1719
				{
1720
					if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1721
					{
1722
						$encodings[] = $charset[1];
1723
					}
1724
					$encodings[] = 'US-ASCII';
1725
				}
1726
				// Text MIME-type default
1727
				elseif (substr($sniffed, 0, 5) === 'text/')
1728
				{
1729
					$encodings[] = 'US-ASCII';
1730
				}
1731
			}
1732
1733
			// Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1734
			$encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1735
			$encodings[] = 'UTF-8';
1736
			$encodings[] = 'ISO-8859-1';
1737
1738
			// There's no point in trying an encoding twice
1739
			$encodings = array_unique($encodings);
1740
1741
			// If we want the XML, just output that with the most likely encoding and quit
1742
			if ($this->xml_dump)
1743
			{
1744
				header('Content-type: text/xml; charset=' . $encodings[0]);
1745
				echo $data;
1746
				exit;
1747
			}
1748
1749
			// Loop through each possible encoding, till we return something, or run out of possibilities
1750
			foreach ($encodings as $encoding)
1751
			{
1752
				// Change the encoding to UTF-8 (as we always use UTF-8 internally)
1753
				if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1754
				{
1755
					// Create new parser
1756 23ca5695 Chris Buechler
					$parser =& new $this->parser_class();
1757 b2e02eef Scott Ullrich
1758
					// If it's parsed fine
1759
					if ($parser->parse($utf8_data, 'UTF-8'))
1760
					{
1761
						$this->data = $parser->get_data();
1762
						if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1763
						{
1764
							if (isset($headers))
1765
							{
1766
								$this->data['headers'] = $headers;
1767
							}
1768
							$this->data['build'] = SIMPLEPIE_BUILD;
1769
1770
							// Cache the file if caching is enabled
1771
							if ($cache && !$cache->save($this))
1772
							{
1773
								trigger_error("$cache->name is not writeable", E_USER_WARNING);
1774
							}
1775
							return true;
1776
						}
1777
						else
1778
						{
1779
							$this->error = "A feed could not be found at $this->feed_url";
1780
							SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1781
							return false;
1782
						}
1783
					}
1784
				}
1785
			}
1786
			// We have an error, just set SimplePie::error to it and quit
1787
			$this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1788
			SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1789
			return false;
1790
		}
1791
		elseif (!empty($this->multifeed_url))
1792
		{
1793
			$i = 0;
1794
			$success = 0;
1795
			$this->multifeed_objects = array();
1796
			foreach ($this->multifeed_url as $url)
1797
			{
1798
				if (SIMPLEPIE_PHP5)
1799
				{
1800
					// This keyword needs to defy coding standards for PHP4 compatibility
1801
					$this->multifeed_objects[$i] = clone($this);
1802
				}
1803
				else
1804
				{
1805
					$this->multifeed_objects[$i] = $this;
1806
				}
1807
				$this->multifeed_objects[$i]->set_feed_url($url);
1808
				$success |= $this->multifeed_objects[$i]->init();
1809
				$i++;
1810
			}
1811
			return (bool) $success;
1812
		}
1813
		else
1814
		{
1815
			return false;
1816
		}
1817
	}
1818
1819
	/**
1820 ab9dc5be Chris Buechler
	 * Return the error message for the occurred error
1821 b2e02eef Scott Ullrich
	 *
1822
	 * @access public
1823
	 * @return string Error message
1824
	 */
1825
	function error()
1826
	{
1827
		return $this->error;
1828
	}
1829
1830
	function get_encoding()
1831
	{
1832
		return $this->sanitize->output_encoding;
1833
	}
1834
1835
	function handle_content_type($mime = 'text/html')
1836
	{
1837
		if (!headers_sent())
1838
		{
1839
			$header = "Content-type: $mime;";
1840
			if ($this->get_encoding())
1841
			{
1842
				$header .= ' charset=' . $this->get_encoding();
1843
			}
1844
			else
1845
			{
1846
				$header .= ' charset=UTF-8';
1847
			}
1848
			header($header);
1849
		}
1850
	}
1851
1852
	function get_type()
1853
	{
1854
		if (!isset($this->data['type']))
1855
		{
1856
			$this->data['type'] = SIMPLEPIE_TYPE_ALL;
1857
			if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1858
			{
1859
				$this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1860
			}
1861
			elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1862
			{
1863
				$this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1864
			}
1865
			elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1866
			{
1867
				if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1868
				|| isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1869
				|| isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1870
				|| isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1871
				{
1872
					$this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1873
				}
1874
				if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1875
				|| isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1876
				|| isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1877
				|| isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1878
				{
1879
					$this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1880
				}
1881
			}
1882
			elseif (isset($this->data['child']['']['rss']))
1883
			{
1884
				$this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1885
				if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1886
				{
1887
					switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1888
					{
1889
						case '0.91':
1890
							$this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1891
							if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1892
							{
1893
								switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1894
								{
1895
									case '0':
1896
										$this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1897
										break;
1898
1899
									case '24':
1900
										$this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1901
										break;
1902
								}
1903
							}
1904
							break;
1905
1906
						case '0.92':
1907
							$this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1908
							break;
1909
1910
						case '0.93':
1911
							$this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1912
							break;
1913
1914
						case '0.94':
1915
							$this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1916
							break;
1917
1918
						case '2.0':
1919
							$this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1920
							break;
1921
					}
1922
				}
1923
			}
1924
			else
1925
			{
1926
				$this->data['type'] = SIMPLEPIE_TYPE_NONE;
1927
			}
1928
		}
1929
		return $this->data['type'];
1930
	}
1931
1932
	/**
1933
	 * Returns the URL for the favicon of the feed's website.
1934
	 *
1935
	 * @todo Cache atom:icon
1936
	 * @access public
1937
	 * @since 1.0
1938
	 */
1939
	function get_favicon()
1940
	{
1941
		if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1942
		{
1943
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1944
		}
1945
		elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1946
		{
1947
			$favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1948
1949
			if ($this->cache && $this->favicon_handler)
1950
			{
1951
				$favicon_filename = call_user_func($this->cache_name_function, $favicon);
1952
				$cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1953
1954
				if ($cache->load())
1955
				{
1956
					return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1957
				}
1958
				else
1959
				{
1960 23ca5695 Chris Buechler
					$file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1961 b2e02eef Scott Ullrich
1962
					if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1963
					{
1964
						$sniffer = new $this->content_type_sniffer_class($file);
1965
						if (substr($sniffer->get_type(), 0, 6) === 'image/')
1966
						{
1967
							if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1968
							{
1969
								return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1970
							}
1971
							else
1972
							{
1973
								trigger_error("$cache->name is not writeable", E_USER_WARNING);
1974
								return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1975
							}
1976
						}
1977
					}
1978
				}
1979
			}
1980
			else
1981
			{
1982
				return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1983
			}
1984
		}
1985
		return false;
1986
	}
1987
1988
	/**
1989
	 * @todo If we have a perm redirect we should return the new URL
1990
	 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1991
	 * @todo Also, |atom:link|@rel=self
1992
	 */
1993
	function subscribe_url()
1994
	{
1995
		if ($this->feed_url !== null)
1996
		{
1997
			return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1998
		}
1999
		else
2000
		{
2001
			return null;
2002
		}
2003
	}
2004
2005
	function subscribe_feed()
2006
	{
2007
		if ($this->feed_url !== null)
2008
		{
2009
			return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2010
		}
2011
		else
2012
		{
2013
			return null;
2014
		}
2015
	}
2016
2017
	function subscribe_outlook()
2018
	{
2019
		if ($this->feed_url !== null)
2020
		{
2021
			return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2022
		}
2023
		else
2024
		{
2025
			return null;
2026
		}
2027
	}
2028
2029
	function subscribe_podcast()
2030
	{
2031
		if ($this->feed_url !== null)
2032
		{
2033
			return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2034
		}
2035
		else
2036
		{
2037
			return null;
2038
		}
2039
	}
2040
2041
	function subscribe_itunes()
2042
	{
2043
		if ($this->feed_url !== null)
2044
		{
2045
			return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2046
		}
2047
		else
2048
		{
2049
			return null;
2050
		}
2051
	}
2052
2053
	/**
2054
	 * Creates the subscribe_* methods' return data
2055
	 *
2056
	 * @access private
2057
	 * @param string $feed_url String to prefix to the feed URL
2058
	 * @param string $site_url String to prefix to the site URL (and
2059
	 * suffix to the feed URL)
2060
	 * @return mixed URL if feed exists, false otherwise
2061
	 */
2062
	function subscribe_service($feed_url, $site_url = null)
2063
	{
2064
		if ($this->subscribe_url())
2065
		{
2066
			$return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2067
			if ($site_url !== null && $this->get_link() !== null)
2068
			{
2069
				$return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2070
			}
2071
			return $return;
2072
		}
2073
		else
2074
		{
2075
			return null;
2076
		}
2077
	}
2078
2079
	function subscribe_aol()
2080
	{
2081
		return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2082
	}
2083
2084
	function subscribe_bloglines()
2085
	{
2086
		return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2087
	}
2088
2089
	function subscribe_eskobo()
2090
	{
2091
		return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2092
	}
2093
2094
	function subscribe_feedfeeds()
2095
	{
2096
		return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2097
	}
2098
2099
	function subscribe_feedster()
2100
	{
2101
		return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2102
	}
2103
2104
	function subscribe_google()
2105
	{
2106
		return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2107
	}
2108
2109
	function subscribe_gritwire()
2110
	{
2111
		return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2112
	}
2113
2114
	function subscribe_msn()
2115
	{
2116
		return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2117
	}
2118
2119
	function subscribe_netvibes()
2120
	{
2121
		return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2122
	}
2123
2124
	function subscribe_newsburst()
2125
	{
2126
		return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2127
	}
2128
2129
	function subscribe_newsgator()
2130
	{
2131
		return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2132
	}
2133
2134
	function subscribe_odeo()
2135
	{
2136
		return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2137
	}
2138
2139
	function subscribe_podnova()
2140
	{
2141
		return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2142
	}
2143
2144
	function subscribe_rojo()
2145
	{
2146
		return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2147
	}
2148
2149
	function subscribe_yahoo()
2150
	{
2151
		return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2152
	}
2153
2154
	function get_feed_tags($namespace, $tag)
2155
	{
2156
		$type = $this->get_type();
2157
		if ($type & SIMPLEPIE_TYPE_ATOM_10)
2158
		{
2159
			if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2160
			{
2161
				return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2162
			}
2163
		}
2164
		if ($type & SIMPLEPIE_TYPE_ATOM_03)
2165
		{
2166
			if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2167
			{
2168
				return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2169
			}
2170
		}
2171
		if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2172
		{
2173
			if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2174
			{
2175
				return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2176
			}
2177
		}
2178
		if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2179
		{
2180
			if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2181
			{
2182
				return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2183
			}
2184
		}
2185
		return null;
2186
	}
2187
2188
	function get_channel_tags($namespace, $tag)
2189
	{
2190
		$type = $this->get_type();
2191
		if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2192
		{
2193
			if ($return = $this->get_feed_tags($namespace, $tag))
2194
			{
2195
				return $return;
2196
			}
2197
		}
2198
		if ($type & SIMPLEPIE_TYPE_RSS_10)
2199
		{
2200
			if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2201
			{
2202
				if (isset($channel[0]['child'][$namespace][$tag]))
2203
				{
2204
					return $channel[0]['child'][$namespace][$tag];
2205
				}
2206
			}
2207
		}
2208
		if ($type & SIMPLEPIE_TYPE_RSS_090)
2209
		{
2210
			if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2211
			{
2212
				if (isset($channel[0]['child'][$namespace][$tag]))
2213
				{
2214
					return $channel[0]['child'][$namespace][$tag];
2215
				}
2216
			}
2217
		}
2218
		if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2219
		{
2220
			if ($channel = $this->get_feed_tags('', 'channel'))
2221
			{
2222
				if (isset($channel[0]['child'][$namespace][$tag]))
2223
				{
2224
					return $channel[0]['child'][$namespace][$tag];
2225
				}
2226
			}
2227
		}
2228
		return null;
2229
	}
2230
2231
	function get_image_tags($namespace, $tag)
2232
	{
2233
		$type = $this->get_type();
2234
		if ($type & SIMPLEPIE_TYPE_RSS_10)
2235
		{
2236
			if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2237
			{
2238
				if (isset($image[0]['child'][$namespace][$tag]))
2239
				{
2240
					return $image[0]['child'][$namespace][$tag];
2241
				}
2242
			}
2243
		}
2244
		if ($type & SIMPLEPIE_TYPE_RSS_090)
2245
		{
2246
			if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2247
			{
2248
				if (isset($image[0]['child'][$namespace][$tag]))
2249
				{
2250
					return $image[0]['child'][$namespace][$tag];
2251
				}
2252
			}
2253
		}
2254
		if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2255
		{
2256
			if ($image = $this->get_channel_tags('', 'image'))
2257
			{
2258
				if (isset($image[0]['child'][$namespace][$tag]))
2259
				{
2260
					return $image[0]['child'][$namespace][$tag];
2261
				}
2262
			}
2263
		}
2264
		return null;
2265
	}
2266
2267
	function get_base($element = array())
2268
	{
2269
		if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2270
		{
2271
			return $element['xml_base'];
2272
		}
2273
		elseif ($this->get_link() !== null)
2274
		{
2275
			return $this->get_link();
2276
		}
2277
		else
2278
		{
2279
			return $this->subscribe_url();
2280
		}
2281
	}
2282
2283
	function sanitize($data, $type, $base = '')
2284
	{
2285
		return $this->sanitize->sanitize($data, $type, $base);
2286
	}
2287
2288
	function get_title()
2289
	{
2290
		if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2291
		{
2292
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2293
		}
2294
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2295
		{
2296
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2297
		}
2298
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2299
		{
2300
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2301
		}
2302
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2303
		{
2304
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2305
		}
2306
		elseif ($return = $this->get_channel_tags('', 'title'))
2307
		{
2308
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2309
		}
2310
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2311
		{
2312
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2313
		}
2314
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2315
		{
2316
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2317
		}
2318
		else
2319
		{
2320
			return null;
2321
		}
2322
	}
2323
2324
	function get_category($key = 0)
2325
	{
2326
		$categories = $this->get_categories();
2327
		if (isset($categories[$key]))
2328
		{
2329
			return $categories[$key];
2330
		}
2331
		else
2332
		{
2333
			return null;
2334
		}
2335
	}
2336
2337
	function get_categories()
2338
	{
2339
		$categories = array();
2340
2341
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2342
		{
2343
			$term = null;
2344
			$scheme = null;
2345
			$label = null;
2346
			if (isset($category['attribs']['']['term']))
2347
			{
2348
				$term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2349
			}
2350
			if (isset($category['attribs']['']['scheme']))
2351
			{
2352
				$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2353
			}
2354
			if (isset($category['attribs']['']['label']))
2355
			{
2356
				$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2357
			}
2358 23ca5695 Chris Buechler
			$categories[] =& new $this->category_class($term, $scheme, $label);
2359 b2e02eef Scott Ullrich
		}
2360
		foreach ((array) $this->get_channel_tags('', 'category') as $category)
2361
		{
2362 23ca5695 Chris Buechler
			$categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2363 b2e02eef Scott Ullrich
		}
2364
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2365
		{
2366 23ca5695 Chris Buechler
			$categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2367 b2e02eef Scott Ullrich
		}
2368
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2369
		{
2370 23ca5695 Chris Buechler
			$categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2371 b2e02eef Scott Ullrich
		}
2372
2373
		if (!empty($categories))
2374
		{
2375
			return SimplePie_Misc::array_unique($categories);
2376
		}
2377
		else
2378
		{
2379
			return null;
2380
		}
2381
	}
2382
2383
	function get_author($key = 0)
2384
	{
2385
		$authors = $this->get_authors();
2386
		if (isset($authors[$key]))
2387
		{
2388
			return $authors[$key];
2389
		}
2390
		else
2391
		{
2392
			return null;
2393
		}
2394
	}
2395
2396
	function get_authors()
2397
	{
2398
		$authors = array();
2399
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2400
		{
2401
			$name = null;
2402
			$uri = null;
2403
			$email = null;
2404
			if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2405
			{
2406
				$name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2407
			}
2408
			if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2409
			{
2410
				$uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
2411
			}
2412
			if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2413
			{
2414
				$email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2415
			}
2416
			if ($name !== null || $email !== null || $uri !== null)
2417
			{
2418 23ca5695 Chris Buechler
				$authors[] =& new $this->author_class($name, $uri, $email);
2419 b2e02eef Scott Ullrich
			}
2420
		}
2421
		if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2422
		{
2423
			$name = null;
2424
			$url = null;
2425
			$email = null;
2426
			if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2427
			{
2428
				$name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2429
			}
2430
			if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2431
			{
2432
				$url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2433
			}
2434
			if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2435
			{
2436
				$email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2437
			}
2438
			if ($name !== null || $email !== null || $url !== null)
2439
			{
2440 23ca5695 Chris Buechler
				$authors[] =& new $this->author_class($name, $url, $email);
2441 b2e02eef Scott Ullrich
			}
2442
		}
2443
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2444
		{
2445 23ca5695 Chris Buechler
			$authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2446 b2e02eef Scott Ullrich
		}
2447
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2448
		{
2449 23ca5695 Chris Buechler
			$authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2450 b2e02eef Scott Ullrich
		}
2451
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2452
		{
2453 23ca5695 Chris Buechler
			$authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2454 b2e02eef Scott Ullrich
		}
2455
2456
		if (!empty($authors))
2457
		{
2458
			return SimplePie_Misc::array_unique($authors);
2459
		}
2460
		else
2461
		{
2462
			return null;
2463
		}
2464
	}
2465
2466
	function get_contributor($key = 0)
2467
	{
2468
		$contributors = $this->get_contributors();
2469
		if (isset($contributors[$key]))
2470
		{
2471
			return $contributors[$key];
2472
		}
2473
		else
2474
		{
2475
			return null;
2476
		}
2477
	}
2478
2479
	function get_contributors()
2480
	{
2481
		$contributors = array();
2482
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2483
		{
2484
			$name = null;
2485
			$uri = null;
2486
			$email = null;
2487
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2488
			{
2489
				$name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2490
			}
2491
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2492
			{
2493
				$uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
2494
			}
2495
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2496
			{
2497
				$email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2498
			}
2499
			if ($name !== null || $email !== null || $uri !== null)
2500
			{
2501 23ca5695 Chris Buechler
				$contributors[] =& new $this->author_class($name, $uri, $email);
2502 b2e02eef Scott Ullrich
			}
2503
		}
2504
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2505
		{
2506
			$name = null;
2507
			$url = null;
2508
			$email = null;
2509
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2510
			{
2511
				$name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2512
			}
2513
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2514
			{
2515
				$url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2516
			}
2517
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2518
			{
2519
				$email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2520
			}
2521
			if ($name !== null || $email !== null || $url !== null)
2522
			{
2523 23ca5695 Chris Buechler
				$contributors[] =& new $this->author_class($name, $url, $email);
2524 b2e02eef Scott Ullrich
			}
2525
		}
2526
2527
		if (!empty($contributors))
2528
		{
2529
			return SimplePie_Misc::array_unique($contributors);
2530
		}
2531
		else
2532
		{
2533
			return null;
2534
		}
2535
	}
2536
2537
	function get_link($key = 0, $rel = 'alternate')
2538
	{
2539
		$links = $this->get_links($rel);
2540
		if (isset($links[$key]))
2541
		{
2542
			return $links[$key];
2543
		}
2544
		else
2545
		{
2546
			return null;
2547
		}
2548
	}
2549
2550
	/**
2551
	 * Added for parity between the parent-level and the item/entry-level.
2552
	 */
2553
	function get_permalink()
2554
	{
2555
		return $this->get_link(0);
2556
	}
2557
2558
	function get_links($rel = 'alternate')
2559
	{
2560
		if (!isset($this->data['links']))
2561
		{
2562
			$this->data['links'] = array();
2563
			if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2564
			{
2565
				foreach ($links as $link)
2566
				{
2567
					if (isset($link['attribs']['']['href']))
2568
					{
2569
						$link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2570
						$this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2571
					}
2572
				}
2573
			}
2574
			if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2575
			{
2576
				foreach ($links as $link)
2577
				{
2578
					if (isset($link['attribs']['']['href']))
2579
					{
2580
						$link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2581
						$this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2582
2583
					}
2584
				}
2585
			}
2586
			if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2587
			{
2588
				$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2589
			}
2590
			if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2591
			{
2592
				$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2593
			}
2594
			if ($links = $this->get_channel_tags('', 'link'))
2595
			{
2596
				$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2597
			}
2598
2599
			$keys = array_keys($this->data['links']);
2600
			foreach ($keys as $key)
2601
			{
2602
				if (SimplePie_Misc::is_isegment_nz_nc($key))
2603
				{
2604
					if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2605
					{
2606
						$this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2607
						$this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2608
					}
2609
					else
2610
					{
2611
						$this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2612
					}
2613
				}
2614
				elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2615
				{
2616
					$this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2617
				}
2618
				$this->data['links'][$key] = array_unique($this->data['links'][$key]);
2619
			}
2620
		}
2621
2622
		if (isset($this->data['links'][$rel]))
2623
		{
2624
			return $this->data['links'][$rel];
2625
		}
2626
		else
2627
		{
2628
			return null;
2629
		}
2630
	}
2631
2632
	function get_description()
2633
	{
2634
		if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2635
		{
2636
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2637
		}
2638
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2639
		{
2640
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2641
		}
2642
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2643
		{
2644
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2645
		}
2646
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2647
		{
2648
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2649
		}
2650
		elseif ($return = $this->get_channel_tags('', 'description'))
2651
		{
2652
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2653
		}
2654
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2655
		{
2656
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2657
		}
2658
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2659
		{
2660
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2661
		}
2662
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2663
		{
2664
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2665
		}
2666
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2667
		{
2668
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2669
		}
2670
		else
2671
		{
2672
			return null;
2673
		}
2674
	}
2675
2676
	function get_copyright()
2677
	{
2678
		if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2679
		{
2680
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2681
		}
2682
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2683
		{
2684
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2685
		}
2686
		elseif ($return = $this->get_channel_tags('', 'copyright'))
2687
		{
2688
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2689
		}
2690
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2691
		{
2692
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2693
		}
2694
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2695
		{
2696
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2697
		}
2698
		else
2699
		{
2700
			return null;
2701
		}
2702
	}
2703
2704
	function get_language()
2705
	{
2706
		if ($return = $this->get_channel_tags('', 'language'))
2707
		{
2708
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2709
		}
2710
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2711
		{
2712
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2713
		}
2714
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2715
		{
2716
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2717
		}
2718
		elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2719
		{
2720
			return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2721
		}
2722
		elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2723
		{
2724
			return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2725
		}
2726
		elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2727
		{
2728
			return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2729
		}
2730
		elseif (isset($this->data['headers']['content-language']))
2731
		{
2732
			return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2733
		}
2734
		else
2735
		{
2736
			return null;
2737
		}
2738
	}
2739
2740
	function get_latitude()
2741
	{
2742
		if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2743
		{
2744
			return (float) $return[0]['data'];
2745
		}
2746
		elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2747
		{
2748
			return (float) $match[1];
2749
		}
2750
		else
2751
		{
2752
			return null;
2753
		}
2754
	}
2755
2756
	function get_longitude()
2757
	{
2758
		if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2759
		{
2760
			return (float) $return[0]['data'];
2761
		}
2762
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2763
		{
2764
			return (float) $return[0]['data'];
2765
		}
2766
		elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2767
		{
2768
			return (float) $match[2];
2769
		}
2770
		else
2771
		{
2772
			return null;
2773
		}
2774
	}
2775
2776
	function get_image_title()
2777
	{
2778
		if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2779
		{
2780
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2781
		}
2782
		elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2783
		{
2784
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2785
		}
2786
		elseif ($return = $this->get_image_tags('', 'title'))
2787
		{
2788
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2789
		}
2790
		elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2791
		{
2792
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2793
		}
2794
		elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2795
		{
2796
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2797
		}
2798
		else
2799
		{
2800
			return null;
2801
		}
2802
	}
2803
2804
	function get_image_url()
2805
	{
2806
		if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2807
		{
2808
			return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2809
		}
2810
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2811
		{
2812
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2813
		}
2814
		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2815
		{
2816
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2817
		}
2818
		elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2819
		{
2820
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2821
		}
2822
		elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2823
		{
2824
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2825
		}
2826
		elseif ($return = $this->get_image_tags('', 'url'))
2827
		{
2828
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2829
		}
2830
		else
2831
		{
2832
			return null;
2833
		}
2834
	}
2835
2836
	function get_image_link()
2837
	{
2838
		if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2839
		{
2840
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2841
		}
2842
		elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2843
		{
2844
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2845
		}
2846
		elseif ($return = $this->get_image_tags('', 'link'))
2847
		{
2848
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2849
		}
2850
		else
2851
		{
2852
			return null;
2853
		}
2854
	}
2855
2856
	function get_image_width()
2857
	{
2858
		if ($return = $this->get_image_tags('', 'width'))
2859
		{
2860
			return round($return[0]['data']);
2861
		}
2862
		elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2863
		{
2864
			return 88.0;
2865
		}
2866
		else
2867
		{
2868
			return null;
2869
		}
2870
	}
2871
2872
	function get_image_height()
2873
	{
2874
		if ($return = $this->get_image_tags('', 'height'))
2875
		{
2876
			return round($return[0]['data']);
2877
		}
2878
		elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2879
		{
2880
			return 31.0;
2881
		}
2882
		else
2883
		{
2884
			return null;
2885
		}
2886
	}
2887
2888
	function get_item_quantity($max = 0)
2889
	{
2890
		$qty = count($this->get_items());
2891
		if ($max == 0)
2892
		{
2893
			return $qty;
2894
		}
2895
		else
2896
		{
2897
			return ($qty > $max) ? $max : $qty;
2898
		}
2899
	}
2900
2901
	function get_item($key = 0)
2902
	{
2903
		$items = $this->get_items();
2904
		if (isset($items[$key]))
2905
		{
2906
			return $items[$key];
2907
		}
2908
		else
2909
		{
2910
			return null;
2911
		}
2912
	}
2913
2914
	function get_items($start = 0, $end = 0)
2915
	{
2916
		if (!empty($this->multifeed_objects))
2917
		{
2918
			return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2919
		}
2920
		elseif (!isset($this->data['items']))
2921
		{
2922
			if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2923
			{
2924
				$keys = array_keys($items);
2925
				foreach ($keys as $key)
2926
				{
2927 23ca5695 Chris Buechler
					$this->data['items'][] =& new $this->item_class($this, $items[$key]);
2928 b2e02eef Scott Ullrich
				}
2929
			}
2930
			if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2931
			{
2932
				$keys = array_keys($items);
2933
				foreach ($keys as $key)
2934
				{
2935 23ca5695 Chris Buechler
					$this->data['items'][] =& new $this->item_class($this, $items[$key]);
2936 b2e02eef Scott Ullrich
				}
2937
			}
2938
			if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2939
			{
2940
				$keys = array_keys($items);
2941
				foreach ($keys as $key)
2942
				{
2943 23ca5695 Chris Buechler
					$this->data['items'][] =& new $this->item_class($this, $items[$key]);
2944 b2e02eef Scott Ullrich
				}
2945
			}
2946
			if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2947
			{
2948
				$keys = array_keys($items);
2949
				foreach ($keys as $key)
2950
				{
2951 23ca5695 Chris Buechler
					$this->data['items'][] =& new $this->item_class($this, $items[$key]);
2952 b2e02eef Scott Ullrich
				}
2953
			}
2954
			if ($items = $this->get_channel_tags('', 'item'))
2955
			{
2956
				$keys = array_keys($items);
2957
				foreach ($keys as $key)
2958
				{
2959 23ca5695 Chris Buechler
					$this->data['items'][] =& new $this->item_class($this, $items[$key]);
2960 b2e02eef Scott Ullrich
				}
2961
			}
2962
		}
2963
2964
		if (!empty($this->data['items']))
2965
		{
2966
			// If we want to order it by date, check if all items have a date, and then sort it
2967
			if ($this->order_by_date)
2968
			{
2969
				if (!isset($this->data['ordered_items']))
2970
				{
2971
					$do_sort = true;
2972
					foreach ($this->data['items'] as $item)
2973
					{
2974
						if (!$item->get_date('U'))
2975
						{
2976
							$do_sort = false;
2977
							break;
2978
						}
2979
					}
2980
					$item = null;
2981
					$this->data['ordered_items'] = $this->data['items'];
2982
					if ($do_sort)
2983
					{
2984
						usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2985
					}
2986
				}
2987
				$items = $this->data['ordered_items'];
2988
			}
2989
			else
2990
			{
2991
				$items = $this->data['items'];
2992
			}
2993
2994
			// Slice the data as desired
2995
			if ($end == 0)
2996
			{
2997
				return array_slice($items, $start);
2998
			}
2999
			else
3000
			{
3001
				return array_slice($items, $start, $end);
3002
			}
3003
		}
3004
		else
3005
		{
3006
			return array();
3007
		}
3008
	}
3009
3010
	function sort_items($a, $b)
3011
	{
3012
		return $a->get_date('U') <= $b->get_date('U');
3013
	}
3014
3015
	function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3016
	{
3017
		if (is_array($urls) && sizeof($urls) > 0)
3018
		{
3019
			$items = array();
3020
			foreach ($urls as $arg)
3021
			{
3022
				if (is_a($arg, 'SimplePie'))
3023
				{
3024
					$items = array_merge($items, $arg->get_items(0, $limit));
3025
				}
3026
				else
3027
				{
3028
					trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3029
				}
3030
			}
3031
3032
			$do_sort = true;
3033
			foreach ($items as $item)
3034
			{
3035
				if (!$item->get_date('U'))
3036
				{
3037
					$do_sort = false;
3038
					break;
3039
				}
3040
			}
3041
			$item = null;
3042
			if ($do_sort)
3043
			{
3044
				usort($items, array('SimplePie', 'sort_items'));
3045
			}
3046
3047
			if ($end == 0)
3048
			{
3049
				return array_slice($items, $start);
3050
			}
3051
			else
3052
			{
3053
				return array_slice($items, $start, $end);
3054
			}
3055
		}
3056
		else
3057
		{
3058
			trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3059
			return array();
3060
		}
3061
	}
3062
}
3063
3064
class SimplePie_Item
3065
{
3066
	var $feed;
3067
	var $data = array();
3068
3069
	function SimplePie_Item($feed, $data)
3070
	{
3071
		$this->feed = $feed;
3072
		$this->data = $data;
3073
	}
3074
3075
	function __toString()
3076
	{
3077
		return md5(serialize($this->data));
3078
	}
3079
3080
	/**
3081
	 * Remove items that link back to this before destroying this object
3082
	 */
3083
	function __destruct()
3084
	{
3085
		unset($this->feed);
3086
	}
3087
3088
	function get_item_tags($namespace, $tag)
3089
	{
3090
		if (isset($this->data['child'][$namespace][$tag]))
3091
		{
3092
			return $this->data['child'][$namespace][$tag];
3093
		}
3094
		else
3095
		{
3096
			return null;
3097
		}
3098
	}
3099
3100
	function get_base($element = array())
3101
	{
3102
		return $this->feed->get_base($element);
3103
	}
3104
3105
	function sanitize($data, $type, $base = '')
3106
	{
3107
		return $this->feed->sanitize($data, $type, $base);
3108
	}
3109
3110
	function get_feed()
3111
	{
3112
		return $this->feed;
3113
	}
3114
3115
	function get_id($hash = false)
3116
	{
3117
		if (!$hash)
3118
		{
3119
			if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3120
			{
3121
				return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3122
			}
3123
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3124
			{
3125
				return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3126
			}
3127
			elseif ($return = $this->get_item_tags('', 'guid'))
3128
			{
3129
				return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3130
			}
3131
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3132
			{
3133
				return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3134
			}
3135
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3136
			{
3137
				return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3138
			}
3139
			elseif (($return = $this->get_permalink()) !== null)
3140
			{
3141
				return $return;
3142
			}
3143
			elseif (($return = $this->get_title()) !== null)
3144
			{
3145
				return $return;
3146
			}
3147
		}
3148
		if ($this->get_permalink() !== null || $this->get_title() !== null)
3149
		{
3150
			return md5($this->get_permalink() . $this->get_title());
3151
		}
3152
		else
3153
		{
3154
			return md5(serialize($this->data));
3155
		}
3156
	}
3157
3158
	function get_title()
3159
	{
3160
		if (!isset($this->data['title']))
3161
		{
3162
			if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3163
			{
3164
				$this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3165
			}
3166
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3167
			{
3168
				$this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3169
			}
3170
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3171
			{
3172
				$this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3173
			}
3174
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3175
			{
3176
				$this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3177
			}
3178
			elseif ($return = $this->get_item_tags('', 'title'))
3179
			{
3180
				$this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3181
			}
3182
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3183
			{
3184
				$this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3185
			}
3186
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3187
			{
3188
				$this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3189
			}
3190
			else
3191
			{
3192
				$this->data['title'] = null;
3193
			}
3194
		}
3195
		return $this->data['title'];
3196
	}
3197
3198
	function get_description($description_only = false)
3199
	{
3200
		if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3201
		{
3202
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3203
		}
3204
		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3205
		{
3206
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3207
		}
3208
		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3209
		{
3210
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3211
		}
3212
		elseif ($return = $this->get_item_tags('', 'description'))
3213
		{
3214
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3215
		}
3216
		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3217
		{
3218
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3219
		}
3220
		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3221
		{
3222
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3223
		}
3224
		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3225
		{
3226
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3227
		}
3228
		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3229
		{
3230
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3231
		}
3232
		elseif (!$description_only)
3233
		{
3234
			return $this->get_content(true);
3235
		}
3236
		else
3237
		{
3238
			return null;
3239
		}
3240
	}
3241
3242
	function get_content($content_only = false)
3243
	{
3244
		if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3245
		{
3246
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3247
		}
3248
		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3249
		{
3250
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3251
		}
3252
		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3253
		{
3254
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3255
		}
3256
		elseif (!$content_only)
3257
		{
3258
			return $this->get_description(true);
3259
		}
3260
		else
3261
		{
3262
			return null;
3263
		}
3264
	}
3265
3266
	function get_category($key = 0)
3267
	{
3268
		$categories = $this->get_categories();
3269
		if (isset($categories[$key]))
3270
		{
3271
			return $categories[$key];
3272
		}
3273
		else
3274
		{
3275
			return null;
3276
		}
3277
	}
3278
3279
	function get_categories()
3280
	{
3281
		$categories = array();
3282
3283
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3284
		{
3285
			$term = null;
3286
			$scheme = null;
3287
			$label = null;
3288
			if (isset($category['attribs']['']['term']))
3289
			{
3290
				$term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3291
			}
3292
			if (isset($category['attribs']['']['scheme']))
3293
			{
3294
				$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3295
			}
3296
			if (isset($category['attribs']['']['label']))
3297
			{
3298
				$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3299
			}
3300 23ca5695 Chris Buechler
			$categories[] =& new $this->feed->category_class($term, $scheme, $label);
3301 b2e02eef Scott Ullrich
		}
3302
		foreach ((array) $this->get_item_tags('', 'category') as $category)
3303
		{
3304 23ca5695 Chris Buechler
			$categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3305 b2e02eef Scott Ullrich
		}
3306
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3307
		{
3308 23ca5695 Chris Buechler
			$categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3309 b2e02eef Scott Ullrich
		}
3310
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3311
		{
3312 23ca5695 Chris Buechler
			$categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3313 b2e02eef Scott Ullrich
		}
3314
3315
		if (!empty($categories))
3316
		{
3317
			return SimplePie_Misc::array_unique($categories);
3318
		}
3319
		else
3320
		{
3321
			return null;
3322
		}
3323
	}
3324
3325
	function get_author($key = 0)
3326
	{
3327
		$authors = $this->get_authors();
3328
		if (isset($authors[$key]))
3329
		{
3330
			return $authors[$key];
3331
		}
3332
		else
3333
		{
3334
			return null;
3335
		}
3336
	}
3337
3338
	function get_contributor($key = 0)
3339
	{
3340
		$contributors = $this->get_contributors();
3341
		if (isset($contributors[$key]))
3342
		{
3343
			return $contributors[$key];
3344
		}
3345
		else
3346
		{
3347
			return null;
3348
		}
3349
	}
3350
3351
	function get_contributors()
3352
	{
3353
		$contributors = array();
3354
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3355
		{
3356
			$name = null;
3357
			$uri = null;
3358
			$email = null;
3359
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3360
			{
3361
				$name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3362
			}
3363
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3364
			{
3365
				$uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
3366
			}
3367
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3368
			{
3369
				$email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3370
			}
3371
			if ($name !== null || $email !== null || $uri !== null)
3372
			{
3373 23ca5695 Chris Buechler
				$contributors[] =& new $this->feed->author_class($name, $uri, $email);
3374 b2e02eef Scott Ullrich
			}
3375
		}
3376
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3377
		{
3378
			$name = null;
3379
			$url = null;
3380
			$email = null;
3381
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3382
			{
3383
				$name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3384
			}
3385
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3386
			{
3387
				$url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
3388
			}
3389
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3390
			{
3391
				$email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3392
			}
3393
			if ($name !== null || $email !== null || $url !== null)
3394
			{
3395 23ca5695 Chris Buechler
				$contributors[] =& new $this->feed->author_class($name, $url, $email);
3396 b2e02eef Scott Ullrich
			}
3397
		}
3398
3399
		if (!empty($contributors))
3400
		{
3401
			return SimplePie_Misc::array_unique($contributors);
3402
		}
3403
		else
3404
		{
3405
			return null;
3406
		}
3407
	}
3408
3409
	/**
3410
	 * @todo Atom inheritance (item author, source author, feed author)
3411
	 */
3412
	function get_authors()
3413
	{
3414
		$authors = array();
3415
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3416
		{
3417
			$name = null;
3418
			$uri = null;
3419
			$email = null;
3420
			if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3421
			{
3422
				$name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3423
			}
3424
			if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3425
			{
3426
				$uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
3427
			}
3428
			if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3429
			{
3430
				$email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3431
			}
3432
			if ($name !== null || $email !== null || $uri !== null)
3433
			{
3434 23ca5695 Chris Buechler
				$authors[] =& new $this->feed->author_class($name, $uri, $email);
3435 b2e02eef Scott Ullrich
			}
3436
		}
3437
		if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3438
		{
3439
			$name = null;
3440
			$url = null;
3441
			$email = null;
3442
			if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3443
			{
3444
				$name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3445
			}
3446
			if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3447
			{
3448
				$url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
3449
			}
3450
			if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3451
			{
3452
				$email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3453
			}
3454
			if ($name !== null || $email !== null || $url !== null)
3455
			{
3456 23ca5695 Chris Buechler
				$authors[] =& new $this->feed->author_class($name, $url, $email);
3457 b2e02eef Scott Ullrich
			}
3458
		}
3459
		if ($author = $this->get_item_tags('', 'author'))
3460
		{
3461 23ca5695 Chris Buechler
			$authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3462 b2e02eef Scott Ullrich
		}
3463
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3464
		{
3465 23ca5695 Chris Buechler
			$authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3466 b2e02eef Scott Ullrich
		}
3467
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3468
		{
3469 23ca5695 Chris Buechler
			$authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3470 b2e02eef Scott Ullrich
		}
3471
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3472
		{
3473 23ca5695 Chris Buechler
			$authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3474 b2e02eef Scott Ullrich
		}
3475
3476
		if (!empty($authors))
3477
		{
3478
			return SimplePie_Misc::array_unique($authors);
3479
		}
3480
		elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3481
		{
3482
			return $authors;
3483
		}
3484
		elseif ($authors = $this->feed->get_authors())
3485
		{
3486
			return $authors;
3487
		}
3488
		else
3489
		{
3490
			return null;
3491
		}
3492
	}
3493
3494
	function get_copyright()
3495
	{
3496
		if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3497
		{
3498
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3499
		}
3500
		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3501
		{
3502
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3503
		}
3504
		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3505
		{
3506
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3507
		}
3508
		else
3509
		{
3510
			return null;
3511
		}
3512
	}
3513
3514
	function get_date($date_format = 'j F Y, g:i a')
3515
	{
3516
		if (!isset($this->data['date']))
3517
		{
3518
			if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3519
			{
3520
				$this->data['date']['raw'] = $return[0]['data'];
3521
			}
3522
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3523
			{
3524
				$this->data['date']['raw'] = $return[0]['data'];
3525
			}
3526
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3527
			{
3528
				$this->data['date']['raw'] = $return[0]['data'];
3529
			}
3530
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3531
			{
3532
				$this->data['date']['raw'] = $return[0]['data'];
3533
			}
3534
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3535
			{
3536
				$this->data['date']['raw'] = $return[0]['data'];
3537
			}
3538
			elseif ($return = $this->get_item_tags('', 'pubDate'))
3539
			{
3540
				$this->data['date']['raw'] = $return[0]['data'];
3541
			}
3542
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3543
			{
3544
				$this->data['date']['raw'] = $return[0]['data'];
3545
			}
3546
			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3547
			{
3548
				$this->data['date']['raw'] = $return[0]['data'];
3549
			}
3550
3551
			if (!empty($this->data['date']['raw']))
3552
			{
3553
				$parser = SimplePie_Parse_Date::get();
3554
				$this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3555
			}
3556
			else
3557
			{
3558
				$this->data['date'] = null;
3559
			}
3560
		}
3561
		if ($this->data['date'])
3562
		{
3563
			$date_format = (string) $date_format;
3564
			switch ($date_format)
3565
			{
3566
				case '':
3567
					return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3568
3569
				case 'U':
3570
					return $this->data['date']['parsed'];
3571
3572
				default:
3573
					return date($date_format, $this->data['date']['parsed']);
3574
			}
3575
		}
3576
		else
3577
		{
3578
			return null;
3579
		}
3580
	}
3581
3582
	function get_local_date($date_format = '%c')
3583
	{
3584
		if (!$date_format)
3585
		{
3586
			return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3587
		}
3588
		elseif (($date = $this->get_date('U')) !== null)
3589
		{
3590
			return strftime($date_format, $date);
3591
		}
3592
		else
3593
		{
3594
			return null;
3595
		}
3596
	}
3597
3598
	function get_permalink()
3599
	{
3600
		$link = $this->get_link();
3601
		$enclosure = $this->get_enclosure(0);
3602
		if ($link !== null)
3603
		{
3604
			return $link;
3605
		}
3606
		elseif ($enclosure !== null)
3607
		{
3608
			return $enclosure->get_link();
3609
		}
3610
		else
3611
		{
3612
			return null;
3613
		}
3614
	}
3615
3616
	function get_link($key = 0, $rel = 'alternate')
3617
	{
3618
		$links = $this->get_links($rel);
3619
		if ($links[$key] !== null)
3620
		{
3621
			return $links[$key];
3622
		}
3623
		else
3624
		{
3625
			return null;
3626
		}
3627
	}
3628
3629
	function get_links($rel = 'alternate')
3630
	{
3631
		if (!isset($this->data['links']))
3632
		{
3633
			$this->data['links'] = array();
3634
			foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3635
			{
3636
				if (isset($link['attribs']['']['href']))
3637
				{
3638
					$link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3639
					$this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3640
3641
				}
3642
			}
3643
			foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3644
			{
3645
				if (isset($link['attribs']['']['href']))
3646
				{
3647
					$link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3648
					$this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3649
				}
3650
			}
3651
			if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3652
			{
3653
				$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3654
			}
3655
			if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3656
			{
3657
				$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3658
			}
3659
			if ($links = $this->get_item_tags('', 'link'))
3660
			{
3661
				$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3662
			}
3663
			if ($links = $this->get_item_tags('', 'guid'))
3664
			{
3665
				if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3666
				{
3667
					$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3668
				}
3669
			}
3670
3671
			$keys = array_keys($this->data['links']);
3672
			foreach ($keys as $key)
3673
			{
3674
				if (SimplePie_Misc::is_isegment_nz_nc($key))
3675
				{
3676
					if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3677
					{
3678
						$this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3679
						$this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3680
					}
3681
					else
3682
					{
3683
						$this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3684
					}
3685
				}
3686
				elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3687
				{
3688
					$this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3689
				}
3690
				$this->data['links'][$key] = array_unique($this->data['links'][$key]);
3691
			}
3692
		}
3693
		if (isset($this->data['links'][$rel]))
3694
		{
3695
			return $this->data['links'][$rel];
3696
		}
3697
		else
3698
		{
3699
			return null;
3700
		}
3701
	}
3702
3703
	/**
3704
	 * @todo Add ability to prefer one type of content over another (in a media group).
3705
	 */
3706
	function get_enclosure($key = 0, $prefer = null)
3707
	{
3708
		$enclosures = $this->get_enclosures();
3709
		if (isset($enclosures[$key]))
3710
		{
3711
			return $enclosures[$key];
3712
		}
3713
		else
3714
		{
3715
			return null;
3716
		}
3717
	}
3718
3719
	/**
3720
	 * Grabs all available enclosures (podcasts, etc.)
3721
	 *
3722
	 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3723
	 *
3724
	 * At this point, we're pretty much assuming that all enclosures for an item are the same content.  Anything else is too complicated to properly support.
3725
	 *
3726
	 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3727
	 * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists).
3728
	 */
3729
	function get_enclosures()
3730
	{
3731
		if (!isset($this->data['enclosures']))
3732
		{
3733
			$this->data['enclosures'] = array();
3734
3735
			// Elements
3736
			$captions_parent = null;
3737
			$categories_parent = null;
3738
			$copyrights_parent = null;
3739
			$credits_parent = null;
3740
			$description_parent = null;
3741
			$duration_parent = null;
3742
			$hashes_parent = null;
3743
			$keywords_parent = null;
3744
			$player_parent = null;
3745
			$ratings_parent = null;
3746
			$restrictions_parent = null;
3747
			$thumbnails_parent = null;
3748
			$title_parent = null;
3749
3750
			// Let's do the channel and item-level ones first, and just re-use them if we need to.
3751
			$parent = $this->get_feed();
3752
3753
			// CAPTIONS
3754
			if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3755
			{
3756
				foreach ($captions as $caption)
3757
				{
3758
					$caption_type = null;
3759
					$caption_lang = null;
3760
					$caption_startTime = null;
3761
					$caption_endTime = null;
3762
					$caption_text = null;
3763
					if (isset($caption['attribs']['']['type']))
3764
					{
3765
						$caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3766
					}
3767
					if (isset($caption['attribs']['']['lang']))
3768
					{
3769
						$caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3770
					}
3771
					if (isset($caption['attribs']['']['start']))
3772
					{
3773
						$caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3774
					}
3775
					if (isset($caption['attribs']['']['end']))
3776
					{
3777
						$caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3778
					}
3779
					if (isset($caption['data']))
3780
					{
3781
						$caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3782
					}
3783 23ca5695 Chris Buechler
					$captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3784 b2e02eef Scott Ullrich
				}
3785
			}
3786
			elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3787
			{
3788
				foreach ($captions as $caption)
3789
				{
3790
					$caption_type = null;
3791
					$caption_lang = null;
3792
					$caption_startTime = null;
3793
					$caption_endTime = null;
3794
					$caption_text = null;
3795
					if (isset($caption['attribs']['']['type']))
3796
					{
3797
						$caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3798
					}
3799
					if (isset($caption['attribs']['']['lang']))
3800
					{
3801
						$caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3802
					}
3803
					if (isset($caption['attribs']['']['start']))
3804
					{
3805
						$caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3806
					}
3807
					if (isset($caption['attribs']['']['end']))
3808
					{
3809
						$caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3810
					}
3811
					if (isset($caption['data']))
3812
					{
3813
						$caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3814
					}
3815 23ca5695 Chris Buechler
					$captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3816 b2e02eef Scott Ullrich
				}
3817
			}
3818
			if (is_array($captions_parent))
3819
			{
3820
				$captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3821
			}
3822
3823
			// CATEGORIES
3824
			foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3825
			{
3826
				$term = null;
3827
				$scheme = null;
3828
				$label = null;
3829
				if (isset($category['data']))
3830
				{
3831
					$term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3832
				}
3833
				if (isset($category['attribs']['']['scheme']))
3834
				{
3835
					$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3836
				}
3837
				else
3838
				{
3839
					$scheme = 'http://search.yahoo.com/mrss/category_schema';
3840
				}
3841
				if (isset($category['attribs']['']['label']))
3842
				{
3843
					$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3844
				}
3845 23ca5695 Chris Buechler
				$categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3846 b2e02eef Scott Ullrich
			}
3847
			foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3848
			{
3849
				$term = null;
3850
				$scheme = null;
3851
				$label = null;
3852
				if (isset($category['data']))
3853
				{
3854
					$term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3855
				}
3856
				if (isset($category['attribs']['']['scheme']))
3857
				{
3858
					$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3859
				}
3860
				else
3861
				{
3862
					$scheme = 'http://search.yahoo.com/mrss/category_schema';
3863
				}
3864
				if (isset($category['attribs']['']['label']))
3865
				{
3866
					$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3867
				}
3868 23ca5695 Chris Buechler
				$categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3869 b2e02eef Scott Ullrich
			}
3870
			foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3871
			{
3872
				$term = null;
3873
				$scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3874
				$label = null;
3875
				if (isset($category['attribs']['']['text']))
3876
				{
3877
					$label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3878
				}
3879 23ca5695 Chris Buechler
				$categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3880 b2e02eef Scott Ullrich
3881
				if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3882
				{
3883
					foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3884
					{
3885
						if (isset($subcategory['attribs']['']['text']))
3886
						{
3887
							$label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3888
						}
3889 23ca5695 Chris Buechler
						$categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3890 b2e02eef Scott Ullrich
					}
3891
				}
3892
			}
3893
			if (is_array($categories_parent))
3894
			{
3895
				$categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3896
			}
3897
3898
			// COPYRIGHT
3899
			if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3900
			{
3901
				$copyright_url = null;
3902
				$copyright_label = null;
3903
				if (isset($copyright[0]['attribs']['']['url']))
3904
				{
3905
					$copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3906
				}
3907
				if (isset($copyright[0]['data']))
3908
				{
3909
					$copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3910
				}
3911 23ca5695 Chris Buechler
				$copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3912 b2e02eef Scott Ullrich
			}
3913
			elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3914
			{
3915
				$copyright_url = null;
3916
				$copyright_label = null;
3917
				if (isset($copyright[0]['attribs']['']['url']))
3918
				{
3919
					$copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3920
				}
3921
				if (isset($copyright[0]['data']))
3922
				{
3923
					$copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3924
				}
3925 23ca5695 Chris Buechler
				$copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3926 b2e02eef Scott Ullrich
			}
3927
3928
			// CREDITS
3929
			if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3930
			{
3931
				foreach ($credits as $credit)
3932
				{
3933
					$credit_role = null;
3934
					$credit_scheme = null;
3935
					$credit_name = null;
3936
					if (isset($credit['attribs']['']['role']))
3937
					{
3938
						$credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3939
					}
3940
					if (isset($credit['attribs']['']['scheme']))
3941
					{
3942
						$credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3943
					}
3944
					else
3945
					{
3946
						$credit_scheme = 'urn:ebu';
3947
					}
3948
					if (isset($credit['data']))
3949
					{
3950
						$credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3951
					}
3952 23ca5695 Chris Buechler
					$credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3953 b2e02eef Scott Ullrich
				}
3954
			}
3955
			elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3956
			{
3957
				foreach ($credits as $credit)
3958
				{
3959
					$credit_role = null;
3960
					$credit_scheme = null;
3961
					$credit_name = null;
3962
					if (isset($credit['attribs']['']['role']))
3963
					{
3964
						$credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3965
					}
3966
					if (isset($credit['attribs']['']['scheme']))
3967
					{
3968
						$credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3969
					}
3970
					else
3971
					{
3972
						$credit_scheme = 'urn:ebu';
3973
					}
3974
					if (isset($credit['data']))
3975
					{
3976
						$credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3977
					}
3978 23ca5695 Chris Buechler
					$credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3979 b2e02eef Scott Ullrich
				}
3980
			}
3981
			if (is_array($credits_parent))
3982
			{
3983
				$credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3984
			}
3985
3986
			// DESCRIPTION
3987
			if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3988
			{
3989
				if (isset($description_parent[0]['data']))
3990
				{
3991
					$description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3992
				}
3993
			}
3994
			elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3995
			{
3996
				if (isset($description_parent[0]['data']))
3997
				{
3998
					$description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3999
				}
4000
			}
4001
4002
			// DURATION
4003
			if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
4004
			{
4005
				$seconds = null;
4006
				$minutes = null;
4007
				$hours = null;
4008
				if (isset($duration_parent[0]['data']))
4009
				{
4010
					$temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4011
					if (sizeof($temp) > 0)
4012
					{
4013
						(int) $seconds = array_pop($temp);
4014
					}
4015
					if (sizeof($temp) > 0)
4016
					{
4017
						(int) $minutes = array_pop($temp);
4018
						$seconds += $minutes * 60;
4019
					}
4020
					if (sizeof($temp) > 0)
4021
					{
4022
						(int) $hours = array_pop($temp);
4023
						$seconds += $hours * 3600;
4024
					}
4025
					unset($temp);
4026
					$duration_parent = $seconds;
4027
				}
4028
			}
4029
4030
			// HASHES
4031
			if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4032
			{
4033
				foreach ($hashes_iterator as $hash)
4034
				{
4035
					$value = null;
4036
					$algo = null;
4037
					if (isset($hash['data']))
4038
					{
4039
						$value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4040
					}
4041
					if (isset($hash['attribs']['']['algo']))
4042
					{
4043
						$algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4044
					}
4045
					else
4046
					{
4047
						$algo = 'md5';
4048
					}
4049
					$hashes_parent[] = $algo.':'.$value;
4050
				}
4051
			}
4052
			elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4053
			{
4054
				foreach ($hashes_iterator as $hash)
4055
				{
4056
					$value = null;
4057
					$algo = null;
4058
					if (isset($hash['data']))
4059
					{
4060
						$value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4061
					}
4062
					if (isset($hash['attribs']['']['algo']))
4063
					{
4064
						$algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4065
					}
4066
					else
4067
					{
4068
						$algo = 'md5';
4069
					}
4070
					$hashes_parent[] = $algo.':'.$value;
4071
				}
4072
			}
4073
			if (is_array($hashes_parent))
4074
			{
4075
				$hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4076
			}
4077
4078
			// KEYWORDS
4079
			if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4080
			{
4081
				if (isset($keywords[0]['data']))
4082
				{
4083
					$temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4084
					foreach ($temp as $word)
4085
					{
4086
						$keywords_parent[] = trim($word);
4087
					}
4088
				}
4089
				unset($temp);
4090
			}
4091
			elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4092
			{
4093
				if (isset($keywords[0]['data']))
4094
				{
4095
					$temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4096
					foreach ($temp as $word)
4097
					{
4098
						$keywords_parent[] = trim($word);
4099
					}
4100
				}
4101
				unset($temp);
4102
			}
4103
			elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4104
			{
4105
				if (isset($keywords[0]['data']))
4106
				{
4107
					$temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4108
					foreach ($temp as $word)
4109
					{
4110
						$keywords_parent[] = trim($word);
4111
					}
4112
				}
4113
				unset($temp);
4114
			}
4115
			elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4116
			{
4117
				if (isset($keywords[0]['data']))
4118
				{
4119
					$temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4120
					foreach ($temp as $word)
4121
					{
4122
						$keywords_parent[] = trim($word);
4123
					}
4124
				}
4125
				unset($temp);
4126
			}
4127
			if (is_array($keywords_parent))
4128
			{
4129
				$keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4130
			}
4131
4132
			// PLAYER
4133
			if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4134
			{
4135
				if (isset($player_parent[0]['attribs']['']['url']))
4136
				{
4137
					$player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4138
				}
4139
			}
4140
			elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4141
			{
4142
				if (isset($player_parent[0]['attribs']['']['url']))
4143
				{
4144
					$player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4145
				}
4146
			}
4147
4148
			// RATINGS
4149
			if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4150
			{
4151
				foreach ($ratings as $rating)
4152
				{
4153
					$rating_scheme = null;
4154
					$rating_value = null;
4155
					if (isset($rating['attribs']['']['scheme']))
4156
					{
4157
						$rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4158
					}
4159
					else
4160
					{
4161
						$rating_scheme = 'urn:simple';
4162
					}
4163
					if (isset($rating['data']))
4164
					{
4165
						$rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4166
					}
4167 23ca5695 Chris Buechler
					$ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4168 b2e02eef Scott Ullrich
				}
4169
			}
4170
			elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4171
			{
4172
				foreach ($ratings as $rating)
4173
				{
4174
					$rating_scheme = 'urn:itunes';
4175
					$rating_value = null;
4176
					if (isset($rating['data']))
4177
					{
4178
						$rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4179
					}
4180 23ca5695 Chris Buechler
					$ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4181 b2e02eef Scott Ullrich
				}
4182
			}
4183
			elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4184
			{
4185
				foreach ($ratings as $rating)
4186
				{
4187
					$rating_scheme = null;
4188
					$rating_value = null;
4189
					if (isset($rating['attribs']['']['scheme']))
4190
					{
4191
						$rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4192
					}
4193
					else
4194
					{
4195
						$rating_scheme = 'urn:simple';
4196
					}
4197
					if (isset($rating['data']))
4198
					{
4199
						$rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4200
					}
4201 23ca5695 Chris Buechler
					$ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4202 b2e02eef Scott Ullrich
				}
4203
			}
4204
			elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4205
			{
4206
				foreach ($ratings as $rating)
4207
				{
4208
					$rating_scheme = 'urn:itunes';
4209
					$rating_value = null;
4210
					if (isset($rating['data']))
4211
					{
4212
						$rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4213
					}
4214 23ca5695 Chris Buechler
					$ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4215 b2e02eef Scott Ullrich
				}
4216
			}
4217
			if (is_array($ratings_parent))
4218
			{
4219
				$ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4220
			}
4221
4222
			// RESTRICTIONS
4223
			if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4224
			{
4225
				foreach ($restrictions as $restriction)
4226
				{
4227
					$restriction_relationship = null;
4228
					$restriction_type = null;
4229
					$restriction_value = null;
4230
					if (isset($restriction['attribs']['']['relationship']))
4231
					{
4232
						$restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4233
					}
4234
					if (isset($restriction['attribs']['']['type']))
4235
					{
4236
						$restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4237
					}
4238
					if (isset($restriction['data']))
4239
					{
4240
						$restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4241
					}
4242 23ca5695 Chris Buechler
					$restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4243 b2e02eef Scott Ullrich
				}
4244
			}
4245
			elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4246
			{
4247
				foreach ($restrictions as $restriction)
4248
				{
4249
					$restriction_relationship = 'allow';
4250
					$restriction_type = null;
4251
					$restriction_value = 'itunes';
4252
					if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4253
					{
4254
						$restriction_relationship = 'deny';
4255
					}
4256 23ca5695 Chris Buechler
					$restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4257 b2e02eef Scott Ullrich
				}
4258
			}
4259
			elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4260
			{
4261
				foreach ($restrictions as $restriction)
4262
				{
4263
					$restriction_relationship = null;
4264
					$restriction_type = null;
4265
					$restriction_value = null;
4266
					if (isset($restriction['attribs']['']['relationship']))
4267
					{
4268
						$restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4269
					}
4270
					if (isset($restriction['attribs']['']['type']))
4271
					{
4272
						$restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4273
					}
4274
					if (isset($restriction['data']))
4275
					{
4276
						$restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4277
					}
4278 23ca5695 Chris Buechler
					$restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4279 b2e02eef Scott Ullrich
				}
4280
			}
4281
			elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4282
			{
4283
				foreach ($restrictions as $restriction)
4284
				{
4285
					$restriction_relationship = 'allow';
4286
					$restriction_type = null;
4287
					$restriction_value = 'itunes';
4288
					if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4289
					{
4290
						$restriction_relationship = 'deny';
4291
					}
4292 23ca5695 Chris Buechler
					$restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4293 b2e02eef Scott Ullrich
				}
4294
			}
4295
			if (is_array($restrictions_parent))
4296
			{
4297
				$restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4298
			}
4299
4300
			// THUMBNAILS
4301
			if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4302
			{
4303
				foreach ($thumbnails as $thumbnail)
4304
				{
4305
					if (isset($thumbnail['attribs']['']['url']))
4306
					{
4307
						$thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4308
					}
4309
				}
4310
			}
4311
			elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4312
			{
4313
				foreach ($thumbnails as $thumbnail)
4314
				{
4315
					if (isset($thumbnail['attribs']['']['url']))
4316
					{
4317
						$thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4318
					}
4319
				}
4320
			}
4321
4322
			// TITLES
4323
			if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4324
			{
4325
				if (isset($title_parent[0]['data']))
4326
				{
4327
					$title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4328
				}
4329
			}
4330
			elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4331
			{
4332
				if (isset($title_parent[0]['data']))
4333
				{
4334
					$title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4335
				}
4336
			}
4337
4338
			// Clear the memory
4339
			unset($parent);
4340
4341
			// Attributes
4342
			$bitrate = null;
4343
			$channels = null;
4344
			$duration = null;
4345
			$expression = null;
4346
			$framerate = null;
4347
			$height = null;
4348
			$javascript = null;
4349
			$lang = null;
4350
			$length = null;
4351
			$medium = null;
4352
			$samplingrate = null;
4353
			$type = null;
4354
			$url = null;
4355
			$width = null;
4356
4357
			// Elements
4358
			$captions = null;
4359
			$categories = null;
4360
			$copyrights = null;
4361
			$credits = null;
4362
			$description = null;
4363
			$hashes = null;
4364
			$keywords = null;
4365
			$player = null;
4366
			$ratings = null;
4367
			$restrictions = null;
4368
			$thumbnails = null;
4369
			$title = null;
4370
4371
			// If we have media:group tags, loop through them.
4372
			foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4373
			{
4374
				// If we have media:content tags, loop through them.
4375
				foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4376
				{
4377
					if (isset($content['attribs']['']['url']))
4378
					{
4379
						// Attributes
4380
						$bitrate = null;
4381
						$channels = null;
4382
						$duration = null;
4383
						$expression = null;
4384
						$framerate = null;
4385
						$height = null;
4386
						$javascript = null;
4387
						$lang = null;
4388
						$length = null;
4389
						$medium = null;
4390
						$samplingrate = null;
4391
						$type = null;
4392
						$url = null;
4393
						$width = null;
4394
4395
						// Elements
4396
						$captions = null;
4397
						$categories = null;
4398
						$copyrights = null;
4399
						$credits = null;
4400
						$description = null;
4401
						$hashes = null;
4402
						$keywords = null;
4403
						$player = null;
4404
						$ratings = null;
4405
						$restrictions = null;
4406
						$thumbnails = null;
4407
						$title = null;
4408
4409
						// Start checking the attributes of media:content
4410
						if (isset($content['attribs']['']['bitrate']))
4411
						{
4412
							$bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4413
						}
4414
						if (isset($content['attribs']['']['channels']))
4415
						{
4416
							$channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4417
						}
4418
						if (isset($content['attribs']['']['duration']))
4419
						{
4420
							$duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4421
						}
4422
						else
4423
						{
4424
							$duration = $duration_parent;
4425
						}
4426
						if (isset($content['attribs']['']['expression']))
4427
						{
4428
							$expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4429
						}
4430
						if (isset($content['attribs']['']['framerate']))
4431
						{
4432
							$framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4433
						}
4434
						if (isset($content['attribs']['']['height']))
4435
						{
4436
							$height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4437
						}
4438
						if (isset($content['attribs']['']['lang']))
4439
						{
4440
							$lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4441
						}
4442
						if (isset($content['attribs']['']['fileSize']))
4443
						{
4444
							$length = ceil($content['attribs']['']['fileSize']);
4445
						}
4446
						if (isset($content['attribs']['']['medium']))
4447
						{
4448
							$medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4449
						}
4450
						if (isset($content['attribs']['']['samplingrate']))
4451
						{
4452
							$samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4453
						}
4454
						if (isset($content['attribs']['']['type']))
4455
						{
4456
							$type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4457
						}
4458
						if (isset($content['attribs']['']['width']))
4459
						{
4460
							$width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4461
						}
4462
						$url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4463
4464
						// Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4465
4466
						// CAPTIONS
4467
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4468
						{
4469
							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4470
							{
4471
								$caption_type = null;
4472
								$caption_lang = null;
4473
								$caption_startTime = null;
4474
								$caption_endTime = null;
4475
								$caption_text = null;
4476
								if (isset($caption['attribs']['']['type']))
4477
								{
4478
									$caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4479
								}
4480
								if (isset($caption['attribs']['']['lang']))
4481
								{
4482
									$caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4483
								}
4484
								if (isset($caption['attribs']['']['start']))
4485
								{
4486
									$caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4487
								}
4488
								if (isset($caption['attribs']['']['end']))
4489
								{
4490
									$caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4491
								}
4492
								if (isset($caption['data']))
4493
								{
4494
									$caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4495
								}
4496 23ca5695 Chris Buechler
								$captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4497 b2e02eef Scott Ullrich
							}
4498
							if (is_array($captions))
4499
							{
4500
								$captions = array_values(SimplePie_Misc::array_unique($captions));
4501
							}
4502
						}
4503
						elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4504
						{
4505
							foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4506
							{
4507
								$caption_type = null;
4508
								$caption_lang = null;
4509
								$caption_startTime = null;
4510
								$caption_endTime = null;
4511
								$caption_text = null;
4512
								if (isset($caption['attribs']['']['type']))
4513
								{
4514
									$caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4515
								}
4516
								if (isset($caption['attribs']['']['lang']))
4517
								{
4518
									$caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4519
								}
4520
								if (isset($caption['attribs']['']['start']))
4521
								{
4522
									$caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4523
								}
4524
								if (isset($caption['attribs']['']['end']))
4525
								{
4526
									$caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4527
								}
4528
								if (isset($caption['data']))
4529
								{
4530
									$caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4531
								}
4532 23ca5695 Chris Buechler
								$captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4533 b2e02eef Scott Ullrich
							}
4534
							if (is_array($captions))
4535
							{
4536
								$captions = array_values(SimplePie_Misc::array_unique($captions));
4537
							}
4538
						}
4539
						else
4540
						{
4541
							$captions = $captions_parent;
4542
						}
4543
4544
						// CATEGORIES
4545
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4546
						{
4547
							foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4548
							{
4549
								$term = null;
4550
								$scheme = null;
4551
								$label = null;
4552
								if (isset($category['data']))
4553
								{
4554
									$term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4555
								}
4556
								if (isset($category['attribs']['']['scheme']))
4557
								{
4558
									$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4559
								}
4560
								else
4561
								{
4562
									$scheme = 'http://search.yahoo.com/mrss/category_schema';
4563
								}
4564
								if (isset($category['attribs']['']['label']))
4565
								{
4566
									$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4567
								}
4568 23ca5695 Chris Buechler
								$categories[] =& new $this->feed->category_class($term, $scheme, $label);
4569 b2e02eef Scott Ullrich
							}
4570
						}
4571
						if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4572
						{
4573
							foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4574
							{
4575
								$term = null;
4576
								$scheme = null;
4577
								$label = null;
4578
								if (isset($category['data']))
4579
								{
4580
									$term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4581
								}
4582
								if (isset($category['attribs']['']['scheme']))
4583
								{
4584
									$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4585
								}
4586
								else
4587
								{
4588
									$scheme = 'http://search.yahoo.com/mrss/category_schema';
4589
								}
4590
								if (isset($category['attribs']['']['label']))
4591
								{
4592
									$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4593
								}
4594 23ca5695 Chris Buechler
								$categories[] =& new $this->feed->category_class($term, $scheme, $label);
4595 b2e02eef Scott Ullrich
							}
4596
						}
4597
						if (is_array($categories) && is_array($categories_parent))
4598
						{
4599
							$categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4600
						}
4601
						elseif (is_array($categories))
4602
						{
4603
							$categories = array_values(SimplePie_Misc::array_unique($categories));
4604
						}
4605
						elseif (is_array($categories_parent))
4606
						{
4607
							$categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4608
						}
4609
4610
						// COPYRIGHTS
4611
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4612
						{
4613
							$copyright_url = null;
4614
							$copyright_label = null;
4615
							if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4616
							{
4617
								$copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4618
							}
4619
							if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4620
							{
4621
								$copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4622
							}
4623 23ca5695 Chris Buechler
							$copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4624 b2e02eef Scott Ullrich
						}
4625
						elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4626
						{
4627
							$copyright_url = null;
4628
							$copyright_label = null;
4629
							if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4630
							{
4631
								$copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4632
							}
4633
							if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4634
							{
4635
								$copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4636
							}
4637 23ca5695 Chris Buechler
							$copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4638 b2e02eef Scott Ullrich
						}
4639
						else
4640
						{
4641
							$copyrights = $copyrights_parent;
4642
						}
4643
4644
						// CREDITS
4645
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4646
						{
4647
							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4648
							{
4649
								$credit_role = null;
4650
								$credit_scheme = null;
4651
								$credit_name = null;
4652
								if (isset($credit['attribs']['']['role']))
4653
								{
4654
									$credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4655
								}
4656
								if (isset($credit['attribs']['']['scheme']))
4657
								{
4658
									$credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4659
								}
4660
								else
4661
								{
4662
									$credit_scheme = 'urn:ebu';
4663
								}
4664
								if (isset($credit['data']))
4665
								{
4666
									$credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4667
								}
4668 23ca5695 Chris Buechler
								$credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4669 b2e02eef Scott Ullrich
							}
4670
							if (is_array($credits))
4671
							{
4672
								$credits = array_values(SimplePie_Misc::array_unique($credits));
4673
							}
4674
						}
4675
						elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4676
						{
4677
							foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4678
							{
4679
								$credit_role = null;
4680
								$credit_scheme = null;
4681
								$credit_name = null;
4682
								if (isset($credit['attribs']['']['role']))
4683
								{
4684
									$credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4685
								}
4686
								if (isset($credit['attribs']['']['scheme']))
4687
								{
4688
									$credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4689
								}
4690
								else
4691
								{
4692
									$credit_scheme = 'urn:ebu';
4693
								}
4694
								if (isset($credit['data']))
4695
								{
4696
									$credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4697
								}
4698 23ca5695 Chris Buechler
								$credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4699 b2e02eef Scott Ullrich
							}
4700
							if (is_array($credits))
4701
							{
4702
								$credits = array_values(SimplePie_Misc::array_unique($credits));
4703
							}
4704
						}
4705
						else
4706
						{
4707
							$credits = $credits_parent;
4708
						}
4709
4710
						// DESCRIPTION
4711
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4712
						{
4713
							$description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4714
						}
4715
						elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4716
						{
4717
							$description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4718
						}
4719
						else
4720
						{
4721
							$description = $description_parent;
4722
						}
4723
4724
						// HASHES
4725
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4726
						{
4727
							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4728
							{
4729
								$value = null;
4730
								$algo = null;
4731
								if (isset($hash['data']))
4732
								{
4733
									$value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4734
								}
4735
								if (isset($hash['attribs']['']['algo']))
4736
								{
4737
									$algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4738
								}
4739
								else
4740
								{
4741
									$algo = 'md5';
4742
								}
4743
								$hashes[] = $algo.':'.$value;
4744
							}
4745
							if (is_array($hashes))
4746
							{
4747
								$hashes = array_values(SimplePie_Misc::array_unique($hashes));
4748
							}
4749
						}
4750
						elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4751
						{
4752
							foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4753
							{
4754
								$value = null;
4755
								$algo = null;
4756
								if (isset($hash['data']))
4757
								{
4758
									$value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4759
								}
4760
								if (isset($hash['attribs']['']['algo']))
4761
								{
4762
									$algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4763
								}
4764
								else
4765
								{
4766
									$algo = 'md5';
4767
								}
4768
								$hashes[] = $algo.':'.$value;
4769
							}
4770
							if (is_array($hashes))
4771
							{
4772
								$hashes = array_values(SimplePie_Misc::array_unique($hashes));
4773
							}
4774
						}
4775
						else
4776
						{
4777
							$hashes = $hashes_parent;
4778
						}
4779
4780
						// KEYWORDS
4781
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4782
						{
4783
							if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4784
							{
4785
								$temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4786
								foreach ($temp as $word)
4787
								{
4788
									$keywords[] = trim($word);
4789
								}
4790
								unset($temp);
4791
							}
4792
							if (is_array($keywords))
4793
							{
4794
								$keywords = array_values(SimplePie_Misc::array_unique($keywords));
4795
							}
4796
						}
4797
						elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4798
						{
4799
							if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4800
							{
4801
								$temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4802
								foreach ($temp as $word)
4803
								{
4804
									$keywords[] = trim($word);
4805
								}
4806
								unset($temp);
4807
							}
4808
							if (is_array($keywords))
4809
							{
4810
								$keywords = array_values(SimplePie_Misc::array_unique($keywords));
4811
							}
4812
						}
4813
						else
4814
						{
4815
							$keywords = $keywords_parent;
4816
						}
4817
4818
						// PLAYER
4819
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4820
						{
4821
							$player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4822
						}
4823
						elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4824
						{
4825
							$player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4826
						}
4827
						else
4828
						{
4829
							$player = $player_parent;
4830
						}
4831
4832
						// RATINGS
4833
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4834
						{
4835
							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4836
							{
4837
								$rating_scheme = null;
4838
								$rating_value = null;
4839
								if (isset($rating['attribs']['']['scheme']))
4840
								{
4841
									$rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4842
								}
4843
								else
4844
								{
4845
									$rating_scheme = 'urn:simple';
4846
								}
4847
								if (isset($rating['data']))
4848
								{
4849
									$rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4850
								}
4851 23ca5695 Chris Buechler
								$ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4852 b2e02eef Scott Ullrich
							}
4853
							if (is_array($ratings))
4854
							{
4855
								$ratings = array_values(SimplePie_Misc::array_unique($ratings));
4856
							}
4857
						}
4858
						elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4859
						{
4860
							foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4861
							{
4862
								$rating_scheme = null;
4863
								$rating_value = null;
4864
								if (isset($rating['attribs']['']['scheme']))
4865
								{
4866
									$rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4867
								}
4868
								else
4869
								{
4870
									$rating_scheme = 'urn:simple';
4871
								}
4872
								if (isset($rating['data']))
4873
								{
4874
									$rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4875
								}
4876 23ca5695 Chris Buechler
								$ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4877 b2e02eef Scott Ullrich
							}
4878
							if (is_array($ratings))
4879
							{
4880
								$ratings = array_values(SimplePie_Misc::array_unique($ratings));
4881
							}
4882
						}
4883
						else
4884
						{
4885
							$ratings = $ratings_parent;
4886
						}
4887
4888
						// RESTRICTIONS
4889
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4890
						{
4891
							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4892
							{
4893
								$restriction_relationship = null;
4894
								$restriction_type = null;
4895
								$restriction_value = null;
4896
								if (isset($restriction['attribs']['']['relationship']))
4897
								{
4898
									$restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4899
								}
4900
								if (isset($restriction['attribs']['']['type']))
4901
								{
4902
									$restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4903
								}
4904
								if (isset($restriction['data']))
4905
								{
4906
									$restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4907
								}
4908 23ca5695 Chris Buechler
								$restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4909 b2e02eef Scott Ullrich
							}
4910
							if (is_array($restrictions))
4911
							{
4912
								$restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4913
							}
4914
						}
4915
						elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4916
						{
4917
							foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4918
							{
4919
								$restriction_relationship = null;
4920
								$restriction_type = null;
4921
								$restriction_value = null;
4922
								if (isset($restriction['attribs']['']['relationship']))
4923
								{
4924
									$restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4925
								}
4926
								if (isset($restriction['attribs']['']['type']))
4927
								{
4928
									$restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4929
								}
4930
								if (isset($restriction['data']))
4931
								{
4932
									$restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4933
								}
4934 23ca5695 Chris Buechler
								$restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4935 b2e02eef Scott Ullrich
							}
4936
							if (is_array($restrictions))
4937
							{
4938
								$restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4939
							}
4940
						}
4941
						else
4942
						{
4943
							$restrictions = $restrictions_parent;
4944
						}
4945
4946
						// THUMBNAILS
4947
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4948
						{
4949
							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4950
							{
4951
								$thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4952
							}
4953
							if (is_array($thumbnails))
4954
							{
4955
								$thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4956
							}
4957
						}
4958
						elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4959
						{
4960
							foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4961
							{
4962
								$thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4963
							}
4964
							if (is_array($thumbnails))
4965
							{
4966
								$thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4967
							}
4968
						}
4969
						else
4970
						{
4971
							$thumbnails = $thumbnails_parent;
4972
						}
4973
4974
						// TITLES
4975
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4976
						{
4977
							$title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4978
						}
4979
						elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4980
						{
4981
							$title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4982
						}
4983
						else
4984
						{
4985
							$title = $title_parent;
4986
						}
4987
4988 23ca5695 Chris Buechler
						$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);
4989 b2e02eef Scott Ullrich
					}
4990
				}
4991
			}
4992
4993
			// If we have standalone media:content tags, loop through them.
4994
			if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4995
			{
4996
				foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4997
				{
4998
					if (isset($content['attribs']['']['url']))
4999
					{
5000
						// Attributes
5001
						$bitrate = null;
5002
						$channels = null;
5003
						$duration = null;
5004
						$expression = null;
5005
						$framerate = null;
5006
						$height = null;
5007
						$javascript = null;
5008
						$lang = null;
5009
						$length = null;
5010
						$medium = null;
5011
						$samplingrate = null;
5012
						$type = null;
5013
						$url = null;
5014
						$width = null;
5015
5016
						// Elements
5017
						$captions = null;
5018
						$categories = null;
5019
						$copyrights = null;
5020
						$credits = null;
5021
						$description = null;
5022
						$hashes = null;
5023
						$keywords = null;
5024
						$player = null;
5025
						$ratings = null;
5026
						$restrictions = null;
5027
						$thumbnails = null;
5028
						$title = null;
5029
5030
						// Start checking the attributes of media:content
5031
						if (isset($content['attribs']['']['bitrate']))
5032
						{
5033
							$bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5034
						}
5035
						if (isset($content['attribs']['']['channels']))
5036
						{
5037
							$channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5038
						}
5039
						if (isset($content['attribs']['']['duration']))
5040
						{
5041
							$duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5042
						}
5043
						else
5044
						{
5045
							$duration = $duration_parent;
5046
						}
5047
						if (isset($content['attribs']['']['expression']))
5048
						{
5049
							$expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5050
						}
5051
						if (isset($content['attribs']['']['framerate']))
5052
						{
5053
							$framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5054
						}
5055
						if (isset($content['attribs']['']['height']))
5056
						{
5057
							$height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5058
						}
5059
						if (isset($content['attribs']['']['lang']))
5060
						{
5061
							$lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5062
						}
5063
						if (isset($content['attribs']['']['fileSize']))
5064
						{
5065
							$length = ceil($content['attribs']['']['fileSize']);
5066
						}
5067
						if (isset($content['attribs']['']['medium']))
5068
						{
5069
							$medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5070
						}
5071
						if (isset($content['attribs']['']['samplingrate']))
5072
						{
5073
							$samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5074
						}
5075
						if (isset($content['attribs']['']['type']))
5076
						{
5077
							$type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5078
						}
5079
						if (isset($content['attribs']['']['width']))
5080
						{
5081
							$width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5082
						}
5083
						$url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5084
5085
						// Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5086
5087
						// CAPTIONS
5088
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5089
						{
5090
							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5091
							{
5092
								$caption_type = null;
5093
								$caption_lang = null;
5094
								$caption_startTime = null;
5095
								$caption_endTime = null;
5096
								$caption_text = null;
5097
								if (isset($caption['attribs']['']['type']))
5098
								{
5099
									$caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5100
								}
5101
								if (isset($caption['attribs']['']['lang']))
5102
								{
5103
									$caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5104
								}
5105
								if (isset($caption['attribs']['']['start']))
5106
								{
5107
									$caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5108
								}
5109
								if (isset($caption['attribs']['']['end']))
5110
								{
5111
									$caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5112
								}
5113
								if (isset($caption['data']))
5114
								{
5115
									$caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5116
								}
5117 23ca5695 Chris Buechler
								$captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5118 b2e02eef Scott Ullrich
							}
5119
							if (is_array($captions))
5120
							{
5121
								$captions = array_values(SimplePie_Misc::array_unique($captions));
5122
							}
5123
						}
5124
						else
5125
						{
5126
							$captions = $captions_parent;
5127
						}
5128
5129
						// CATEGORIES
5130
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5131
						{
5132
							foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5133
							{
5134
								$term = null;
5135
								$scheme = null;
5136
								$label = null;
5137
								if (isset($category['data']))
5138
								{
5139
									$term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5140
								}
5141
								if (isset($category['attribs']['']['scheme']))
5142
								{
5143
									$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5144
								}
5145
								else
5146
								{
5147
									$scheme = 'http://search.yahoo.com/mrss/category_schema';
5148
								}
5149
								if (isset($category['attribs']['']['label']))
5150
								{
5151
									$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5152
								}
5153 23ca5695 Chris Buechler
								$categories[] =& new $this->feed->category_class($term, $scheme, $label);
5154 b2e02eef Scott Ullrich
							}
5155
						}
5156
						if (is_array($categories) && is_array($categories_parent))
5157
						{
5158
							$categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5159
						}
5160
						elseif (is_array($categories))
5161
						{
5162
							$categories = array_values(SimplePie_Misc::array_unique($categories));
5163
						}
5164
						elseif (is_array($categories_parent))
5165
						{
5166
							$categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5167
						}
5168
						else
5169
						{
5170
							$categories = null;
5171
						}
5172
5173
						// COPYRIGHTS
5174
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5175
						{
5176
							$copyright_url = null;
5177
							$copyright_label = null;
5178
							if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5179
							{
5180
								$copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5181
							}
5182
							if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5183
							{
5184
								$copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5185
							}
5186 23ca5695 Chris Buechler
							$copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
5187 b2e02eef Scott Ullrich
						}
5188
						else
5189
						{
5190
							$copyrights = $copyrights_parent;
5191
						}
5192
5193
						// CREDITS
5194
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5195
						{
5196
							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5197
							{
5198
								$credit_role = null;
5199
								$credit_scheme = null;
5200
								$credit_name = null;
5201
								if (isset($credit['attribs']['']['role']))
5202
								{
5203
									$credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5204
								}
5205
								if (isset($credit['attribs']['']['scheme']))
5206
								{
5207
									$credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5208
								}
5209
								else
5210
								{
5211
									$credit_scheme = 'urn:ebu';
5212
								}
5213
								if (isset($credit['data']))
5214
								{
5215
									$credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5216
								}
5217 23ca5695 Chris Buechler
								$credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5218 b2e02eef Scott Ullrich
							}
5219
							if (is_array($credits))
5220
							{
5221
								$credits = array_values(SimplePie_Misc::array_unique($credits));
5222
							}
5223
						}
5224
						else
5225
						{
5226
							$credits = $credits_parent;
5227
						}
5228
5229
						// DESCRIPTION
5230
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5231
						{
5232
							$description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5233
						}
5234
						else
5235
						{
5236
							$description = $description_parent;
5237
						}
5238
5239
						// HASHES
5240
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5241
						{
5242
							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5243
							{
5244
								$value = null;
5245
								$algo = null;
5246
								if (isset($hash['data']))
5247
								{
5248
									$value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5249
								}
5250
								if (isset($hash['attribs']['']['algo']))
5251
								{
5252
									$algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5253
								}
5254
								else
5255
								{
5256
									$algo = 'md5';
5257
								}
5258
								$hashes[] = $algo.':'.$value;
5259
							}
5260
							if (is_array($hashes))
5261
							{
5262
								$hashes = array_values(SimplePie_Misc::array_unique($hashes));
5263
							}
5264
						}
5265
						else
5266
						{
5267
							$hashes = $hashes_parent;
5268
						}
5269
5270
						// KEYWORDS
5271
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5272
						{
5273
							if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5274
							{
5275
								$temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5276
								foreach ($temp as $word)
5277
								{
5278
									$keywords[] = trim($word);
5279
								}
5280
								unset($temp);
5281
							}
5282
							if (is_array($keywords))
5283
							{
5284
								$keywords = array_values(SimplePie_Misc::array_unique($keywords));
5285
							}
5286
						}
5287
						else
5288
						{
5289
							$keywords = $keywords_parent;
5290
						}
5291
5292
						// PLAYER
5293
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5294
						{
5295
							$player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5296
						}
5297
						else
5298
						{
5299
							$player = $player_parent;
5300
						}
5301
5302
						// RATINGS
5303
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5304
						{
5305
							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5306
							{
5307
								$rating_scheme = null;
5308
								$rating_value = null;
5309
								if (isset($rating['attribs']['']['scheme']))
5310
								{
5311
									$rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5312
								}
5313
								else
5314
								{
5315
									$rating_scheme = 'urn:simple';
5316
								}
5317
								if (isset($rating['data']))
5318
								{
5319
									$rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5320
								}
5321 23ca5695 Chris Buechler
								$ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
5322 b2e02eef Scott Ullrich
							}
5323
							if (is_array($ratings))
5324
							{
5325
								$ratings = array_values(SimplePie_Misc::array_unique($ratings));
5326
							}
5327
						}
5328
						else
5329
						{
5330
							$ratings = $ratings_parent;
5331
						}
5332
5333
						// RESTRICTIONS
5334
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5335
						{
5336
							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5337
							{
5338
								$restriction_relationship = null;
5339
								$restriction_type = null;
5340
								$restriction_value = null;
5341
								if (isset($restriction['attribs']['']['relationship']))
5342
								{
5343
									$restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5344
								}
5345
								if (isset($restriction['attribs']['']['type']))
5346
								{
5347
									$restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5348
								}
5349
								if (isset($restriction['data']))
5350
								{
5351
									$restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5352
								}
5353 23ca5695 Chris Buechler
								$restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5354 b2e02eef Scott Ullrich
							}
5355
							if (is_array($restrictions))
5356
							{
5357
								$restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5358
							}
5359
						}
5360
						else
5361
						{
5362
							$restrictions = $restrictions_parent;
5363
						}
5364
5365
						// THUMBNAILS
5366
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5367
						{
5368
							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5369
							{
5370
								$thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5371
							}
5372
							if (is_array($thumbnails))
5373
							{
5374
								$thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5375
							}
5376
						}
5377
						else
5378
						{
5379
							$thumbnails = $thumbnails_parent;
5380
						}
5381
5382
						// TITLES
5383
						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5384
						{
5385
							$title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5386
						}
5387
						else
5388
						{
5389
							$title = $title_parent;
5390
						}
5391
5392 23ca5695 Chris Buechler
						$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);
5393 b2e02eef Scott Ullrich
					}
5394
				}
5395
			}
5396
5397
			foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5398
			{
5399
				if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5400
				{
5401
					// Attributes
5402
					$bitrate = null;
5403
					$channels = null;
5404
					$duration = null;
5405
					$expression = null;
5406
					$framerate = null;
5407
					$height = null;
5408
					$javascript = null;
5409
					$lang = null;
5410
					$length = null;
5411
					$medium = null;
5412
					$samplingrate = null;
5413
					$type = null;
5414
					$url = null;
5415
					$width = null;
5416
5417
					$url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5418
					if (isset($link['attribs']['']['type']))
5419
					{
5420
						$type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5421
					}
5422
					if (isset($link['attribs']['']['length']))
5423
					{
5424
						$length = ceil($link['attribs']['']['length']);
5425
					}
5426
5427
					// Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5428 23ca5695 Chris Buechler
					$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);
5429 b2e02eef Scott Ullrich
				}
5430
			}
5431
5432
			foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5433
			{
5434
				if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5435
				{
5436
					// Attributes
5437
					$bitrate = null;
5438
					$channels = null;
5439
					$duration = null;
5440
					$expression = null;
5441
					$framerate = null;
5442
					$height = null;
5443
					$javascript = null;
5444
					$lang = null;
5445
					$length = null;
5446
					$medium = null;
5447
					$samplingrate = null;
5448
					$type = null;
5449
					$url = null;
5450
					$width = null;
5451
5452
					$url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5453
					if (isset($link['attribs']['']['type']))
5454
					{
5455
						$type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5456
					}
5457
					if (isset($link['attribs']['']['length']))
5458
					{
5459
						$length = ceil($link['attribs']['']['length']);
5460
					}
5461
5462
					// Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5463 23ca5695 Chris Buechler
					$this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
5464 b2e02eef Scott Ullrich
				}
5465
			}
5466
5467
			if ($enclosure = $this->get_item_tags('', 'enclosure'))
5468
			{
5469
				if (isset($enclosure[0]['attribs']['']['url']))
5470
				{
5471
					// Attributes
5472
					$bitrate = null;
5473
					$channels = null;
5474
					$duration = null;
5475
					$expression = null;
5476
					$framerate = null;
5477
					$height = null;
5478
					$javascript = null;
5479
					$lang = null;
5480
					$length = null;
5481
					$medium = null;
5482
					$samplingrate = null;
5483
					$type = null;
5484
					$url = null;
5485
					$width = null;
5486
5487
					$url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5488
					if (isset($enclosure[0]['attribs']['']['type']))
5489
					{
5490
						$type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5491
					}
5492
					if (isset($enclosure[0]['attribs']['']['length']))
5493
					{
5494
						$length = ceil($enclosure[0]['attribs']['']['length']);
5495
					}
5496
5497
					// Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5498 23ca5695 Chris Buechler
					$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);
5499 b2e02eef Scott Ullrich
				}
5500
			}
5501
5502
			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))
5503
			{
5504
				// Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5505 23ca5695 Chris Buechler
				$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);
5506 b2e02eef Scott Ullrich
			}
5507
5508
			$this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5509
		}
5510
		if (!empty($this->data['enclosures']))
5511
		{
5512
			return $this->data['enclosures'];
5513
		}
5514
		else
5515
		{
5516
			return null;
5517
		}
5518
	}
5519
5520
	function get_latitude()
5521
	{
5522
		if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5523
		{
5524
			return (float) $return[0]['data'];
5525
		}
5526
		elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5527
		{
5528
			return (float) $match[1];
5529
		}
5530
		else
5531
		{
5532
			return null;
5533
		}
5534
	}
5535
5536
	function get_longitude()
5537
	{
5538
		if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5539
		{
5540
			return (float) $return[0]['data'];
5541
		}
5542
		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5543
		{
5544
			return (float) $return[0]['data'];
5545
		}
5546
		elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5547
		{
5548
			return (float) $match[2];
5549
		}
5550
		else
5551
		{
5552
			return null;
5553
		}
5554
	}
5555
5556
	function get_source()
5557
	{
5558
		if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5559
		{
5560
			return new $this->feed->source_class($this, $return[0]);
5561
		}
5562
		else
5563
		{
5564
			return null;
5565
		}
5566
	}
5567
5568
	/**
5569
	 * Creates the add_to_* methods' return data
5570
	 *
5571
	 * @access private
5572
	 * @param string $item_url String to prefix to the item permalink
5573
	 * @param string $title_url String to prefix to the item title
5574
	 * (and suffix to the item permalink)
5575
	 * @return mixed URL if feed exists, false otherwise
5576
	 */
5577
	function add_to_service($item_url, $title_url = null, $summary_url = null)
5578
	{
5579
		if ($this->get_permalink() !== null)
5580
		{
5581
			$return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5582
			if ($title_url !== null && $this->get_title() !== null)
5583
			{
5584
				$return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5585
			}
5586
			if ($summary_url !== null && $this->get_description() !== null)
5587
			{
5588
				$return .= $this->sanitize($summary_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_description());
5589
			}
5590
			return $return;
5591
		}
5592
		else
5593
		{
5594
			return null;
5595
		}
5596
	}
5597
5598
	function add_to_blinklist()
5599
	{
5600
		return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5601
	}
5602
5603
	function add_to_blogmarks()
5604
	{
5605
		return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5606
	}
5607
5608
	function add_to_delicious()
5609
	{
5610
		return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5611
	}
5612
5613
	function add_to_digg()
5614
	{
5615
		return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
5616
	}
5617
5618
	function add_to_furl()
5619
	{
5620
		return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5621
	}
5622
5623
	function add_to_magnolia()
5624
	{
5625
		return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5626
	}
5627
5628
	function add_to_myweb20()
5629
	{
5630
		return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5631
	}
5632
5633
	function add_to_newsvine()
5634
	{
5635
		return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5636
	}
5637
5638
	function add_to_reddit()
5639
	{
5640
		return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5641
	}
5642
5643
	function add_to_segnalo()
5644
	{
5645
		return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5646
	}
5647
5648
	function add_to_simpy()
5649
	{
5650
		return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5651
	}
5652
5653
	function add_to_spurl()
5654
	{
5655
		return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5656
	}
5657
5658
	function add_to_wists()
5659
	{
5660
		return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5661
	}
5662
5663
	function search_technorati()
5664
	{
5665
		return $this->add_to_service('http://www.technorati.com/search/');
5666
	}
5667
}
5668
5669
class SimplePie_Source
5670
{
5671
	var $item;
5672
	var $data = array();
5673
5674
	function SimplePie_Source($item, $data)
5675
	{
5676
		$this->item = $item;
5677
		$this->data = $data;
5678
	}
5679
5680
	function __toString()
5681
	{
5682
		return md5(serialize($this->data));
5683
	}
5684
5685
	/**
5686
	 * Remove items that link back to this before destroying this object
5687
	 */
5688
	function __destruct()
5689
	{
5690
		unset($this->item);
5691
	}
5692
5693
	function get_source_tags($namespace, $tag)
5694
	{
5695
		if (isset($this->data['child'][$namespace][$tag]))
5696
		{
5697
			return $this->data['child'][$namespace][$tag];
5698
		}
5699
		else
5700
		{
5701
			return null;
5702
		}
5703
	}
5704
5705
	function get_base($element = array())
5706
	{
5707
		return $this->item->get_base($element);
5708
	}
5709
5710
	function sanitize($data, $type, $base = '')
5711
	{
5712
		return $this->item->sanitize($data, $type, $base);
5713
	}
5714
5715
	function get_item()
5716
	{
5717
		return $this->item;
5718
	}
5719
5720
	function get_title()
5721
	{
5722
		if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5723
		{
5724
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5725
		}
5726
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5727
		{
5728
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5729
		}
5730
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5731
		{
5732
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5733
		}
5734
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5735
		{
5736
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5737
		}
5738
		elseif ($return = $this->get_source_tags('', 'title'))
5739
		{
5740
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5741
		}
5742
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5743
		{
5744
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5745
		}
5746
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5747
		{
5748
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5749
		}
5750
		else
5751
		{
5752
			return null;
5753
		}
5754
	}
5755
5756
	function get_category($key = 0)
5757
	{
5758
		$categories = $this->get_categories();
5759
		if (isset($categories[$key]))
5760
		{
5761
			return $categories[$key];
5762
		}
5763
		else
5764
		{
5765
			return null;
5766
		}
5767
	}
5768
5769
	function get_categories()
5770
	{
5771
		$categories = array();
5772
5773
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5774
		{
5775
			$term = null;
5776
			$scheme = null;
5777
			$label = null;
5778
			if (isset($category['attribs']['']['term']))
5779
			{
5780
				$term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5781
			}
5782
			if (isset($category['attribs']['']['scheme']))
5783
			{
5784
				$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5785
			}
5786
			if (isset($category['attribs']['']['label']))
5787
			{
5788
				$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5789
			}
5790 23ca5695 Chris Buechler
			$categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
5791 b2e02eef Scott Ullrich
		}
5792
		foreach ((array) $this->get_source_tags('', 'category') as $category)
5793
		{
5794 23ca5695 Chris Buechler
			$categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5795 b2e02eef Scott Ullrich
		}
5796
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5797
		{
5798 23ca5695 Chris Buechler
			$categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5799 b2e02eef Scott Ullrich
		}
5800
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5801
		{
5802 23ca5695 Chris Buechler
			$categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5803 b2e02eef Scott Ullrich
		}
5804
5805
		if (!empty($categories))
5806
		{
5807
			return SimplePie_Misc::array_unique($categories);
5808
		}
5809
		else
5810
		{
5811
			return null;
5812
		}
5813
	}
5814
5815
	function get_author($key = 0)
5816
	{
5817
		$authors = $this->get_authors();
5818
		if (isset($authors[$key]))
5819
		{
5820
			return $authors[$key];
5821
		}
5822
		else
5823
		{
5824
			return null;
5825
		}
5826
	}
5827
5828
	function get_authors()
5829
	{
5830
		$authors = array();
5831
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5832
		{
5833
			$name = null;
5834
			$uri = null;
5835
			$email = null;
5836
			if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5837
			{
5838
				$name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5839
			}
5840
			if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5841
			{
5842
				$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]));
5843
			}
5844
			if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5845
			{
5846
				$email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5847
			}
5848
			if ($name !== null || $email !== null || $uri !== null)
5849
			{
5850 23ca5695 Chris Buechler
				$authors[] =& new $this->item->feed->author_class($name, $uri, $email);
5851 b2e02eef Scott Ullrich
			}
5852
		}
5853
		if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5854
		{
5855
			$name = null;
5856
			$url = null;
5857
			$email = null;
5858
			if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5859
			{
5860
				$name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5861
			}
5862
			if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5863
			{
5864
				$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]));
5865
			}
5866
			if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5867
			{
5868
				$email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5869
			}
5870
			if ($name !== null || $email !== null || $url !== null)
5871
			{
5872 23ca5695 Chris Buechler
				$authors[] =& new $this->item->feed->author_class($name, $url, $email);
5873 b2e02eef Scott Ullrich
			}
5874
		}
5875
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5876
		{
5877 23ca5695 Chris Buechler
			$authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5878 b2e02eef Scott Ullrich
		}
5879
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5880
		{
5881 23ca5695 Chris Buechler
			$authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5882 b2e02eef Scott Ullrich
		}
5883
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5884
		{
5885 23ca5695 Chris Buechler
			$authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5886 b2e02eef Scott Ullrich
		}
5887
5888
		if (!empty($authors))
5889
		{
5890
			return SimplePie_Misc::array_unique($authors);
5891
		}
5892
		else
5893
		{
5894
			return null;
5895
		}
5896
	}
5897
5898
	function get_contributor($key = 0)
5899
	{
5900
		$contributors = $this->get_contributors();
5901
		if (isset($contributors[$key]))
5902
		{
5903
			return $contributors[$key];
5904
		}
5905
		else
5906
		{
5907
			return null;
5908
		}
5909
	}
5910
5911
	function get_contributors()
5912
	{
5913
		$contributors = array();
5914
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5915
		{
5916
			$name = null;
5917
			$uri = null;
5918
			$email = null;
5919
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5920
			{
5921
				$name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5922
			}
5923
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5924
			{
5925
				$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]));
5926
			}
5927
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5928
			{
5929
				$email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5930
			}
5931
			if ($name !== null || $email !== null || $uri !== null)
5932
			{
5933 23ca5695 Chris Buechler
				$contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
5934 b2e02eef Scott Ullrich
			}
5935
		}
5936
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
5937
		{
5938
			$name = null;
5939
			$url = null;
5940
			$email = null;
5941
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5942
			{
5943
				$name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5944
			}
5945
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5946
			{
5947
				$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]));
5948
			}
5949
			if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5950
			{
5951
				$email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5952
			}
5953
			if ($name !== null || $email !== null || $url !== null)
5954
			{
5955 23ca5695 Chris Buechler
				$contributors[] =& new $this->item->feed->author_class($name, $url, $email);
5956 b2e02eef Scott Ullrich
			}
5957
		}
5958
5959
		if (!empty($contributors))
5960
		{
5961
			return SimplePie_Misc::array_unique($contributors);
5962
		}
5963
		else
5964
		{
5965
			return null;
5966
		}
5967
	}
5968
5969
	function get_link($key = 0, $rel = 'alternate')
5970
	{
5971
		$links = $this->get_links($rel);
5972
		if (isset($links[$key]))
5973
		{
5974
			return $links[$key];
5975
		}
5976
		else
5977
		{
5978
			return null;
5979
		}
5980
	}
5981
5982
	/**
5983
	 * Added for parity between the parent-level and the item/entry-level.
5984
	 */
5985
	function get_permalink()
5986
	{
5987
		return $this->get_link(0);
5988
	}
5989
5990
	function get_links($rel = 'alternate')
5991
	{
5992
		if (!isset($this->data['links']))
5993
		{
5994
			$this->data['links'] = array();
5995
			if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
5996
			{
5997
				foreach ($links as $link)
5998
				{
5999
					if (isset($link['attribs']['']['href']))
6000
					{
6001
						$link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6002
						$this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6003
					}
6004
				}
6005
			}
6006
			if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
6007
			{
6008
				foreach ($links as $link)
6009
				{
6010
					if (isset($link['attribs']['']['href']))
6011
					{
6012
						$link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6013
						$this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6014
6015
					}
6016
				}
6017
			}
6018
			if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
6019
			{
6020
				$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6021
			}
6022
			if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6023
			{
6024
				$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6025
			}
6026
			if ($links = $this->get_source_tags('', 'link'))
6027
			{
6028
				$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6029
			}
6030
6031
			$keys = array_keys($this->data['links']);
6032
			foreach ($keys as $key)
6033
			{
6034
				if (SimplePie_Misc::is_isegment_nz_nc($key))
6035
				{
6036
					if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6037
					{
6038
						$this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6039
						$this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6040
					}
6041
					else
6042
					{
6043
						$this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6044
					}
6045
				}
6046
				elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6047
				{
6048
					$this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6049
				}
6050
				$this->data['links'][$key] = array_unique($this->data['links'][$key]);
6051
			}
6052
		}
6053
6054
		if (isset($this->data['links'][$rel]))
6055
		{
6056
			return $this->data['links'][$rel];
6057
		}
6058
		else
6059
		{
6060
			return null;
6061
		}
6062
	}
6063
6064
	function get_description()
6065
	{
6066
		if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6067
		{
6068
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6069
		}
6070
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6071
		{
6072
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6073
		}
6074
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6075
		{
6076
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6077
		}
6078
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6079
		{
6080
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6081
		}
6082
		elseif ($return = $this->get_source_tags('', 'description'))
6083
		{
6084
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6085
		}
6086
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6087
		{
6088
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6089
		}
6090
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6091
		{
6092
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6093
		}
6094
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6095
		{
6096
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6097
		}
6098
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6099
		{
6100
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6101
		}
6102
		else
6103
		{
6104
			return null;
6105
		}
6106
	}
6107
6108
	function get_copyright()
6109
	{
6110
		if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6111
		{
6112
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6113
		}
6114
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6115
		{
6116
			return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6117
		}
6118
		elseif ($return = $this->get_source_tags('', 'copyright'))
6119
		{
6120
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6121
		}
6122
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6123
		{
6124
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6125
		}
6126
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6127
		{
6128
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6129
		}
6130
		else
6131
		{
6132
			return null;
6133
		}
6134
	}
6135
6136
	function get_language()
6137
	{
6138
		if ($return = $this->get_source_tags('', 'language'))
6139
		{
6140
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6141
		}
6142
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6143
		{
6144
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6145
		}
6146
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6147
		{
6148
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6149
		}
6150
		elseif (isset($this->data['xml_lang']))
6151
		{
6152
			return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6153
		}
6154
		else
6155
		{
6156
			return null;
6157
		}
6158
	}
6159
6160
	function get_latitude()
6161
	{
6162
		if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6163
		{
6164
			return (float) $return[0]['data'];
6165
		}
6166
		elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6167
		{
6168
			return (float) $match[1];
6169
		}
6170
		else
6171
		{
6172
			return null;
6173
		}
6174
	}
6175
6176
	function get_longitude()
6177
	{
6178
		if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6179
		{
6180
			return (float) $return[0]['data'];
6181
		}
6182
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6183
		{
6184
			return (float) $return[0]['data'];
6185
		}
6186
		elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6187
		{
6188
			return (float) $match[2];
6189
		}
6190
		else
6191
		{
6192
			return null;
6193
		}
6194
	}
6195
6196
	function get_image_url()
6197
	{
6198
		if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6199
		{
6200
			return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6201
		}
6202
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6203
		{
6204
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6205
		}
6206
		elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6207
		{
6208
			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6209
		}
6210
		else
6211
		{
6212
			return null;
6213
		}
6214
	}
6215
}
6216
6217
class SimplePie_Author
6218
{
6219
	var $name;
6220
	var $link;
6221
	var $email;
6222
6223
	// Constructor, used to input the data
6224
	function SimplePie_Author($name = null, $link = null, $email = null)
6225
	{
6226
		$this->name = $name;
6227
		$this->link = $link;
6228
		$this->email = $email;
6229
	}
6230
6231
	function __toString()
6232
	{
6233
		// There is no $this->data here
6234
		return md5(serialize($this));
6235
	}
6236
6237
	function get_name()
6238
	{
6239
		if ($this->name !== null)
6240
		{
6241
			return $this->name;
6242
		}
6243
		else
6244
		{
6245
			return null;
6246
		}
6247
	}
6248
6249
	function get_link()
6250
	{
6251
		if ($this->link !== null)
6252
		{
6253
			return $this->link;
6254
		}
6255
		else
6256
		{
6257
			return null;
6258
		}
6259
	}
6260
6261
	function get_email()
6262
	{
6263
		if ($this->email !== null)
6264
		{
6265
			return $this->email;
6266
		}
6267
		else
6268
		{
6269
			return null;
6270
		}
6271
	}
6272
}
6273
6274
class SimplePie_Category
6275
{
6276
	var $term;
6277
	var $scheme;
6278
	var $label;
6279
6280
	// Constructor, used to input the data
6281
	function SimplePie_Category($term = null, $scheme = null, $label = null)
6282
	{
6283
		$this->term = $term;
6284
		$this->scheme = $scheme;
6285
		$this->label = $label;
6286
	}
6287
6288
	function __toString()
6289
	{
6290
		// There is no $this->data here
6291
		return md5(serialize($this));
6292
	}
6293
6294
	function get_term()
6295
	{
6296
		if ($this->term !== null)
6297
		{
6298
			return $this->term;
6299
		}
6300
		else
6301
		{
6302
			return null;
6303
		}
6304
	}
6305
6306
	function get_scheme()
6307
	{
6308
		if ($this->scheme !== null)
6309
		{
6310
			return $this->scheme;
6311
		}
6312
		else
6313
		{
6314
			return null;
6315
		}
6316
	}
6317
6318
	function get_label()
6319
	{
6320
		if ($this->label !== null)
6321
		{
6322
			return $this->label;
6323
		}
6324
		else
6325
		{
6326
			return $this->get_term();
6327
		}
6328
	}
6329
}
6330
6331
class SimplePie_Enclosure
6332
{
6333
	var $bitrate;
6334
	var $captions;
6335
	var $categories;
6336
	var $channels;
6337
	var $copyright;
6338
	var $credits;
6339
	var $description;
6340
	var $duration;
6341
	var $expression;
6342
	var $framerate;
6343
	var $handler;
6344
	var $hashes;
6345
	var $height;
6346
	var $javascript;
6347
	var $keywords;
6348
	var $lang;
6349
	var $length;
6350
	var $link;
6351
	var $medium;
6352
	var $player;
6353
	var $ratings;
6354
	var $restrictions;
6355
	var $samplingrate;
6356
	var $thumbnails;
6357
	var $title;
6358
	var $type;
6359
	var $width;
6360
6361
	// Constructor, used to input the data
6362
	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)
6363
	{
6364
		$this->bitrate = $bitrate;
6365
		$this->captions = $captions;
6366
		$this->categories = $categories;
6367
		$this->channels = $channels;
6368
		$this->copyright = $copyright;
6369
		$this->credits = $credits;
6370
		$this->description = $description;
6371
		$this->duration = $duration;
6372
		$this->expression = $expression;
6373
		$this->framerate = $framerate;
6374
		$this->hashes = $hashes;
6375
		$this->height = $height;
6376
		$this->javascript = $javascript;
6377
		$this->keywords = $keywords;
6378
		$this->lang = $lang;
6379
		$this->length = $length;
6380
		$this->link = $link;
6381
		$this->medium = $medium;
6382
		$this->player = $player;
6383
		$this->ratings = $ratings;
6384
		$this->restrictions = $restrictions;
6385
		$this->samplingrate = $samplingrate;
6386
		$this->thumbnails = $thumbnails;
6387
		$this->title = $title;
6388
		$this->type = $type;
6389
		$this->width = $width;
6390
		if (class_exists('idna_convert'))
6391
		{
6392 23ca5695 Chris Buechler
			$idn =& new idna_convert;
6393 b2e02eef Scott Ullrich
			$parsed = SimplePie_Misc::parse_url($link);
6394
			$this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6395
		}
6396
		$this->handler = $this->get_handler(); // Needs to load last
6397
	}
6398
6399
	function __toString()
6400
	{
6401
		// There is no $this->data here
6402
		return md5(serialize($this));
6403
	}
6404
6405
	function get_bitrate()
6406
	{
6407
		if ($this->bitrate !== null)
6408
		{
6409
			return $this->bitrate;
6410
		}
6411
		else
6412
		{
6413
			return null;
6414
		}
6415
	}
6416
6417
	function get_caption($key = 0)
6418
	{
6419
		$captions = $this->get_captions();
6420
		if (isset($captions[$key]))
6421
		{
6422
			return $captions[$key];
6423
		}
6424
		else
6425
		{
6426
			return null;
6427
		}
6428
	}
6429
6430
	function get_captions()
6431
	{
6432
		if ($this->captions !== null)
6433
		{
6434
			return $this->captions;
6435
		}
6436
		else
6437
		{
6438
			return null;
6439
		}
6440
	}
6441
6442
	function get_category($key = 0)
6443
	{
6444
		$categories = $this->get_categories();
6445
		if (isset($categories[$key]))
6446
		{
6447
			return $categories[$key];
6448
		}
6449
		else
6450
		{
6451
			return null;
6452
		}
6453
	}
6454
6455
	function get_categories()
6456
	{
6457
		if ($this->categories !== null)
6458
		{
6459
			return $this->categories;
6460
		}
6461
		else
6462
		{
6463
			return null;
6464
		}
6465
	}
6466
6467
	function get_channels()
6468
	{
6469
		if ($this->channels !== null)
6470
		{
6471
			return $this->channels;
6472
		}
6473
		else
6474
		{
6475
			return null;
6476
		}
6477
	}
6478
6479
	function get_copyright()
6480
	{
6481
		if ($this->copyright !== null)
6482
		{
6483
			return $this->copyright;
6484
		}
6485
		else
6486
		{
6487
			return null;
6488
		}
6489
	}
6490
6491
	function get_credit($key = 0)
6492
	{
6493
		$credits = $this->get_credits();
6494
		if (isset($credits[$key]))
6495
		{
6496
			return $credits[$key];
6497
		}
6498
		else
6499
		{
6500
			return null;
6501
		}
6502
	}
6503
6504
	function get_credits()
6505
	{
6506
		if ($this->credits !== null)
6507
		{
6508
			return $this->credits;
6509
		}
6510
		else
6511
		{
6512
			return null;
6513
		}
6514
	}
6515
6516
	function get_description()
6517
	{
6518
		if ($this->description !== null)
6519
		{
6520
			return $this->description;
6521
		}
6522
		else
6523
		{
6524
			return null;
6525
		}
6526
	}
6527
6528
	function get_duration($convert = false)
6529
	{
6530
		if ($this->duration !== null)
6531
		{
6532
			if ($convert)
6533
			{
6534
				$time = SimplePie_Misc::time_hms($this->duration);
6535
				return $time;
6536
			}
6537
			else
6538
			{
6539
				return $this->duration;
6540
			}
6541
		}
6542
		else
6543
		{
6544
			return null;
6545
		}
6546
	}
6547
6548
	function get_expression()
6549
	{
6550
		if ($this->expression !== null)
6551
		{
6552
			return $this->expression;
6553
		}
6554
		else
6555
		{
6556
			return 'full';
6557
		}
6558
	}
6559
6560
	function get_extension()
6561
	{
6562
		if ($this->link !== null)
6563
		{
6564
			$url = SimplePie_Misc::parse_url($this->link);
6565
			if ($url['path'] !== '')
6566
			{
6567
				return pathinfo($url['path'], PATHINFO_EXTENSION);
6568
			}
6569
		}
6570
		return null;
6571
	}
6572
6573
	function get_framerate()
6574
	{
6575
		if ($this->framerate !== null)
6576
		{
6577
			return $this->framerate;
6578
		}
6579
		else
6580
		{
6581
			return null;
6582
		}
6583
	}
6584
6585
	function get_handler()
6586
	{
6587
		return $this->get_real_type(true);
6588
	}
6589
6590
	function get_hash($key = 0)
6591
	{
6592
		$hashes = $this->get_hashes();
6593
		if (isset($hashes[$key]))
6594
		{
6595
			return $hashes[$key];
6596
		}
6597
		else
6598
		{
6599
			return null;
6600
		}
6601
	}
6602
6603
	function get_hashes()
6604
	{
6605
		if ($this->hashes !== null)
6606
		{
6607
			return $this->hashes;
6608
		}
6609
		else
6610
		{
6611
			return null;
6612
		}
6613
	}
6614
6615
	function get_height()
6616
	{
6617
		if ($this->height !== null)
6618
		{
6619
			return $this->height;
6620
		}
6621
		else
6622
		{
6623
			return null;
6624
		}
6625
	}
6626
6627
	function get_language()
6628
	{
6629
		if ($this->lang !== null)
6630
		{
6631
			return $this->lang;
6632
		}
6633
		else
6634
		{
6635
			return null;
6636
		}
6637
	}
6638
6639
	function get_keyword($key = 0)
6640
	{
6641
		$keywords = $this->get_keywords();
6642
		if (isset($keywords[$key]))
6643
		{
6644
			return $keywords[$key];
6645
		}
6646
		else
6647
		{
6648
			return null;
6649
		}
6650
	}
6651
6652
	function get_keywords()
6653
	{
6654
		if ($this->keywords !== null)
6655
		{
6656
			return $this->keywords;
6657
		}
6658
		else
6659
		{
6660
			return null;
6661
		}
6662
	}
6663
6664
	function get_length()
6665
	{
6666
		if ($this->length !== null)
6667
		{
6668
			return $this->length;
6669
		}
6670
		else
6671
		{
6672
			return null;
6673
		}
6674
	}
6675
6676
	function get_link()
6677
	{
6678
		if ($this->link !== null)
6679
		{
6680
			return urldecode($this->link);
6681
		}
6682
		else
6683
		{
6684
			return null;
6685
		}
6686
	}
6687
6688
	function get_medium()
6689
	{
6690
		if ($this->medium !== null)
6691
		{
6692
			return $this->medium;
6693
		}
6694
		else
6695
		{
6696
			return null;
6697
		}
6698
	}
6699
6700
	function get_player()
6701
	{
6702
		if ($this->player !== null)
6703
		{
6704
			return $this->player;
6705
		}
6706
		else
6707
		{
6708
			return null;
6709
		}
6710
	}
6711
6712
	function get_rating($key = 0)
6713
	{
6714
		$ratings = $this->get_ratings();
6715
		if (isset($ratings[$key]))
6716
		{
6717
			return $ratings[$key];
6718
		}
6719
		else
6720
		{
6721
			return null;
6722
		}
6723
	}
6724
6725
	function get_ratings()
6726
	{
6727
		if ($this->ratings !== null)
6728
		{
6729
			return $this->ratings;
6730
		}
6731
		else
6732
		{
6733
			return null;
6734
		}
6735
	}
6736
6737
	function get_restriction($key = 0)
6738
	{
6739
		$restrictions = $this->get_restrictions();
6740
		if (isset($restrictions[$key]))
6741
		{
6742
			return $restrictions[$key];
6743
		}
6744
		else
6745
		{
6746
			return null;
6747
		}
6748
	}
6749
6750
	function get_restrictions()
6751
	{
6752
		if ($this->restrictions !== null)
6753
		{
6754
			return $this->restrictions;
6755
		}
6756
		else
6757
		{
6758
			return null;
6759
		}
6760
	}
6761
6762
	function get_sampling_rate()
6763
	{
6764
		if ($this->samplingrate !== null)
6765
		{
6766
			return $this->samplingrate;
6767
		}
6768
		else
6769
		{
6770
			return null;
6771
		}
6772
	}
6773
6774
	function get_size()
6775
	{
6776
		$length = $this->get_length();
6777
		if ($length !== null)
6778
		{
6779
			return round($length/1048576, 2);
6780
		}
6781
		else
6782
		{
6783
			return null;
6784
		}
6785
	}
6786
6787
	function get_thumbnail($key = 0)
6788
	{
6789
		$thumbnails = $this->get_thumbnails();
6790
		if (isset($thumbnails[$key]))
6791
		{
6792
			return $thumbnails[$key];
6793
		}
6794
		else
6795
		{
6796
			return null;
6797
		}
6798
	}
6799
6800
	function get_thumbnails()
6801
	{
6802
		if ($this->thumbnails !== null)
6803
		{
6804
			return $this->thumbnails;
6805
		}
6806
		else
6807
		{
6808
			return null;
6809
		}
6810
	}
6811
6812
	function get_title()
6813
	{
6814
		if ($this->title !== null)
6815
		{
6816
			return $this->title;
6817
		}
6818
		else
6819
		{
6820
			return null;
6821
		}
6822
	}
6823
6824
	function get_type()
6825
	{
6826
		if ($this->type !== null)
6827
		{
6828
			return $this->type;
6829
		}
6830
		else
6831
		{
6832
			return null;
6833
		}
6834
	}
6835
6836
	function get_width()
6837
	{
6838
		if ($this->width !== null)
6839
		{
6840
			return $this->width;
6841
		}
6842
		else
6843
		{
6844
			return null;
6845
		}
6846
	}
6847
6848
	function native_embed($options='')
6849
	{
6850
		return $this->embed($options, true);
6851
	}
6852
6853
	/**
6854
	 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6855
	 */
6856
	function embed($options = '', $native = false)
6857
	{
6858
		// Set up defaults
6859
		$audio = '';
6860
		$video = '';
6861
		$alt = '';
6862
		$altclass = '';
6863
		$loop = 'false';
6864
		$width = 'auto';
6865
		$height = 'auto';
6866
		$bgcolor = '#ffffff';
6867
		$mediaplayer = '';
6868
		$widescreen = false;
6869
		$handler = $this->get_handler();
6870
		$type = $this->get_real_type();
6871
6872
		// Process options and reassign values as necessary
6873
		if (is_array($options))
6874
		{
6875
			extract($options);
6876
		}
6877
		else
6878
		{
6879
			$options = explode(',', $options);
6880
			foreach($options as $option)
6881
			{
6882
				$opt = explode(':', $option, 2);
6883
				if (isset($opt[0], $opt[1]))
6884
				{
6885
					$opt[0] = trim($opt[0]);
6886
					$opt[1] = trim($opt[1]);
6887
					switch ($opt[0])
6888
					{
6889
						case 'audio':
6890
							$audio = $opt[1];
6891
							break;
6892
6893
						case 'video':
6894
							$video = $opt[1];
6895
							break;
6896
6897
						case 'alt':
6898
							$alt = $opt[1];
6899
							break;
6900
6901
						case 'altclass':
6902
							$altclass = $opt[1];
6903
							break;
6904
6905
						case 'loop':
6906
							$loop = $opt[1];
6907
							break;
6908
6909
						case 'width':
6910
							$width = $opt[1];
6911
							break;
6912
6913
						case 'height':
6914
							$height = $opt[1];
6915
							break;
6916
6917
						case 'bgcolor':
6918
							$bgcolor = $opt[1];
6919
							break;
6920
6921
						case 'mediaplayer':
6922
							$mediaplayer = $opt[1];
6923
							break;
6924
6925
						case 'widescreen':
6926
							$widescreen = $opt[1];
6927
							break;
6928
					}
6929
				}
6930
			}
6931
		}
6932
6933
		$mime = explode('/', $type, 2);
6934
		$mime = $mime[0];
6935
6936
		// Process values for 'auto'
6937
		if ($width == 'auto')
6938
		{
6939
			if ($mime == 'video')
6940
			{
6941
				if ($height == 'auto')
6942
				{
6943
					$width = 480;
6944
				}
6945
				elseif ($widescreen)
6946
				{
6947
					$width = round((intval($height)/9)*16);
6948
				}
6949
				else
6950
				{
6951
					$width = round((intval($height)/3)*4);
6952
				}
6953
			}
6954
			else
6955
			{
6956
				$width = '100%';
6957
			}
6958
		}
6959
6960
		if ($height == 'auto')
6961
		{
6962
			if ($mime == 'audio')
6963
			{
6964
				$height = 0;
6965
			}
6966
			elseif ($mime == 'video')
6967
			{
6968
				if ($width == 'auto')
6969
				{
6970
					if ($widescreen)
6971
					{
6972
						$height = 270;
6973
					}
6974
					else
6975
					{
6976
						$height = 360;
6977
					}
6978
				}
6979
				elseif ($widescreen)
6980
				{
6981
					$height = round((intval($width)/16)*9);
6982
				}
6983
				else
6984
				{
6985
					$height = round((intval($width)/4)*3);
6986
				}
6987
			}
6988
			else
6989
			{
6990
				$height = 376;
6991
			}
6992
		}
6993
		elseif ($mime == 'audio')
6994
		{
6995
			$height = 0;
6996
		}
6997
6998
		// Set proper placeholder value
6999
		if ($mime == 'audio')
7000
		{
7001
			$placeholder = $audio;
7002
		}
7003
		elseif ($mime == 'video')
7004
		{
7005
			$placeholder = $video;
7006
		}
7007
7008
		$embed = '';
7009
7010
		// Make sure the JS library is included
7011
		if (!$native)
7012
		{
7013
			static $javascript_outputted = null;
7014
			if (!$javascript_outputted && $this->javascript)
7015
			{
7016
				$embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7017
				$javascript_outputted = true;
7018
			}
7019
		}
7020
7021
		// Odeo Feed MP3's
7022
		if ($handler == 'odeo')
7023
		{
7024
			if ($native)
7025
			{
7026
				$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>';
7027
			}
7028
			else
7029
			{
7030
				$embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
7031
			}
7032
		}
7033
7034
		// Flash
7035
		elseif ($handler == 'flash')
7036
		{
7037
			if ($native)
7038
			{
7039
				$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>";
7040
			}
7041
			else
7042
			{
7043
				$embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
7044
			}
7045
		}
7046
7047
		// Flash Media Player file types.
7048
		// Preferred handler for MP3 file types.
7049
		elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7050
		{
7051
			$height += 20;
7052
			if ($native)
7053
			{
7054
				$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>";
7055
			}
7056
			else
7057
			{
7058
				$embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7059
			}
7060
		}
7061
7062
		// QuickTime 7 file types.  Need to test with QuickTime 6.
7063
		// Only handle MP3's if the Flash Media Player is not present.
7064
		elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7065
		{
7066
			$height += 16;
7067
			if ($native)
7068
			{
7069
				if ($placeholder != ""){
7070
					$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>";
7071
				}
7072
				else {
7073
					$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>";
7074
				}
7075
			}
7076
			else
7077
			{
7078
				$embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7079
			}
7080
		}
7081
7082
		// Windows Media
7083
		elseif ($handler == 'wmedia')
7084
		{
7085
			$height += 45;
7086
			if ($native)
7087
			{
7088
				$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>";
7089
			}
7090
			else
7091
			{
7092
				$embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7093
			}
7094
		}
7095
7096
		// Everything else
7097
		else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7098
7099
		return $embed;
7100
	}
7101
7102
	function get_real_type($find_handler = false)
7103
	{
7104
		// If it's Odeo, let's get it out of the way.
7105
		if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
7106
		{
7107
			return 'odeo';
7108
		}
7109
7110
		// Mime-types by handler.
7111
		$types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7112
		$types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
7113
		$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
7114
		$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
7115
		$types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7116
7117
		if ($this->get_type() !== null)
7118
		{
7119
			$type = strtolower($this->type);
7120
		}
7121
		else
7122
		{
7123
			$type = null;
7124
		}
7125
7126
		// If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7127
		if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7128
		{
7129
			switch (strtolower($this->get_extension()))
7130
			{
7131
				// Audio mime-types
7132
				case 'aac':
7133
				case 'adts':
7134
					$type = 'audio/acc';
7135
					break;
7136
7137
				case 'aif':
7138
				case 'aifc':
7139
				case 'aiff':
7140
				case 'cdda':
7141
					$type = 'audio/aiff';
7142
					break;
7143
7144
				case 'bwf':
7145
					$type = 'audio/wav';
7146
					break;
7147
7148
				case 'kar':
7149
				case 'mid':
7150
				case 'midi':
7151
				case 'smf':
7152
					$type = 'audio/midi';
7153
					break;
7154
7155
				case 'm4a':
7156
					$type = 'audio/x-m4a';
7157
					break;
7158
7159
				case 'mp3':
7160
				case 'swa':
7161
					$type = 'audio/mp3';
7162
					break;
7163
7164
				case 'wav':
7165
					$type = 'audio/wav';
7166
					break;
7167
7168
				case 'wax':
7169
					$type = 'audio/x-ms-wax';
7170
					break;
7171
7172
				case 'wma':
7173
					$type = 'audio/x-ms-wma';
7174
					break;
7175
7176
				// Video mime-types
7177
				case '3gp':
7178
				case '3gpp':
7179
					$type = 'video/3gpp';
7180
					break;
7181
7182
				case '3g2':
7183
				case '3gp2':
7184
					$type = 'video/3gpp2';
7185
					break;
7186
7187
				case 'asf':
7188
					$type = 'video/x-ms-asf';
7189
					break;
7190
7191
				case 'flv':
7192
					$type = 'video/x-flv';
7193
					break;
7194
7195
				case 'm1a':
7196
				case 'm1s':
7197
				case 'm1v':
7198
				case 'm15':
7199
				case 'm75':
7200
				case 'mp2':
7201
				case 'mpa':
7202
				case 'mpeg':
7203
				case 'mpg':
7204
				case 'mpm':
7205
				case 'mpv':
7206
					$type = 'video/mpeg';
7207
					break;
7208
7209
				case 'm4v':
7210
					$type = 'video/x-m4v';
7211
					break;
7212
7213
				case 'mov':
7214
				case 'qt':
7215
					$type = 'video/quicktime';
7216
					break;
7217
7218
				case 'mp4':
7219
				case 'mpg4':
7220
					$type = 'video/mp4';
7221
					break;
7222
7223
				case 'sdv':
7224
					$type = 'video/sd-video';
7225
					break;
7226
7227
				case 'wm':
7228
					$type = 'video/x-ms-wm';
7229
					break;
7230
7231
				case 'wmv':
7232
					$type = 'video/x-ms-wmv';
7233
					break;
7234
7235
				case 'wvx':
7236
					$type = 'video/x-ms-wvx';
7237
					break;
7238
7239
				// Flash mime-types
7240
				case 'spl':
7241
					$type = 'application/futuresplash';
7242
					break;
7243
7244
				case 'swf':
7245
					$type = 'application/x-shockwave-flash';
7246
					break;
7247
			}
7248
		}
7249
7250
		if ($find_handler)
7251
		{
7252
			if (in_array($type, $types_flash))
7253
			{
7254
				return 'flash';
7255
			}
7256
			elseif (in_array($type, $types_fmedia))
7257
			{
7258
				return 'fmedia';
7259
			}
7260
			elseif (in_array($type, $types_quicktime))
7261
			{
7262
				return 'quicktime';
7263
			}
7264
			elseif (in_array($type, $types_wmedia))
7265
			{
7266
				return 'wmedia';
7267
			}
7268
			elseif (in_array($type, $types_mp3))
7269
			{
7270
				return 'mp3';
7271
			}
7272
			else
7273
			{
7274
				return null;
7275
			}
7276
		}
7277
		else
7278
		{
7279
			return $type;
7280
		}
7281
	}
7282
}
7283
7284
class SimplePie_Caption
7285
{
7286
	var $type;
7287
	var $lang;
7288
	var $startTime;
7289
	var $endTime;
7290
	var $text;
7291
7292
	// Constructor, used to input the data
7293
	function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7294
	{
7295
		$this->type = $type;
7296
		$this->lang = $lang;
7297
		$this->startTime = $startTime;
7298
		$this->endTime = $endTime;
7299
		$this->text = $text;
7300
	}
7301
7302
	function __toString()
7303
	{
7304
		// There is no $this->data here
7305
		return md5(serialize($this));
7306
	}
7307
7308
	function get_endtime()
7309
	{
7310
		if ($this->endTime !== null)
7311
		{
7312
			return $this->endTime;
7313
		}
7314
		else
7315
		{
7316
			return null;
7317
		}
7318
	}
7319
7320
	function get_language()
7321
	{
7322
		if ($this->lang !== null)
7323
		{
7324
			return $this->lang;
7325
		}
7326
		else
7327
		{
7328
			return null;
7329
		}
7330
	}
7331
7332
	function get_starttime()
7333
	{
7334
		if ($this->startTime !== null)
7335
		{
7336
			return $this->startTime;
7337
		}
7338
		else
7339
		{
7340
			return null;
7341
		}
7342
	}
7343
7344
	function get_text()
7345
	{
7346
		if ($this->text !== null)
7347
		{
7348
			return $this->text;
7349
		}
7350
		else
7351
		{
7352
			return null;
7353
		}
7354
	}
7355
7356
	function get_type()
7357
	{
7358
		if ($this->type !== null)
7359
		{
7360
			return $this->type;
7361
		}
7362
		else
7363
		{
7364
			return null;
7365
		}
7366
	}
7367
}
7368
7369
class SimplePie_Credit
7370
{
7371
	var $role;
7372
	var $scheme;
7373
	var $name;
7374
7375
	// Constructor, used to input the data
7376
	function SimplePie_Credit($role = null, $scheme = null, $name = null)
7377
	{
7378
		$this->role = $role;
7379
		$this->scheme = $scheme;
7380
		$this->name = $name;
7381
	}
7382
7383
	function __toString()
7384
	{
7385
		// There is no $this->data here
7386
		return md5(serialize($this));
7387
	}
7388
7389
	function get_role()
7390
	{
7391
		if ($this->role !== null)
7392
		{
7393
			return $this->role;
7394
		}
7395
		else
7396
		{
7397
			return null;
7398
		}
7399
	}
7400
7401
	function get_scheme()
7402
	{
7403
		if ($this->scheme !== null)
7404
		{
7405
			return $this->scheme;
7406
		}
7407
		else
7408
		{
7409
			return null;
7410
		}
7411
	}
7412
7413
	function get_name()
7414
	{
7415
		if ($this->name !== null)
7416
		{
7417
			return $this->name;
7418
		}
7419
		else
7420
		{
7421
			return null;
7422
		}
7423
	}
7424
}
7425
7426
class SimplePie_Copyright
7427
{
7428
	var $url;
7429
	var $label;
7430
7431
	// Constructor, used to input the data
7432
	function SimplePie_Copyright($url = null, $label = null)
7433
	{
7434
		$this->url = $url;
7435
		$this->label = $label;
7436
	}
7437
7438
	function __toString()
7439
	{
7440
		// There is no $this->data here
7441
		return md5(serialize($this));
7442
	}
7443
7444
	function get_url()
7445
	{
7446
		if ($this->url !== null)
7447
		{
7448
			return $this->url;
7449
		}
7450
		else
7451
		{
7452
			return null;
7453
		}
7454
	}
7455
7456
	function get_attribution()
7457
	{
7458
		if ($this->label !== null)
7459
		{
7460
			return $this->label;
7461
		}
7462
		else
7463
		{
7464
			return null;
7465
		}
7466
	}
7467
}
7468
7469
class SimplePie_Rating
7470
{
7471
	var $scheme;
7472
	var $value;
7473
7474
	// Constructor, used to input the data
7475
	function SimplePie_Rating($scheme = null, $value = null)
7476
	{
7477
		$this->scheme = $scheme;
7478
		$this->value = $value;
7479
	}
7480
7481
	function __toString()
7482
	{
7483
		// There is no $this->data here
7484
		return md5(serialize($this));
7485
	}
7486
7487
	function get_scheme()
7488
	{
7489
		if ($this->scheme !== null)
7490
		{
7491
			return $this->scheme;
7492
		}
7493
		else
7494
		{
7495
			return null;
7496
		}
7497
	}
7498
7499
	function get_value()
7500
	{
7501
		if ($this->value !== null)
7502
		{
7503
			return $this->value;
7504
		}
7505
		else
7506
		{
7507
			return null;
7508
		}
7509
	}
7510
}
7511
7512
class SimplePie_Restriction
7513
{
7514
	var $relationship;
7515
	var $type;
7516
	var $value;
7517
7518
	// Constructor, used to input the data
7519
	function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7520
	{
7521
		$this->relationship = $relationship;
7522
		$this->type = $type;
7523
		$this->value = $value;
7524
	}
7525
7526
	function __toString()
7527
	{
7528
		// There is no $this->data here
7529
		return md5(serialize($this));
7530
	}
7531
7532
	function get_relationship()
7533
	{
7534
		if ($this->relationship !== null)
7535
		{
7536
			return $this->relationship;
7537
		}
7538
		else
7539
		{
7540
			return null;
7541
		}
7542
	}
7543
7544
	function get_type()
7545
	{
7546
		if ($this->type !== null)
7547
		{
7548
			return $this->type;
7549
		}
7550
		else
7551
		{
7552
			return null;
7553
		}
7554
	}
7555
7556
	function get_value()
7557
	{
7558
		if ($this->value !== null)
7559
		{
7560
			return $this->value;
7561
		}
7562
		else
7563
		{
7564
			return null;
7565
		}
7566
	}
7567
}
7568
7569
/**
7570
 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7571
 */
7572
class SimplePie_File
7573
{
7574
	var $url;
7575
	var $useragent;
7576
	var $success = true;
7577
	var $headers = array();
7578
	var $body;
7579
	var $status_code;
7580
	var $redirects = 0;
7581
	var $error;
7582
	var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7583
7584
	function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7585
	{
7586
		if (class_exists('idna_convert'))
7587
		{
7588 23ca5695 Chris Buechler
			$idn =& new idna_convert;
7589 b2e02eef Scott Ullrich
			$parsed = SimplePie_Misc::parse_url($url);
7590
			$url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7591
		}
7592
		$this->url = $url;
7593
		$this->useragent = $useragent;
7594
		if (preg_match('/^http(s)?:\/\//i', $url))
7595
		{
7596
			if ($useragent === null)
7597
			{
7598
				$useragent = ini_get('user_agent');
7599
				$this->useragent = $useragent;
7600
			}
7601
			if (!is_array($headers))
7602
			{
7603
				$headers = array();
7604
			}
7605
			if (!$force_fsockopen && function_exists('curl_exec'))
7606
			{
7607
				$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7608
				$fp = curl_init();
7609
				$headers2 = array();
7610
				foreach ($headers as $key => $value)
7611
				{
7612
					$headers2[] = "$key: $value";
7613
				}
7614
				if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7615
				{
7616
					curl_setopt($fp, CURLOPT_ENCODING, '');
7617
				}
7618
				curl_setopt($fp, CURLOPT_URL, $url);
7619
				curl_setopt($fp, CURLOPT_HEADER, 1);
7620
				curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7621
				curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7622
				curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7623
				curl_setopt($fp, CURLOPT_REFERER, $url);
7624
				curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7625
				curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7626
				if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7627
				{
7628
					curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7629
					curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7630
				}
7631
7632
				$this->headers = curl_exec($fp);
7633
				if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7634
				{
7635
					curl_setopt($fp, CURLOPT_ENCODING, 'none');
7636
					$this->headers = curl_exec($fp);
7637
				}
7638
				if (curl_errno($fp))
7639
				{
7640
					$this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7641
					$this->success = false;
7642
				}
7643
				else
7644
				{
7645
					$info = curl_getinfo($fp);
7646
					curl_close($fp);
7647
					$this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7648
					$this->headers = array_pop($this->headers);
7649 23ca5695 Chris Buechler
					$parser =& new SimplePie_HTTP_Parser($this->headers);
7650 b2e02eef Scott Ullrich
					if ($parser->parse())
7651
					{
7652
						$this->headers = $parser->headers;
7653
						$this->body = $parser->body;
7654
						$this->status_code = $parser->status_code;
7655
						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)
7656
						{
7657
							$this->redirects++;
7658
							$location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7659
							return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7660
						}
7661
					}
7662
				}
7663
			}
7664
			else
7665
			{
7666
				$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7667
				$url_parts = parse_url($url);
7668
				if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7669
				{
7670
					$url_parts['host'] = "ssl://$url_parts[host]";
7671
					$url_parts['port'] = 443;
7672
				}
7673
				if (!isset($url_parts['port']))
7674
				{
7675
					$url_parts['port'] = 80;
7676
				}
7677
				$fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7678
				if (!$fp)
7679
				{
7680
					$this->error = 'fsockopen error: ' . $errstr;
7681
					$this->success = false;
7682
				}
7683
				else
7684
				{
7685
					stream_set_timeout($fp, $timeout);
7686
					if (isset($url_parts['path']))
7687
					{
7688
						if (isset($url_parts['query']))
7689
						{
7690
							$get = "$url_parts[path]?$url_parts[query]";
7691
						}
7692
						else
7693
						{
7694
							$get = $url_parts['path'];
7695
						}
7696
					}
7697
					else
7698
					{
7699
						$get = '/';
7700
					}
7701
					$out = "GET $get HTTP/1.0\r\n";
7702
					$out .= "Host: $url_parts[host]\r\n";
7703
					$out .= "User-Agent: $useragent\r\n";
7704
					if (extension_loaded('zlib'))
7705
					{
7706
						$out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7707
					}
7708
7709
					if (isset($url_parts['user']) && isset($url_parts['pass']))
7710
					{
7711
						$out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7712
					}
7713
					foreach ($headers as $key => $value)
7714
					{
7715
						$out .= "$key: $value\r\n";
7716
					}
7717
					$out .= "Connection: Close\r\n\r\n";
7718
					fwrite($fp, $out);
7719
7720
					$info = stream_get_meta_data($fp);
7721
7722
					$this->headers = '';
7723
					while (!$info['eof'] && !$info['timed_out'])
7724
					{
7725
						$this->headers .= fread($fp, 1160);
7726
						$info = stream_get_meta_data($fp);
7727
					}
7728
					if (!$info['timed_out'])
7729
					{
7730 23ca5695 Chris Buechler
						$parser =& new SimplePie_HTTP_Parser($this->headers);
7731 b2e02eef Scott Ullrich
						if ($parser->parse())
7732
						{
7733
							$this->headers = $parser->headers;
7734
							$this->body = $parser->body;
7735
							$this->status_code = $parser->status_code;
7736
							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)
7737
							{
7738
								$this->redirects++;
7739
								$location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7740
								return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7741
							}
7742
							if (isset($this->headers['content-encoding']))
7743
							{
7744
								// Hey, we act dumb elsewhere, so let's do that here too
7745
								switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
7746
								{
7747
									case 'gzip':
7748
									case 'x-gzip':
7749
										$decoder = new SimplePie_gzdecode($this->body);
7750
										if (!$decoder->parse())
7751
										{
7752
											$this->error = 'Unable to decode HTTP "gzip" stream';
7753
											$this->success = false;
7754
										}
7755
										else
7756
										{
7757
											$this->body = $decoder->data;
7758
										}
7759
										break;
7760
7761
									case 'deflate':
7762
										if (($body = gzuncompress($this->body)) === false)
7763
										{
7764
											if (($body = gzinflate($this->body)) === false)
7765
											{
7766
												$this->error = 'Unable to decode HTTP "deflate" stream';
7767
												$this->success = false;
7768
											}
7769
										}
7770
										$this->body = $body;
7771
										break;
7772
7773
									default:
7774
										$this->error = 'Unknown content coding';
7775
										$this->success = false;
7776
								}
7777
							}
7778
						}
7779
					}
7780
					else
7781
					{
7782
						$this->error = 'fsocket timed out';
7783
						$this->success = false;
7784
					}
7785
					fclose($fp);
7786
				}
7787
			}
7788
		}
7789
		else
7790
		{
7791
			$this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7792
			if (!$this->body = file_get_contents($url))
7793
			{
7794
				$this->error = 'file_get_contents could not read the file';
7795
				$this->success = false;
7796
			}
7797
		}
7798
	}
7799
}
7800
7801
/**
7802
 * HTTP Response Parser
7803
 *
7804
 * @package SimplePie
7805
 */
7806
class SimplePie_HTTP_Parser
7807
{
7808
	/**
7809
	 * HTTP Version
7810
	 *
7811
	 * @access public
7812
	 * @var float
7813
	 */
7814
	var $http_version = 0.0;
7815
7816
	/**
7817
	 * Status code
7818
	 *
7819
	 * @access public
7820
	 * @var int
7821
	 */
7822
	var $status_code = 0;
7823
7824
	/**
7825
	 * Reason phrase
7826
	 *
7827
	 * @access public
7828
	 * @var string
7829
	 */
7830
	var $reason = '';
7831
7832
	/**
7833
	 * Key/value pairs of the headers
7834
	 *
7835
	 * @access public
7836
	 * @var array
7837
	 */
7838
	var $headers = array();
7839
7840
	/**
7841
	 * Body of the response
7842
	 *
7843
	 * @access public
7844
	 * @var string
7845
	 */
7846
	var $body = '';
7847
7848
	/**
7849
	 * Current state of the state machine
7850
	 *
7851
	 * @access private
7852
	 * @var string
7853
	 */
7854
	var $state = 'http_version';
7855
7856
	/**
7857
	 * Input data
7858
	 *
7859
	 * @access private
7860
	 * @var string
7861
	 */
7862
	var $data = '';
7863
7864
	/**
7865
	 * Input data length (to avoid calling strlen() everytime this is needed)
7866
	 *
7867
	 * @access private
7868
	 * @var int
7869
	 */
7870
	var $data_length = 0;
7871
7872
	/**
7873
	 * Current position of the pointer
7874
	 *
7875
	 * @var int
7876
	 * @access private
7877
	 */
7878
	var $position = 0;
7879
7880
	/**
7881
	 * Name of the hedaer currently being parsed
7882
	 *
7883
	 * @access private
7884
	 * @var string
7885
	 */
7886
	var $name = '';
7887
7888
	/**
7889
	 * Value of the hedaer currently being parsed
7890
	 *
7891
	 * @access private
7892
	 * @var string
7893
	 */
7894
	var $value = '';
7895
7896
	/**
7897
	 * Create an instance of the class with the input data
7898
	 *
7899
	 * @access public
7900
	 * @param string $data Input data
7901
	 */
7902
	function SimplePie_HTTP_Parser($data)
7903
	{
7904
		$this->data = $data;
7905
		$this->data_length = strlen($this->data);
7906
	}
7907
7908
	/**
7909
	 * Parse the input data
7910
	 *
7911
	 * @access public
7912
	 * @return bool true on success, false on failure
7913
	 */
7914
	function parse()
7915
	{
7916
		while ($this->state && $this->state !== 'emit' && $this->has_data())
7917
		{
7918
			$state = $this->state;
7919
			$this->$state();
7920
		}
7921
		$this->data = '';
7922
		if ($this->state === 'emit' || $this->state === 'body')
7923
		{
7924
			return true;
7925
		}
7926
		else
7927
		{
7928
			$this->http_version = '';
7929
			$this->status_code = '';
7930
			$this->reason = '';
7931
			$this->headers = array();
7932
			$this->body = '';
7933
			return false;
7934
		}
7935
	}
7936
7937
	/**
7938
	 * Check whether there is data beyond the pointer
7939
	 *
7940
	 * @access private
7941
	 * @return bool true if there is further data, false if not
7942
	 */
7943
	function has_data()
7944
	{
7945
		return (bool) ($this->position < $this->data_length);
7946
	}
7947
7948
	/**
7949
	 * See if the next character is LWS
7950
	 *
7951
	 * @access private
7952
	 * @return bool true if the next character is LWS, false if not
7953
	 */
7954
	function is_linear_whitespace()
7955
	{
7956
		return (bool) ($this->data[$this->position] === "\x09"
7957
			|| $this->data[$this->position] === "\x20"
7958
			|| ($this->data[$this->position] === "\x0A"
7959
				&& isset($this->data[$this->position + 1])
7960
				&& ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
7961
	}
7962
7963
	/**
7964
	 * Parse the HTTP version
7965
	 *
7966
	 * @access private
7967
	 */
7968
	function http_version()
7969
	{
7970
		if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
7971
		{
7972
			$len = strspn($this->data, '0123456789.', 5);
7973
			$this->http_version = substr($this->data, 5, $len);
7974
			$this->position += 5 + $len;
7975
			if (substr_count($this->http_version, '.') <= 1)
7976
			{
7977
				$this->http_version = (float) $this->http_version;
7978
				$this->position += strspn($this->data, "\x09\x20", $this->position);
7979
				$this->state = 'status';
7980
			}
7981
			else
7982
			{
7983
				$this->state = false;
7984
			}
7985
		}
7986
		else
7987
		{
7988
			$this->state = false;
7989
		}
7990
	}
7991
7992
	/**
7993
	 * Parse the status code
7994
	 *
7995
	 * @access private
7996
	 */
7997
	function status()
7998
	{
7999
		if ($len = strspn($this->data, '0123456789', $this->position))
8000
		{
8001
			$this->status_code = (int) substr($this->data, $this->position, $len);
8002
			$this->position += $len;
8003
			$this->state = 'reason';
8004
		}
8005
		else
8006
		{
8007
			$this->state = false;
8008
		}
8009
	}
8010
8011
	/**
8012
	 * Parse the reason phrase
8013
	 *
8014
	 * @access private
8015
	 */
8016
	function reason()
8017
	{
8018
		$len = strcspn($this->data, "\x0A", $this->position);
8019
		$this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
8020
		$this->position += $len + 1;
8021
		$this->state = 'new_line';
8022
	}
8023
8024
	/**
8025
	 * Deal with a new line, shifting data around as needed
8026
	 *
8027
	 * @access private
8028
	 */
8029
	function new_line()
8030
	{
8031
		$this->value = trim($this->value, "\x0D\x20");
8032
		if ($this->name !== '' && $this->value !== '')
8033
		{
8034
			$this->name = strtolower($this->name);
8035
			if (isset($this->headers[$this->name]))
8036
			{
8037
				$this->headers[$this->name] .= ', ' . $this->value;
8038
			}
8039
			else
8040
			{
8041
				$this->headers[$this->name] = $this->value;
8042
			}
8043
		}
8044
		$this->name = '';
8045
		$this->value = '';
8046
		if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8047
		{
8048
			$this->position += 2;
8049
			$this->state = 'body';
8050
		}
8051
		elseif ($this->data[$this->position] === "\x0A")
8052
		{
8053
			$this->position++;
8054
			$this->state = 'body';
8055
		}
8056
		else
8057
		{
8058
			$this->state = 'name';
8059
		}
8060
	}
8061
8062
	/**
8063
	 * Parse a header name
8064
	 *
8065
	 * @access private
8066
	 */
8067
	function name()
8068
	{
8069
		$len = strcspn($this->data, "\x0A:", $this->position);
8070
		if (isset($this->data[$this->position + $len]))
8071
		{
8072
			if ($this->data[$this->position + $len] === "\x0A")
8073
			{
8074
				$this->position += $len;
8075
				$this->state = 'new_line';
8076
			}
8077
			else
8078
			{
8079
				$this->name = substr($this->data, $this->position, $len);
8080
				$this->position += $len + 1;
8081
				$this->state = 'value';
8082
			}
8083
		}
8084
		else
8085
		{
8086
			$this->state = false;
8087
		}
8088
	}
8089
8090
	/**
8091
	 * Parse LWS, replacing consecutive LWS characters with a single space
8092
	 *
8093
	 * @access private
8094
	 */
8095
	function linear_whitespace()
8096
	{
8097
		do
8098
		{
8099
			if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8100
			{
8101
				$this->position += 2;
8102
			}
8103
			elseif ($this->data[$this->position] === "\x0A")
8104
			{
8105
				$this->position++;
8106
			}
8107
			$this->position += strspn($this->data, "\x09\x20", $this->position);
8108
		} while ($this->has_data() && $this->is_linear_whitespace());
8109
		$this->value .= "\x20";
8110
	}
8111
8112
	/**
8113
	 * See what state to move to while within non-quoted header values
8114
	 *
8115
	 * @access private
8116
	 */
8117
	function value()
8118
	{
8119
		if ($this->is_linear_whitespace())
8120
		{
8121
			$this->linear_whitespace();
8122
		}
8123
		else
8124
		{
8125
			switch ($this->data[$this->position])
8126
			{
8127
				case '"':
8128
					$this->position++;
8129
					$this->state = 'quote';
8130
					break;
8131
8132
				case "\x0A":
8133
					$this->position++;
8134
					$this->state = 'new_line';
8135
					break;
8136
8137
				default:
8138
					$this->state = 'value_char';
8139
					break;
8140
			}
8141
		}
8142
	}
8143
8144
	/**
8145
	 * Parse a header value while outside quotes
8146
	 *
8147
	 * @access private
8148
	 */
8149
	function value_char()
8150
	{
8151
		$len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8152
		$this->value .= substr($this->data, $this->position, $len);
8153
		$this->position += $len;
8154
		$this->state = 'value';
8155
	}
8156
8157
	/**
8158
	 * See what state to move to while within quoted header values
8159
	 *
8160
	 * @access private
8161
	 */
8162
	function quote()
8163
	{
8164
		if ($this->is_linear_whitespace())
8165
		{
8166
			$this->linear_whitespace();
8167
		}
8168
		else
8169
		{
8170
			switch ($this->data[$this->position])
8171
			{
8172
				case '"':
8173
					$this->position++;
8174
					$this->state = 'value';
8175
					break;
8176
8177
				case "\x0A":
8178
					$this->position++;
8179
					$this->state = 'new_line';
8180
					break;
8181
8182
				case '\\':
8183
					$this->position++;
8184
					$this->state = 'quote_escaped';
8185
					break;
8186
8187
				default:
8188
					$this->state = 'quote_char';
8189
					break;
8190
			}
8191
		}
8192
	}
8193
8194
	/**
8195
	 * Parse a header value while within quotes
8196
	 *
8197
	 * @access private
8198
	 */
8199
	function quote_char()
8200
	{
8201
		$len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8202
		$this->value .= substr($this->data, $this->position, $len);
8203
		$this->position += $len;
8204
		$this->state = 'value';
8205
	}
8206
8207
	/**
8208
	 * Parse an escaped character within quotes
8209
	 *
8210
	 * @access private
8211
	 */
8212
	function quote_escaped()
8213
	{
8214
		$this->value .= $this->data[$this->position];
8215
		$this->position++;
8216
		$this->state = 'quote';
8217
	}
8218
8219
	/**
8220
	 * Parse the body
8221
	 *
8222
	 * @access private
8223
	 */
8224
	function body()
8225
	{
8226
		$this->body = substr($this->data, $this->position);
8227
		$this->state = 'emit';
8228
	}
8229
}
8230
8231
/**
8232
 * gzdecode
8233
 *
8234
 * @package SimplePie
8235
 */
8236
class SimplePie_gzdecode
8237
{
8238
	/**
8239
	 * Compressed data
8240
	 *
8241
	 * @access private
8242
	 * @see gzdecode::$data
8243
	 */
8244
	var $compressed_data;
8245
8246
	/**
8247
	 * Size of compressed data
8248
	 *
8249
	 * @access private
8250
	 */
8251
	var $compressed_size;
8252
8253
	/**
8254
	 * Minimum size of a valid gzip string
8255
	 *
8256
	 * @access private
8257
	 */
8258
	var $min_compressed_size = 18;
8259
8260
	/**
8261
	 * Current position of pointer
8262
	 *
8263
	 * @access private
8264
	 */
8265
	var $position = 0;
8266
8267
	/**
8268
	 * Flags (FLG)
8269
	 *
8270
	 * @access private
8271
	 */
8272
	var $flags;
8273
8274
	/**
8275
	 * Uncompressed data
8276
	 *
8277
	 * @access public
8278
	 * @see gzdecode::$compressed_data
8279
	 */
8280
	var $data;
8281
8282
	/**
8283
	 * Modified time
8284
	 *
8285
	 * @access public
8286
	 */
8287
	var $MTIME;
8288
8289
	/**
8290
	 * Extra Flags
8291
	 *
8292
	 * @access public
8293
	 */
8294
	var $XFL;
8295
8296
	/**
8297
	 * Operating System
8298
	 *
8299
	 * @access public
8300
	 */
8301
	var $OS;
8302
8303
	/**
8304
	 * Subfield ID 1
8305
	 *
8306
	 * @access public
8307
	 * @see gzdecode::$extra_field
8308
	 * @see gzdecode::$SI2
8309
	 */
8310
	var $SI1;
8311
8312
	/**
8313
	 * Subfield ID 2
8314
	 *
8315
	 * @access public
8316
	 * @see gzdecode::$extra_field
8317
	 * @see gzdecode::$SI1
8318
	 */
8319
	var $SI2;
8320
8321
	/**
8322
	 * Extra field content
8323
	 *
8324
	 * @access public
8325
	 * @see gzdecode::$SI1
8326
	 * @see gzdecode::$SI2
8327
	 */
8328
	var $extra_field;
8329
8330
	/**
8331
	 * Original filename
8332
	 *
8333
	 * @access public
8334
	 */
8335
	var $filename;
8336
8337
	/**
8338
	 * Human readable comment
8339
	 *
8340
	 * @access public
8341
	 */
8342
	var $comment;
8343
8344
	/**
8345
	 * Don't allow anything to be set
8346
	 *
8347
	 * @access public
8348
	 */
8349
	function __set($name, $value)
8350
	{
8351
		trigger_error("Cannot write property $name", E_USER_ERROR);
8352
	}
8353
8354
	/**
8355
	 * Set the compressed string and related properties
8356
	 *
8357
	 * @access public
8358
	 */
8359
	function SimplePie_gzdecode($data)
8360
	{
8361
		$this->compressed_data = $data;
8362
		$this->compressed_size = strlen($data);
8363
	}
8364
8365
	/**
8366
	 * Decode the GZIP stream
8367
	 *
8368
	 * @access public
8369
	 */
8370
	function parse()
8371
	{
8372
		if ($this->compressed_size >= $this->min_compressed_size)
8373
		{
8374
			// Check ID1, ID2, and CM
8375
			if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
8376
			{
8377
				return false;
8378
			}
8379
8380
			// Get the FLG (FLaGs)
8381
			$this->flags = ord($this->compressed_data[3]);
8382
8383
			// FLG bits above (1 << 4) are reserved
8384
			if ($this->flags > 0x1F)
8385
			{
8386
				return false;
8387
			}
8388
8389
			// Advance the pointer after the above
8390
			$this->position += 4;
8391
8392
			// MTIME
8393
			$mtime = substr($this->compressed_data, $this->position, 4);
8394
			// Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8395
			if (current(unpack('S', "\x00\x01")) === 1)
8396
			{
8397
				$mtime = strrev($mtime);
8398
			}
8399
			$this->MTIME = current(unpack('l', $mtime));
8400
			$this->position += 4;
8401
8402
			// Get the XFL (eXtra FLags)
8403
			$this->XFL = ord($this->compressed_data[$this->position++]);
8404
8405
			// Get the OS (Operating System)
8406
			$this->OS = ord($this->compressed_data[$this->position++]);
8407
8408
			// Parse the FEXTRA
8409
			if ($this->flags & 4)
8410
			{
8411
				// Read subfield IDs
8412
				$this->SI1 = $this->compressed_data[$this->position++];
8413
				$this->SI2 = $this->compressed_data[$this->position++];
8414
8415
				// SI2 set to zero is reserved for future use
8416
				if ($this->SI2 === "\x00")
8417
				{
8418
					return false;
8419
				}
8420
8421
				// Get the length of the extra field
8422
				$len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8423
				$position += 2;
8424
8425
				// Check the length of the string is still valid
8426
				$this->min_compressed_size += $len + 4;
8427
				if ($this->compressed_size >= $this->min_compressed_size)
8428
				{
8429
					// Set the extra field to the given data
8430
					$this->extra_field = substr($this->compressed_data, $this->position, $len);
8431
					$this->position += $len;
8432
				}
8433
				else
8434
				{
8435
					return false;
8436
				}
8437
			}
8438
8439
			// Parse the FNAME
8440
			if ($this->flags & 8)
8441
			{
8442
				// Get the length of the filename
8443
				$len = strspn($this->compressed_data, "\x00", $this->position);
8444
8445
				// Check the length of the string is still valid
8446
				$this->min_compressed_size += $len + 1;
8447
				if ($this->compressed_size >= $this->min_compressed_size)
8448
				{
8449
					// Set the original filename to the given string
8450
					$this->filename = substr($this->compressed_data, $this->position, $len);
8451
					$this->position += $len + 1;
8452
				}
8453
				else
8454
				{
8455
					return false;
8456
				}
8457
			}
8458
8459
			// Parse the FCOMMENT
8460
			if ($this->flags & 16)
8461
			{
8462
				// Get the length of the comment
8463
				$len = strspn($this->compressed_data, "\x00", $this->position);
8464
8465
				// Check the length of the string is still valid
8466
				$this->min_compressed_size += $len + 1;
8467
				if ($this->compressed_size >= $this->min_compressed_size)
8468
				{
8469
					// Set the original comment to the given string
8470
					$this->comment = substr($this->compressed_data, $this->position, $len);
8471
					$this->position += $len + 1;
8472
				}
8473
				else
8474
				{
8475
					return false;
8476
				}
8477
			}
8478
8479
			// Parse the FHCRC
8480
			if ($this->flags & 2)
8481
			{
8482
				// Check the length of the string is still valid
8483
				$this->min_compressed_size += $len + 2;
8484
				if ($this->compressed_size >= $this->min_compressed_size)
8485
				{
8486
					// Read the CRC
8487
					$crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8488
8489
					// Check the CRC matches
8490
					if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
8491
					{
8492
						$this->position += 2;
8493
					}
8494
					else
8495
					{
8496
						return false;
8497
					}
8498
				}
8499
				else
8500
				{
8501
					return false;
8502
				}
8503
			}
8504
8505
			// Decompress the actual data
8506
			if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
8507
			{
8508
				return false;
8509
			}
8510
			else
8511
			{
8512
				$this->position = $this->compressed_size - 8;
8513
			}
8514
8515
			// Check CRC of data
8516
			$crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8517
			$this->position += 4;
8518
			/*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8519
			{
8520
				return false;
8521
			}*/
8522
8523
			// Check ISIZE of data
8524
			$isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8525
			$this->position += 4;
8526
			if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8527
			{
8528
				return false;
8529
			}
8530
8531
			// Wow, against all odds, we've actually got a valid gzip string
8532
			return true;
8533
		}
8534
		else
8535
		{
8536
			return false;
8537
		}
8538
	}
8539
}
8540
8541
class SimplePie_Cache
8542
{
8543
	/**
8544
	 * Don't call the constructor. Please.
8545
	 *
8546
	 * @access private
8547
	 */
8548
	function SimplePie_Cache()
8549
	{
8550
		trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8551
	}
8552
8553
	/**
8554
	 * Create a new SimplePie_Cache object
8555
	 *
8556
	 * @static
8557
	 * @access public
8558
	 */
8559 23ca5695 Chris Buechler
	function create($location, $filename, $extension)
8560 b2e02eef Scott Ullrich
	{
8561
		return new SimplePie_Cache_File($location, $filename, $extension);
8562
	}
8563
}
8564
8565
class SimplePie_Cache_File
8566
{
8567
	var $location;
8568
	var $filename;
8569
	var $extension;
8570
	var $name;
8571
8572
	function SimplePie_Cache_File($location, $filename, $extension)
8573
	{
8574
		$this->location = $location;
8575
		$this->filename = rawurlencode($filename);
8576
		$this->extension = rawurlencode($extension);
8577
		$this->name = "$location/$this->filename.$this->extension";
8578
	}
8579
8580
	function save($data)
8581
	{
8582
		if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8583
		{
8584
			if (is_a($data, 'SimplePie'))
8585
			{
8586
				$data = $data->data;
8587
			}
8588
8589
			$data = serialize($data);
8590
8591
			if (function_exists('file_put_contents'))
8592
			{
8593
				return (bool) file_put_contents($this->name, $data);
8594
			}
8595
			else
8596
			{
8597
				$fp = fopen($this->name, 'wb');
8598
				if ($fp)
8599
				{
8600
					fwrite($fp, $data);
8601
					fclose($fp);
8602
					return true;
8603
				}
8604
			}
8605
		}
8606
		return false;
8607
	}
8608
8609
	function load()
8610
	{
8611
		if (file_exists($this->name) && is_readable($this->name))
8612
		{
8613
			return unserialize(file_get_contents($this->name));
8614
		}
8615
		return false;
8616
	}
8617
8618
	function mtime()
8619
	{
8620
		if (file_exists($this->name))
8621
		{
8622
			return filemtime($this->name);
8623
		}
8624
		return false;
8625
	}
8626
8627
	function touch()
8628
	{
8629
		if (file_exists($this->name))
8630
		{
8631
			return touch($this->name);
8632
		}
8633
		return false;
8634
	}
8635
8636
	function unlink()
8637
	{
8638
		if (file_exists($this->name))
8639
		{
8640
			return unlink($this->name);
8641
		}
8642
		return false;
8643
	}
8644
}
8645
8646
class SimplePie_Misc
8647
{
8648
	function time_hms($seconds)
8649
	{
8650
		$time = '';
8651
8652
		$hours = floor($seconds / 3600);
8653
		$remainder = $seconds % 3600;
8654
		if ($hours > 0)
8655
		{
8656
			$time .= $hours.':';
8657
		}
8658
8659
		$minutes = floor($remainder / 60);
8660
		$seconds = $remainder % 60;
8661
		if ($minutes < 10 && $hours > 0)
8662
		{
8663
			$minutes = '0' . $minutes;
8664
		}
8665
		if ($seconds < 10)
8666
		{
8667
			$seconds = '0' . $seconds;
8668
		}
8669
8670
		$time .= $minutes.':';
8671
		$time .= $seconds;
8672
8673
		return $time;
8674
	}
8675
8676 23ca5695 Chris Buechler
	function absolutize_url($relative, $base)
8677 b2e02eef Scott Ullrich
	{
8678
		if ($relative !== '')
8679
		{
8680
			$relative = SimplePie_Misc::parse_url($relative);
8681
			if ($relative['scheme'] !== '')
8682
			{
8683
				$target = $relative;
8684
			}
8685
			elseif ($base !== '')
8686
			{
8687
				$base = SimplePie_Misc::parse_url($base);
8688
				$target = SimplePie_Misc::parse_url('');
8689
				if ($relative['authority'] !== '')
8690
				{
8691
					$target = $relative;
8692
					$target['scheme'] = $base['scheme'];
8693
				}
8694
				else
8695
				{
8696
					$target['scheme'] = $base['scheme'];
8697
					$target['authority'] = $base['authority'];
8698
					if ($relative['path'] !== '')
8699
					{
8700
						if (strpos($relative['path'], '/') === 0)
8701
						{
8702
							$target['path'] = $relative['path'];
8703
						}
8704
						elseif ($base['authority'] !== '' && $base['path'] === '')
8705
						{
8706
							$target['path'] = '/' . $relative['path'];
8707
						}
8708
						elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8709
						{
8710
							$target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8711
						}
8712
						else
8713
						{
8714
							$target['path'] = $relative['path'];
8715
						}
8716
						$target['query'] = $relative['query'];
8717
					}
8718
					else
8719
					{
8720
						$target['path'] = $base['path'];
8721
						if ($relative['query'] !== '')
8722
						{
8723
							$target['query'] = $relative['query'];
8724
						}
8725
						elseif ($base['query'] !== '')
8726
						{
8727
							$target['query'] = $base['query'];
8728
						}
8729
					}
8730
				}
8731
				$target['fragment'] = $relative['fragment'];
8732
			}
8733
			else
8734
			{
8735
				// No base URL, just return the relative URL
8736
				$target = $relative;
8737
			}
8738
			$return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8739
		}
8740
		else
8741
		{
8742
			$return = $base;
8743
		}
8744
		$return = SimplePie_Misc::normalize_url($return);
8745
		return $return;
8746
	}
8747
8748 23ca5695 Chris Buechler
	function remove_dot_segments($input)
8749 b2e02eef Scott Ullrich
	{
8750
		$output = '';
8751
		while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8752
		{
8753
			// A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8754
			if (strpos($input, '../') === 0)
8755
			{
8756
				$input = substr($input, 3);
8757
			}
8758
			elseif (strpos($input, './') === 0)
8759
			{
8760
				$input = substr($input, 2);
8761
			}
8762
			// 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,
8763
			elseif (strpos($input, '/./') === 0)
8764
			{
8765
				$input = substr_replace($input, '/', 0, 3);
8766
			}
8767
			elseif ($input == '/.')
8768
			{
8769
				$input = '/';
8770
			}
8771
			// 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,
8772
			elseif (strpos($input, '/../') === 0)
8773
			{
8774
				$input = substr_replace($input, '/', 0, 4);
8775
				$output = substr_replace($output, '', strrpos($output, '/'));
8776
			}
8777
			elseif ($input == '/..')
8778
			{
8779
				$input = '/';
8780
				$output = substr_replace($output, '', strrpos($output, '/'));
8781
			}
8782
			// D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8783
			elseif ($input == '.' || $input == '..')
8784
			{
8785
				$input = '';
8786
			}
8787
			// 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
8788
			elseif (($pos = strpos($input, '/', 1)) !== false)
8789
			{
8790
				$output .= substr($input, 0, $pos);
8791
				$input = substr_replace($input, '', 0, $pos);
8792
			}
8793
			else
8794
			{
8795
				$output .= $input;
8796
				$input = '';
8797
			}
8798
		}
8799
		return $output . $input;
8800
	}
8801
8802 23ca5695 Chris Buechler
	function get_element($realname, $string)
8803 b2e02eef Scott Ullrich
	{
8804
		$return = array();
8805
		$name = preg_quote($realname, '/');
8806
		if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8807
		{
8808
			for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8809
			{
8810
				$return[$i]['tag'] = $realname;
8811
				$return[$i]['full'] = $matches[$i][0][0];
8812
				$return[$i]['offset'] = $matches[$i][0][1];
8813
				if (strlen($matches[$i][3][0]) <= 2)
8814
				{
8815
					$return[$i]['self_closing'] = true;
8816
				}
8817
				else
8818
				{
8819
					$return[$i]['self_closing'] = false;
8820
					$return[$i]['content'] = $matches[$i][4][0];
8821
				}
8822
				$return[$i]['attribs'] = array();
8823
				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))
8824
				{
8825
					for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8826
					{
8827
						if (count($attribs[$j]) == 2)
8828
						{
8829
							$attribs[$j][2] = $attribs[$j][1];
8830
						}
8831
						$return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8832
					}
8833
				}
8834
			}
8835
		}
8836
		return $return;
8837
	}
8838
8839 23ca5695 Chris Buechler
	function element_implode($element)
8840 b2e02eef Scott Ullrich
	{
8841
		$full = "<$element[tag]";
8842
		foreach ($element['attribs'] as $key => $value)
8843
		{
8844
			$key = strtolower($key);
8845
			$full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8846
		}
8847
		if ($element['self_closing'])
8848
		{
8849
			$full .= ' />';
8850
		}
8851
		else
8852
		{
8853
			$full .= ">$element[content]</$element[tag]>";
8854
		}
8855
		return $full;
8856
	}
8857
8858
	function error($message, $level, $file, $line)
8859
	{
8860
		switch ($level)
8861
		{
8862
			case E_USER_ERROR:
8863
				$note = 'PHP Error';
8864
				break;
8865
			case E_USER_WARNING:
8866
				$note = 'PHP Warning';
8867
				break;
8868
			case E_USER_NOTICE:
8869
				$note = 'PHP Notice';
8870
				break;
8871
			default:
8872
				$note = 'Unknown Error';
8873
				break;
8874
		}
8875
		error_log("$note: $message in $file on line $line", 0);
8876
		return $message;
8877
	}
8878
8879
	/**
8880
	 * If a file has been cached, retrieve and display it.
8881
	 *
8882
	 * This is most useful for caching images (get_favicon(), etc.),
8883
	 * however it works for all cached files.  This WILL NOT display ANY
8884
	 * file/image/page/whatever, but rather only display what has already
8885
	 * been cached by SimplePie.
8886
	 *
8887
	 * @access public
8888
	 * @see SimplePie::get_favicon()
8889
	 * @param str $identifier_url URL that is used to identify the content.
8890
	 * This may or may not be the actual URL of the live content.
8891
	 * @param str $cache_location Location of SimplePie's cache.  Defaults
8892
	 * to './cache'.
8893
	 * @param str $cache_extension The file extension that the file was
8894
	 * cached with.  Defaults to 'spc'.
8895
	 * @param str $cache_class Name of the cache-handling class being used
8896
	 * in SimplePie.  Defaults to 'SimplePie_Cache', and should be left
8897
	 * as-is unless you've overloaded the class.
8898
	 * @param str $cache_name_function Obsolete. Exists for backwards
8899
	 * compatibility reasons only.
8900
	 */
8901
	function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8902
	{
8903
		$cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
8904
8905
		if ($file = $cache->load())
8906
		{
8907
			if (isset($file['headers']['content-type']))
8908
			{
8909
				header('Content-type:' . $file['headers']['content-type']);
8910
			}
8911
			else
8912
			{
8913
				header('Content-type: application/octet-stream');
8914
			}
8915
			header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8916
			echo $file['body'];
8917
			exit;
8918
		}
8919
8920
		die('Cached file for ' . $identifier_url . ' cannot be found.');
8921
	}
8922
8923 23ca5695 Chris Buechler
	function fix_protocol($url, $http = 1)
8924 b2e02eef Scott Ullrich
	{
8925
		$url = SimplePie_Misc::normalize_url($url);
8926
		$parsed = SimplePie_Misc::parse_url($url);
8927
		if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8928
		{
8929
			return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8930
		}
8931
8932
		if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8933
		{
8934
			return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8935
		}
8936
8937
		if ($http == 2 && $parsed['scheme'] !== '')
8938
		{
8939
			return "feed:$url";
8940
		}
8941
		elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
8942
		{
8943
			return substr_replace($url, 'podcast', 0, 4);
8944
		}
8945
		elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
8946
		{
8947
			return substr_replace($url, 'itpc', 0, 4);
8948
		}
8949
		else
8950
		{
8951
			return $url;
8952
		}
8953
	}
8954
8955 23ca5695 Chris Buechler
	function parse_url($url)
8956 b2e02eef Scott Ullrich
	{
8957
		static $cache = array();
8958
		if (isset($cache[$url]))
8959
		{
8960
			return $cache[$url];
8961
		}
8962
		elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
8963
		{
8964
			for ($i = count($match); $i <= 9; $i++)
8965
			{
8966
				$match[$i] = '';
8967
			}
8968
			return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
8969
		}
8970
		else
8971
		{
8972
			return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
8973
		}
8974
	}
8975
8976 23ca5695 Chris Buechler
	function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
8977 b2e02eef Scott Ullrich
	{
8978
		$return = '';
8979
		if ($scheme !== '')
8980
		{
8981
			$return .= "$scheme:";
8982
		}
8983
		if ($authority !== '')
8984
		{
8985
			$return .= "//$authority";
8986
		}
8987
		if ($path !== '')
8988
		{
8989
			$return .= $path;
8990
		}
8991
		if ($query !== '')
8992
		{
8993
			$return .= "?$query";
8994
		}
8995
		if ($fragment !== '')
8996
		{
8997
			$return .= "#$fragment";
8998
		}
8999
		return $return;
9000
	}
9001
9002 23ca5695 Chris Buechler
	function normalize_url($url)
9003 b2e02eef Scott Ullrich
	{
9004
		$url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
9005
		$url = SimplePie_Misc::parse_url($url);
9006
		$url['scheme'] = strtolower($url['scheme']);
9007
		if ($url['authority'] !== '')
9008
		{
9009
			$url['authority'] = strtolower($url['authority']);
9010
			$url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
9011
		}
9012
		return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
9013
	}
9014
9015 23ca5695 Chris Buechler
	function percent_encoding_normalization($match)
9016 b2e02eef Scott Ullrich
	{
9017
		$integer = hexdec($match[1]);
9018
		if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
9019
		{
9020
			return chr($integer);
9021
		}
9022
		else
9023
		{
9024
			return strtoupper($match[0]);
9025
		}
9026
	}
9027
9028
	/**
9029
	 * Remove bad UTF-8 bytes
9030
	 *
9031
	 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9032
	 * FAQ: Multilingual Forms (modified to include full ASCII range)
9033
	 *
9034
	 * @author Geoffrey Sneddon
9035
	 * @see http://www.w3.org/International/questions/qa-forms-utf-8
9036
	 * @param string $str String to remove bad UTF-8 bytes from
9037
	 * @return string UTF-8 string
9038
	 */
9039
	function utf8_bad_replace($str)
9040
	{
9041
		if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9042
		{
9043
			return $return;
9044
		}
9045
		elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9046
		{
9047
			return $return;
9048
		}
9049
		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))
9050
		{
9051
			return implode("\xEF\xBF\xBD", $matches[0]);
9052
		}
9053
		elseif ($str !== '')
9054
		{
9055
			return "\xEF\xBF\xBD";
9056
		}
9057
		else
9058
		{
9059
			return '';
9060
		}
9061
	}
9062
9063
	/**
9064
	 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9065
	 *
9066
	 * @static
9067
	 * @access public
9068
	 * @param string $string Windows-1252 encoded string
9069
	 * @return string UTF-8 encoded string
9070
	 */
9071
	function windows_1252_to_utf8($string)
9072
	{
9073
		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");
9074
9075
		return strtr($string, $convert_table);
9076
	}
9077
9078 23ca5695 Chris Buechler
	function change_encoding($data, $input, $output)
9079 b2e02eef Scott Ullrich
	{
9080
		$input = SimplePie_Misc::encoding($input);
9081
		$output = SimplePie_Misc::encoding($output);
9082
9083
		// We fail to fail on non US-ASCII bytes
9084
		if ($input === 'US-ASCII')
9085
		{
9086
			static $non_ascii_octects = '';
9087
			if (!$non_ascii_octects)
9088
			{
9089
				for ($i = 0x80; $i <= 0xFF; $i++)
9090
				{
9091
					$non_ascii_octects .= chr($i);
9092
				}
9093
			}
9094
			$data = substr($data, 0, strcspn($data, $non_ascii_octects));
9095
		}
9096
9097
		// This is first, as behaviour of this is completely predictable
9098
		if ($input === 'Windows-1252' && $output === 'UTF-8')
9099
		{
9100
			return SimplePie_Misc::windows_1252_to_utf8($data);
9101
		}
9102
		// This is second, as behaviour of this varies only with PHP version
9103
		elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
9104
		{
9105
			return $return;
9106
		}
9107
		// This is last, as behaviour of this varies with OS userland and PHP version
9108
		elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9109
		{
9110
			return $return;
9111
		}
9112
		// If we can't do anything, just fail
9113
		else
9114
		{
9115
			return false;
9116
		}
9117
	}
9118
9119 23ca5695 Chris Buechler
	function encoding($charset)
9120 b2e02eef Scott Ullrich
	{
9121
		/* Character sets are case-insensitive, and also need some further
9122
		normalization in the real world (though we'll return them in the form given
9123
		in their registration). */
9124
		switch (strtolower(preg_replace('/[\x09-\x0D\x20-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]/', '', $charset)))
9125
		{
9126
			case 'adobestandardencoding':
9127
			case 'csadobestandardencoding':
9128
				return 'Adobe-Standard-Encoding';
9129
9130
			case 'adobesymbolencoding':
9131
			case 'cshppsmath':
9132
				return 'Adobe-Symbol-Encoding';
9133
9134
			case 'ami1251':
9135
			case 'ami1251':
9136
			case 'amiga1251':
9137
			case 'amiga1251':
9138
				return 'Amiga-1251';
9139
9140
			case 'ansix31101983':
9141
			case 'csat5001983':
9142
			case 'csiso99naplps':
9143
			case 'isoir99':
9144
			case 'naplps':
9145
				return 'ANSI_X3.110-1983';
9146
9147
			case 'arabic7':
9148
			case 'asmo449':
9149
			case 'csiso89asmo449':
9150
			case 'isoir89':
9151
			case 'iso9036':
9152
				return 'ASMO_449';
9153
9154
			case 'big5':
9155
			case 'csbig5':
9156
			case 'xxbig5':
9157
				return 'Big5';
9158
9159
			case 'big5hkscs':
9160
				return 'Big5-HKSCS';
9161
9162
			case 'bocu1':
9163
			case 'csbocu1':
9164
				return 'BOCU-1';
9165
9166
			case 'brf':
9167
			case 'csbrf':
9168
				return 'BRF';
9169
9170
			case 'bs4730':
9171
			case 'csiso4unitedkingdom':
9172
			case 'gb':
9173
			case 'isoir4':
9174
			case 'iso646gb':
9175
			case 'uk':
9176
				return 'BS_4730';
9177
9178
			case 'bsviewdata':
9179
			case 'csiso47bsviewdata':
9180
			case 'isoir47':
9181
				return 'BS_viewdata';
9182
9183
			case 'cesu8':
9184
			case 'cscesu8':
9185
				return 'CESU-8';
9186
9187
			case 'ca':
9188
			case 'csa71':
9189
			case 'csaz243419851':
9190
			case 'csiso121canadian1':
9191
			case 'isoir121':
9192
			case 'iso646ca':
9193
				return 'CSA_Z243.4-1985-1';
9194
9195
			case 'csa72':
9196
			case 'csaz243419852':
9197
			case 'csiso122canadian2':
9198
			case 'isoir122':
9199
			case 'iso646ca2':
9200
				return 'CSA_Z243.4-1985-2';
9201
9202
			case 'csaz24341985gr':
9203
			case 'csiso123csaz24341985gr':
9204
			case 'isoir123':
9205
				return 'CSA_Z243.4-1985-gr';
9206
9207
			case 'csiso139csn369103':
9208
			case 'csn369103':
9209
			case 'isoir139':
9210
				return 'CSN_369103';
9211
9212
			case 'csdecmcs':
9213
			case 'dec':
9214
			case 'decmcs':
9215
				return 'DEC-MCS';
9216
9217
			case 'csiso21german':
9218
			case 'de':
9219
			case 'din66003':
9220
			case 'isoir21':
9221
			case 'iso646de':
9222
				return 'DIN_66003';
9223
9224
			case 'csdkus':
9225
			case 'dkus':
9226
				return 'dk-us';
9227
9228
			case 'csiso646danish':
9229
			case 'dk':
9230
			case 'ds2089':
9231
			case 'ds2089':
9232
			case 'iso646dk':
9233
				return 'DS_2089';
9234
9235
			case 'csibmebcdicatde':
9236
			case 'ebcdicatde':
9237
				return 'EBCDIC-AT-DE';
9238
9239
			case 'csebcdicatdea':
9240
			case 'ebcdicatdea':
9241
				return 'EBCDIC-AT-DE-A';
9242
9243
			case 'csebcdiccafr':
9244
			case 'ebcdiccafr':
9245
				return 'EBCDIC-CA-FR';
9246
9247
			case 'csebcdicdkno':
9248
			case 'ebcdicdkno':
9249
				return 'EBCDIC-DK-NO';
9250
9251
			case 'csebcdicdknoa':
9252
			case 'ebcdicdknoa':
9253
				return 'EBCDIC-DK-NO-A';
9254
9255
			case 'csebcdices':
9256
			case 'ebcdices':
9257
				return 'EBCDIC-ES';
9258
9259
			case 'csebcdicesa':
9260
			case 'ebcdicesa':
9261
				return 'EBCDIC-ES-A';
9262
9263
			case 'csebcdicess':
9264
			case 'ebcdicess':
9265
				return 'EBCDIC-ES-S';
9266
9267
			case 'csebcdicfise':
9268
			case 'ebcdicfise':
9269
				return 'EBCDIC-FI-SE';
9270
9271
			case 'csebcdicfisea':
9272
			case 'ebcdicfisea':
9273
				return 'EBCDIC-FI-SE-A';
9274
9275
			case 'csebcdicfr':
9276
			case 'ebcdicfr':
9277
				return 'EBCDIC-FR';
9278
9279
			case 'csebcdicit':
9280
			case 'ebcdicit':
9281
				return 'EBCDIC-IT';
9282
9283
			case 'csebcdicpt':
9284
			case 'ebcdicpt':
9285
				return 'EBCDIC-PT';
9286
9287
			case 'csebcdicuk':
9288
			case 'ebcdicuk':
9289
				return 'EBCDIC-UK';
9290
9291
			case 'csebcdicus':
9292
			case 'ebcdicus':
9293
				return 'EBCDIC-US';
9294
9295
			case 'csiso111ecmacyrillic':
9296
			case 'ecmacyrillic':
9297
			case 'isoir111':
9298
			case 'koi8e':
9299
				return 'ECMA-cyrillic';
9300
9301
			case 'csiso17spanish':
9302
			case 'es':
9303
			case 'isoir17':
9304
			case 'iso646es':
9305
				return 'ES';
9306
9307
			case 'csiso85spanish2':
9308
			case 'es2':
9309
			case 'isoir85':
9310
			case 'iso646es2':
9311
				return 'ES2';
9312
9313
			case 'cseucfixwidjapanese':
9314
			case 'extendedunixcodefixedwidthforjapanese':
9315
				return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9316
9317
			case 'cseucpkdfmtjapanese':
9318
			case 'eucjp':
9319
			case 'extendedunixcodepackedformatforjapanese':
9320
				return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
9321
9322
			case 'gb18030':
9323
				return 'GB18030';
9324
9325
			case 'cp936':
9326
			case 'gbk':
9327
			case 'ms936':
9328
			case 'windows936':
9329
			case 'csgb2312':
9330
			case 'gb2312':
9331
			case 'chinese':
9332
			case 'csiso58gb231280':
9333
			case 'gb231280':
9334
			case 'isoir58':
9335
				return 'GBK';
9336
9337
			case 'cn':
9338
			case 'csiso57gb1988':
9339
			case 'gb198880':
9340
			case 'isoir57':
9341
			case 'iso646cn':
9342
				return 'GB_1988-80';
9343
9344
			case 'csiso153gost1976874':
9345
			case 'gost1976874':
9346
			case 'isoir153':
9347
			case 'stsev35888':
9348
				return 'GOST_19768-74';
9349
9350
			case 'csiso150':
9351
			case 'csiso150greekccitt':
9352
			case 'greekccitt':
9353
			case 'isoir150':
9354
				return 'greek-ccitt';
9355
9356
			case 'csiso88greek7':
9357
			case 'greek7':
9358
			case 'isoir88':
9359
				return 'greek7';
9360
9361
			case 'csiso18greek7old':
9362
			case 'greek7old':
9363
			case 'isoir18':
9364
				return 'greek7-old';
9365
9366
			case 'cshpdesktop':
9367
			case 'hpdesktop':
9368
				return 'HP-DeskTop';
9369
9370
			case 'cshplegal':
9371
			case 'hplegal':
9372
				return 'HP-Legal';
9373
9374
			case 'cshpmath8':
9375
			case 'hpmath8':
9376
				return 'HP-Math8';
9377
9378
			case 'cshppifont':
9379
			case 'hppifont':
9380
				return 'HP-Pi-font';
9381
9382
			case 'cshproman8':
9383
			case 'hproman8':
9384
			case 'r8':
9385
			case 'roman8':
9386
				return 'hp-roman8';
9387
9388
			case 'hzgb2312':
9389
				return 'HZ-GB-2312';
9390
9391
			case 'csibmsymbols':
9392
			case 'ibmsymbols':
9393
				return 'IBM-Symbols';
9394
9395
			case 'csibmthai':
9396
			case 'ibmthai':
9397
				return 'IBM-Thai';
9398
9399
			case 'ccsid00858':
9400
			case 'cp00858':
9401
			case 'ibm00858':
9402
			case 'pcmultilingual850euro':
9403
				return 'IBM00858';
9404
9405
			case 'ccsid00924':
9406
			case 'cp00924':
9407
			case 'ebcdiclatin9euro':
9408
			case 'ibm00924':
9409
				return 'IBM00924';
9410
9411
			case 'ccsid01140':
9412
			case 'cp01140':
9413
			case 'ebcdicus37euro':
9414
			case 'ibm01140':
9415
				return 'IBM01140';
9416
9417
			case 'ccsid01141':
9418
			case 'cp01141':
9419
			case 'ebcdicde273euro':
9420
			case 'ibm01141':
9421
				return 'IBM01141';
9422
9423
			case 'ccsid01142':
9424
			case 'cp01142':
9425
			case 'ebcdicdk277euro':
9426
			case 'ebcdicno277euro':
9427
			case 'ibm01142':
9428
				return 'IBM01142';
9429
9430
			case 'ccsid01143':
9431
			case 'cp01143':
9432
			case 'ebcdicfi278euro':
9433
			case 'ebcdicse278euro':
9434
			case 'ibm01143':
9435
				return 'IBM01143';
9436
9437
			case 'ccsid01144':
9438
			case 'cp01144':
9439
			case 'ebcdicit280euro':
9440
			case 'ibm01144':
9441
				return 'IBM01144';
9442
9443
			case 'ccsid01145':
9444
			case 'cp01145':
9445
			case 'ebcdices284euro':
9446
			case 'ibm01145':
9447
				return 'IBM01145';
9448
9449
			case 'ccsid01146':
9450
			case 'cp01146':
9451
			case 'ebcdicgb285euro':
9452
			case 'ibm01146':
9453
				return 'IBM01146';
9454
9455
			case 'ccsid01147':
9456
			case 'cp01147':
9457
			case 'ebcdicfr297euro':
9458
			case 'ibm01147':
9459
				return 'IBM01147';
9460
9461
			case 'ccsid01148':
9462
			case 'cp01148':
9463
			case 'ebcdicinternational500euro':
9464
			case 'ibm01148':
9465
				return 'IBM01148';
9466
9467
			case 'ccsid01149':
9468
			case 'cp01149':
9469
			case 'ebcdicis871euro':
9470
			case 'ibm01149':
9471
				return 'IBM01149';
9472
9473
			case 'cp037':
9474
			case 'csibm037':
9475
			case 'ebcdiccpca':
9476
			case 'ebcdiccpnl':
9477
			case 'ebcdiccpus':
9478
			case 'ebcdiccpwt':
9479
			case 'ibm037':
9480
				return 'IBM037';
9481
9482
			case 'cp038':
9483
			case 'csibm038':
9484
			case 'ebcdicint':
9485
			case 'ibm038':
9486
				return 'IBM038';
9487
9488
			case 'cp273':
9489
			case 'csibm273':
9490
			case 'ibm273':
9491
				return 'IBM273';
9492
9493
			case 'cp274':
9494
			case 'csibm274':
9495
			case 'ebcdicbe':
9496
			case 'ibm274':
9497
				return 'IBM274';
9498
9499
			case 'cp275':
9500
			case 'csibm275':
9501
			case 'ebcdicbr':
9502
			case 'ibm275':
9503
				return 'IBM275';
9504
9505
			case 'csibm277':
9506
			case 'ebcdiccpdk':
9507
			case 'ebcdiccpno':
9508
			case 'ibm277':
9509
				return 'IBM277';
9510
9511
			case 'cp278':
9512
			case 'csibm278':
9513
			case 'ebcdiccpfi':
9514
			case 'ebcdiccpse':
9515
			case 'ibm278':
9516
				return 'IBM278';
9517
9518
			case 'cp280':
9519
			case 'csibm280':
9520
			case 'ebcdiccpit':
9521
			case 'ibm280':
9522
				return 'IBM280';
9523
9524
			case 'cp281':
9525
			case 'csibm281':
9526
			case 'ebcdicjpe':
9527
			case 'ibm281':
9528
				return 'IBM281';
9529
9530
			case 'cp284':
9531
			case 'csibm284':
9532
			case 'ebcdiccpes':
9533
			case 'ibm284':
9534
				return 'IBM284';
9535
9536
			case 'cp285':
9537
			case 'csibm285':
9538
			case 'ebcdiccpgb':
9539
			case 'ibm285':
9540
				return 'IBM285';
9541
9542
			case 'cp290':
9543
			case 'csibm290':
9544
			case 'ebcdicjpkana':
9545
			case 'ibm290':
9546
				return 'IBM290';
9547
9548
			case 'cp297':
9549
			case 'csibm297':
9550
			case 'ebcdiccpfr':
9551
			case 'ibm297':
9552
				return 'IBM297';
9553
9554
			case 'cp420':
9555
			case 'csibm420':
9556
			case 'ebcdiccpar1':
9557
			case 'ibm420':
9558
				return 'IBM420';
9559
9560
			case 'cp423':
9561
			case 'csibm423':
9562
			case 'ebcdiccpgr':
9563
			case 'ibm423':
9564
				return 'IBM423';
9565
9566
			case 'cp424':
9567
			case 'csibm424':
9568
			case 'ebcdiccphe':
9569
			case 'ibm424':
9570
				return 'IBM424';
9571
9572
			case '437':
9573
			case 'cp437':
9574
			case 'cspc8codepage437':
9575
			case 'ibm437':
9576
				return 'IBM437';
9577
9578
			case 'cp500':
9579
			case 'csibm500':
9580
			case 'ebcdiccpbe':
9581
			case 'ebcdiccpch':
9582
			case 'ibm500':
9583
				return 'IBM500';
9584
9585
			case 'cp775':
9586
			case 'cspc775baltic':
9587
			case 'ibm775':
9588
				return 'IBM775';
9589
9590
			case '850':
9591
			case 'cp850':
9592
			case 'cspc850multilingual':
9593
			case 'ibm850':
9594
				return 'IBM850';
9595
9596
			case '851':
9597
			case 'cp851':
9598
			case 'csibm851':
9599
			case 'ibm851':
9600
				return 'IBM851';
9601
9602
			case '852':
9603
			case 'cp852':
9604
			case 'cspcp852':
9605
			case 'ibm852':
9606
				return 'IBM852';
9607
9608
			case '855':
9609
			case 'cp855':
9610
			case 'csibm855':
9611
			case 'ibm855':
9612
				return 'IBM855';
9613
9614
			case '857':
9615
			case 'cp857':
9616
			case 'csibm857':
9617
			case 'ibm857':
9618
				return 'IBM857';
9619
9620
			case '860':
9621
			case 'cp860':
9622
			case 'csibm860':
9623
			case 'ibm860':
9624
				return 'IBM860';
9625
9626
			case '861':
9627
			case 'cpis':
9628
			case 'cp861':
9629
			case 'csibm861':
9630
			case 'ibm861':
9631
				return 'IBM861';
9632
9633
			case '862':
9634
			case 'cp862':
9635
			case 'cspc862latinhebrew':
9636
			case 'ibm862':
9637
				return 'IBM862';
9638
9639
			case '863':
9640
			case 'cp863':
9641
			case 'csibm863':
9642
			case 'ibm863':
9643
				return 'IBM863';
9644
9645
			case 'cp864':
9646
			case 'csibm864':
9647
			case 'ibm864':
9648
				return 'IBM864';
9649
9650
			case '865':
9651
			case 'cp865':
9652
			case 'csibm865':
9653
			case 'ibm865':
9654
				return 'IBM865';
9655
9656
			case '866':
9657
			case 'cp866':
9658
			case 'csibm866':
9659
			case 'ibm866':
9660
				return 'IBM866';
9661
9662
			case 'cpar':
9663
			case 'cp868':
9664
			case 'csibm868':
9665
			case 'ibm868':
9666
				return 'IBM868';
9667
9668
			case '869':
9669
			case 'cpgr':
9670
			case 'cp869':
9671
			case 'csibm869':
9672
			case 'ibm869':
9673
				return 'IBM869';
9674
9675
			case 'cp870':
9676
			case 'csibm870':
9677
			case 'ebcdiccproece':
9678
			case 'ebcdiccpyu':
9679
			case 'ibm870':
9680
				return 'IBM870';
9681
9682
			case 'cp871':
9683
			case 'csibm871':
9684
			case 'ebcdiccpis':
9685
			case 'ibm871':
9686
				return 'IBM871';
9687
9688
			case 'cp880':
9689
			case 'csibm880':
9690
			case 'ebcdiccyrillic':
9691
			case 'ibm880':
9692
				return 'IBM880';
9693
9694
			case 'cp891':
9695
			case 'csibm891':
9696
			case 'ibm891':
9697
				return 'IBM891';
9698
9699
			case 'cp903':
9700
			case 'csibm903':
9701
			case 'ibm903':
9702
				return 'IBM903';
9703
9704
			case '904':
9705
			case 'cp904':
9706
			case 'csibbm904':
9707
			case 'ibm904':
9708
				return 'IBM904';
9709
9710
			case 'cp905':
9711
			case 'csibm905':
9712
			case 'ebcdiccptr':
9713
			case 'ibm905':
9714
				return 'IBM905';
9715
9716
			case 'cp918':
9717
			case 'csibm918':
9718
			case 'ebcdiccpar2':
9719
			case 'ibm918':
9720
				return 'IBM918';
9721
9722
			case 'cp1026':
9723
			case 'csibm1026':
9724
			case 'ibm1026':
9725
				return 'IBM1026';
9726
9727
			case 'ibm1047':
9728
			case 'ibm1047':
9729
				return 'IBM1047';
9730
9731
			case 'csiso143iecp271':
9732
			case 'iecp271':
9733
			case 'isoir143':
9734
				return 'IEC_P27-1';
9735
9736
			case 'csiso49inis':
9737
			case 'inis':
9738
			case 'isoir49':
9739
				return 'INIS';
9740
9741
			case 'csiso50inis8':
9742
			case 'inis8':
9743
			case 'isoir50':
9744
				return 'INIS-8';
9745
9746
			case 'csiso51iniscyrillic':
9747
			case 'iniscyrillic':
9748
			case 'isoir51':
9749
				return 'INIS-cyrillic';
9750
9751
			case 'csinvariant':
9752
			case 'invariant':
9753
				return 'INVARIANT';
9754
9755
			case 'iso2022cn':
9756
				return 'ISO-2022-CN';
9757
9758
			case 'iso2022cnext':
9759
				return 'ISO-2022-CN-EXT';
9760
9761
			case 'csiso2022jp':
9762
			case 'iso2022jp':
9763
				return 'ISO-2022-JP';
9764
9765
			case 'csiso2022jp2':
9766
			case 'iso2022jp2':
9767
				return 'ISO-2022-JP-2';
9768
9769
			case 'csiso2022kr':
9770
			case 'iso2022kr':
9771
				return 'ISO-2022-KR';
9772
9773
			case 'cswindows30latin1':
9774
			case 'iso88591windows30latin1':
9775
				return 'ISO-8859-1-Windows-3.0-Latin-1';
9776
9777
			case 'cswindows31latin1':
9778
			case 'iso88591windows31latin1':
9779
				return 'ISO-8859-1-Windows-3.1-Latin-1';
9780
9781
			case 'csisolatin2':
9782
			case 'iso88592':
9783
			case 'isoir101':
9784
			case 'iso88592':
9785
			case 'iso885921987':
9786
			case 'l2':
9787
			case 'latin2':
9788
				return 'ISO-8859-2';
9789
9790
			case 'cswindows31latin2':
9791
			case 'iso88592windowslatin2':
9792
				return 'ISO-8859-2-Windows-Latin-2';
9793
9794
			case 'csisolatin3':
9795
			case 'iso88593':
9796
			case 'isoir109':
9797
			case 'iso88593':
9798
			case 'iso885931988':
9799
			case 'l3':
9800
			case 'latin3':
9801
				return 'ISO-8859-3';
9802
9803
			case 'csisolatin4':
9804
			case 'iso88594':
9805
			case 'isoir110':
9806
			case 'iso88594':
9807
			case 'iso885941988':
9808
			case 'l4':
9809
			case 'latin4':
9810
				return 'ISO-8859-4';
9811
9812
			case 'csisolatincyrillic':
9813
			case 'cyrillic':
9814
			case 'iso88595':
9815
			case 'isoir144':
9816
			case 'iso88595':
9817
			case 'iso885951988':
9818
				return 'ISO-8859-5';
9819
9820
			case 'arabic':
9821
			case 'asmo708':
9822
			case 'csisolatinarabic':
9823
			case 'ecma114':
9824
			case 'iso88596':
9825
			case 'isoir127':
9826
			case 'iso88596':
9827
			case 'iso885961987':
9828
				return 'ISO-8859-6';
9829
9830
			case 'csiso88596e':
9831
			case 'iso88596e':
9832
			case 'iso88596e':
9833
				return 'ISO-8859-6-E';
9834
9835
			case 'csiso88596i':
9836
			case 'iso88596i':
9837
			case 'iso88596i':
9838
				return 'ISO-8859-6-I';
9839
9840
			case 'csisolatingreek':
9841
			case 'ecma118':
9842
			case 'elot928':
9843
			case 'greek':
9844
			case 'greek8':
9845
			case 'iso88597':
9846
			case 'isoir126':
9847
			case 'iso88597':
9848
			case 'iso885971987':
9849
				return 'ISO-8859-7';
9850
9851
			case 'csisolatinhebrew':
9852
			case 'hebrew':
9853
			case 'iso88598':
9854
			case 'isoir138':
9855
			case 'iso88598':
9856
			case 'iso885981988':
9857
				return 'ISO-8859-8';
9858
9859
			case 'csiso88598e':
9860
			case 'iso88598e':
9861
			case 'iso88598e':
9862
				return 'ISO-8859-8-E';
9863
9864
			case 'csiso88598i':
9865
			case 'iso88598i':
9866
			case 'iso88598i':
9867
				return 'ISO-8859-8-I';
9868
9869
			case 'cswindows31latin5':
9870
			case 'iso88599windowslatin5':
9871
				return 'ISO-8859-9-Windows-Latin-5';
9872
9873
			case 'csisolatin6':
9874
			case 'iso885910':
9875
			case 'isoir157':
9876
			case 'iso8859101992':
9877
			case 'l6':
9878
			case 'latin6':
9879
				return 'ISO-8859-10';
9880
9881
			case 'iso885913':
9882
				return 'ISO-8859-13';
9883
9884
			case 'iso885914':
9885
			case 'isoceltic':
9886
			case 'isoir199':
9887
			case 'iso885914':
9888
			case 'iso8859141998':
9889
			case 'l8':
9890
			case 'latin8':
9891
				return 'ISO-8859-14';
9892
9893
			case 'iso885915':
9894
			case 'iso885915':
9895
			case 'latin9':
9896
				return 'ISO-8859-15';
9897
9898
			case 'iso885916':
9899
			case 'isoir226':
9900
			case 'iso885916':
9901
			case 'iso8859162001':
9902
			case 'l10':
9903
			case 'latin10':
9904
				return 'ISO-8859-16';
9905
9906
			case 'iso10646j1':
9907
				return 'ISO-10646-J-1';
9908
9909
			case 'csunicode':
9910
			case 'iso10646ucs2':
9911
				return 'ISO-10646-UCS-2';
9912
9913
			case 'csucs4':
9914
			case 'iso10646ucs4':
9915
				return 'ISO-10646-UCS-4';
9916
9917
			case 'csunicodeascii':
9918
			case 'iso10646ucsbasic':
9919
				return 'ISO-10646-UCS-Basic';
9920
9921
			case 'csunicodelatin1':
9922
			case 'iso10646':
9923
			case 'iso10646unicodelatin1':
9924
				return 'ISO-10646-Unicode-Latin1';
9925
9926
			case 'csiso10646utf1':
9927
			case 'iso10646utf1':
9928
				return 'ISO-10646-UTF-1';
9929
9930
			case 'csiso115481':
9931
			case 'iso115481':
9932
			case 'iso115481':
9933
			case 'isotr115481':
9934
				return 'ISO-11548-1';
9935
9936
			case 'csiso90':
9937
			case 'isoir90':
9938
				return 'iso-ir-90';
9939
9940
			case 'csunicodeibm1261':
9941
			case 'isounicodeibm1261':
9942
				return 'ISO-Unicode-IBM-1261';
9943
9944
			case 'csunicodeibm1264':
9945
			case 'isounicodeibm1264':
9946
				return 'ISO-Unicode-IBM-1264';
9947
9948
			case 'csunicodeibm1265':
9949
			case 'isounicodeibm1265':
9950
				return 'ISO-Unicode-IBM-1265';
9951
9952
			case 'csunicodeibm1268':
9953
			case 'isounicodeibm1268':
9954
				return 'ISO-Unicode-IBM-1268';
9955
9956
			case 'csunicodeibm1276':
9957
			case 'isounicodeibm1276':
9958
				return 'ISO-Unicode-IBM-1276';
9959
9960
			case 'csiso646basic1983':
9961
			case 'iso646basic1983':
9962
			case 'ref':
9963
				return 'ISO_646.basic:1983';
9964
9965
			case 'csiso2intlrefversion':
9966
			case 'irv':
9967
			case 'isoir2':
9968
			case 'iso646irv1983':
9969
				return 'ISO_646.irv:1983';
9970
9971
			case 'csiso2033':
9972
			case 'e13b':
9973
			case 'isoir98':
9974
			case 'iso20331983':
9975
				return 'ISO_2033-1983';
9976
9977
			case 'csiso5427cyrillic':
9978
			case 'isoir37':
9979
			case 'iso5427':
9980
				return 'ISO_5427';
9981
9982
			case 'isoir54':
9983
			case 'iso5427cyrillic1981':
9984
			case 'iso54271981':
9985
				return 'ISO_5427:1981';
9986
9987
			case 'csiso5428greek':
9988
			case 'isoir55':
9989
			case 'iso54281980':
9990
				return 'ISO_5428:1980';
9991
9992
			case 'csiso6937add':
9993
			case 'isoir152':
9994
			case 'iso6937225':
9995
				return 'ISO_6937-2-25';
9996
9997
			case 'csisotextcomm':
9998
			case 'isoir142':
9999
			case 'iso69372add':
10000
				return 'ISO_6937-2-add';
10001
10002
			case 'csiso8859supp':
10003
			case 'isoir154':
10004
			case 'iso8859supp':
10005
			case 'latin125':
10006
				return 'ISO_8859-supp';
10007
10008
			case 'csiso10367box':
10009
			case 'isoir155':
10010
			case 'iso10367box':
10011
				return 'ISO_10367-box';
10012
10013
			case 'csiso15italian':
10014
			case 'isoir15':
10015
			case 'iso646it':
10016
			case 'it':
10017
				return 'IT';
10018
10019
			case 'csiso13jisc6220jp':
10020
			case 'isoir13':
10021
			case 'jisc62201969':
10022
			case 'jisc62201969jp':
10023
			case 'katakana':
10024
			case 'x02017':
10025
				return 'JIS_C6220-1969-jp';
10026
10027
			case 'csiso14jisc6220ro':
10028
			case 'isoir14':
10029
			case 'iso646jp':
10030
			case 'jisc62201969ro':
10031
			case 'jp':
10032
				return 'JIS_C6220-1969-ro';
10033
10034
			case 'csiso42jisc62261978':
10035
			case 'isoir42':
10036
			case 'jisc62261978':
10037
				return 'JIS_C6226-1978';
10038
10039
			case 'csiso87jisx0208':
10040
			case 'isoir87':
10041
			case 'jisc62261983':
10042
			case 'jisx02081983':
10043
			case 'x0208':
10044
				return 'JIS_C6226-1983';
10045
10046
			case 'csiso91jisc62291984a':
10047
			case 'isoir91':
10048
			case 'jisc62291984a':
10049
			case 'jpocra':
10050
				return 'JIS_C6229-1984-a';
10051
10052
			case 'csiso92jisc62991984b':
10053
			case 'isoir92':
10054
			case 'iso646jpocrb':
10055
			case 'jisc62291984b':
10056
			case 'jpocrb':
10057
				return 'JIS_C6229-1984-b';
10058
10059
			case 'csiso93jis62291984badd':
10060
			case 'isoir93':
10061
			case 'jisc62291984badd':
10062
			case 'jpocrbadd':
10063
				return 'JIS_C6229-1984-b-add';
10064
10065
			case 'csiso94jis62291984hand':
10066
			case 'isoir94':
10067
			case 'jisc62291984hand':
10068
			case 'jpocrhand':
10069
				return 'JIS_C6229-1984-hand';
10070
10071
			case 'csiso95jis62291984handadd':
10072
			case 'isoir95':
10073
			case 'jisc62291984handadd':
10074
			case 'jpocrhandadd':
10075
				return 'JIS_C6229-1984-hand-add';
10076
10077
			case 'csiso96jisc62291984kana':
10078
			case 'isoir96':
10079
			case 'jisc62291984kana':
10080
				return 'JIS_C6229-1984-kana';
10081
10082
			case 'csjisencoding':
10083
			case 'jisencoding':
10084
				return 'JIS_Encoding';
10085
10086
			case 'cshalfwidthkatakana':
10087
			case 'jisx0201':
10088
			case 'x0201':
10089
				return 'JIS_X0201';
10090
10091
			case 'csiso159jisx02121990':
10092
			case 'isoir159':
10093
			case 'jisx02121990':
10094
			case 'x0212':
10095
				return 'JIS_X0212-1990';
10096
10097
			case 'csiso141jusib1002':
10098
			case 'isoir141':
10099
			case 'iso646yu':
10100
			case 'js':
10101
			case 'jusib1002':
10102
			case 'yu':
10103
				return 'JUS_I.B1.002';
10104
10105
			case 'csiso147macedonian':
10106
			case 'isoir147':
10107
			case 'jusib1003mac':
10108
			case 'macedonian':
10109
				return 'JUS_I.B1.003-mac';
10110
10111
			case 'csiso146serbian':
10112
			case 'isoir146':
10113
			case 'jusib1003serb':
10114
			case 'serbian':
10115
				return 'JUS_I.B1.003-serb';
10116
10117
			case 'koi7switched':
10118
				return 'KOI7-switched';
10119
10120
			case 'cskoi8r':
10121
			case 'koi8r':
10122
				return 'KOI8-R';
10123
10124
			case 'koi8u':
10125
				return 'KOI8-U';
10126
10127
			case 'csksc5636':
10128
			case 'iso646kr':
10129
			case 'ksc5636':
10130
				return 'KSC5636';
10131
10132
			case 'cskz1048':
10133
			case 'kz1048':
10134
			case 'rk1048':
10135
			case 'strk10482002':
10136
				return 'KZ-1048';
10137
10138
			case 'csiso19latingreek':
10139
			case 'isoir19':
10140
			case 'latingreek':
10141
				return 'latin-greek';
10142
10143
			case 'csiso27latingreek1':
10144
			case 'isoir27':
10145
			case 'latingreek1':
10146
				return 'Latin-greek-1';
10147
10148
			case 'csiso158lap':
10149
			case 'isoir158':
10150
			case 'lap':
10151
			case 'latinlap':
10152
				return 'latin-lap';
10153
10154
			case 'csmacintosh':
10155
			case 'mac':
10156
			case 'macintosh':
10157
				return 'macintosh';
10158
10159
			case 'csmicrosoftpublishing':
10160
			case 'microsoftpublishing':
10161
				return 'Microsoft-Publishing';
10162
10163
			case 'csmnem':
10164
			case 'mnem':
10165
				return 'MNEM';
10166
10167
			case 'csmnemonic':
10168
			case 'mnemonic':
10169
				return 'MNEMONIC';
10170
10171
			case 'csiso86hungarian':
10172
			case 'hu':
10173
			case 'isoir86':
10174
			case 'iso646hu':
10175
			case 'msz77953':
10176
				return 'MSZ_7795.3';
10177
10178
			case 'csnatsdano':
10179
			case 'isoir91':
10180
			case 'natsdano':
10181
				return 'NATS-DANO';
10182
10183
			case 'csnatsdanoadd':
10184
			case 'isoir92':
10185
			case 'natsdanoadd':
10186
				return 'NATS-DANO-ADD';
10187
10188
			case 'csnatssefi':
10189
			case 'isoir81':
10190
			case 'natssefi':
10191
				return 'NATS-SEFI';
10192
10193
			case 'csnatssefiadd':
10194
			case 'isoir82':
10195
			case 'natssefiadd':
10196
				return 'NATS-SEFI-ADD';
10197
10198
			case 'csiso151cuba':
10199
			case 'cuba':
10200
			case 'isoir151':
10201
			case 'iso646cu':
10202
			case 'ncnc001081':
10203
				return 'NC_NC00-10:81';
10204
10205
			case 'csiso69french':
10206
			case 'fr':
10207
			case 'isoir69':
10208
			case 'iso646fr':
10209
			case 'nfz62010':
10210
				return 'NF_Z_62-010';
10211
10212
			case 'csiso25french':
10213
			case 'isoir25':
10214
			case 'iso646fr1':
10215
			case 'nfz620101973':
10216
				return 'NF_Z_62-010_(1973)';
10217
10218
			case 'csiso60danishnorwegian':
10219
			case 'csiso60norwegian1':
10220
			case 'isoir60':
10221
			case 'iso646no':
10222
			case 'no':
10223
			case 'ns45511':
10224
				return 'NS_4551-1';
10225
10226
			case 'csiso61norwegian2':
10227
			case 'isoir61':
10228
			case 'iso646no2':
10229
			case 'no2':
10230
			case 'ns45512':
10231
				return 'NS_4551-2';
10232
10233
			case 'osdebcdicdf03irv':
10234
				return 'OSD_EBCDIC_DF03_IRV';
10235
10236
			case 'osdebcdicdf041':
10237
				return 'OSD_EBCDIC_DF04_1';
10238
10239
			case 'osdebcdicdf0415':
10240
				return 'OSD_EBCDIC_DF04_15';
10241
10242
			case 'cspc8danishnorwegian':
10243
			case 'pc8danishnorwegian':
10244
				return 'PC8-Danish-Norwegian';
10245
10246
			case 'cspc8turkish':
10247
			case 'pc8turkish':
10248
				return 'PC8-Turkish';
10249
10250
			case 'csiso16portuguese':
10251
			case 'isoir16':
10252
			case 'iso646pt':
10253
			case 'pt':
10254
				return 'PT';
10255
10256
			case 'csiso84portuguese2':
10257
			case 'isoir84':
10258
			case 'iso646pt2':
10259
			case 'pt2':
10260
				return 'PT2';
10261
10262
			case 'cp154':
10263
			case 'csptcp154':
10264
			case 'cyrillicasian':
10265
			case 'pt154':
10266
			case 'ptcp154':
10267
				return 'PTCP154';
10268
10269
			case 'scsu':
10270
				return 'SCSU';
10271
10272
			case 'csiso10swedish':
10273
			case 'fi':
10274
			case 'isoir10':
10275
			case 'iso646fi':
10276
			case 'iso646se':
10277
			case 'se':
10278
			case 'sen850200b':
10279
				return 'SEN_850200_B';
10280
10281
			case 'csiso11swedishfornames':
10282
			case 'isoir11':
10283
			case 'iso646se2':
10284
			case 'se2':
10285
			case 'sen850200c':
10286
				return 'SEN_850200_C';
10287
10288
			case 'csshiftjis':
10289
			case 'mskanji':
10290
			case 'shiftjis':
10291
				return 'Shift_JIS';
10292
10293
			case 'csiso102t617bit':
10294
			case 'isoir102':
10295
			case 't617bit':
10296
				return 'T.61-7bit';
10297
10298
			case 'csiso103t618bit':
10299
			case 'isoir103':
10300
			case 't61':
10301
			case 't618bit':
10302
				return 'T.61-8bit';
10303
10304
			case 'csiso128t101g2':
10305
			case 'isoir128':
10306
			case 't101g2':
10307
				return 'T.101-G2';
10308
10309
			case 'cstscii':
10310
			case 'tscii':
10311
				return 'TSCII';
10312
10313
			case 'csunicode11':
10314
			case 'unicode11':
10315
				return 'UNICODE-1-1';
10316
10317
			case 'csunicode11utf7':
10318
			case 'unicode11utf7':
10319
				return 'UNICODE-1-1-UTF-7';
10320
10321
			case 'csunknown8bit':
10322
			case 'unknown8bit':
10323
				return 'UNKNOWN-8BIT';
10324
10325
			case 'ansix341968':
10326
			case 'ansix341986':
10327
			case 'ascii':
10328
			case 'cp367':
10329
			case 'csascii':
10330
			case 'ibm367':
10331
			case 'isoir6':
10332
			case 'iso646us':
10333
			case 'iso646irv1991':
10334
			case 'us':
10335
			case 'usascii':
10336
				return 'US-ASCII';
10337
10338
			case 'csusdk':
10339
			case 'usdk':
10340
				return 'us-dk';
10341
10342
			case 'utf7':
10343
				return 'UTF-7';
10344
10345
			case 'utf8':
10346
				return 'UTF-8';
10347
10348
			case 'utf16':
10349
				return 'UTF-16';
10350
10351
			case 'utf16be':
10352
				return 'UTF-16BE';
10353
10354
			case 'utf16le':
10355
				return 'UTF-16LE';
10356
10357
			case 'utf32':
10358
				return 'UTF-32';
10359
10360
			case 'utf32be':
10361
				return 'UTF-32BE';
10362
10363
			case 'utf32le':
10364
				return 'UTF-32LE';
10365
10366
			case 'csventurainternational':
10367
			case 'venturainternational':
10368
				return 'Ventura-International';
10369
10370
			case 'csventuramath':
10371
			case 'venturamath':
10372
				return 'Ventura-Math';
10373
10374
			case 'csventuraus':
10375
			case 'venturaus':
10376
				return 'Ventura-US';
10377
10378
			case 'csiso70videotexsupp1':
10379
			case 'isoir70':
10380
			case 'videotexsuppl':
10381
				return 'videotex-suppl';
10382
10383
			case 'csviqr':
10384
			case 'viqr':
10385
				return 'VIQR';
10386
10387
			case 'csviscii':
10388
			case 'viscii':
10389
				return 'VISCII';
10390
10391
			case 'cswindows31j':
10392
			case 'windows31j':
10393
				return 'Windows-31J';
10394
10395
			case 'iso885911':
10396
			case 'tis620':
10397
				return 'Windows-874';
10398
10399
			case 'cseuckr':
10400
			case 'euckr':
10401
			case 'windows949':
10402
			case 'csksc56011987':
10403
			case 'isoir149':
10404
			case 'korean':
10405
			case 'ksc5601':
10406
			case 'ksc56011987':
10407
			case 'ksc56011989':
10408
				return 'Windows-949';
10409
10410
			case 'windows1250':
10411
				return 'windows-1250';
10412
10413
			case 'windows1251':
10414
				return 'windows-1251';
10415
10416
			case 'cp819':
10417
			case 'csisolatin1':
10418
			case 'ibm819':
10419
			case 'iso88591':
10420
			case 'isoir100':
10421
			case 'iso885911987':
10422
			case 'l1':
10423
			case 'latin1':
10424
			case 'windows1252':
10425
				return 'Windows-1252';
10426
10427
			case 'windows1252':
10428
				return 'windows-1252';
10429
10430
			case 'windows1253':
10431
				return 'windows-1253';
10432
10433
			case 'csisolatin5':
10434
			case 'iso88599':
10435
			case 'isoir148':
10436
			case 'iso885991989':
10437
			case 'l5':
10438
			case 'latin5':
10439
			case 'windows1254':
10440
				return 'Windows-1254';
10441
10442
			case 'windows1254':
10443
				return 'windows-1254';
10444
10445
			case 'windows1255':
10446
				return 'windows-1255';
10447
10448
			case 'windows1256':
10449
				return 'windows-1256';
10450
10451
			case 'windows1257':
10452
				return 'windows-1257';
10453
10454
			case 'windows1258':
10455
				return 'windows-1258';
10456
10457
			default:
10458
				return $charset;
10459
		}
10460
	}
10461
10462 23ca5695 Chris Buechler
	function get_curl_version()
10463 b2e02eef Scott Ullrich
	{
10464
		if (is_array($curl = curl_version()))
10465
		{
10466
			$curl = $curl['version'];
10467
		}
10468
		elseif (substr($curl, 0, 5) == 'curl/')
10469
		{
10470
			$curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10471
		}
10472
		elseif (substr($curl, 0, 8) == 'libcurl/')
10473
		{
10474
			$curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10475
		}
10476
		else
10477
		{
10478
			$curl = 0;
10479
		}
10480
		return $curl;
10481
	}
10482
10483
	function is_subclass_of($class1, $class2)
10484
	{
10485
		if (func_num_args() != 2)
10486
		{
10487
			trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10488
		}
10489
		elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10490
		{
10491
			return is_subclass_of($class1, $class2);
10492
		}
10493
		elseif (is_string($class1) && is_string($class2))
10494
		{
10495
			if (class_exists($class1))
10496
			{
10497
				if (class_exists($class2))
10498
				{
10499
					$class2 = strtolower($class2);
10500
					while ($class1 = strtolower(get_parent_class($class1)))
10501
					{
10502
						if ($class1 == $class2)
10503
						{
10504
							return true;
10505
						}
10506
					}
10507
				}
10508
			}
10509
			else
10510
			{
10511
				trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10512
			}
10513
		}
10514
		return false;
10515
	}
10516
10517
	/**
10518
	 * Strip HTML comments
10519
	 *
10520
	 * @access public
10521
	 * @param string $data Data to strip comments from
10522
	 * @return string Comment stripped string
10523
	 */
10524
	function strip_comments($data)
10525
	{
10526
		$output = '';
10527
		while (($start = strpos($data, '<!--')) !== false)
10528
		{
10529
			$output .= substr($data, 0, $start);
10530
			if (($end = strpos($data, '-->', $start)) !== false)
10531
			{
10532
				$data = substr_replace($data, '', 0, $end + 3);
10533
			}
10534
			else
10535
			{
10536
				$data = '';
10537
			}
10538
		}
10539
		return $output . $data;
10540
	}
10541
10542
	function parse_date($dt)
10543
	{
10544
		$parser = SimplePie_Parse_Date::get();
10545
		return $parser->parse($dt);
10546
	}
10547
10548
	/**
10549
	 * Decode HTML entities
10550
	 *
10551
	 * @static
10552
	 * @access public
10553
	 * @param string $data Input data
10554
	 * @return string Output data
10555
	 */
10556 23ca5695 Chris Buechler
	function entities_decode($data)
10557 b2e02eef Scott Ullrich
	{
10558
		$decoder = new SimplePie_Decode_HTML_Entities($data);
10559
		return $decoder->parse();
10560
	}
10561
10562
	/**
10563
	 * Remove RFC822 comments
10564
	 *
10565
	 * @access public
10566
	 * @param string $data Data to strip comments from
10567
	 * @return string Comment stripped string
10568
	 */
10569
	function uncomment_rfc822($string)
10570
	{
10571
		$string = (string) $string;
10572
		$position = 0;
10573
		$length = strlen($string);
10574
		$depth = 0;
10575
10576
		$output = '';
10577
10578
		while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10579
		{
10580
			$output .= substr($string, $position, $pos - $position);
10581
			$position = $pos + 1;
10582
			if ($string[$pos - 1] !== '\\')
10583
			{
10584
				$depth++;
10585
				while ($depth && $position < $length)
10586
				{
10587
					$position += strcspn($string, '()', $position);
10588
					if ($string[$position - 1] === '\\')
10589
					{
10590
						$position++;
10591
						continue;
10592
					}
10593
					elseif (isset($string[$position]))
10594
					{
10595
						switch ($string[$position])
10596
						{
10597
							case '(':
10598
								$depth++;
10599
								break;
10600
10601
							case ')':
10602
								$depth--;
10603
								break;
10604
						}
10605
						$position++;
10606
					}
10607
					else
10608
					{
10609
						break;
10610
					}
10611
				}
10612
			}
10613
			else
10614
			{
10615
				$output .= '(';
10616
			}
10617
		}
10618
		$output .= substr($string, $position);
10619
10620
		return $output;
10621
	}
10622
10623
	function parse_mime($mime)
10624
	{
10625
		if (($pos = strpos($mime, ';')) === false)
10626
		{
10627
			return trim($mime);
10628
		}
10629
		else
10630
		{
10631
			return trim(substr($mime, 0, $pos));
10632
		}
10633
	}
10634
10635
	function htmlspecialchars_decode($string, $quote_style)
10636
	{
10637
		if (function_exists('htmlspecialchars_decode'))
10638
		{
10639
			return htmlspecialchars_decode($string, $quote_style);
10640
		}
10641
		else
10642
		{
10643
			return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10644
		}
10645
	}
10646
10647
	function atom_03_construct_type($attribs)
10648
	{
10649
		if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10650
		{
10651
			$mode = SIMPLEPIE_CONSTRUCT_BASE64;
10652
		}
10653
		else
10654
		{
10655
			$mode = SIMPLEPIE_CONSTRUCT_NONE;
10656
		}
10657
		if (isset($attribs['']['type']))
10658
		{
10659
			switch (strtolower(trim($attribs['']['type'])))
10660
			{
10661
				case 'text':
10662
				case 'text/plain':
10663
					return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10664
10665
				case 'html':
10666
				case 'text/html':
10667
					return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10668
10669
				case 'xhtml':
10670
				case 'application/xhtml+xml':
10671
					return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10672
10673
				default:
10674
					return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10675
			}
10676
		}
10677
		else
10678
		{
10679
			return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10680
		}
10681
	}
10682
10683
	function atom_10_construct_type($attribs)
10684
	{
10685
		if (isset($attribs['']['type']))
10686
		{
10687
			switch (strtolower(trim($attribs['']['type'])))
10688
			{
10689
				case 'text':
10690
					return SIMPLEPIE_CONSTRUCT_TEXT;
10691
10692
				case 'html':
10693
					return SIMPLEPIE_CONSTRUCT_HTML;
10694
10695
				case 'xhtml':
10696
					return SIMPLEPIE_CONSTRUCT_XHTML;
10697
10698
				default:
10699
					return SIMPLEPIE_CONSTRUCT_NONE;
10700
			}
10701
		}
10702
		return SIMPLEPIE_CONSTRUCT_TEXT;
10703
	}
10704
10705
	function atom_10_content_construct_type($attribs)
10706
	{
10707
		if (isset($attribs['']['type']))
10708
		{
10709
			$type = strtolower(trim($attribs['']['type']));
10710
			switch ($type)
10711
			{
10712
				case 'text':
10713
					return SIMPLEPIE_CONSTRUCT_TEXT;
10714
10715
				case 'html':
10716
					return SIMPLEPIE_CONSTRUCT_HTML;
10717
10718
				case 'xhtml':
10719
					return SIMPLEPIE_CONSTRUCT_XHTML;
10720
			}
10721
			if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10722
			{
10723
				return SIMPLEPIE_CONSTRUCT_NONE;
10724
			}
10725
			else
10726
			{
10727
				return SIMPLEPIE_CONSTRUCT_BASE64;
10728
			}
10729
		}
10730
		else
10731
		{
10732
			return SIMPLEPIE_CONSTRUCT_TEXT;
10733
		}
10734
	}
10735
10736 23ca5695 Chris Buechler
	function is_isegment_nz_nc($string)
10737 b2e02eef Scott Ullrich
	{
10738
		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);
10739
	}
10740
10741 5aa68a55 Renato Botelho
	function space_separated_tokens($string)
10742 b2e02eef Scott Ullrich
	{
10743
		$space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10744
		$string_length = strlen($string);
10745
10746
		$position = strspn($string, $space_characters);
10747
		$tokens = array();
10748
10749
		while ($position < $string_length)
10750
		{
10751
			$len = strcspn($string, $space_characters, $position);
10752
			$tokens[] = substr($string, $position, $len);
10753
			$position += $len;
10754
			$position += strspn($string, $space_characters, $position);
10755
		}
10756
10757
		return $tokens;
10758
	}
10759
10760 23ca5695 Chris Buechler
	function array_unique($array)
10761 b2e02eef Scott Ullrich
	{
10762
		if (version_compare(PHP_VERSION, '5.2', '>='))
10763
		{
10764
			return array_unique($array);
10765
		}
10766
		else
10767
		{
10768
			$array = (array) $array;
10769
			$new_array = array();
10770
			$new_array_strings = array();
10771
			foreach ($array as $key => $value)
10772
			{
10773
				if (is_object($value))
10774
				{
10775
					if (method_exists($value, '__toString'))
10776
					{
10777
						$cmp = $value->__toString();
10778
					}
10779
					else
10780
					{
10781
						trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10782
					}
10783
				}
10784
				elseif (is_array($value))
10785
				{
10786
					$cmp = (string) reset($value);
10787
				}
10788
				else
10789
				{
10790
					$cmp = (string) $value;
10791
				}
10792
				if (!in_array($cmp, $new_array_strings))
10793
				{
10794
					$new_array[$key] = $value;
10795
					$new_array_strings[] = $cmp;
10796
				}
10797
			}
10798
			return $new_array;
10799
		}
10800
	}
10801
10802
	/**
10803
	 * Converts a unicode codepoint to a UTF-8 character
10804
	 *
10805
	 * @static
10806
	 * @access public
10807
	 * @param int $codepoint Unicode codepoint
10808
	 * @return string UTF-8 character
10809
	 */
10810 23ca5695 Chris Buechler
	function codepoint_to_utf8($codepoint)
10811 b2e02eef Scott Ullrich
	{
10812
		static $cache = array();
10813
		$codepoint = (int) $codepoint;
10814
		if (isset($cache[$codepoint]))
10815
		{
10816
			return $cache[$codepoint];
10817
		}
10818
		elseif ($codepoint < 0)
10819
		{
10820
			return $cache[$codepoint] = false;
10821
		}
10822
		else if ($codepoint <= 0x7f)
10823
		{
10824
			return $cache[$codepoint] = chr($codepoint);
10825
		}
10826
		else if ($codepoint <= 0x7ff)
10827
		{
10828
			return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10829
		}
10830
		else if ($codepoint <= 0xffff)
10831
		{
10832
			return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10833
		}
10834
		else if ($codepoint <= 0x10ffff)
10835
		{
10836
			return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10837
		}
10838
		else
10839
		{
10840
			// U+FFFD REPLACEMENT CHARACTER
10841
			return $cache[$codepoint] = "\xEF\xBF\xBD";
10842
		}
10843
	}
10844
10845
	/**
10846
	 * Re-implementation of PHP 5's stripos()
10847
	 *
10848
	 * Returns the numeric position of the first occurrence of needle in the
10849
	 * haystack string.
10850
	 *
10851
	 * @static
10852
	 * @access string
10853
	 * @param object $haystack
10854
	 * @param string $needle Note that the needle may be a string of one or more
10855
	 *     characters. If needle is not a string, it is converted to an integer
10856
	 *     and applied as the ordinal value of a character.
10857
	 * @param int $offset The optional offset parameter allows you to specify which
10858
	 *     character in haystack to start searching. The position returned is still
10859
	 *     relative to the beginning of haystack.
10860
	 * @return bool If needle is not found, stripos() will return boolean false.
10861
	 */
10862
	function stripos($haystack, $needle, $offset = 0)
10863
	{
10864
		if (function_exists('stripos'))
10865
		{
10866
			return stripos($haystack, $needle, $offset);
10867
		}
10868
		else
10869
		{
10870
			if (is_string($needle))
10871
			{
10872
				$needle = strtolower($needle);
10873
			}
10874
			elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10875
			{
10876
				$needle = strtolower(chr($needle));
10877
			}
10878
			else
10879
			{
10880
				trigger_error('needle is not a string or an integer', E_USER_WARNING);
10881
				return false;
10882
			}
10883
10884
			return strpos(strtolower($haystack), $needle, $offset);
10885
		}
10886
	}
10887
10888
	/**
10889
	 * Similar to parse_str()
10890
	 *
10891
	 * Returns an associative array of name/value pairs, where the value is an
10892
	 * array of values that have used the same name
10893
	 *
10894
	 * @static
10895
	 * @access string
10896
	 * @param string $str The input string.
10897
	 * @return array
10898
	 */
10899
	function parse_str($str)
10900
	{
10901
		$return = array();
10902
		$str = explode('&', $str);
10903
10904
		foreach ($str as $section)
10905
		{
10906
			if (strpos($section, '=') !== false)
10907
			{
10908
				list($name, $value) = explode('=', $section, 2);
10909
				$return[urldecode($name)][] = urldecode($value);
10910
			}
10911
			else
10912
			{
10913
				$return[urldecode($section)][] = null;
10914
			}
10915
		}
10916
10917
		return $return;
10918
	}
10919
10920
	/**
10921
	 * Detect XML encoding, as per XML 1.0 Appendix F.1
10922
	 *
10923
	 * @todo Add support for EBCDIC
10924
	 * @param string $data XML data
10925
	 * @return array Possible encodings
10926
	 */
10927 23ca5695 Chris Buechler
	function xml_encoding($data)
10928 b2e02eef Scott Ullrich
	{
10929
		// UTF-32 Big Endian BOM
10930
		if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10931
		{
10932
			$encoding[] = 'UTF-32BE';
10933
		}
10934
		// UTF-32 Little Endian BOM
10935
		elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10936
		{
10937
			$encoding[] = 'UTF-32LE';
10938
		}
10939
		// UTF-16 Big Endian BOM
10940
		elseif (substr($data, 0, 2) === "\xFE\xFF")
10941
		{
10942
			$encoding[] = 'UTF-16BE';
10943
		}
10944
		// UTF-16 Little Endian BOM
10945
		elseif (substr($data, 0, 2) === "\xFF\xFE")
10946
		{
10947
			$encoding[] = 'UTF-16LE';
10948
		}
10949
		// UTF-8 BOM
10950
		elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10951
		{
10952
			$encoding[] = 'UTF-8';
10953
		}
10954
		// UTF-32 Big Endian Without BOM
10955
		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")
10956
		{
10957
			if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
10958
			{
10959
				$parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
10960
				if ($parser->parse())
10961
				{
10962
					$encoding[] = $parser->encoding;
10963
				}
10964
			}
10965
			$encoding[] = 'UTF-32BE';
10966
		}
10967
		// UTF-32 Little Endian Without BOM
10968
		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")
10969
		{
10970
			if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
10971
			{
10972
				$parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
10973
				if ($parser->parse())
10974
				{
10975
					$encoding[] = $parser->encoding;
10976
				}
10977
			}
10978
			$encoding[] = 'UTF-32LE';
10979
		}
10980
		// UTF-16 Big Endian Without BOM
10981
		elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
10982
		{
10983
			if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
10984
			{
10985
				$parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
10986
				if ($parser->parse())
10987
				{
10988
					$encoding[] = $parser->encoding;
10989
				}
10990
			}
10991
			$encoding[] = 'UTF-16BE';
10992
		}
10993
		// UTF-16 Little Endian Without BOM
10994
		elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
10995
		{
10996
			if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
10997
			{
10998
				$parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
10999
				if ($parser->parse())
11000
				{
11001
					$encoding[] = $parser->encoding;
11002
				}
11003
			}
11004
			$encoding[] = 'UTF-16LE';
11005
		}
11006
		// US-ASCII (or superset)
11007
		elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
11008
		{
11009
			if ($pos = strpos($data, "\x3F\x3E"))
11010
			{
11011
				$parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
11012
				if ($parser->parse())
11013
				{
11014
					$encoding[] = $parser->encoding;
11015
				}
11016
			}
11017
			$encoding[] = 'UTF-8';
11018
		}
11019
		// Fallback to UTF-8
11020
		else
11021
		{
11022
			$encoding[] = 'UTF-8';
11023
		}
11024
		return $encoding;
11025
	}
11026
}
11027
11028
/**
11029
 * Decode HTML Entities
11030
 *
11031
 * This implements HTML5 as of revision 967 (2007-06-28)
11032
 *
11033
 * @package SimplePie
11034
 */
11035
class SimplePie_Decode_HTML_Entities
11036
{
11037
	/**
11038
	 * Data to be parsed
11039
	 *
11040
	 * @access private
11041
	 * @var string
11042
	 */
11043
	var $data = '';
11044
11045
	/**
11046
	 * Currently consumed bytes
11047
	 *
11048
	 * @access private
11049
	 * @var string
11050
	 */
11051
	var $consumed = '';
11052
11053
	/**
11054
	 * Position of the current byte being parsed
11055
	 *
11056
	 * @access private
11057
	 * @var int
11058
	 */
11059
	var $position = 0;
11060
11061
	/**
11062
	 * Create an instance of the class with the input data
11063
	 *
11064
	 * @access public
11065
	 * @param string $data Input data
11066
	 */
11067
	function SimplePie_Decode_HTML_Entities($data)
11068
	{
11069
		$this->data = $data;
11070
	}
11071
11072
	/**
11073
	 * Parse the input data
11074
	 *
11075
	 * @access public
11076
	 * @return string Output data
11077
	 */
11078
	function parse()
11079
	{
11080
		while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11081
		{
11082
			$this->consume();
11083
			$this->entity();
11084
			$this->consumed = '';
11085
		}
11086
		return $this->data;
11087
	}
11088
11089
	/**
11090
	 * Consume the next byte
11091
	 *
11092
	 * @access private
11093
	 * @return mixed The next byte, or false, if there is no more data
11094
	 */
11095
	function consume()
11096
	{
11097
		if (isset($this->data[$this->position]))
11098
		{
11099
			$this->consumed .= $this->data[$this->position];
11100
			return $this->data[$this->position++];
11101
		}
11102
		else
11103
		{
11104
			$this->consumed = false;
11105
			return false;
11106
		}
11107
	}
11108
11109
	/**
11110
	 * Consume a range of characters
11111
	 *
11112
	 * @access private
11113
	 * @param string $chars Characters to consume
11114
	 * @return mixed A series of characters that match the range, or false
11115
	 */
11116
	function consume_range($chars)
11117
	{
11118
		if ($len = strspn($this->data, $chars, $this->position))
11119
		{
11120
			$data = substr($this->data, $this->position, $len);
11121
			$this->consumed .= $data;
11122
			$this->position += $len;
11123
			return $data;
11124
		}
11125
		else
11126
		{
11127
			$this->consumed = false;
11128
			return false;
11129
		}
11130
	}
11131
11132
	/**
11133
	 * Unconsume one byte
11134
	 *
11135
	 * @access private
11136
	 */
11137
	function unconsume()
11138
	{
11139
		$this->consumed = substr($this->consumed, 0, -1);
11140
		$this->position--;
11141
	}
11142
11143
	/**
11144
	 * Decode an entity
11145
	 *
11146
	 * @access private
11147
	 */
11148
	function entity()
11149
	{
11150
		switch ($this->consume())
11151
		{
11152
			case "\x09":
11153
			case "\x0A":
11154
			case "\x0B":
11155
			case "\x0B":
11156
			case "\x0C":
11157
			case "\x20":
11158
			case "\x3C":
11159
			case "\x26":
11160
			case false:
11161
				break;
11162
11163
			case "\x23":
11164
				switch ($this->consume())
11165
				{
11166
					case "\x78":
11167
					case "\x58":
11168
						$range = '0123456789ABCDEFabcdef';
11169
						$hex = true;
11170
						break;
11171
11172
					default:
11173
						$range = '0123456789';
11174
						$hex = false;
11175
						$this->unconsume();
11176
						break;
11177
				}
11178
11179
				if ($codepoint = $this->consume_range($range))
11180
				{
11181
					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");
11182
11183
					if ($hex)
11184
					{
11185
						$codepoint = hexdec($codepoint);
11186
					}
11187
					else
11188
					{
11189
						$codepoint = intval($codepoint);
11190
					}
11191
11192
					if (isset($windows_1252_specials[$codepoint]))
11193
					{
11194
						$replacement = $windows_1252_specials[$codepoint];
11195
					}
11196
					else
11197
					{
11198
						$replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11199
					}
11200
11201
					if ($this->consume() != ';')
11202
					{
11203
						$this->unconsume();
11204
					}
11205
11206
					$consumed_length = strlen($this->consumed);
11207
					$this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11208
					$this->position += strlen($replacement) - $consumed_length;
11209
				}
11210
				break;
11211
11212
			default:
11213
				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");
11214
11215
				for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11216
				{
11217
					$consumed = substr($this->consumed, 1);
11218
					if (isset($entities[$consumed]))
11219
					{
11220
						$match = $consumed;
11221
					}
11222
				}
11223
11224
				if ($match !== null)
11225
				{
11226
 					$this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11227
					$this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11228
				}
11229
				break;
11230
		}
11231
	}
11232
}
11233
11234
/**
11235
 * Date Parser
11236
 *
11237
 * @package SimplePie
11238
 */
11239
class SimplePie_Parse_Date
11240
{
11241
	/**
11242
	 * Input data
11243
	 *
11244
	 * @access protected
11245
	 * @var string
11246
	 */
11247
	var $date;
11248
11249
	/**
11250
	 * List of days, calendar day name => ordinal day number in the week
11251
	 *
11252
	 * @access protected
11253
	 * @var array
11254
	 */
11255
	var $day = array(
11256
		// English
11257
		'mon' => 1,
11258
		'monday' => 1,
11259
		'tue' => 2,
11260
		'tuesday' => 2,
11261
		'wed' => 3,
11262
		'wednesday' => 3,
11263
		'thu' => 4,
11264
		'thursday' => 4,
11265
		'fri' => 5,
11266
		'friday' => 5,
11267
		'sat' => 6,
11268
		'saturday' => 6,
11269
		'sun' => 7,
11270
		'sunday' => 7,
11271
		// Dutch
11272
		'maandag' => 1,
11273
		'dinsdag' => 2,
11274
		'woensdag' => 3,
11275
		'donderdag' => 4,
11276
		'vrijdag' => 5,
11277
		'zaterdag' => 6,
11278
		'zondag' => 7,
11279
		// French
11280
		'lundi' => 1,
11281
		'mardi' => 2,
11282
		'mercredi' => 3,
11283
		'jeudi' => 4,
11284
		'vendredi' => 5,
11285
		'samedi' => 6,
11286
		'dimanche' => 7,
11287
		// German
11288
		'montag' => 1,
11289
		'dienstag' => 2,
11290
		'mittwoch' => 3,
11291
		'donnerstag' => 4,
11292
		'freitag' => 5,
11293
		'samstag' => 6,
11294
		'sonnabend' => 6,
11295
		'sonntag' => 7,
11296
		// Italian
11297
		'lunedì' => 1,
11298
		'martedì' => 2,
11299
		'mercoledì' => 3,
11300
		'giovedì' => 4,
11301
		'venerdì' => 5,
11302
		'sabato' => 6,
11303
		'domenica' => 7,
11304
		// Spanish
11305
		'lunes' => 1,
11306
		'martes' => 2,
11307
		'miércoles' => 3,
11308
		'jueves' => 4,
11309
		'viernes' => 5,
11310
		'sábado' => 6,
11311
		'domingo' => 7,
11312
		// Finnish
11313
		'maanantai' => 1,
11314
		'tiistai' => 2,
11315
		'keskiviikko' => 3,
11316
		'torstai' => 4,
11317
		'perjantai' => 5,
11318
		'lauantai' => 6,
11319
		'sunnuntai' => 7,
11320
		// Hungarian
11321
		'hétfő' => 1,
11322
		'kedd' => 2,
11323
		'szerda' => 3,
11324
		'csütörtok' => 4,
11325
		'péntek' => 5,
11326
		'szombat' => 6,
11327
		'vasárnap' => 7,
11328
		// Greek
11329
		'Δευ' => 1,
11330
		'Τρι' => 2,
11331
		'Τετ' => 3,
11332
		'Πεμ' => 4,
11333
		'Παρ' => 5,
11334
		'Σαβ' => 6,
11335
		'Κυρ' => 7,
11336
	);
11337
11338
	/**
11339
	 * List of months, calendar month name => calendar month number
11340
	 *
11341
	 * @access protected
11342
	 * @var array
11343
	 */
11344
	var $month = array(
11345
		// English
11346
		'jan' => 1,
11347
		'january' => 1,
11348
		'feb' => 2,
11349
		'february' => 2,
11350
		'mar' => 3,
11351
		'march' => 3,
11352
		'apr' => 4,
11353
		'april' => 4,
11354
		'may' => 5,
11355
		// No long form of May
11356
		'jun' => 6,
11357
		'june' => 6,
11358
		'jul' => 7,
11359
		'july' => 7,
11360
		'aug' => 8,
11361
		'august' => 8,
11362
		'sep' => 9,
11363
		'september' => 8,
11364
		'oct' => 10,
11365
		'october' => 10,
11366
		'nov' => 11,
11367
		'november' => 11,
11368
		'dec' => 12,
11369
		'december' => 12,
11370
		// Dutch
11371
		'januari' => 1,
11372
		'februari' => 2,
11373
		'maart' => 3,
11374
		'april' => 4,
11375
		'mei' => 5,
11376
		'juni' => 6,
11377
		'juli' => 7,
11378
		'augustus' => 8,
11379
		'september' => 9,
11380
		'oktober' => 10,
11381
		'november' => 11,
11382
		'december' => 12,
11383
		// French
11384
		'janvier' => 1,
11385
		'février' => 2,
11386
		'mars' => 3,
11387
		'avril' => 4,
11388
		'mai' => 5,
11389
		'juin' => 6,
11390
		'juillet' => 7,
11391
		'août' => 8,
11392
		'septembre' => 9,
11393
		'octobre' => 10,
11394
		'novembre' => 11,
11395
		'décembre' => 12,
11396
		// German
11397
		'januar' => 1,
11398
		'februar' => 2,
11399
		'märz' => 3,
11400
		'april' => 4,
11401
		'mai' => 5,
11402
		'juni' => 6,
11403
		'juli' => 7,
11404
		'august' => 8,
11405
		'september' => 9,
11406
		'oktober' => 10,
11407
		'november' => 11,
11408
		'dezember' => 12,
11409
		// Italian
11410
		'gennaio' => 1,
11411
		'febbraio' => 2,
11412
		'marzo' => 3,
11413
		'aprile' => 4,
11414
		'maggio' => 5,
11415
		'giugno' => 6,
11416
		'luglio' => 7,
11417
		'agosto' => 8,
11418
		'settembre' => 9,
11419
		'ottobre' => 10,
11420
		'novembre' => 11,
11421
		'dicembre' => 12,
11422
		// Spanish
11423
		'enero' => 1,
11424
		'febrero' => 2,
11425
		'marzo' => 3,
11426
		'abril' => 4,
11427
		'mayo' => 5,
11428
		'junio' => 6,
11429
		'julio' => 7,
11430
		'agosto' => 8,
11431
		'septiembre' => 9,
11432
		'setiembre' => 9,
11433
		'octubre' => 10,
11434
		'noviembre' => 11,
11435
		'diciembre' => 12,
11436
		// Finnish
11437
		'tammikuu' => 1,
11438
		'helmikuu' => 2,
11439
		'maaliskuu' => 3,
11440
		'huhtikuu' => 4,
11441
		'toukokuu' => 5,
11442
		'kesäkuu' => 6,
11443
		'heinäkuu' => 7,
11444
		'elokuu' => 8,
11445
		'suuskuu' => 9,
11446
		'lokakuu' => 10,
11447
		'marras' => 11,
11448
		'joulukuu' => 12,
11449
		// Hungarian
11450
		'január' => 1,
11451
		'február' => 2,
11452
		'március' => 3,
11453
		'április' => 4,
11454
		'május' => 5,
11455
		'június' => 6,
11456
		'július' => 7,
11457
		'augusztus' => 8,
11458
		'szeptember' => 9,
11459
		'október' => 10,
11460
		'november' => 11,
11461
		'december' => 12,
11462
		// Greek
11463
		'Ιαν' => 1,
11464
		'Φεβ' => 2,
11465
		'Μάώ' => 3,
11466
		'Μαώ' => 3,
11467
		'Απρ' => 4,
11468
		'Μάι' => 5,
11469
		'Μαϊ' => 5,
11470
		'Μαι' => 5,
11471
		'Ιούν' => 6,
11472
		'Ιον' => 6,
11473
		'Ιούλ' => 7,
11474
		'Ιολ' => 7,
11475
		'Αύγ' => 8,
11476
		'Αυγ' => 8,
11477
		'Σεπ' => 9,
11478
		'Οκτ' => 10,
11479
		'Νοέ' => 11,
11480
		'Δεκ' => 12,
11481
	);
11482
11483
	/**
11484
	 * List of timezones, abbreviation => offset from UTC
11485
	 *
11486
	 * @access protected
11487
	 * @var array
11488
	 */
11489
	var $timezone = array(
11490
		'ACDT' => 37800,
11491
		'ACIT' => 28800,
11492
		'ACST' => 34200,
11493
		'ACT' => -18000,
11494
		'ACWDT' => 35100,
11495
		'ACWST' => 31500,
11496
		'AEDT' => 39600,
11497
		'AEST' => 36000,
11498
		'AFT' => 16200,
11499
		'AKDT' => -28800,
11500
		'AKST' => -32400,
11501
		'AMDT' => 18000,
11502
		'AMT' => -14400,
11503
		'ANAST' => 46800,
11504
		'ANAT' => 43200,
11505
		'ART' => -10800,
11506
		'AZOST' => -3600,
11507
		'AZST' => 18000,
11508
		'AZT' => 14400,
11509
		'BIOT' => 21600,
11510
		'BIT' => -43200,
11511
		'BOT' => -14400,
11512
		'BRST' => -7200,
11513
		'BRT' => -10800,
11514
		'BST' => 3600,
11515
		'BTT' => 21600,
11516
		'CAST' => 18000,
11517
		'CAT' => 7200,
11518
		'CCT' => 23400,
11519
		'CDT' => -18000,
11520
		'CEDT' => 7200,
11521
		'CET' => 3600,
11522
		'CGST' => -7200,
11523
		'CGT' => -10800,
11524
		'CHADT' => 49500,
11525
		'CHAST' => 45900,
11526
		'CIST' => -28800,
11527
		'CKT' => -36000,
11528
		'CLDT' => -10800,
11529
		'CLST' => -14400,
11530
		'COT' => -18000,
11531
		'CST' => -21600,
11532
		'CVT' => -3600,
11533
		'CXT' => 25200,
11534
		'DAVT' => 25200,
11535
		'DTAT' => 36000,
11536
		'EADT' => -18000,
11537
		'EAST' => -21600,
11538
		'EAT' => 10800,
11539
		'ECT' => -18000,
11540
		'EDT' => -14400,
11541
		'EEST' => 10800,
11542
		'EET' => 7200,
11543
		'EGT' => -3600,
11544
		'EKST' => 21600,
11545
		'EST' => -18000,
11546
		'FJT' => 43200,
11547
		'FKDT' => -10800,
11548
		'FKST' => -14400,
11549
		'FNT' => -7200,
11550
		'GALT' => -21600,
11551
		'GEDT' => 14400,
11552
		'GEST' => 10800,
11553
		'GFT' => -10800,
11554
		'GILT' => 43200,
11555
		'GIT' => -32400,
11556
		'GST' => 14400,
11557
		'GST' => -7200,
11558
		'GYT' => -14400,
11559
		'HAA' => -10800,
11560
		'HAC' => -18000,
11561
		'HADT' => -32400,
11562
		'HAE' => -14400,
11563
		'HAP' => -25200,
11564
		'HAR' => -21600,
11565
		'HAST' => -36000,
11566
		'HAT' => -9000,
11567
		'HAY' => -28800,
11568
		'HKST' => 28800,
11569
		'HMT' => 18000,
11570
		'HNA' => -14400,
11571
		'HNC' => -21600,
11572
		'HNE' => -18000,
11573
		'HNP' => -28800,
11574
		'HNR' => -25200,
11575
		'HNT' => -12600,
11576
		'HNY' => -32400,
11577
		'IRDT' => 16200,
11578
		'IRKST' => 32400,
11579
		'IRKT' => 28800,
11580
		'IRST' => 12600,
11581
		'JFDT' => -10800,
11582
		'JFST' => -14400,
11583
		'JST' => 32400,
11584
		'KGST' => 21600,
11585
		'KGT' => 18000,
11586
		'KOST' => 39600,
11587
		'KOVST' => 28800,
11588
		'KOVT' => 25200,
11589
		'KRAST' => 28800,
11590
		'KRAT' => 25200,
11591
		'KST' => 32400,
11592
		'LHDT' => 39600,
11593
		'LHST' => 37800,
11594
		'LINT' => 50400,
11595
		'LKT' => 21600,
11596
		'MAGST' => 43200,
11597
		'MAGT' => 39600,
11598
		'MAWT' => 21600,
11599
		'MDT' => -21600,
11600
		'MESZ' => 7200,
11601
		'MEZ' => 3600,
11602
		'MHT' => 43200,
11603
		'MIT' => -34200,
11604
		'MNST' => 32400,
11605
		'MSDT' => 14400,
11606
		'MSST' => 10800,
11607
		'MST' => -25200,
11608
		'MUT' => 14400,
11609
		'MVT' => 18000,
11610
		'MYT' => 28800,
11611
		'NCT' => 39600,
11612
		'NDT' => -9000,
11613
		'NFT' => 41400,
11614
		'NMIT' => 36000,
11615
		'NOVST' => 25200,
11616
		'NOVT' => 21600,
11617
		'NPT' => 20700,
11618
		'NRT' => 43200,
11619
		'NST' => -12600,
11620
		'NUT' => -39600,
11621
		'NZDT' => 46800,
11622
		'NZST' => 43200,
11623
		'OMSST' => 25200,
11624
		'OMST' => 21600,
11625
		'PDT' => -25200,
11626
		'PET' => -18000,
11627
		'PETST' => 46800,
11628
		'PETT' => 43200,
11629
		'PGT' => 36000,
11630
		'PHOT' => 46800,
11631
		'PHT' => 28800,
11632
		'PKT' => 18000,
11633
		'PMDT' => -7200,
11634
		'PMST' => -10800,
11635
		'PONT' => 39600,
11636
		'PST' => -28800,
11637
		'PWT' => 32400,
11638
		'PYST' => -10800,
11639
		'PYT' => -14400,
11640
		'RET' => 14400,
11641
		'ROTT' => -10800,
11642
		'SAMST' => 18000,
11643
		'SAMT' => 14400,
11644
		'SAST' => 7200,
11645
		'SBT' => 39600,
11646
		'SCDT' => 46800,
11647
		'SCST' => 43200,
11648
		'SCT' => 14400,
11649
		'SEST' => 3600,
11650
		'SGT' => 28800,
11651
		'SIT' => 28800,
11652
		'SRT' => -10800,
11653
		'SST' => -39600,
11654
		'SYST' => 10800,
11655
		'SYT' => 7200,
11656
		'TFT' => 18000,
11657
		'THAT' => -36000,
11658
		'TJT' => 18000,
11659
		'TKT' => -36000,
11660
		'TMT' => 18000,
11661
		'TOT' => 46800,
11662
		'TPT' => 32400,
11663
		'TRUT' => 36000,
11664
		'TVT' => 43200,
11665
		'TWT' => 28800,
11666
		'UYST' => -7200,
11667
		'UYT' => -10800,
11668
		'UZT' => 18000,
11669
		'VET' => -14400,
11670
		'VLAST' => 39600,
11671
		'VLAT' => 36000,
11672
		'VOST' => 21600,
11673
		'VUT' => 39600,
11674
		'WAST' => 7200,
11675
		'WAT' => 3600,
11676
		'WDT' => 32400,
11677
		'WEST' => 3600,
11678
		'WFT' => 43200,
11679
		'WIB' => 25200,
11680
		'WIT' => 32400,
11681
		'WITA' => 28800,
11682
		'WKST' => 18000,
11683
		'WST' => 28800,
11684
		'YAKST' => 36000,
11685
		'YAKT' => 32400,
11686
		'YAPT' => 36000,
11687
		'YEKST' => 21600,
11688
		'YEKT' => 18000,
11689
	);
11690
11691
	/**
11692
	 * Cached PCRE for SimplePie_Parse_Date::$day
11693
	 *
11694
	 * @access protected
11695
	 * @var string
11696
	 */
11697
	var $day_pcre;
11698
11699
	/**
11700
	 * Cached PCRE for SimplePie_Parse_Date::$month
11701
	 *
11702
	 * @access protected
11703
	 * @var string
11704
	 */
11705
	var $month_pcre;
11706
11707
	/**
11708
	 * Array of user-added callback methods
11709
	 *
11710
	 * @access private
11711
	 * @var array
11712
	 */
11713
	var $built_in = array();
11714
11715
	/**
11716
	 * Array of user-added callback methods
11717
	 *
11718
	 * @access private
11719
	 * @var array
11720
	 */
11721
	var $user = array();
11722
11723
	/**
11724
	 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11725
	 * self::month_pcre, and self::built_in
11726
	 *
11727
	 * @access private
11728
	 */
11729
	function SimplePie_Parse_Date()
11730
	{
11731
		$this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11732
		$this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11733
11734
		static $cache;
11735
		if (!isset($cache[get_class($this)]))
11736
		{
11737
			if (extension_loaded('Reflection'))
11738
			{
11739
				$class = new ReflectionClass(get_class($this));
11740
				$methods = $class->getMethods();
11741
				$all_methods = array();
11742
				foreach ($methods as $method)
11743
				{
11744
					$all_methods[] = $method->getName();
11745
				}
11746
			}
11747
			else
11748
			{
11749
				$all_methods = get_class_methods($this);
11750
			}
11751
11752
			foreach ($all_methods as $method)
11753
			{
11754
				if (strtolower(substr($method, 0, 5)) === 'date_')
11755
				{
11756
					$cache[get_class($this)][] = $method;
11757
				}
11758
			}
11759
		}
11760
11761
		foreach ($cache[get_class($this)] as $method)
11762
		{
11763
			$this->built_in[] = $method;
11764
		}
11765
	}
11766
11767
	/**
11768
	 * Get the object
11769
	 *
11770
	 * @access public
11771
	 */
11772 23ca5695 Chris Buechler
	function get()
11773 b2e02eef Scott Ullrich
	{
11774
		static $object;
11775
		if (!$object)
11776
		{
11777
			$object = new SimplePie_Parse_Date;
11778
		}
11779
		return $object;
11780
	}
11781
11782
	/**
11783
	 * Parse a date
11784
	 *
11785
	 * @final
11786
	 * @access public
11787
	 * @param string $date Date to parse
11788
	 * @return int Timestamp corresponding to date string, or false on failure
11789
	 */
11790
	function parse($date)
11791
	{
11792
		foreach ($this->user as $method)
11793
		{
11794
			if (($returned = call_user_func($method, $date)) !== false)
11795
			{
11796
				return $returned;
11797
			}
11798
		}
11799
11800
		foreach ($this->built_in as $method)
11801
		{
11802
			if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11803
			{
11804
				return $returned;
11805
			}
11806
		}
11807
11808
		return false;
11809
	}
11810
11811
	/**
11812
	 * Add a callback method to parse a date
11813
	 *
11814
	 * @final
11815
	 * @access public
11816
	 * @param callback $callback
11817
	 */
11818
	function add_callback($callback)
11819
	{
11820
		if (is_callable($callback))
11821
		{
11822
			$this->user[] = $callback;
11823
		}
11824
		else
11825
		{
11826
			trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
11827
		}
11828
	}
11829
11830
	/**
11831
	 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11832
	 * well as allowing any of upper or lower case "T", horizontal tabs, or
11833 5aa68a55 Renato Botelho
	 * spaces to be used as the time separator (including more than one))
11834 b2e02eef Scott Ullrich
	 *
11835
	 * @access protected
11836
	 * @return int Timestamp
11837
	 */
11838
	function date_w3cdtf($date)
11839
	{
11840
		static $pcre;
11841
		if (!$pcre)
11842
		{
11843
			$year = '([0-9]{4})';
11844
			$month = $day = $hour = $minute = $second = '([0-9]{2})';
11845
			$decimal = '([0-9]*)';
11846
			$zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11847
			$pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11848
		}
11849
		if (preg_match($pcre, $date, $match))
11850
		{
11851
			/*
11852
			Capturing subpatterns:
11853
			1: Year
11854
			2: Month
11855
			3: Day
11856
			4: Hour
11857
			5: Minute
11858
			6: Second
11859
			7: Decimal fraction of a second
11860
			8: Zulu
11861
			9: Timezone ±
11862
			10: Timezone hours
11863
			11: Timezone minutes
11864
			*/
11865
11866
			// Fill in empty matches
11867
			for ($i = count($match); $i <= 3; $i++)
11868
			{
11869
				$match[$i] = '1';
11870
			}
11871
11872
			for ($i = count($match); $i <= 7; $i++)
11873
			{
11874
				$match[$i] = '0';
11875
			}
11876
11877
			// Numeric timezone
11878
			if (isset($match[9]) && $match[9] !== '')
11879
			{
11880
				$timezone = $match[10] * 3600;
11881
				$timezone += $match[11] * 60;
11882
				if ($match[9] === '-')
11883
				{
11884
					$timezone = 0 - $timezone;
11885
				}
11886
			}
11887
			else
11888
			{
11889
				$timezone = 0;
11890
			}
11891
11892
			// Convert the number of seconds to an integer, taking decimals into account
11893
			$second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11894
11895
			return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
11896
		}
11897
		else
11898
		{
11899
			return false;
11900
		}
11901
	}
11902
11903
	/**
11904
	 * Remove RFC822 comments
11905
	 *
11906
	 * @access protected
11907
	 * @param string $data Data to strip comments from
11908
	 * @return string Comment stripped string
11909
	 */
11910
	function remove_rfc2822_comments($string)
11911
	{
11912
		$string = (string) $string;
11913
		$position = 0;
11914
		$length = strlen($string);
11915
		$depth = 0;
11916
11917
		$output = '';
11918
11919
		while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
11920
		{
11921
			$output .= substr($string, $position, $pos - $position);
11922
			$position = $pos + 1;
11923
			if ($string[$pos - 1] !== '\\')
11924
			{
11925
				$depth++;
11926
				while ($depth && $position < $length)
11927
				{
11928
					$position += strcspn($string, '()', $position);
11929
					if ($string[$position - 1] === '\\')
11930
					{
11931
						$position++;
11932
						continue;
11933
					}
11934
					elseif (isset($string[$position]))
11935
					{
11936
						switch ($string[$position])
11937
						{
11938
							case '(':
11939
								$depth++;
11940
								break;
11941
11942
							case ')':
11943
								$depth--;
11944
								break;
11945
						}
11946
						$position++;
11947
					}
11948
					else
11949
					{
11950
						break;
11951
					}
11952
				}
11953
			}
11954
			else
11955
			{
11956
				$output .= '(';
11957
			}
11958
		}
11959
		$output .= substr($string, $position);
11960
11961
		return $output;
11962
	}
11963
11964
	/**
11965
	 * Parse RFC2822's date format
11966
	 *
11967
	 * @access protected
11968
	 * @return int Timestamp
11969
	 */
11970
	function date_rfc2822($date)
11971
	{
11972
		static $pcre;
11973
		if (!$pcre)
11974
		{
11975
			$wsp = '[\x09\x20]';
11976
			$fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
11977
			$optional_fws = $fws . '?';
11978
			$day_name = $this->day_pcre;
11979
			$month = $this->month_pcre;
11980
			$day = '([0-9]{1,2})';
11981
			$hour = $minute = $second = '([0-9]{2})';
11982
			$year = '([0-9]{2,4})';
11983
			$num_zone = '([+\-])([0-9]{2})([0-9]{2})';
11984
			$character_zone = '([A-Z]{1,5})';
11985
			$zone = '(?:' . $num_zone . '|' . $character_zone . ')';
11986
			$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';
11987
		}
11988
		if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
11989
		{
11990
			/*
11991
			Capturing subpatterns:
11992
			1: Day name
11993
			2: Day
11994
			3: Month
11995
			4: Year
11996
			5: Hour
11997
			6: Minute
11998
			7: Second
11999
			8: Timezone ±
12000
			9: Timezone hours
12001
			10: Timezone minutes
12002
			11: Alphabetic timezone
12003
			*/
12004
12005
			// Find the month number
12006
			$month = $this->month[strtolower($match[3])];
12007
12008
			// Numeric timezone
12009
			if ($match[8] !== '')
12010
			{
12011
				$timezone = $match[9] * 3600;
12012
				$timezone += $match[10] * 60;
12013
				if ($match[8] === '-')
12014
				{
12015
					$timezone = 0 - $timezone;
12016
				}
12017
			}
12018
			// Character timezone
12019
			elseif (isset($this->timezone[strtoupper($match[11])]))
12020
			{
12021
				$timezone = $this->timezone[strtoupper($match[11])];
12022
			}
12023
			// Assume everything else to be -0000
12024
			else
12025
			{
12026
				$timezone = 0;
12027
			}
12028
12029
			// Deal with 2/3 digit years
12030
			if ($match[4] < 50)
12031
			{
12032
				$match[4] += 2000;
12033
			}
12034
			elseif ($match[4] < 1000)
12035
			{
12036
				$match[4] += 1900;
12037
			}
12038
12039
			// Second is optional, if it is empty set it to zero
12040
			if ($match[7] !== '')
12041
			{
12042
				$second = $match[7];
12043
			}
12044
			else
12045
			{
12046
				$second = 0;
12047
			}
12048
12049
			return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
12050
		}
12051
		else
12052
		{
12053
			return false;
12054
		}
12055
	}
12056
12057
	/**
12058
	 * Parse RFC850's date format
12059
	 *
12060
	 * @access protected
12061
	 * @return int Timestamp
12062
	 */
12063
	function date_rfc850($date)
12064
	{
12065
		static $pcre;
12066
		if (!$pcre)
12067
		{
12068
			$space = '[\x09\x20]+';
12069
			$day_name = $this->day_pcre;
12070
			$month = $this->month_pcre;
12071
			$day = '([0-9]{1,2})';
12072
			$year = $hour = $minute = $second = '([0-9]{2})';
12073
			$zone = '([A-Z]{1,5})';
12074
			$pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
12075
		}
12076
		if (preg_match($pcre, $date, $match))
12077
		{
12078
			/*
12079
			Capturing subpatterns:
12080
			1: Day name
12081
			2: Day
12082
			3: Month
12083
			4: Year
12084
			5: Hour
12085
			6: Minute
12086
			7: Second
12087
			8: Timezone
12088
			*/
12089
12090
			// Month
12091
			$month = $this->month[strtolower($match[3])];
12092
12093
			// Character timezone
12094
			if (isset($this->timezone[strtoupper($match[8])]))
12095
			{
12096
				$timezone = $this->timezone[strtoupper($match[8])];
12097
			}
12098
			// Assume everything else to be -0000
12099
			else
12100
			{
12101
				$timezone = 0;
12102
			}
12103
12104
			// Deal with 2 digit year
12105
			if ($match[4] < 50)
12106
			{
12107
				$match[4] += 2000;
12108
			}
12109
			else
12110
			{
12111
				$match[4] += 1900;
12112
			}
12113
12114
			return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
12115
		}
12116
		else
12117
		{
12118
			return false;
12119
		}
12120
	}
12121
12122
	/**
12123
	 * Parse C99's asctime()'s date format
12124
	 *
12125
	 * @access protected
12126
	 * @return int Timestamp
12127
	 */
12128
	function date_asctime($date)
12129
	{
12130
		static $pcre;
12131
		if (!$pcre)
12132
		{
12133
			$space = '[\x09\x20]+';
12134
			$wday_name = $this->day_pcre;
12135
			$mon_name = $this->month_pcre;
12136
			$day = '([0-9]{1,2})';
12137
			$hour = $sec = $min = '([0-9]{2})';
12138
			$year = '([0-9]{4})';
12139
			$terminator = '\x0A?\x00?';
12140
			$pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
12141
		}
12142
		if (preg_match($pcre, $date, $match))
12143
		{
12144
			/*
12145
			Capturing subpatterns:
12146
			1: Day name
12147
			2: Month
12148
			3: Day
12149
			4: Hour
12150
			5: Minute
12151
			6: Second
12152
			7: Year
12153
			*/
12154
12155
			$month = $this->month[strtolower($match[2])];
12156
			return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
12157
		}
12158
		else
12159
		{
12160
			return false;
12161
		}
12162
	}
12163
12164
	/**
12165
	 * Parse dates using strtotime()
12166
	 *
12167
	 * @access protected
12168
	 * @return int Timestamp
12169
	 */
12170
	function date_strtotime($date)
12171
	{
12172
		$strtotime = strtotime($date);
12173
		if ($strtotime === -1 || $strtotime === false)
12174
		{
12175
			return false;
12176
		}
12177
		else
12178
		{
12179
			return $strtotime;
12180
		}
12181
	}
12182
}
12183
12184
/**
12185
 * Content-type sniffing
12186
 *
12187
 * @package SimplePie
12188
 */
12189
class SimplePie_Content_Type_Sniffer
12190
{
12191
	/**
12192
	 * File object
12193
	 *
12194
	 * @var SimplePie_File
12195
	 * @access private
12196
	 */
12197
	var $file;
12198
12199
	/**
12200
	 * Create an instance of the class with the input file
12201
	 *
12202
	 * @access public
12203
	 * @param SimplePie_Content_Type_Sniffer $file Input file
12204
	 */
12205
	function SimplePie_Content_Type_Sniffer($file)
12206
	{
12207
		$this->file = $file;
12208
	}
12209
12210
	/**
12211
	 * Get the Content-Type of the specified file
12212
	 *
12213
	 * @access public
12214
	 * @return string Actual Content-Type
12215
	 */
12216
	function get_type()
12217
	{
12218
		if (isset($this->file->headers['content-type']))
12219
		{
12220
			if (!isset($this->file->headers['content-encoding'])
12221
				&& ($this->file->headers['content-type'] === 'text/plain'
12222
					|| $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
12223
					|| $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
12224
			{
12225
				return $this->text_or_binary();
12226
			}
12227
12228
			if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
12229
			{
12230
				$official = substr($this->file->headers['content-type'], 0, $pos);
12231
			}
12232
			else
12233
			{
12234
				$official = $this->file->headers['content-type'];
12235
			}
12236
			$official = strtolower($official);
12237
12238
			if ($official === 'unknown/unknown'
12239
				|| $official === 'application/unknown')
12240
			{
12241
				return $this->unknown();
12242
			}
12243
			elseif (substr($official, -4) === '+xml'
12244
				|| $official === 'text/xml'
12245
				|| $official === 'application/xml')
12246
			{
12247
				return $official;
12248
			}
12249
			elseif (substr($official, 0, 6) === 'image/')
12250
			{
12251
				if ($return = $this->image())
12252
				{
12253
					return $return;
12254
				}
12255
				else
12256
				{
12257
					return $official;
12258
				}
12259
			}
12260
			elseif ($official === 'text/html')
12261
			{
12262
				return $this->feed_or_html();
12263
			}
12264
			else
12265
			{
12266
				return $official;
12267
			}
12268
		}
12269
		else
12270
		{
12271
			return $this->unknown();
12272
		}
12273
	}
12274
12275
	/**
12276
	 * Sniff text or binary
12277
	 *
12278
	 * @access private
12279
	 * @return string Actual Content-Type
12280
	 */
12281
	function text_or_binary()
12282
	{
12283
		if (substr($this->file->body, 0, 2) === "\xFE\xFF"
12284
			|| substr($this->file->body, 0, 2) === "\xFF\xFE"
12285
			|| substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
12286
			|| substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
12287
		{
12288
			return 'text/plain';
12289
		}
12290
		elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
12291
		{
12292
			return 'application/octect-stream';
12293
		}
12294
		else
12295
		{
12296
			return 'text/plain';
12297
		}
12298
	}
12299
12300
	/**
12301
	 * Sniff unknown
12302
	 *
12303
	 * @access private
12304
	 * @return string Actual Content-Type
12305
	 */
12306
	function unknown()
12307
	{
12308
		$ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
12309
		if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
12310
			|| strtolower(substr($this->file->body, $ws, 5)) === '<html'
12311
			|| strtolower(substr($this->file->body, $ws, 7)) === '<script')
12312
		{
12313
			return 'text/html';
12314
		}
12315
		elseif (substr($this->file->body, 0, 5) === '%PDF-')
12316
		{
12317
			return 'application/pdf';
12318
		}
12319
		elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
12320
		{
12321
			return 'application/postscript';
12322
		}
12323
		elseif (substr($this->file->body, 0, 6) === 'GIF87a'
12324
			|| substr($this->file->body, 0, 6) === 'GIF89a')
12325
		{
12326
			return 'image/gif';
12327
		}
12328
		elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12329
		{
12330
			return 'image/png';
12331
		}
12332
		elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12333
		{
12334
			return 'image/jpeg';
12335
		}
12336
		elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12337
		{
12338
			return 'image/bmp';
12339
		}
12340
		else
12341
		{
12342
			return $this->text_or_binary();
12343
		}
12344
	}
12345
12346
	/**
12347
	 * Sniff images
12348
	 *
12349
	 * @access private
12350
	 * @return string Actual Content-Type
12351
	 */
12352
	function image()
12353
	{
12354
		if (substr($this->file->body, 0, 6) === 'GIF87a'
12355
			|| substr($this->file->body, 0, 6) === 'GIF89a')
12356
		{
12357
			return 'image/gif';
12358
		}
12359
		elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12360
		{
12361
			return 'image/png';
12362
		}
12363
		elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12364
		{
12365
			return 'image/jpeg';
12366
		}
12367
		elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12368
		{
12369
			return 'image/bmp';
12370
		}
12371
		else
12372
		{
12373
			return false;
12374
		}
12375
	}
12376
12377
	/**
12378
	 * Sniff HTML
12379
	 *
12380
	 * @access private
12381
	 * @return string Actual Content-Type
12382
	 */
12383
	function feed_or_html()
12384
	{
12385
		$len = strlen($this->file->body);
12386
		$pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
12387
12388
		while ($pos < $len)
12389
		{
12390
			switch ($this->file->body[$pos])
12391
			{
12392
				case "\x09":
12393
				case "\x0A":
12394
				case "\x0D":
12395
				case "\x20":
12396
					$pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12397
					continue 2;
12398
12399
				case '<':
12400
					$pos++;
12401
					break;
12402
12403
				default:
12404
					return 'text/html';
12405
			}
12406
12407
			if (substr($this->file->body, $pos, 3) === '!--')
12408
			{
12409
				$pos += 3;
12410
				if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12411
				{
12412
					$pos += 3;
12413
				}
12414
				else
12415
				{
12416
					return 'text/html';
12417
				}
12418
			}
12419
			elseif (substr($this->file->body, $pos, 1) === '!')
12420
			{
12421
				if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12422
				{
12423
					$pos++;
12424
				}
12425
				else
12426
				{
12427
					return 'text/html';
12428
				}
12429
			}
12430
			elseif (substr($this->file->body, $pos, 1) === '?')
12431
			{
12432
				if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12433
				{
12434
					$pos += 2;
12435
				}
12436
				else
12437
				{
12438
					return 'text/html';
12439
				}
12440
			}
12441
			elseif (substr($this->file->body, $pos, 3) === 'rss'
12442
				|| substr($this->file->body, $pos, 7) === 'rdf:RDF')
12443
			{
12444
				return 'application/rss+xml';
12445
			}
12446
			elseif (substr($this->file->body, $pos, 4) === 'feed')
12447
			{
12448
				return 'application/atom+xml';
12449
			}
12450
			else
12451
			{
12452
				return 'text/html';
12453
			}
12454
		}
12455
12456
		return 'text/html';
12457
	}
12458
}
12459
12460
/**
12461
 * Parses the XML Declaration
12462
 *
12463
 * @package SimplePie
12464
 */
12465
class SimplePie_XML_Declaration_Parser
12466
{
12467
	/**
12468
	 * XML Version
12469
	 *
12470
	 * @access public
12471
	 * @var string
12472
	 */
12473
	var $version = '1.0';
12474
12475
	/**
12476
	 * Encoding
12477
	 *
12478
	 * @access public
12479
	 * @var string
12480
	 */
12481
	var $encoding = 'UTF-8';
12482
12483
	/**
12484
	 * Standalone
12485
	 *
12486
	 * @access public
12487
	 * @var bool
12488
	 */
12489
	var $standalone = false;
12490
12491
	/**
12492
	 * Current state of the state machine
12493
	 *
12494
	 * @access private
12495
	 * @var string
12496
	 */
12497
	var $state = 'before_version_name';
12498
12499
	/**
12500
	 * Input data
12501
	 *
12502
	 * @access private
12503
	 * @var string
12504
	 */
12505
	var $data = '';
12506
12507
	/**
12508
	 * Input data length (to avoid calling strlen() everytime this is needed)
12509
	 *
12510
	 * @access private
12511
	 * @var int
12512
	 */
12513
	var $data_length = 0;
12514
12515
	/**
12516
	 * Current position of the pointer
12517
	 *
12518
	 * @var int
12519
	 * @access private
12520
	 */
12521
	var $position = 0;
12522
12523
	/**
12524
	 * Create an instance of the class with the input data
12525
	 *
12526
	 * @access public
12527
	 * @param string $data Input data
12528
	 */
12529
	function SimplePie_XML_Declaration_Parser($data)
12530
	{
12531
		$this->data = $data;
12532
		$this->data_length = strlen($this->data);
12533
	}
12534
12535
	/**
12536
	 * Parse the input data
12537
	 *
12538
	 * @access public
12539
	 * @return bool true on success, false on failure
12540
	 */
12541
	function parse()
12542
	{
12543
		while ($this->state && $this->state !== 'emit' && $this->has_data())
12544
		{
12545
			$state = $this->state;
12546
			$this->$state();
12547
		}
12548
		$this->data = '';
12549
		if ($this->state === 'emit')
12550
		{
12551
			return true;
12552
		}
12553
		else
12554
		{
12555
			$this->version = '';
12556
			$this->encoding = '';
12557
			$this->standalone = '';
12558
			return false;
12559
		}
12560
	}
12561
12562
	/**
12563
	 * Check whether there is data beyond the pointer
12564
	 *
12565
	 * @access private
12566
	 * @return bool true if there is further data, false if not
12567
	 */
12568
	function has_data()
12569
	{
12570
		return (bool) ($this->position < $this->data_length);
12571
	}
12572
12573
	/**
12574
	 * Advance past any whitespace
12575
	 *
12576
	 * @return int Number of whitespace characters passed
12577
	 */
12578
	function skip_whitespace()
12579
	{
12580
		$whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12581
		$this->position += $whitespace;
12582
		return $whitespace;
12583
	}
12584
12585
	/**
12586
	 * Read value
12587
	 */
12588
	function get_value()
12589
	{
12590
		$quote = substr($this->data, $this->position, 1);
12591
		if ($quote === '"' || $quote === "'")
12592
		{
12593
			$this->position++;
12594
			$len = strcspn($this->data, $quote, $this->position);
12595
			if ($this->has_data())
12596
			{
12597
				$value = substr($this->data, $this->position, $len);
12598
				$this->position += $len + 1;
12599
				return $value;
12600
			}
12601
		}
12602
		return false;
12603
	}
12604
12605
	function before_version_name()
12606
	{
12607
		if ($this->skip_whitespace())
12608
		{
12609
			$this->state = 'version_name';
12610
		}
12611
		else
12612
		{
12613
			$this->state = false;
12614
		}
12615
	}
12616
12617
	function version_name()
12618
	{
12619
		if (substr($this->data, $this->position, 7) === 'version')
12620
		{
12621
			$this->position += 7;
12622
			$this->skip_whitespace();
12623
			$this->state = 'version_equals';
12624
		}
12625
		else
12626
		{
12627
			$this->state = false;
12628
		}
12629
	}
12630
12631
	function version_equals()
12632
	{
12633
		if (substr($this->data, $this->position, 1) === '=')
12634
		{
12635
			$this->position++;
12636
			$this->skip_whitespace();
12637
			$this->state = 'version_value';
12638
		}
12639
		else
12640
		{
12641
			$this->state = false;
12642
		}
12643
	}
12644
12645
	function version_value()
12646
	{
12647
		if ($this->version = $this->get_value())
12648
		{
12649
			$this->skip_whitespace();
12650
			if ($this->has_data())
12651
			{
12652
				$this->state = 'encoding_name';
12653
			}
12654
			else
12655
			{
12656
				$this->state = 'emit';
12657
			}
12658
		}
12659
		else
12660
		{
12661
			$this->state = 'standalone_name';
12662
		}
12663
	}
12664
12665
	function encoding_name()
12666
	{
12667
		if (substr($this->data, $this->position, 8) === 'encoding')
12668
		{
12669
			$this->position += 8;
12670
			$this->skip_whitespace();
12671
			$this->state = 'encoding_equals';
12672
		}
12673
		else
12674
		{
12675
			$this->state = false;
12676
		}
12677
	}
12678
12679
	function encoding_equals()
12680
	{
12681
		if (substr($this->data, $this->position, 1) === '=')
12682
		{
12683
			$this->position++;
12684
			$this->skip_whitespace();
12685
			$this->state = 'encoding_value';
12686
		}
12687
		else
12688
		{
12689
			$this->state = false;
12690
		}
12691
	}
12692
12693
	function encoding_value()
12694
	{
12695
		if ($this->encoding = $this->get_value())
12696
		{
12697
			$this->skip_whitespace();
12698
			if ($this->has_data())
12699
			{
12700
				$this->state = 'standalone_name';
12701
			}
12702
			else
12703
			{
12704
				$this->state = 'emit';
12705
			}
12706
		}
12707
		else
12708
		{
12709
			$this->state = false;
12710
		}
12711
	}
12712
12713
	function standalone_name()
12714
	{
12715
		if (substr($this->data, $this->position, 10) === 'standalone')
12716
		{
12717
			$this->position += 10;
12718
			$this->skip_whitespace();
12719
			$this->state = 'standalone_equals';
12720
		}
12721
		else
12722
		{
12723
			$this->state = false;
12724
		}
12725
	}
12726
12727
	function standalone_equals()
12728
	{
12729
		if (substr($this->data, $this->position, 1) === '=')
12730
		{
12731
			$this->position++;
12732
			$this->skip_whitespace();
12733
			$this->state = 'standalone_value';
12734
		}
12735
		else
12736
		{
12737
			$this->state = false;
12738
		}
12739
	}
12740
12741
	function standalone_value()
12742
	{
12743
		if ($standalone = $this->get_value())
12744
		{
12745
			switch ($standalone)
12746
			{
12747
				case 'yes':
12748
					$this->standalone = true;
12749
					break;
12750
12751
				case 'no':
12752
					$this->standalone = false;
12753
					break;
12754
12755
				default:
12756
					$this->state = false;
12757
					return;
12758
			}
12759
12760
			$this->skip_whitespace();
12761
			if ($this->has_data())
12762
			{
12763
				$this->state = false;
12764
			}
12765
			else
12766
			{
12767
				$this->state = 'emit';
12768
			}
12769
		}
12770
		else
12771
		{
12772
			$this->state = false;
12773
		}
12774
	}
12775
}
12776
12777
class SimplePie_Locator
12778
{
12779
	var $useragent;
12780
	var $timeout;
12781
	var $file;
12782
	var $local = array();
12783
	var $elsewhere = array();
12784
	var $file_class = 'SimplePie_File';
12785
	var $cached_entities = array();
12786
	var $http_base;
12787
	var $base;
12788
	var $base_location = 0;
12789
	var $checked_feeds = 0;
12790
	var $max_checked_feeds = 10;
12791
	var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
12792
12793
	function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
12794
	{
12795
		$this->file =& $file;
12796
		$this->file_class = $file_class;
12797
		$this->useragent = $useragent;
12798
		$this->timeout = $timeout;
12799
		$this->max_checked_feeds = $max_checked_feeds;
12800
		$this->content_type_sniffer_class = $content_type_sniffer_class;
12801
	}
12802
12803
	function find($type = SIMPLEPIE_LOCATOR_ALL)
12804
	{
12805
		if ($this->is_feed($this->file))
12806
		{
12807
			return $this->file;
12808
		}
12809
12810
		if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12811
		{
12812
			$sniffer = new $this->content_type_sniffer_class($this->file);
12813
			if ($sniffer->get_type() !== 'text/html')
12814
			{
12815
				return null;
12816
			}
12817
		}
12818
12819
		if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12820
		{
12821
			$this->get_base();
12822
		}
12823
12824
		if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12825
		{
12826
			return $working;
12827
		}
12828
12829
		if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12830
		{
12831
			if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12832
			{
12833
				return $working;
12834
			}
12835
12836
			if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12837
			{
12838
				return $working;
12839
			}
12840
12841
			if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12842
			{
12843
				return $working;
12844
			}
12845
12846
			if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12847
			{
12848
				return $working;
12849
			}
12850
		}
12851
		return null;
12852
	}
12853
12854
	function is_feed(&$file)
12855
	{
12856
		if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12857
		{
12858
			$sniffer = new $this->content_type_sniffer_class($file);
12859
			$sniffed = $sniffer->get_type();
12860
			if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
12861
			{
12862
				return true;
12863
			}
12864
			else
12865
			{
12866
				return false;
12867
			}
12868
		}
12869
		elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
12870
		{
12871
			return true;
12872
		}
12873
		else
12874
		{
12875
			return false;
12876
		}
12877
	}
12878
12879
	function get_base()
12880
	{
12881
		$this->http_base = $this->file->url;
12882
		$this->base = $this->http_base;
12883
		$elements = SimplePie_Misc::get_element('base', $this->file->body);
12884
		foreach ($elements as $element)
12885
		{
12886
			if ($element['attribs']['href']['data'] !== '')
12887
			{
12888
				$this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12889
				$this->base_location = $element['offset'];
12890
				break;
12891
			}
12892
		}
12893
	}
12894
12895
	function autodiscovery()
12896
	{
12897
		$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));
12898
		$done = array();
12899
		foreach ($links as $link)
12900
		{
12901
			if ($this->checked_feeds == $this->max_checked_feeds)
12902
			{
12903
				break;
12904
			}
12905
			if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12906
			{
12907 5aa68a55 Renato Botelho
				$rel = array_unique(SimplePie_Misc::space_separated_tokens(strtolower($link['attribs']['rel']['data'])));
12908 b2e02eef Scott Ullrich
12909
				if ($this->base_location < $link['offset'])
12910
				{
12911
					$href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12912
				}
12913
				else
12914
				{
12915
					$href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12916
				}
12917
12918
				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'))))
12919
				{
12920
					$this->checked_feeds++;
12921 23ca5695 Chris Buechler
					$feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
12922 b2e02eef Scott Ullrich
					if ($this->is_feed($feed))
12923
					{
12924
						return $feed;
12925
					}
12926
				}
12927
				$done[] = $href;
12928
			}
12929
		}
12930
		return null;
12931
	}
12932
12933
	function get_links()
12934
	{
12935
		$links = SimplePie_Misc::get_element('a', $this->file->body);
12936
		foreach ($links as $link)
12937
		{
12938
			if (isset($link['attribs']['href']['data']))
12939
			{
12940
				$href = trim($link['attribs']['href']['data']);
12941
				$parsed = SimplePie_Misc::parse_url($href);
12942
				if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12943
				{
12944
					if ($this->base_location < $link['offset'])
12945
					{
12946
						$href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12947
					}
12948
					else
12949
					{
12950
						$href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12951
					}
12952
12953
					$current = SimplePie_Misc::parse_url($this->file->url);
12954
12955
					if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
12956
					{
12957
						$this->local[] = $href;
12958
					}
12959
					else
12960
					{
12961
						$this->elsewhere[] = $href;
12962
					}
12963
				}
12964
			}
12965
		}
12966
		$this->local = array_unique($this->local);
12967
		$this->elsewhere = array_unique($this->elsewhere);
12968
		if (!empty($this->local) || !empty($this->elsewhere))
12969
		{
12970
			return true;
12971
		}
12972
		return null;
12973
	}
12974
12975
	function extension(&$array)
12976
	{
12977
		foreach ($array as $key => $value)
12978
		{
12979
			if ($this->checked_feeds == $this->max_checked_feeds)
12980
			{
12981
				break;
12982
			}
12983
			if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
12984
			{
12985
				$this->checked_feeds++;
12986 23ca5695 Chris Buechler
				$feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12987 b2e02eef Scott Ullrich
				if ($this->is_feed($feed))
12988
				{
12989
					return $feed;
12990
				}
12991
				else
12992
				{
12993
					unset($array[$key]);
12994
				}
12995
			}
12996
		}
12997
		return null;
12998
	}
12999
13000
	function body(&$array)
13001
	{
13002
		foreach ($array as $key => $value)
13003
		{
13004
			if ($this->checked_feeds == $this->max_checked_feeds)
13005
			{
13006
				break;
13007
			}
13008
			if (preg_match('/(rss|rdf|atom|xml)/i', $value))
13009
			{
13010
				$this->checked_feeds++;
13011 23ca5695 Chris Buechler
				$feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
13012 b2e02eef Scott Ullrich
				if ($this->is_feed($feed))
13013
				{
13014
					return $feed;
13015
				}
13016
				else
13017
				{
13018
					unset($array[$key]);
13019
				}
13020
			}
13021
		}
13022
		return null;
13023
	}
13024
}
13025
13026
class SimplePie_Parser
13027
{
13028
	var $error_code;
13029
	var $error_string;
13030
	var $current_line;
13031
	var $current_column;
13032
	var $current_byte;
13033
	var $separator = ' ';
13034
	var $feed = false;
13035
	var $namespace = array('');
13036
	var $element = array('');
13037
	var $xml_base = array('');
13038
	var $xml_base_explicit = array(false);
13039
	var $xml_lang = array('');
13040
	var $data = array();
13041
	var $datas = array(array());
13042
	var $current_xhtml_construct = -1;
13043
	var $encoding;
13044
13045
	function parse(&$data, $encoding)
13046
	{
13047
		// Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
13048
		if (strtoupper($encoding) == 'US-ASCII')
13049
		{
13050
			$this->encoding = 'UTF-8';
13051
		}
13052
		else
13053
		{
13054
			$this->encoding = $encoding;
13055
		}
13056
13057
		// Strip BOM:
13058
		// UTF-32 Big Endian BOM
13059
		if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
13060
		{
13061
			$data = substr($data, 4);
13062
		}
13063
		// UTF-32 Little Endian BOM
13064
		elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
13065
		{
13066
			$data = substr($data, 4);
13067
		}
13068
		// UTF-16 Big Endian BOM
13069
		elseif (substr($data, 0, 2) === "\xFE\xFF")
13070
		{
13071
			$data = substr($data, 2);
13072
		}
13073
		// UTF-16 Little Endian BOM
13074
		elseif (substr($data, 0, 2) === "\xFF\xFE")
13075
		{
13076
			$data = substr($data, 2);
13077
		}
13078
		// UTF-8 BOM
13079
		elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
13080
		{
13081
			$data = substr($data, 3);
13082
		}
13083
13084
		if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
13085
		{
13086
			$declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
13087
			if ($declaration->parse())
13088
			{
13089
				$data = substr($data, $pos + 2);
13090
				$data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
13091
			}
13092
			else
13093
			{
13094
				$this->error_string = 'SimplePie bug! Please report this!';
13095
				return false;
13096
			}
13097
		}
13098
13099
		// Work around libxml bug
13100
		$data = str_replace('&lt;', '&#60;', $data);
13101
		$data = str_replace('&gt;', '&#62;', $data);
13102
		$data = str_replace('&amp;', '&#38;', $data);
13103
		$data = str_replace('&apos;', '&#39;', $data);
13104
		$data = str_replace('&quot;', '&#34;', $data);
13105
13106
		$return = true;
13107
13108
		// Create the parser
13109
		$xml = xml_parser_create_ns($this->encoding, $this->separator);
13110
		xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
13111
		xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
13112
		xml_set_object($xml, $this);
13113
		xml_set_character_data_handler($xml, 'cdata');
13114
		xml_set_element_handler($xml, 'tag_open', 'tag_close');
13115
13116
		// Parse!
13117
		if (!xml_parse($xml, $data, true))
13118
		{
13119
			$this->error_code = xml_get_error_code($xml);
13120
			$this->error_string = xml_error_string($this->error_code);
13121
			$return = false;
13122
		}
13123
		$this->current_line = xml_get_current_line_number($xml);
13124
		$this->current_column = xml_get_current_column_number($xml);
13125
		$this->current_byte = xml_get_current_byte_index($xml);
13126
		xml_parser_free($xml);
13127
		return $return;
13128
	}
13129
13130
	function get_error_code()
13131
	{
13132
		return $this->error_code;
13133
	}
13134
13135
	function get_error_string()
13136
	{
13137
		return $this->error_string;
13138
	}
13139
13140
	function get_current_line()
13141
	{
13142
		return $this->current_line;
13143
	}
13144
13145
	function get_current_column()
13146
	{
13147
		return $this->current_column;
13148
	}
13149
13150
	function get_current_byte()
13151
	{
13152
		return $this->current_byte;
13153
	}
13154
13155
	function get_data()
13156
	{
13157
		return $this->data;
13158
	}
13159
13160
	function tag_open($parser, $tag, $attributes)
13161
	{
13162
		if ($this->feed === 0)
13163
		{
13164
			return;
13165
		}
13166
		elseif ($this->feed == false)
13167
		{
13168
			if (in_array($tag, array(
13169
				SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
13170
				SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
13171
				'rss',
13172
				SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
13173
			)))
13174
			{
13175
					$this->feed = 1;
13176
			}
13177
		}
13178
		else
13179
		{
13180
			$this->feed++;
13181
		}
13182
13183
		list($this->namespace[], $this->element[]) = $this->split_ns($tag);
13184
13185
		$attribs = array();
13186
		foreach ($attributes as $name => $value)
13187
		{
13188
			list($attrib_namespace, $attribute) = $this->split_ns($name);
13189
			$attribs[$attrib_namespace][$attribute] = $value;
13190
		}
13191
13192
		if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
13193
		{
13194
			$this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
13195
			$this->xml_base_explicit[] = true;
13196
		}
13197
		else
13198
		{
13199
			$this->xml_base[] = end($this->xml_base);
13200
			$this->xml_base_explicit[] = end($this->xml_base_explicit);
13201
		}
13202
13203
		if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
13204
		{
13205
			$this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
13206
		}
13207
		else
13208
		{
13209
			$this->xml_lang[] = end($this->xml_lang);
13210
		}
13211
13212
		if ($this->current_xhtml_construct >= 0)
13213
		{
13214
			$this->current_xhtml_construct++;
13215
			if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
13216
			{
13217
				$this->data['data'] .= '<' . end($this->element);
13218
				if (isset($attribs['']))
13219
				{
13220
					foreach ($attribs[''] as $name => $value)
13221
					{
13222
						$this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
13223
					}
13224
				}
13225
				$this->data['data'] .= '>';
13226
			}
13227
		}
13228
		else
13229
		{
13230
			$this->datas[] =& $this->data;
13231
			$this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
13232
			$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));
13233
			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')
13234
			|| (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'))
13235
			{
13236
				$this->current_xhtml_construct = 0;
13237
			}
13238
		}
13239
	}
13240
13241
	function cdata($parser, $cdata)
13242
	{
13243
		if ($this->current_xhtml_construct >= 0)
13244
		{
13245
			$this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
13246
		}
13247
		elseif ($this->feed > 1)
13248
		{
13249
			$this->data['data'] .= $cdata;
13250
		}
13251
	}
13252
13253
	function tag_close($parser, $tag)
13254
	{
13255
		if (!$this->feed)
13256
		{
13257
			return;
13258
		}
13259
13260
		if ($this->current_xhtml_construct >= 0)
13261
		{
13262
			$this->current_xhtml_construct--;
13263
			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')))
13264
			{
13265
				$this->data['data'] .= '</' . end($this->element) . '>';
13266
			}
13267
		}
13268
		if ($this->current_xhtml_construct == -1)
13269
		{
13270
			$this->data =& $this->datas[$this->feed];
13271
			array_pop($this->datas);
13272
		}
13273
13274
		array_pop($this->element);
13275
		array_pop($this->namespace);
13276
		array_pop($this->xml_base);
13277
		array_pop($this->xml_base_explicit);
13278
		array_pop($this->xml_lang);
13279
		$this->feed--;
13280
	}
13281
13282
	function split_ns($string)
13283
	{
13284
		static $cache = array();
13285
		if (!isset($cache[$string]))
13286
		{
13287
			if ($pos = strpos($string, $this->separator))
13288
			{
13289
				static $separator_length;
13290
				if (!$separator_length)
13291
				{
13292
					$separator_length = strlen($this->separator);
13293
				}
13294
				$namespace = substr($string, 0, $pos);
13295
				$local_name = substr($string, $pos + $separator_length);
13296
				if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
13297
				{
13298
					$namespace = SIMPLEPIE_NAMESPACE_ITUNES;
13299
				}
13300
13301
				// Normalize the Media RSS namespaces
13302
				if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
13303
				{
13304
					$namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
13305
				}
13306
				$cache[$string] = array($namespace, $local_name);
13307
			}
13308
			else
13309
			{
13310
				$cache[$string] = array('', $string);
13311
			}
13312
		}
13313
		return $cache[$string];
13314
	}
13315
}
13316
13317
/**
13318
 * @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
13319
 */
13320
class SimplePie_Sanitize
13321
{
13322
	// Private vars
13323
	var $base;
13324
13325
	// Options
13326
	var $remove_div = true;
13327
	var $image_handler = '';
13328
	var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
13329
	var $encode_instead_of_strip = false;
13330
	var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
13331
	var $strip_comments = false;
13332
	var $output_encoding = 'UTF-8';
13333
	var $enable_cache = true;
13334
	var $cache_location = './cache';
13335
	var $cache_name_function = 'md5';
13336
	var $cache_class = 'SimplePie_Cache';
13337
	var $file_class = 'SimplePie_File';
13338
	var $timeout = 10;
13339
	var $useragent = '';
13340
	var $force_fsockopen = false;
13341
13342
	var $replace_url_attributes = array(
13343
		'a' => 'href',
13344
		'area' => 'href',
13345
		'blockquote' => 'cite',
13346
		'del' => 'cite',
13347
		'form' => 'action',
13348
		'img' => array('longdesc', 'src'),
13349
		'input' => 'src',
13350
		'ins' => 'cite',
13351
		'q' => 'cite'
13352
	);
13353
13354
	function remove_div($enable = true)
13355
	{
13356
		$this->remove_div = (bool) $enable;
13357
	}
13358
13359
	function set_image_handler($page = false)
13360
	{
13361
		if ($page)
13362
		{
13363
			$this->image_handler = (string) $page;
13364
		}
13365
		else
13366
		{
13367
			$this->image_handler = false;
13368
		}
13369
	}
13370
13371
	function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
13372
	{
13373
		if (isset($enable_cache))
13374
		{
13375
			$this->enable_cache = (bool) $enable_cache;
13376
		}
13377
13378
		if ($cache_location)
13379
		{
13380
			$this->cache_location = (string) $cache_location;
13381
		}
13382
13383
		if ($cache_name_function)
13384
		{
13385
			$this->cache_name_function = (string) $cache_name_function;
13386
		}
13387
13388
		if ($cache_class)
13389
		{
13390
			$this->cache_class = (string) $cache_class;
13391
		}
13392
	}
13393
13394
	function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
13395
	{
13396
		if ($file_class)
13397
		{
13398
			$this->file_class = (string) $file_class;
13399
		}
13400
13401
		if ($timeout)
13402
		{
13403
			$this->timeout = (string) $timeout;
13404
		}
13405
13406
		if ($useragent)
13407
		{
13408
			$this->useragent = (string) $useragent;
13409
		}
13410
13411
		if ($force_fsockopen)
13412
		{
13413
			$this->force_fsockopen = (string) $force_fsockopen;
13414
		}
13415
	}
13416
13417
	function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13418
	{
13419
		if ($tags)
13420
		{
13421
			if (is_array($tags))
13422
			{
13423
				$this->strip_htmltags = $tags;
13424
			}
13425
			else
13426
			{
13427
				$this->strip_htmltags = explode(',', $tags);
13428
			}
13429
		}
13430
		else
13431
		{
13432
			$this->strip_htmltags = false;
13433
		}
13434
	}
13435
13436
	function encode_instead_of_strip($encode = false)
13437
	{
13438
		$this->encode_instead_of_strip = (bool) $encode;
13439
	}
13440
13441
	function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13442
	{
13443
		if ($attribs)
13444
		{
13445
			if (is_array($attribs))
13446
			{
13447
				$this->strip_attributes = $attribs;
13448
			}
13449
			else
13450
			{
13451
				$this->strip_attributes = explode(',', $attribs);
13452
			}
13453
		}
13454
		else
13455
		{
13456
			$this->strip_attributes = false;
13457
		}
13458
	}
13459
13460
	function strip_comments($strip = false)
13461
	{
13462
		$this->strip_comments = (bool) $strip;
13463
	}
13464
13465
	function set_output_encoding($encoding = 'UTF-8')
13466
	{
13467
		$this->output_encoding = (string) $encoding;
13468
	}
13469
13470
	/**
13471
	 * Set element/attribute key/value pairs of HTML attributes
13472
	 * containing URLs that need to be resolved relative to the feed
13473
	 *
13474
	 * @access public
13475
	 * @since 1.0
13476
	 * @param array $element_attribute Element/attribute key/value pairs
13477
	 */
13478
	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'))
13479
	{
13480
		$this->replace_url_attributes = (array) $element_attribute;
13481
	}
13482
13483
	function sanitize($data, $type, $base = '')
13484
	{
13485
		$data = trim($data);
13486
		if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13487
		{
13488
			if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13489
			{
13490
				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))
13491
				{
13492
					$type |= SIMPLEPIE_CONSTRUCT_HTML;
13493
				}
13494
				else
13495
				{
13496
					$type |= SIMPLEPIE_CONSTRUCT_TEXT;
13497
				}
13498
			}
13499
13500
			if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13501
			{
13502
				$data = base64_decode($data);
13503
			}
13504
13505
			if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13506
			{
13507
				if ($this->remove_div)
13508
				{
13509
					$data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13510
					$data = preg_replace('/<\/div>$/', '', $data);
13511
				}
13512
				else
13513
				{
13514
					$data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13515
				}
13516
			}
13517
13518
			if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13519
			{
13520
				// Strip comments
13521
				if ($this->strip_comments)
13522
				{
13523
					$data = SimplePie_Misc::strip_comments($data);
13524
				}
13525
13526
				// Strip out HTML tags and attributes that might cause various security problems.
13527
				// Based on recommendations by Mark Pilgrim at:
13528
				// http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13529
				if ($this->strip_htmltags)
13530
				{
13531
					foreach ($this->strip_htmltags as $tag)
13532
					{
13533
						$pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13534
						while (preg_match($pcre, $data))
13535
						{
13536
							$data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13537
						}
13538
					}
13539
				}
13540
13541
				if ($this->strip_attributes)
13542
				{
13543
					foreach ($this->strip_attributes as $attrib)
13544
					{
13545
						$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);
13546
					}
13547
				}
13548
13549
				// Replace relative URLs
13550
				$this->base = $base;
13551
				foreach ($this->replace_url_attributes as $element => $attributes)
13552
				{
13553
					$data = $this->replace_urls($data, $element, $attributes);
13554
				}
13555
13556
				// If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13557
				if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13558
				{
13559
					$images = SimplePie_Misc::get_element('img', $data);
13560
					foreach ($images as $img)
13561
					{
13562
						if (isset($img['attribs']['src']['data']))
13563
						{
13564
							$image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13565
							$cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
13566
13567
							if ($cache->load())
13568
							{
13569
								$img['attribs']['src']['data'] = $this->image_handler . $image_url;
13570
								$data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13571
							}
13572
							else
13573
							{
13574 23ca5695 Chris Buechler
								$file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
13575 b2e02eef Scott Ullrich
								$headers = $file->headers;
13576
13577
								if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13578
								{
13579
									if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13580
									{
13581
										$img['attribs']['src']['data'] = $this->image_handler . $image_url;
13582
										$data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13583
									}
13584
									else
13585
									{
13586
										trigger_error("$cache->name is not writeable", E_USER_WARNING);
13587
									}
13588
								}
13589
							}
13590
						}
13591
					}
13592
				}
13593
13594
				// Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13595
				$data = trim($data);
13596
			}
13597
13598
			if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13599
			{
13600
				$data = SimplePie_Misc::absolutize_url($data, $base);
13601
			}
13602
13603
			if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13604
			{
13605
				$data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13606
			}
13607
13608
			if ($this->output_encoding != 'UTF-8')
13609
			{
13610
				$data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13611
			}
13612
		}
13613
		return $data;
13614
	}
13615
13616
	function replace_urls($data, $tag, $attributes)
13617
	{
13618
		if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13619
		{
13620
			$elements = SimplePie_Misc::get_element($tag, $data);
13621
			foreach ($elements as $element)
13622
			{
13623
				if (is_array($attributes))
13624
				{
13625
					foreach ($attributes as $attribute)
13626
					{
13627
						if (isset($element['attribs'][$attribute]['data']))
13628
						{
13629
							$element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
13630
							$new_element = SimplePie_Misc::element_implode($element);
13631
							$data = str_replace($element['full'], $new_element, $data);
13632
							$element['full'] = $new_element;
13633
						}
13634
					}
13635
				}
13636
				elseif (isset($element['attribs'][$attributes]['data']))
13637
				{
13638
					$element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13639
					$data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13640
				}
13641
			}
13642
		}
13643
		return $data;
13644
	}
13645
13646
	function do_strip_htmltags($match)
13647
	{
13648
		if ($this->encode_instead_of_strip)
13649
		{
13650
			if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13651
			{
13652
				$match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13653
				$match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13654
				return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
13655
			}
13656
			else
13657
			{
13658
				return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13659
			}
13660
		}
13661
		elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13662
		{
13663
			return $match[4];
13664
		}
13665
		else
13666
		{
13667
			return '';
13668
		}
13669
	}
13670
}
13671
13672 5aa68a55 Renato Botelho
?>