Project

General

Profile

Download (348 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * SimplePie
4
 *
5
 * A PHP-Based RSS and Atom Feed Framework.
6
 * Takes the hard work out of managing a complete RSS/Atom solution.
7
 *
8
 * Copyright (c) 2004-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
		$this->sanitize =& new SimplePie_Sanitize;
721

    
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
			$this->sanitize =& new $class;
1088
			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
								$file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1596
								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
						$file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1637
					}
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
					$locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1657
					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
					$parser =& new $this->parser_class();
1757

    
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
	 * Return the error message for the occured error
1821
	 *
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
					$file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1961

    
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
			$categories[] =& new $this->category_class($term, $scheme, $label);
2359
		}
2360
		foreach ((array) $this->get_channel_tags('', 'category') as $category)
2361
		{
2362
			$categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2363
		}
2364
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2365
		{
2366
			$categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2367
		}
2368
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2369
		{
2370
			$categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2371
		}
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
				$authors[] =& new $this->author_class($name, $uri, $email);
2419
			}
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
				$authors[] =& new $this->author_class($name, $url, $email);
2441
			}
2442
		}
2443
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2444
		{
2445
			$authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2446
		}
2447
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2448
		{
2449
			$authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2450
		}
2451
		foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2452
		{
2453
			$authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2454
		}
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
				$contributors[] =& new $this->author_class($name, $uri, $email);
2502
			}
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
				$contributors[] =& new $this->author_class($name, $url, $email);
2524
			}
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
					$this->data['items'][] =& new $this->item_class($this, $items[$key]);
2928
				}
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
					$this->data['items'][] =& new $this->item_class($this, $items[$key]);
2936
				}
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
					$this->data['items'][] =& new $this->item_class($this, $items[$key]);
2944
				}
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
					$this->data['items'][] =& new $this->item_class($this, $items[$key]);
2952
				}
2953
			}
2954
			if ($items = $this->get_channel_tags('', 'item'))
2955
			{
2956
				$keys = array_keys($items);
2957
				foreach ($keys as $key)
2958
				{
2959
					$this->data['items'][] =& new $this->item_class($this, $items[$key]);
2960
				}
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
			$categories[] =& new $this->feed->category_class($term, $scheme, $label);
3301
		}
3302
		foreach ((array) $this->get_item_tags('', 'category') as $category)
3303
		{
3304
			$categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3305
		}
3306
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3307
		{
3308
			$categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3309
		}
3310
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3311
		{
3312
			$categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3313
		}
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
				$contributors[] =& new $this->feed->author_class($name, $uri, $email);
3374
			}
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
				$contributors[] =& new $this->feed->author_class($name, $url, $email);
3396
			}
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
				$authors[] =& new $this->feed->author_class($name, $uri, $email);
3435
			}
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
				$authors[] =& new $this->feed->author_class($name, $url, $email);
3457
			}
3458
		}
3459
		if ($author = $this->get_item_tags('', 'author'))
3460
		{
3461
			$authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3462
		}
3463
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3464
		{
3465
			$authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3466
		}
3467
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3468
		{
3469
			$authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3470
		}
3471
		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3472
		{
3473
			$authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3474
		}
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
					$captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3784
				}
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
					$captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3816
				}
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
				$categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3846
			}
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
				$categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3869
			}
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
				$categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3880

    
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
						$categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3890
					}
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
				$copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3912
			}
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
				$copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3926
			}
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
					$credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3953
				}
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
					$credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3979
				}
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
					$ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4168
				}
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
					$ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4181
				}
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
					$ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4202
				}
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
					$ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4215
				}
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
					$restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4243
				}
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
					$restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4257
				}
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
					$restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4279
				}
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
					$restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4293
				}
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
								$captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4497
							}
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
								$captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4533
							}
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
								$categories[] =& new $this->feed->category_class($term, $scheme, $label);
4569
							}
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
								$categories[] =& new $this->feed->category_class($term, $scheme, $label);
4595
							}
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
							$copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4624
						}
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
							$copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4638
						}
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
								$credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4669
							}
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
								$credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4699
							}
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
								$ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4852
							}
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
								$ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4877
							}
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
								$restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4909
							}
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
								$restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4935
							}
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
						$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
					}
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
								$captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5118
							}
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
								$categories[] =& new $this->feed->category_class($term, $scheme, $label);
5154
							}
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
							$copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
5187
						}
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
								$credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5218
							}
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
								$ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
5322
							}
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
								$restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5354
							}
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
						$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
					}
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
					$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
				}
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
					$this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
5464
				}
5465
			}
5466

    
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
					$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
				}
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
				$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
			}
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
			$categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
5791
		}
5792
		foreach ((array) $this->get_source_tags('', 'category') as $category)
5793
		{
5794
			$categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5795
		}
5796
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5797
		{
5798
			$categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5799
		}
5800
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5801
		{
5802
			$categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5803
		}
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
				$authors[] =& new $this->item->feed->author_class($name, $uri, $email);
5851
			}
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
				$authors[] =& new $this->item->feed->author_class($name, $url, $email);
5873
			}
5874
		}
5875
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5876
		{
5877
			$authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5878
		}
5879
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5880
		{
5881
			$authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5882
		}
5883
		foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5884
		{
5885
			$authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5886
		}
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
				$contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
5934
			}
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
				$contributors[] =& new $this->item->feed->author_class($name, $url, $email);
5956
			}
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
			$idn =& new idna_convert;
6393
			$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
			$idn =& new idna_convert;
7589
			$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
					$parser =& new SimplePie_HTTP_Parser($this->headers);
7650
					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
						$parser =& new SimplePie_HTTP_Parser($this->headers);
7731
						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
	function create($location, $filename, $extension)
8560
	{
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
	function absolutize_url($relative, $base)
8677
	{
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
	function remove_dot_segments($input)
8749
	{
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
	function get_element($realname, $string)
8803
	{
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
	function element_implode($element)
8840
	{
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
	function fix_protocol($url, $http = 1)
8924
	{
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
	function parse_url($url)
8956
	{
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
	function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
8977
	{
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
	function normalize_url($url)
9003
	{
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
	function percent_encoding_normalization($match)
9016
	{
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
	function change_encoding($data, $input, $output)
9079
	{
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
	function encoding($charset)
9120
	{
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
	function get_curl_version()
10463
	{
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
	function entities_decode($data)
10557
	{
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
	function is_isegment_nz_nc($string)
10737
	{
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
	function space_seperated_tokens($string)
10742
	{
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
	function array_unique($array)
10761
	{
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
	function codepoint_to_utf8($codepoint)
10811
	{
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
	function xml_encoding($data)
10928
	{
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
	function get()
11773
	{
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
	 * spaces to be used as the time seperator (including more than one))
11834
	 *
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
				$rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12908

    
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
					$feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
12922
					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
				$feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12987
				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
				$feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
13012
				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
								$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
								$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
?>
(2-2/2)