~ubuntu-branches/ubuntu/karmic/dokuwiki/karmic

« back to all changes in this revision

Viewing changes to inc/SimplePie.php

  • Committer: Bazaar Package Importer
  • Author(s): Mohammed Adnène Trojette
  • Date: 2007-03-29 19:44:52 UTC
  • mfrom: (2.1.6 feisty)
  • Revision ID: james.westby@ubuntu.com-20070329194452-8r2w798oo21ago6l
Tags: 0.0.20061106-6
* High-urgency upload for fixing RC bug.
* Make fr.po's translation of "global" consistent. (Closes: #416509)
* Remove /etc/apache*/conf.d/ on purge. (Closes: #387974)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/****************************************************
 
3
SIMPLEPIE
 
4
A PHP-Based RSS and Atom Feed Framework
 
5
Takes the hard work out of managing a complete RSS/Atom solution.
 
6
 
 
7
Version: 1.0 Beta 2
 
8
Updated: 30 May 2006
 
9
Copyright: 2004-2006 Ryan Parman, Geoffrey Sneddon
 
10
http://simplepie.org
 
11
 
 
12
*****************************************************
 
13
LICENSE:
 
14
 
 
15
GNU Lesser General Public License 2.1 (LGPL)
 
16
http://creativecommons.org/licenses/LGPL/2.1/
 
17
 
 
18
*****************************************************
 
19
Please submit all bug reports and feature requests to the SimplePie forums.
 
20
http://simplepie.org/support/
 
21
 
 
22
****************************************************/
 
23
 
 
24
class SimplePie {
 
25
 
 
26
    // SimplePie Information
 
27
    var $name = 'SimplePie';
 
28
    var $version = '1.0 Beta 2';
 
29
    var $build = '20060530';
 
30
    var $url = 'http://simplepie.org/';
 
31
    var $useragent;
 
32
    var $linkback;
 
33
 
 
34
    // Run-time Variables
 
35
    var $rss_url;
 
36
    var $encoding;
 
37
    var $xml_dump = false;
 
38
    var $caching = true;
 
39
    var $max_minutes = 60;
 
40
    var $cache_location = './cache';
 
41
    var $bypass_image_hotlink = 'i';
 
42
    var $bypass_image_hotlink_page = false;
 
43
    var $replace_headers = false;
 
44
    var $remove_div = true;
 
45
    var $order_by_date = true;
 
46
    var $strip_ads = false;
 
47
    var $strip_htmltags = 'blink,body,doctype,embed,font,form,frame,frameset,html,iframe,input,marquee,meta,noscript,object,param,script,style';
 
48
    var $strip_attributes = 'class,id,style,onclick,onmouseover,onmouseout,onfocus,onblur';
 
49
    var $encode_instead_of_strip = false;
 
50
 
 
51
    // RSS Auto-Discovery Variables
 
52
    var $parsed_url;
 
53
    var $local = array();
 
54
    var $elsewhere = array();
 
55
 
 
56
    // XML Parsing Variables
 
57
    var $xml;
 
58
    var $tagName;
 
59
    var $insideItem;
 
60
    var $insideChannel;
 
61
    var $insideImage;
 
62
    var $insideAuthor;
 
63
    var $itemNumber = 0;
 
64
    var $authorNumber = 0;
 
65
    var $categoryNumber = 0;
 
66
    var $enclosureNumber = 0;
 
67
    var $linkNumber = 0;
 
68
    var $itemLinkNumber = 0;
 
69
    var $data = false;
 
70
    var $attribs;
 
71
    var $xmldata;
 
72
    var $feed_xmlbase;
 
73
    var $item_xmlbase;
 
74
    var $xhtml_prefix;
 
75
 
 
76
 
 
77
 
 
78
 
 
79
    /****************************************************
 
80
    CONSTRUCTOR
 
81
    Initiates a couple of variables.  Accepts feed_url, cache_location,
 
82
    and cache_max_minutes.
 
83
    ****************************************************/
 
84
    function SimplePie($feed_url = null, $cache_location = null, $cache_max_minutes = null) {
 
85
        $this->useragent = $this->name . '/' . $this->version . ' (Feed Parser; ' . $this->url . '; Allow like Gecko) Build/' . $this->build;
 
86
        $this->linkback = '<a href="' . $this->url . '" title="' . $this->name . ' ' . $this->version . '">' . $this->name . '</a>';
 
87
 
 
88
        if (!is_null($feed_url)) {
 
89
            $this->feed_url($feed_url);
 
90
        }
 
91
 
 
92
        if (!is_null($cache_location)) {
 
93
            $this->cache_location($cache_location);
 
94
        }
 
95
 
 
96
        if (!is_null($cache_max_minutes)) {
 
97
            $this->cache_max_minutes($cache_max_minutes);
 
98
        }
 
99
 
 
100
        if (!is_null($feed_url)) {
 
101
            return $this->init();
 
102
        }
 
103
 
 
104
        // If we've passed an xmldump variable in the URL, snap into XMLdump mode
 
105
        if (isset($_GET['xmldump'])) {
 
106
            $this->enable_xmldump($_GET['xmldump']);
 
107
        }
 
108
    }
 
109
 
 
110
 
 
111
 
 
112
 
 
113
    /****************************************************
 
114
    CONFIGURE OPTIONS
 
115
    Set various options (feed URL, XML dump, caching, etc.)
 
116
    ****************************************************/
 
117
    // Feed URL
 
118
    function feed_url($url) {
 
119
        $url = $this->fix_protocol($url, 1);
 
120
        $this->rss_url = $url;
 
121
        return true;
 
122
    }
 
123
 
 
124
    // XML Dump
 
125
    function enable_xmldump($enable) {
 
126
        $this->xml_dump = (bool) $enable;
 
127
        return true;
 
128
    }
 
129
 
 
130
    // Bypass Image Hotlink
 
131
    function bypass_image_hotlink($getvar='i') {
 
132
        $this->bypass_image_hotlink = (string) $getvar;
 
133
        return true;
 
134
    }
 
135
 
 
136
    // Bypass Image Hotlink Page
 
137
    function bypass_image_hotlink_page($page = false) {
 
138
        $this->bypass_image_hotlink_page = (string) $page;
 
139
        return true;
 
140
    }
 
141
 
 
142
    // Caching
 
143
    function enable_caching($enable) {
 
144
        $this->caching = (bool) $enable;
 
145
        return true;
 
146
    }
 
147
 
 
148
    // Cache Timeout
 
149
    function cache_max_minutes($minutes) {
 
150
        $this->max_minutes = (int) $minutes;
 
151
        return true;
 
152
    }
 
153
 
 
154
    // Cache Location
 
155
    function cache_location($location) {
 
156
        $this->cache_location = (string) $location;
 
157
        return true;
 
158
    }
 
159
 
 
160
    // Replace H1, H2, and H3 tags with the less important H4 tags.
 
161
    function replace_headers($enable) {
 
162
        $this->replace_headers = (bool) $enable;
 
163
        return true;
 
164
    }
 
165
 
 
166
    // Remove outer div in XHTML content within Atom
 
167
    function remove_div($enable) {
 
168
        $this->remove_div = (bool) $enable;
 
169
        return true;
 
170
    }
 
171
 
 
172
    // Order the items by date
 
173
    function order_by_date($enable) {
 
174
        $this->order_by_date = (bool) $enable;
 
175
        return true;
 
176
    }
 
177
 
 
178
    // Strip out certain well-known ads
 
179
    function strip_ads($enable) {
 
180
        $this->strip_ads = (bool) $enable;
 
181
        return true;
 
182
    }
 
183
 
 
184
    // Strip out potentially dangerous tags
 
185
    function strip_htmltags($tags, $encode=false) {
 
186
        $this->strip_htmltags = (string) $tags;
 
187
        $this->encode_instead_of_strip = (bool) $encode;
 
188
        return true;
 
189
    }
 
190
 
 
191
    // Encode dangerous tags instead of stripping them
 
192
    function encode_instead_of_strip($encode=true) {
 
193
        $this->encode_instead_of_strip = (bool) $encode;
 
194
        return true;
 
195
    }
 
196
 
 
197
    // Strip out potentially dangerous attributes
 
198
    function strip_attributes($attrib) {
 
199
        $this->strip_attributes = (string) $attrib;
 
200
        return true;
 
201
    }
 
202
 
 
203
 
 
204
 
 
205
 
 
206
    /****************************************************
 
207
    MAIN INITIALIZATION FUNCTION
 
208
    Rewrites the feed so that it actually resembles XML, processes the XML,
 
209
    and builds an array from the feed.
 
210
    ****************************************************/
 
211
    function init() {
 
212
        // If Bypass Image Hotlink is enabled, send image to the page and quit.
 
213
        if ($this->bypass_image_hotlink) {
 
214
            if (isset($_GET[$this->bypass_image_hotlink]) && !empty($_GET[$this->bypass_image_hotlink])) {
 
215
                $this->display_image($_GET[$this->bypass_image_hotlink]);
 
216
                exit;
 
217
            }
 
218
        }
 
219
 
 
220
        // If Bypass Image Hotlink is enabled, send image to the page and quit.
 
221
        if (isset($_GET['js'])) {
 
222
 
 
223
            // JavaScript for the Odeo Player
 
224
            $embed='';
 
225
            $embed.='function embed_odeo(link) {';
 
226
            $embed.='document.writeln(\'';
 
227
            $embed.='<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
 
228
            $embed.='    codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" ';
 
229
            $embed.='    width="440" ';
 
230
            $embed.='    height="80" ';
 
231
            $embed.='    align="middle">';
 
232
            $embed.='<param name="movie" value="http://odeo.com/flash/audio_player_fullsize.swf" />';
 
233
            $embed.='<param name="allowScriptAccess" value="any" />';
 
234
            $embed.='<param name="quality" value="high">';
 
235
            $embed.='<param name="wmode" value="transparent">';
 
236
            $embed.='<param name="flashvars" value="valid_sample_rate=true&external_url=\'+link+\'" />';
 
237
            $embed.='<embed src="http://odeo.com/flash/audio_player_fullsize.swf" ';
 
238
            $embed.='    pluginspage="http://www.macromedia.com/go/getflashplayer" ';
 
239
            $embed.='    type="application/x-shockwave-flash" ';
 
240
            $embed.='    quality="high" ';
 
241
            $embed.='    width="440" ';
 
242
            $embed.='    height="80" ';
 
243
            $embed.='    wmode="transparent" ';
 
244
            $embed.='    allowScriptAccess="any" ';
 
245
            $embed.='    flashvars="valid_sample_rate=true&external_url=\'+link+\'">';
 
246
            $embed.='</embed>';
 
247
            $embed.='</object>';
 
248
            $embed.='\');';
 
249
            $embed.='}';
 
250
 
 
251
            $embed.="\r\n";
 
252
 
 
253
            $embed.='function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {';
 
254
            $embed.='document.writeln(\'';
 
255
            $embed.='<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" ';
 
256
            $embed.='    style="cursor:hand; cursor:pointer;" ';
 
257
            $embed.='    type="\'+type+\'" ';
 
258
            $embed.='    codebase="http://www.apple.com/qtactivex/qtplugin.cab" ';
 
259
            $embed.='    bgcolor="\'+bgcolor+\'" ';
 
260
            $embed.='    width="\'+width+\'" ';
 
261
            $embed.='    height="\'+height+\'">';
 
262
            $embed.='<param name="href" value="\'+link+\'" />';
 
263
            $embed.='<param name="src" value="\'+placeholder+\'" />';
 
264
            $embed.='<param name="autoplay" value="false" />';
 
265
            $embed.='<param name="target" value="myself" />';
 
266
            $embed.='<param name="controller" value="false" />';
 
267
            $embed.='<param name="loop" value="\'+loop+\'" />';
 
268
            $embed.='<param name="scale" value="aspect" />';
 
269
            $embed.='<param name="bgcolor" value="\'+bgcolor+\'">';
 
270
            $embed.='<embed type="\'+type+\'" ';
 
271
            $embed.='    style="cursor:hand; cursor:pointer;" ';
 
272
            $embed.='    href="\'+link+\'" ';
 
273
            $embed.='    src="\'+placeholder+\'"';
 
274
            $embed.='    width="\'+width+\'" ';
 
275
            $embed.='    height="\'+height+\'" ';
 
276
            $embed.='    autoplay="false" ';
 
277
            $embed.='    target="myself" ';
 
278
            $embed.='    controller="false" ';
 
279
            $embed.='    loop="\'+loop+\'" ';
 
280
            $embed.='    scale="aspect" ';
 
281
            $embed.='    bgcolor="\'+bgcolor+\'" ';
 
282
            $embed.='    pluginspage="http://www.apple.com/quicktime/download/">';
 
283
            $embed.='</embed>';
 
284
            $embed.='</object>';
 
285
            $embed.='\');';
 
286
            $embed.='}';
 
287
 
 
288
            $embed.="\r\n";
 
289
 
 
290
            $embed.='function embed_flash(bgcolor, width, height, link, loop, type) {';
 
291
            $embed.='document.writeln(\'';
 
292
            $embed.='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
 
293
            $embed.='    codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" ';
 
294
            $embed.='    bgcolor="\'+bgcolor+\'" ';
 
295
            $embed.='    width="\'+width+\'" ';
 
296
            $embed.='    height="\'+height+\'">';
 
297
            $embed.='<param name="movie" value="\'+link+\'">';
 
298
            $embed.='<param name="quality" value="high">';
 
299
            $embed.='<param name="loop" value="\'+loop+\'">';
 
300
            $embed.='<param name="bgcolor" value="\'+bgcolor+\'">';
 
301
            $embed.='<embed src="\'+link+\'" ';
 
302
            $embed.='    pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" ';
 
303
            $embed.='    type="\'+type+\'" ';
 
304
            $embed.='    quality="high" ';
 
305
            $embed.='    width="\'+width+\'" ';
 
306
            $embed.='    height="\'+height+\'" ';
 
307
            $embed.='    bgcolor="\'+bgcolor+\'" ';
 
308
            $embed.='    loop="\'+loop+\'">';
 
309
            $embed.='</embed>';
 
310
            $embed.='</object>';
 
311
            $embed.='\');';
 
312
            $embed.='}';
 
313
 
 
314
            $embed.="\r\n";
 
315
 
 
316
            $embed.='function embed_wmedia(width, height, link) {';
 
317
            $embed.='document.writeln(\'';
 
318
            $embed.='<object classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"';
 
319
            $embed.='    type="application/x-oleobject"';
 
320
            $embed.='    width="\'+width+\'"';
 
321
            $embed.='    height="\'+height+\'"';
 
322
            $embed.='    standby="Loading Windows Media Player...">';
 
323
            $embed.='<param name="FileName" value="\'+link+\'">';
 
324
            $embed.='<param name="autosize" value="true">';
 
325
            $embed.='<param name="ShowControls" value="true">';
 
326
            $embed.='<param name="ShowStatusBar" value="false">';
 
327
            $embed.='<param name="ShowDisplay" value="false">';
 
328
            $embed.='<param name="autostart" value="false">';
 
329
            $embed.='<embed type="application/x-mplayer2" ';
 
330
            $embed.='    src="\'+link+\'" ';
 
331
            $embed.='    autosize="1" ';
 
332
            $embed.='    width="\'+width+\'" ';
 
333
            $embed.='    height="\'+height+\'" ';
 
334
            $embed.='    showcontrols="1" ';
 
335
            $embed.='    showstatusbar="0" ';
 
336
            $embed.='    showdisplay="0" ';
 
337
            $embed.='    autostart="0">';
 
338
            $embed.='</embed>';
 
339
            $embed.='</object>';
 
340
            $embed.='\');';
 
341
            $embed.='}';
 
342
 
 
343
            $embed.="\r\n";
 
344
 
 
345
            // enable gzip compression
 
346
            ob_start ("ob_gzhandler");
 
347
            header("Content-type: text/javascript; charset: UTF-8");
 
348
            header("Cache-Control: must-revalidate");
 
349
            header("Expires: " .  gmdate("D, d M Y H:i:s", time() + 60*60*24) . " GMT");
 
350
            echo $embed;
 
351
            exit;
 
352
        }
 
353
 
 
354
        // If this is a .Mac Photocast, change it to the real URL.
 
355
        if (stristr($this->rss_url, 'http://photocast.mac.com')) {
 
356
            $this->rss_url = preg_replace('%http://photocast.mac.com%i', 'http://web.mac.com', $this->rss_url);
 
357
        }
 
358
 
 
359
        // Clear all outdated cache from the server's cache folder
 
360
        $this->clear_cache($this->cache_location, $this->max_minutes);
 
361
 
 
362
        if (!empty($this->rss_url)) {
 
363
            // Read the XML file for processing.
 
364
            $cache_filename = $this->cache_location . '/' . urlencode($this->rss_url) . '.spc';
 
365
            if ($this->caching && !$this->xml_dump && substr($this->rss_url, 0, 7) == 'http://' && file_exists($cache_filename)) {
 
366
                if ($fp = fopen($cache_filename, 'r')) {
 
367
                    $data = '';
 
368
                    while (!feof($fp)) {
 
369
                        $data .= fread($fp, 2048);
 
370
                    }
 
371
                    fclose($fp);
 
372
                    $mp_rss = unserialize($data);
 
373
                    if (empty($mp_rss)) {
 
374
                        $this->caching = false;
 
375
                        return $this->init();
 
376
                    } else if (isset($mp_rss['feed_url'])) {
 
377
                        $this->rss_url = $mp_rss['feed_url'];
 
378
                        return $this->init();
 
379
                    } else {
 
380
                        $this->data = $mp_rss;
 
381
                        return true;
 
382
                    }
 
383
                } else {
 
384
                    $this->caching = false;
 
385
                    return $this->init();
 
386
                }
 
387
            } else {
 
388
                // Get the file
 
389
                $mp_rss = $this->get_file($this->rss_url);
 
390
 
 
391
                // Check if file is a feed or a webpage
 
392
                // If it's a webpage, auto-discover the feed and re-pass it to init()
 
393
                $discovery = $this->rss_locator($mp_rss, $this->rss_url);
 
394
                if ($discovery) {
 
395
                    if ($discovery != $this->rss_url) {
 
396
                        $this->rss_url = $discovery;
 
397
                        if ($this->caching && substr($this->rss_url, 0, 7) == 'http://') {
 
398
                            if ($this->is_writeable_createable($cache_filename)) {
 
399
                                $fp = fopen($cache_filename, 'w');
 
400
                                fwrite($fp, serialize(array('feed_url' => $discovery)));
 
401
                                fclose($fp);
 
402
                            }
 
403
                            else trigger_error("$cache_filename is not writeable", E_USER_WARNING);
 
404
                        }
 
405
                        return $this->init();
 
406
                    }
 
407
                } else {
 
408
                    $this->sp_error("A feed could not be found at $this->rss_url", E_USER_WARNING, __FILE__, __LINE__);
 
409
                    return false;
 
410
                }
 
411
 
 
412
                // Trim out any whitespace at the beginning or the end of the file
 
413
                $mp_rss = trim($mp_rss);
 
414
 
 
415
                // Get encoding
 
416
                // Attempt to support everything from libiconv (http://www.gnu.org/software/libiconv/)
 
417
                // Support everything from mbstring (http://www.php.net/manual/en/ref.mbstring.php#mbstring.supported-encodings)
 
418
                $use_iconv = false;
 
419
                $use_mbstring = false;
 
420
                $utf8_fail = true;
 
421
                if (preg_match('/encoding=["|\'](.*)["|\']/Ui', $mp_rss, $encoding)) {
 
422
                    $match = $encoding;
 
423
                    switch (strtolower($encoding[1])) {
 
424
 
 
425
                        // 7bit
 
426
                        case '7bit':
 
427
                        case '7-bit':
 
428
                            $encoding = '7bit';
 
429
                            $use_mbstring = true;
 
430
                            break;
 
431
 
 
432
                        // 8bit
 
433
                        case '8bit':
 
434
                        case '8-bit':
 
435
                            $encoding = '8bit';
 
436
                            $use_mbstring = true;
 
437
                            break;
 
438
 
 
439
                        // ARMSCII-8
 
440
                        case 'armscii-8':
 
441
                        case 'armscii':
 
442
                            $encoding = 'ARMSCII-8';
 
443
                            $use_iconv = true;
 
444
                            break;
 
445
 
 
446
                        // ASCII
 
447
                        case 'us-ascii':
 
448
                        case 'ascii':
 
449
                            $encoding = 'US-ASCII';
 
450
                            $use_iconv = true;
 
451
                            $use_mbstring = true;
 
452
                            $utf8_fail = false;
 
453
                            break;
 
454
 
 
455
                        // BASE64
 
456
                        case 'base64':
 
457
                        case 'base-64':
 
458
                            $encoding = 'BASE64';
 
459
                            $use_mbstring = true;
 
460
                            break;
 
461
 
 
462
                        // Big5 - Traditional Chinese, mainly used in Taiwan
 
463
                        case 'big5':
 
464
                        case '950':
 
465
                            $encoding = 'BIG5';
 
466
                            $use_iconv = true;
 
467
                            $use_mbstring = true;
 
468
                            break;
 
469
 
 
470
                        // Big5 with Hong Kong extensions, Traditional Chinese
 
471
                        case 'big5-hkscs':
 
472
                            $encoding = 'BIG5-HKSCS';
 
473
                            $use_iconv = true;
 
474
                            $use_mbstring = true;
 
475
                            break;
 
476
 
 
477
                        // byte2be
 
478
                        case 'byte2be':
 
479
                            $encoding = 'byte2be';
 
480
                            $use_mbstring = true;
 
481
                            break;
 
482
 
 
483
                        // byte2le
 
484
                        case 'byte2le':
 
485
                            $encoding = 'byte2le';
 
486
                            $use_mbstring = true;
 
487
                            break;
 
488
 
 
489
                        // byte4be
 
490
                        case 'byte4be':
 
491
                            $encoding = 'byte4be';
 
492
                            $use_mbstring = true;
 
493
                            break;
 
494
 
 
495
                        // byte4le
 
496
                        case 'byte4le':
 
497
                            $encoding = 'byte4le';
 
498
                            $use_mbstring = true;
 
499
                            break;
 
500
 
 
501
                        // EUC-CN
 
502
                        case 'euc-cn':
 
503
                        case 'euccn':
 
504
                            $encoding = 'EUC-CN';
 
505
                            $use_iconv = true;
 
506
                            $use_mbstring = true;
 
507
                            break;
 
508
 
 
509
                        // EUC-JISX0213
 
510
                        case 'euc-jisx0213':
 
511
                        case 'eucjisx0213':
 
512
                            $encoding = 'EUC-JISX0213';
 
513
                            $use_iconv = true;
 
514
                            break;
 
515
 
 
516
                        // EUC-JP
 
517
                        case 'euc-jp':
 
518
                        case 'eucjp':
 
519
                            $encoding = 'EUC-JP';
 
520
                            $use_iconv = true;
 
521
                            $use_mbstring = true;
 
522
                            break;
 
523
 
 
524
                        // EUCJP-win
 
525
                        case 'euc-jp-win':
 
526
                        case 'eucjp-win':
 
527
                        case 'eucjpwin':
 
528
                            $encoding = 'EUCJP-win';
 
529
                            $use_iconv = true;
 
530
                            $use_mbstring = true;
 
531
                            break;
 
532
 
 
533
                        // EUC-KR
 
534
                        case 'euc-kr':
 
535
                        case 'euckr':
 
536
                            $encoding = 'EUC-KR';
 
537
                            $use_iconv = true;
 
538
                            $use_mbstring = true;
 
539
                            break;
 
540
 
 
541
                        // EUC-TW
 
542
                        case 'euc-tw':
 
543
                        case 'euctw':
 
544
                            $encoding = 'EUC-TW';
 
545
                            $use_iconv = true;
 
546
                            $use_mbstring = true;
 
547
                            break;
 
548
 
 
549
                        // GB18030 - Simplified Chinese, national standard character set
 
550
                        case 'gb18030-2000':
 
551
                        case 'gb18030':
 
552
                            $encoding = 'GB18030';
 
553
                            $use_iconv = true;
 
554
                            break;
 
555
 
 
556
                        // GB2312 - Simplified Chinese, national standard character set
 
557
                        case 'gb2312':
 
558
                        case '936':
 
559
                            $encoding = 'GB2312';
 
560
                            $use_mbstring = true;
 
561
                            break;
 
562
 
 
563
                        // GBK
 
564
                        case 'gbk':
 
565
                            $encoding = 'GBK';
 
566
                            $use_iconv = true;
 
567
                            break;
 
568
 
 
569
                        // Georgian-Academy
 
570
                        case 'georgian-academy':
 
571
                            $encoding = 'Georgian-Academy';
 
572
                            $use_iconv = true;
 
573
                            break;
 
574
 
 
575
                        // Georgian-PS
 
576
                        case 'georgian-ps':
 
577
                            $encoding = 'Georgian-PS';
 
578
                            $use_iconv = true;
 
579
                            break;
 
580
 
 
581
                        // HTML-ENTITIES
 
582
                        case 'html-entities':
 
583
                        case 'htmlentities':
 
584
                            $encoding = 'HTML-ENTITIES';
 
585
                            $use_mbstring = true;
 
586
                            break;
 
587
 
 
588
                        // HZ
 
589
                        case 'hz':
 
590
                            $encoding = 'HZ';
 
591
                            $use_iconv = true;
 
592
                            $use_mbstring = true;
 
593
                            break;
 
594
 
 
595
                        // ISO-2022-CN
 
596
                        case 'iso-2022-cn':
 
597
                        case 'iso2022-cn':
 
598
                        case 'iso2022cn':
 
599
                            $encoding = 'ISO-2022-CN';
 
600
                            $use_iconv = true;
 
601
                            break;
 
602
 
 
603
                        // ISO-2022-CN-EXT
 
604
                        case 'iso-2022-cn-ext':
 
605
                        case 'iso2022-cn-ext':
 
606
                        case 'iso2022cn-ext':
 
607
                        case 'iso2022cnext':
 
608
                            $encoding = 'ISO-2022-CN';
 
609
                            $use_iconv = true;
 
610
                            break;
 
611
 
 
612
                        // ISO-2022-JP
 
613
                        case 'iso-2022-jp':
 
614
                        case 'iso2022-jp':
 
615
                        case 'iso2022jp':
 
616
                            $encoding = 'ISO-2022-JP';
 
617
                            $use_iconv = true;
 
618
                            $use_mbstring = true;
 
619
                            break;
 
620
 
 
621
                        // ISO-2022-JP-1
 
622
                        case 'iso-2022-jp-1':
 
623
                        case 'iso2022-jp-1':
 
624
                        case 'iso2022jp-1':
 
625
                        case 'iso2022jp1':
 
626
                            $encoding = 'ISO-2022-JP-1';
 
627
                            $use_iconv = true;
 
628
                            break;
 
629
 
 
630
                        // ISO-2022-JP-2
 
631
                        case 'iso-2022-jp-2':
 
632
                        case 'iso2022-jp-2':
 
633
                        case 'iso2022jp-2':
 
634
                        case 'iso2022jp2':
 
635
                            $encoding = 'ISO-2022-JP-2';
 
636
                            $use_iconv = true;
 
637
                            break;
 
638
 
 
639
                        // ISO-2022-JP-3
 
640
                        case 'iso-2022-jp-3':
 
641
                        case 'iso2022-jp-3':
 
642
                        case 'iso2022jp-3':
 
643
                        case 'iso2022jp3':
 
644
                            $encoding = 'ISO-2022-JP-3';
 
645
                            $use_iconv = true;
 
646
                            break;
 
647
 
 
648
                        // ISO-2022-KR
 
649
                        case 'iso-2022-kr':
 
650
                        case 'iso2022-kr':
 
651
                        case 'iso2022kr':
 
652
                            $encoding = 'ISO-2022-KR';
 
653
                            $use_iconv = true;
 
654
                            $use_mbstring = true;
 
655
                            break;
 
656
 
 
657
                        // ISO-8859-1
 
658
                        case 'iso-8859-1':
 
659
                        case 'iso8859-1':
 
660
                            $encoding = 'ISO-8859-1';
 
661
                            $use_iconv = true;
 
662
                            $use_mbstring = true;
 
663
                            $utf8_fail = false;
 
664
                            break;
 
665
 
 
666
                        // ISO-8859-2
 
667
                        case 'iso-8859-2':
 
668
                        case 'iso8859-2':
 
669
                            $encoding = 'ISO-8859-2';
 
670
                            $use_iconv = true;
 
671
                            $use_mbstring = true;
 
672
                            break;
 
673
 
 
674
                        // ISO-8859-3
 
675
                        case 'iso-8859-3':
 
676
                        case 'iso8859-3':
 
677
                            $encoding = 'ISO-8859-3';
 
678
                            $use_iconv = true;
 
679
                            $use_mbstring = true;
 
680
                            break;
 
681
 
 
682
                        // ISO-8859-4
 
683
                        case 'iso-8859-4':
 
684
                        case 'iso8859-4':
 
685
                            $encoding = 'ISO-8859-4';
 
686
                            $use_iconv = true;
 
687
                            $use_mbstring = true;
 
688
                            break;
 
689
 
 
690
                        // ISO-8859-5
 
691
                        case 'iso-8859-5':
 
692
                        case 'iso8859-5':
 
693
                            $encoding = 'ISO-8859-5';
 
694
                            $use_iconv = true;
 
695
                            $use_mbstring = true;
 
696
                            break;
 
697
 
 
698
                        // ISO-8859-6
 
699
                        case 'iso-8859-6':
 
700
                        case 'iso8859-6':
 
701
                            $encoding = 'ISO-8859-6';
 
702
                            $use_iconv = true;
 
703
                            $use_mbstring = true;
 
704
                            break;
 
705
 
 
706
                        // ISO-8859-7
 
707
                        case 'iso-8859-7':
 
708
                        case 'iso8859-7':
 
709
                            $encoding = 'ISO-8859-7';
 
710
                            $use_iconv = true;
 
711
                            $use_mbstring = true;
 
712
                            break;
 
713
 
 
714
                        // ISO-8859-8
 
715
                        case 'iso-8859-8':
 
716
                        case 'iso8859-8':
 
717
                            $encoding = 'ISO-8859-8';
 
718
                            $use_iconv = true;
 
719
                            $use_mbstring = true;
 
720
                            break;
 
721
 
 
722
                        // ISO-8859-9
 
723
                        case 'iso-8859-9':
 
724
                        case 'iso8859-9':
 
725
                            $encoding = 'ISO-8859-9';
 
726
                            $use_iconv = true;
 
727
                            $use_mbstring = true;
 
728
                            break;
 
729
 
 
730
                        // ISO-8859-10
 
731
                        case 'iso-8859-10':
 
732
                        case 'iso8859-10':
 
733
                            $encoding = 'ISO-8859-10';
 
734
                            $use_iconv = true;
 
735
                            $use_mbstring = true;
 
736
                            break;
 
737
 
 
738
                        // mbstring/iconv functions don't appear to support 11 & 12
 
739
 
 
740
                        // ISO-8859-13
 
741
                        case 'iso-8859-13':
 
742
                        case 'iso8859-13':
 
743
                            $encoding = 'ISO-8859-13';
 
744
                            $use_iconv = true;
 
745
                            $use_mbstring = true;
 
746
                            break;
 
747
 
 
748
                        // ISO-8859-14
 
749
                        case 'iso-8859-14':
 
750
                        case 'iso8859-14':
 
751
                            $encoding = 'ISO-8859-14';
 
752
                            $use_iconv = true;
 
753
                            $use_mbstring = true;
 
754
                            break;
 
755
 
 
756
                        // ISO-8859-15
 
757
                        case 'iso-8859-15':
 
758
                        case 'iso8859-15':
 
759
                            $encoding = 'ISO-8859-15';
 
760
                            $use_iconv = true;
 
761
                            $use_mbstring = true;
 
762
                            break;
 
763
 
 
764
                        // ISO-8859-16
 
765
                        case 'iso-8859-16':
 
766
                        case 'iso8859-16':
 
767
                            $encoding = 'ISO-8859-16';
 
768
                            $use_iconv = true;
 
769
                            break;
 
770
 
 
771
                        // JIS
 
772
                        case 'jis':
 
773
                            $encoding = 'JIS';
 
774
                            $use_mbstring = true;
 
775
                            break;
 
776
 
 
777
                        // JOHAB - Korean
 
778
                        case 'johab':
 
779
                            $encoding = 'JOHAB';
 
780
                            $use_iconv = true;
 
781
                            break;
 
782
 
 
783
                        // Russian
 
784
                        case 'koi8-r':
 
785
                        case 'koi8r':
 
786
                            $encoding = 'KOI8-R';
 
787
                            $use_iconv = true;
 
788
                            $use_mbstring = true;
 
789
                            break;
 
790
 
 
791
                        // Turkish
 
792
                        case 'koi8-t':
 
793
                        case 'koi8t':
 
794
                            $encoding = 'KOI8-T';
 
795
                            $use_iconv = true;
 
796
                            break;
 
797
 
 
798
                        // Ukrainian
 
799
                        case 'koi8-u':
 
800
                        case 'koi8u':
 
801
                            $encoding = 'KOI8-U';
 
802
                            $use_iconv = true;
 
803
                            break;
 
804
 
 
805
                        // Russian+Ukrainian
 
806
                        case 'koi8-ru':
 
807
                        case 'koi8ru':
 
808
                            $encoding = 'KOI8-RU';
 
809
                            $use_iconv = true;
 
810
                            break;
 
811
 
 
812
                        // Macintosh (Mac OS Classic)
 
813
                        case 'macintosh':
 
814
                            $encoding = 'Macintosh';
 
815
                            $use_iconv = true;
 
816
                            break;
 
817
 
 
818
                        // MacArabic (Mac OS Classic)
 
819
                        case 'macarabic':
 
820
                            $encoding = 'MacArabic';
 
821
                            $use_iconv = true;
 
822
                            break;
 
823
 
 
824
                        // MacCentralEurope (Mac OS Classic)
 
825
                        case 'maccentraleurope':
 
826
                            $encoding = 'MacCentralEurope';
 
827
                            $use_iconv = true;
 
828
                            break;
 
829
 
 
830
                        // MacCroatian (Mac OS Classic)
 
831
                        case 'maccroatian':
 
832
                            $encoding = 'MacCroatian';
 
833
                            $use_iconv = true;
 
834
                            break;
 
835
 
 
836
                        // MacCyrillic (Mac OS Classic)
 
837
                        case 'maccyrillic':
 
838
                            $encoding = 'MacCyrillic';
 
839
                            $use_iconv = true;
 
840
                            break;
 
841
 
 
842
                        // MacGreek (Mac OS Classic)
 
843
                        case 'macgreek':
 
844
                            $encoding = 'MacGreek';
 
845
                            $use_iconv = true;
 
846
                            break;
 
847
 
 
848
                        // MacHebrew (Mac OS Classic)
 
849
                        case 'machebrew':
 
850
                            $encoding = 'MacHebrew';
 
851
                            $use_iconv = true;
 
852
                            break;
 
853
 
 
854
                        // MacIceland (Mac OS Classic)
 
855
                        case 'maciceland':
 
856
                            $encoding = 'MacIceland';
 
857
                            $use_iconv = true;
 
858
                            break;
 
859
 
 
860
                        // MacRoman (Mac OS Classic)
 
861
                        case 'macroman':
 
862
                            $encoding = 'MacRoman';
 
863
                            $use_iconv = true;
 
864
                            break;
 
865
 
 
866
                        // MacRomania (Mac OS Classic)
 
867
                        case 'macromania':
 
868
                            $encoding = 'MacRomania';
 
869
                            $use_iconv = true;
 
870
                            break;
 
871
 
 
872
                        // MacThai (Mac OS Classic)
 
873
                        case 'macthai':
 
874
                            $encoding = 'MacThai';
 
875
                            $use_iconv = true;
 
876
                            break;
 
877
 
 
878
                        // MacTurkish (Mac OS Classic)
 
879
                        case 'macturkish':
 
880
                            $encoding = 'MacTurkish';
 
881
                            $use_iconv = true;
 
882
                            break;
 
883
 
 
884
                        // MacUkraine (Mac OS Classic)
 
885
                        case 'macukraine':
 
886
                            $encoding = 'MacUkraine';
 
887
                            $use_iconv = true;
 
888
                            break;
 
889
 
 
890
                        // MuleLao-1
 
891
                        case 'mulelao-1':
 
892
                        case 'mulelao1':
 
893
                            $encoding = 'MuleLao-1';
 
894
                            $use_iconv = true;
 
895
                            break;
 
896
 
 
897
                        // Shift_JIS
 
898
                        case 'shift_jis':
 
899
                        case 'sjis':
 
900
                        case '932':
 
901
                            $encoding = 'Shift_JIS';
 
902
                            $use_iconv = true;
 
903
                            $use_mbstring = true;
 
904
                            break;
 
905
 
 
906
                        // Shift_JISX0213
 
907
                        case 'shift-jisx0213':
 
908
                        case 'shiftjisx0213':
 
909
                            $encoding = 'Shift_JISX0213';
 
910
                            $use_iconv = true;
 
911
                            break;
 
912
 
 
913
                        // SJIS-win
 
914
                        case 'sjis-win':
 
915
                        case 'sjiswin':
 
916
                        case 'shift_jis-win':
 
917
                            $encoding = 'SJIS-win';
 
918
                            $use_iconv = true;
 
919
                            $use_mbstring = true;
 
920
                            break;
 
921
 
 
922
                        // TCVN - Vietnamese
 
923
                        case 'tcvn':
 
924
                            $encoding = 'TCVN';
 
925
                            $use_iconv = true;
 
926
                            break;
 
927
 
 
928
                        // TDS565 - Turkish
 
929
                        case 'tds565':
 
930
                            $encoding = 'TDS565';
 
931
                            $use_iconv = true;
 
932
                            break;
 
933
 
 
934
                        // TIS-620 Thai
 
935
                        case 'tis-620':
 
936
                        case 'tis620':
 
937
                            $encoding = 'TIS-620';
 
938
                            $use_iconv = true;
 
939
                            $use_mbstring = true;
 
940
                            break;
 
941
 
 
942
                        // UCS-2
 
943
                        case 'ucs-2':
 
944
                        case 'ucs2':
 
945
                        case 'utf-16':
 
946
                        case 'utf16':
 
947
                            $encoding = 'UCS-2';
 
948
                            $use_iconv = true;
 
949
                            $use_mbstring = true;
 
950
                            break;
 
951
 
 
952
                        // UCS-2BE
 
953
                        case 'ucs-2be':
 
954
                        case 'ucs2be':
 
955
                        case 'utf-16be':
 
956
                        case 'utf16be':
 
957
                            $encoding = 'UCS-2BE';
 
958
                            $use_iconv = true;
 
959
                            $use_mbstring = true;
 
960
                            break;
 
961
 
 
962
                        // UCS-2LE
 
963
                        case 'ucs-2le':
 
964
                        case 'ucs2le':
 
965
                        case 'utf-16le':
 
966
                        case 'utf16le':
 
967
                            $encoding = 'UCS-2LE';
 
968
                            $use_iconv = true;
 
969
                            $use_mbstring = true;
 
970
                            break;
 
971
 
 
972
                        // UCS-2-INTERNAL
 
973
                        case 'ucs-2-internal':
 
974
                        case 'ucs2internal':
 
975
                            $encoding = 'UCS-2-INTERNAL';
 
976
                            $use_iconv = true;
 
977
                            break;
 
978
 
 
979
                        // UCS-4
 
980
                        case 'ucs-4':
 
981
                        case 'ucs4':
 
982
                        case 'utf-32':
 
983
                        case 'utf32':
 
984
                            $encoding = 'UCS-4';
 
985
                            $use_iconv = true;
 
986
                            $use_mbstring = true;
 
987
                            break;
 
988
 
 
989
                        // UCS-4BE
 
990
                        case 'ucs-4be':
 
991
                        case 'ucs4be':
 
992
                        case 'utf-32be':
 
993
                        case 'utf32be':
 
994
                            $encoding = 'UCS-4BE';
 
995
                            $use_iconv = true;
 
996
                            $use_mbstring = true;
 
997
                            break;
 
998
 
 
999
                        // UCS-4LE
 
1000
                        case 'ucs-4le':
 
1001
                        case 'ucs4le':
 
1002
                        case 'utf-32le':
 
1003
                        case 'utf32le':
 
1004
                            $encoding = 'UCS-4LE';
 
1005
                            $use_iconv = true;
 
1006
                            $use_mbstring = true;
 
1007
                            break;
 
1008
 
 
1009
                        // UCS-4-INTERNAL
 
1010
                        case 'ucs-4-internal':
 
1011
                        case 'ucs4internal':
 
1012
                            $encoding = 'UCS-4-INTERNAL';
 
1013
                            $use_iconv = true;
 
1014
                            break;
 
1015
 
 
1016
                        // UCS-16
 
1017
                        case 'ucs-16':
 
1018
                        case 'ucs16':
 
1019
                            $encoding = 'UCS-16';
 
1020
                            $use_iconv = true;
 
1021
                            $use_mbstring = true;
 
1022
                            break;
 
1023
 
 
1024
                        // UCS-16BE
 
1025
                        case 'ucs-16be':
 
1026
                        case 'ucs16be':
 
1027
                            $encoding = 'UCS-16BE';
 
1028
                            $use_iconv = true;
 
1029
                            $use_mbstring = true;
 
1030
                            break;
 
1031
 
 
1032
                        // UCS-16LE
 
1033
                        case 'ucs-16le':
 
1034
                        case 'ucs16le':
 
1035
                            $encoding = 'UCS-16LE';
 
1036
                            $use_iconv = true;
 
1037
                            $use_mbstring = true;
 
1038
                            break;
 
1039
 
 
1040
                        // UCS-32
 
1041
                        case 'ucs-32':
 
1042
                        case 'ucs32':
 
1043
                            $encoding = 'UCS-32';
 
1044
                            $use_iconv = true;
 
1045
                            $use_mbstring = true;
 
1046
                            break;
 
1047
 
 
1048
                        // UCS-32BE
 
1049
                        case 'ucs-32be':
 
1050
                        case 'ucs32be':
 
1051
                            $encoding = 'UCS-32BE';
 
1052
                            $use_iconv = true;
 
1053
                            $use_mbstring = true;
 
1054
                            break;
 
1055
 
 
1056
                        // UCS-32LE
 
1057
                        case 'ucs-32le':
 
1058
                        case 'ucs32le':
 
1059
                            $encoding = 'UCS-32LE';
 
1060
                            $use_iconv = true;
 
1061
                            $use_mbstring = true;
 
1062
                            break;
 
1063
 
 
1064
                        // UTF-7
 
1065
                        case 'utf-7':
 
1066
                        case 'utf7':
 
1067
                            $encoding = 'UTF-7';
 
1068
                            $use_iconv = true;
 
1069
                            $use_mbstring = true;
 
1070
                            break;
 
1071
 
 
1072
                        // UTF7-IMAP
 
1073
                        case 'utf-7-imap':
 
1074
                        case 'utf7-imap':
 
1075
                        case 'utf7imap':
 
1076
                            $encoding = 'UTF7-IMAP';
 
1077
                            $use_mbstring = true;
 
1078
                            break;
 
1079
 
 
1080
                        // VISCII - Vietnamese ASCII
 
1081
                        case 'viscii':
 
1082
                            $encoding = 'VISCII';
 
1083
                            $use_iconv = true;
 
1084
                            break;
 
1085
 
 
1086
                        // Windows-specific Central & Eastern Europe
 
1087
                        case 'cp1250':
 
1088
                        case 'windows-1250':
 
1089
                        case 'win-1250':
 
1090
                        case '1250':
 
1091
                            $encoding = 'Windows-1250';
 
1092
                            $use_iconv = true;
 
1093
                            break;
 
1094
 
 
1095
                        // Windows-specific Cyrillic
 
1096
                        case 'cp1251':
 
1097
                        case 'windows-1251':
 
1098
                        case 'win-1251':
 
1099
                        case '1251':
 
1100
                            $encoding = 'Windows-1251';
 
1101
                            $use_iconv = true;
 
1102
                            $use_mbstring = true;
 
1103
                            break;
 
1104
 
 
1105
                        // Windows-specific Western Europe
 
1106
                        case 'cp1252':
 
1107
                        case 'windows-1252':
 
1108
                        case '1252':
 
1109
                            $encoding = 'Windows-1252';
 
1110
                            $use_iconv = true;
 
1111
                            $use_mbstring = true;
 
1112
                            break;
 
1113
 
 
1114
                        // Windows-specific Greek
 
1115
                        case 'cp1253':
 
1116
                        case 'windows-1253':
 
1117
                        case '1253':
 
1118
                            $encoding = 'Windows-1253';
 
1119
                            $use_iconv = true;
 
1120
                            break;
 
1121
 
 
1122
                        // Windows-specific Turkish
 
1123
                        case 'cp1254':
 
1124
                        case 'windows-1254':
 
1125
                        case '1254':
 
1126
                            $encoding = 'Windows-1254';
 
1127
                            $use_iconv = true;
 
1128
                            break;
 
1129
 
 
1130
                        // Windows-specific Hebrew
 
1131
                        case 'cp1255':
 
1132
                        case 'windows-1255':
 
1133
                        case '1255':
 
1134
                            $encoding = 'Windows-1255';
 
1135
                            $use_iconv = true;
 
1136
                            break;
 
1137
 
 
1138
                        // Windows-specific Arabic
 
1139
                        case 'cp1256':
 
1140
                        case 'windows-1256':
 
1141
                        case '1256':
 
1142
                            $encoding = 'Windows-1256';
 
1143
                            $use_iconv = true;
 
1144
                            break;
 
1145
 
 
1146
                        // Windows-specific Baltic
 
1147
                        case 'cp1257':
 
1148
                        case 'windows-1257':
 
1149
                        case '1257':
 
1150
                            $encoding = 'Windows-1257';
 
1151
                            $use_iconv = true;
 
1152
                            break;
 
1153
 
 
1154
                        // Windows-specific Vietnamese
 
1155
                        case 'cp1258':
 
1156
                        case 'windows-1258':
 
1157
                        case '1258':
 
1158
                            $encoding = 'Windows-1258';
 
1159
                            $use_iconv = true;
 
1160
                            break;
 
1161
 
 
1162
                        // Default to UTF-8
 
1163
                        default:
 
1164
                            $encoding = 'UTF-8';
 
1165
                            break;
 
1166
                    }
 
1167
                } else {
 
1168
                    $mp_rss = preg_replace ('/<\?xml(.*)( standalone="no")(.*)\?>/msiU', '<?xml\\1\\3?>', $mp_rss, 1);
 
1169
                    $mp_rss = preg_replace ('/<\?xml(.*)\?>/msiU', '<?xml\\1 encoding="UTF-8"?>', $mp_rss, 1);
 
1170
                    preg_match('/encoding=["|\'](.*)["|\']/Ui', $mp_rss, $match);
 
1171
                    $use_iconv = true;
 
1172
                    $use_mbstring = true;
 
1173
                    $utf8_fail = false;
 
1174
                    $encoding = 'UTF-8';
 
1175
                }
 
1176
                $this->encoding = $encoding;
 
1177
 
 
1178
                // If function is available and able, convert characters to UTF-8, and overwrite $this->encoding
 
1179
                if (function_exists('iconv') && $use_iconv && iconv($encoding, 'UTF-8', $mp_rss)) {
 
1180
                    $mp_rss = iconv($encoding, 'UTF-8//TRANSLIT', $mp_rss);
 
1181
                    $mp_rss = str_replace ($match[0], 'encoding="UTF-8"', $mp_rss);
 
1182
                    $this->encoding = 'UTF-8';
 
1183
                }
 
1184
                else if (function_exists('mb_convert_encoding') && $use_mbstring) {
 
1185
                    $mp_rss = mb_convert_encoding($mp_rss, 'UTF-8', $encoding);
 
1186
                    $mp_rss = str_replace ($match[0], 'encoding="UTF-8"', $mp_rss);
 
1187
                    $this->encoding = 'UTF-8';
 
1188
                }
 
1189
                else if (($use_mbstring || $use_iconv) && $utf8_fail) {
 
1190
                        $this->encoding = 'UTF-8';
 
1191
                        $mp_rss = str_replace ($match[0], 'encoding="UTF-8"', $mp_rss);
 
1192
                }
 
1193
                $mp_rss = preg_replace('/<(.*)>[\s]*<\!\[CDATA\[/msiU', '<\\1 spencoded="false"><![CDATA[', $mp_rss); // Add an internal attribute to CDATA sections
 
1194
                $mp_rss = str_replace(']] spencoded="false">', ']]>', $mp_rss); // Remove it when we're on the end of a CDATA block (therefore making it ill-formed)
 
1195
 
 
1196
                // If we're RSS
 
1197
                if (preg_match('/<rdf:rdf/i', $mp_rss) || preg_match('/<rss/i', $mp_rss)) {
 
1198
                    $sp_elements = array(
 
1199
                        'author',
 
1200
                        'link',
 
1201
                    );
 
1202
                // Or if we're Atom
 
1203
                } else {
 
1204
                    $sp_elements = array(
 
1205
                        'content',
 
1206
                        'copyright',
 
1207
                        'name',
 
1208
                        'subtitle',
 
1209
                        'summary',
 
1210
                        'tagline',
 
1211
                        'title',
 
1212
                    );
 
1213
                }
 
1214
                foreach ($sp_elements as $full) {
 
1215
                    // The (<\!\[CDATA\[)? never matches any CDATA block, therefore the CDATA gets added, but never replaced
 
1216
                    $mp_rss = preg_replace("/<$full(.*)>[\s]*(<\!\[CDATA\[)?(.*)(]]>)?[\s]*<\/$full>/msiU", "<$full\\1><![CDATA[\\3]]></$full>", $mp_rss);
 
1217
                    // The following line is a work-around for the above bug
 
1218
                    $mp_rss = preg_replace("/<$full(.*)><\!\[CDATA\[[\s]*<\!\[CDATA\[/msiU", "<$full\\1><![CDATA[", $mp_rss);
 
1219
                    // Deal with CDATA within CDATA (this can be caused by us inserting CDATA above)
 
1220
                    $mp_rss = preg_replace_callback("/<($full)(.*)><!\[CDATA\[(.*)\]\]><\/$full>/msiU", array(&$this, 'cdata_in_cdata'), $mp_rss);
 
1221
                }
 
1222
 
 
1223
                // If XML Dump is enabled, send feed to the page and quit.
 
1224
                if ($this->xml_dump) {
 
1225
                    header("Content-type: text/xml; charset=" . $this->encoding);
 
1226
                    echo $mp_rss;
 
1227
                    exit;
 
1228
                }
 
1229
 
 
1230
                $this->xml = xml_parser_create_ns($this->encoding);
 
1231
                $this->namespaces = array('xml' => 'HTTP://WWW.W3.ORG/XML/1998/NAMESPACE', 'atom' => 'ATOM', 'rss2' => 'RSS', 'rdf' => 'RDF', 'rss1' => 'RSS', 'dc' => 'DC', 'xhtml' => 'XHTML', 'content' => 'CONTENT');
 
1232
                xml_parser_set_option($this->xml, XML_OPTION_SKIP_WHITE, 1);
 
1233
                xml_set_object($this->xml, $this);
 
1234
                xml_set_character_data_handler($this->xml, 'dataHandler');
 
1235
                xml_set_element_handler($this->xml, 'startHandler', 'endHandler');
 
1236
                xml_set_start_namespace_decl_handler($this->xml, 'startNameSpace');
 
1237
                xml_set_end_namespace_decl_handler($this->xml, 'endNameSpace');
 
1238
                if (xml_parse($this->xml, $mp_rss))
 
1239
                {
 
1240
                    xml_parser_free($this->xml);
 
1241
                    $this->parse_xml_data_array();
 
1242
                    $this->data['feedinfo']['encoding'] = $this->encoding;
 
1243
                    if ($this->order_by_date && !empty($this->data['items'])) {
 
1244
                        usort($this->data['items'], create_function('$a,$b', 'if ($a->date == $b->date) return 0; return ($a->date < $b->date) ? 1 : -1;'));
 
1245
                    }
 
1246
                    if ($this->caching && substr($this->rss_url, 0, 7) == 'http://') {
 
1247
                        if ($this->is_writeable_createable($cache_filename)) {
 
1248
                            $fp = fopen($cache_filename, 'w');
 
1249
                            fwrite($fp, serialize($this->data));
 
1250
                            fclose($fp);
 
1251
                        }
 
1252
                        else trigger_error("$cache_filename is not writeable", E_USER_WARNING);
 
1253
                    }
 
1254
                    return true;
 
1255
                }
 
1256
                else
 
1257
                {
 
1258
                    $this->sp_error(sprintf('XML error: %s at line %d, column %d', xml_error_string(xml_get_error_code($this->xml)), xml_get_current_line_number($this->xml), xml_get_current_column_number($this->xml)), E_USER_WARNING, __FILE__, __LINE__);
 
1259
                    xml_parser_free($this->xml);
 
1260
                    $this->data = array();
 
1261
                    return false;
 
1262
                }
 
1263
            }
 
1264
        }
 
1265
        else {
 
1266
            return false;
 
1267
        }
 
1268
    }
 
1269
 
 
1270
 
 
1271
 
 
1272
 
 
1273
    /****************************************************
 
1274
    SIMPLEPIE ERROR (internal function)
 
1275
    ****************************************************/
 
1276
    function sp_error($message, $level, $file, $line) {
 
1277
        $this->error = $message;
 
1278
        switch ($level) {
 
1279
            case E_USER_ERROR:
 
1280
                $note = 'PHP Error';
 
1281
                break;
 
1282
            case E_USER_WARNING:
 
1283
                $note = 'PHP Warning';
 
1284
                break;
 
1285
            case E_USER_NOTICE:
 
1286
                $note = 'PHP Notice';
 
1287
                break;
 
1288
            default:
 
1289
                $note = 'Unknown Error';
 
1290
                break;
 
1291
        }
 
1292
        error_log("$note: $message in $file on line $line", 0);
 
1293
    }
 
1294
 
 
1295
 
 
1296
 
 
1297
 
 
1298
    /****************************************************
 
1299
    GET FEED ENCODING
 
1300
    ****************************************************/
 
1301
    function get_encoding() {
 
1302
        if (isset($this->encoding)) {
 
1303
            return $this->encoding;
 
1304
        } else if (isset($this->data['feedinfo']['encoding'])) {
 
1305
            return $this->data['feedinfo']['encoding'];
 
1306
        } else return false;
 
1307
    }
 
1308
 
 
1309
    function handle_content_type($mime='text/html') {
 
1310
        if (!headers_sent() && $this->get_encoding()) header('Content-type: ' . $mime . '; charset=' . $this->get_encoding());
 
1311
    }
 
1312
 
 
1313
 
 
1314
 
 
1315
 
 
1316
    /****************************************************
 
1317
    GET FEED VERSION NUMBER
 
1318
    ****************************************************/
 
1319
    function get_version() {
 
1320
        if (isset($this->data['feedinfo'])) {
 
1321
            return (isset($this->data['feedinfo']['version'])) ? $this->data[feedinfo][type] . ' ' . $this->data[feedinfo][version] : $this->data['feedinfo']['type'];
 
1322
        }
 
1323
        else return false;
 
1324
    }
 
1325
 
 
1326
 
 
1327
 
 
1328
 
 
1329
    /****************************************************
 
1330
    SUBSCRIPTION URLS
 
1331
    This allows people to subscribe to the feed in various services.
 
1332
    ****************************************************/
 
1333
    function subscribe_url() {
 
1334
        return (empty($this->rss_url)) ? false : $this->fix_protocol($this->rss_url, 1);
 
1335
    }
 
1336
 
 
1337
    function subscribe_feed() {
 
1338
        return (empty($this->rss_url)) ? false : $this->fix_protocol($this->rss_url, 2);
 
1339
    }
 
1340
 
 
1341
    function subscribe_podcast() {
 
1342
        return (empty($this->rss_url)) ? false : $this->fix_protocol($this->rss_url, 3);
 
1343
    }
 
1344
 
 
1345
    function subscribe_aol() {
 
1346
        return (empty($this->rss_url)) ? false : 'http://feeds.my.aol.com/add.jsp?url=' . rawurlencode($this->subscribe_url());
 
1347
    }
 
1348
 
 
1349
    function subscribe_bloglines() {
 
1350
        return (empty($this->rss_url)) ? false : 'http://www.bloglines.com/sub/' . rawurlencode($this->subscribe_url());
 
1351
    }
 
1352
 
 
1353
    function subscribe_google() {
 
1354
        return (empty($this->rss_url)) ? false : 'http://fusion.google.com/add?feedurl=' . rawurlencode($this->subscribe_url());
 
1355
    }
 
1356
 
 
1357
    function subscribe_msn() {
 
1358
        return (empty($this->rss_url)) ? false : 'http://my.msn.com/addtomymsn.armx?id=rss&amp;ut=' . rawurlencode($this->subscribe_url()) . '&amp;ru=' . rawurlencode($this->get_feed_link());
 
1359
    }
 
1360
 
 
1361
    function subscribe_netvibes() {
 
1362
        return (empty($this->rss_url)) ? false : 'http://www.netvibes.com/subscribe.php?url=' . rawurlencode($this->subscribe_url());
 
1363
    }
 
1364
 
 
1365
    function subscribe_newsburst() {
 
1366
        return (empty($this->rss_url)) ? false : 'http://www.newsburst.com/Source/?add=' . rawurlencode($this->subscribe_url());
 
1367
    }
 
1368
 
 
1369
    function subscribe_newsgator() {
 
1370
        return (empty($this->rss_url)) ? false : 'http://www.newsgator.com/ngs/subscriber/subext.aspx?url=' . rawurlencode($this->subscribe_url());
 
1371
    }
 
1372
 
 
1373
    function subscribe_odeo() {
 
1374
        return (empty($this->rss_url)) ? false : 'http://www.odeo.com/listen/subscribe?feed=' . rawurlencode($this->subscribe_url());
 
1375
    }
 
1376
 
 
1377
    function subscribe_pluck() {
 
1378
        return (empty($this->rss_url)) ? false : 'http://client.pluck.com/pluckit/prompt.aspx?GCID=C12286x053&amp;a=' . rawurlencode($this->subscribe_url());
 
1379
    }
 
1380
 
 
1381
    function subscribe_podnova() {
 
1382
        return (empty($this->rss_url)) ? false : 'http://www.podnova.com/index_your_podcasts.srf?action=add&url=' . rawurlencode($this->subscribe_url());
 
1383
    }
 
1384
 
 
1385
    function subscribe_rojo() {
 
1386
        return (empty($this->rss_url)) ? false : 'http://www.rojo.com/add-subscription?resource=' . rawurlencode($this->subscribe_url());
 
1387
    }
 
1388
 
 
1389
    function subscribe_yahoo() {
 
1390
        return (empty($this->rss_url)) ? false : 'http://add.my.yahoo.com/rss?url=' . rawurlencode($this->subscribe_url());
 
1391
    }
 
1392
 
 
1393
 
 
1394
 
 
1395
 
 
1396
    /****************************************************
 
1397
    PARSE OUT GENERAL FEED-RELATED DATA
 
1398
    ****************************************************/
 
1399
    // Reads the feed's title
 
1400
    function get_feed_title() {
 
1401
        return (isset($this->data['info']['title'])) ? $this->data['info']['title'] : false;
 
1402
    }
 
1403
 
 
1404
    // Reads the feed's link (URL)
 
1405
    function get_feed_link() {
 
1406
        return (isset($this->data['info']['link'][0])) ? $this->data['info']['link'][0] : false;
 
1407
    }
 
1408
 
 
1409
    // Reads the feed's link (URL)
 
1410
    function get_feed_links($key) {
 
1411
        return (isset($this->data['info']['link'][$key])) ? $this->data['info']['link'][$key] : false;
 
1412
    }
 
1413
 
 
1414
    // Reads the feed's description
 
1415
    function get_feed_description() {
 
1416
        return (isset($this->data['info']['description'])) ? $this->data['info']['description'] : false;
 
1417
    }
 
1418
 
 
1419
    // Reads the feed's copyright information.
 
1420
    function get_feed_copyright() {
 
1421
        return (isset($this->data['info']['copyright'])) ? $this->data['info']['copyright'] : false;
 
1422
    }
 
1423
 
 
1424
    // Reads the feed's language
 
1425
    function get_feed_language() {
 
1426
        return (isset($this->data['info']['language'])) ? $this->data['info']['language'] : false;
 
1427
    }
 
1428
 
 
1429
 
 
1430
 
 
1431
 
 
1432
    /****************************************************
 
1433
    PARSE OUT IMAGE-RELATED DATA
 
1434
    Apparently Atom doesn't have feed images.
 
1435
    ****************************************************/
 
1436
    // Check if an image element exists (returns true/false)
 
1437
    function get_image_exist() {
 
1438
        return (isset($this->data['info']['image']['url'])) ? true : false;
 
1439
    }
 
1440
 
 
1441
    // Get the image title (to be used in alt and/or title)
 
1442
    function get_image_title() {
 
1443
        return (isset($this->data['info']['image']['title'])) ? $this->data['info']['image']['title'] : false;
 
1444
    }
 
1445
 
 
1446
    // The path to the actual image
 
1447
    function get_image_url() {
 
1448
        return (isset($this->data['info']['image']['url'])) ? $this->data['info']['image']['url'] : false;
 
1449
    }
 
1450
 
 
1451
    // The URL that the image is supposed to link to.
 
1452
    function get_image_link() {
 
1453
        return (isset($this->data['info']['image']['link'])) ? $this->data['info']['image']['link'] : false;
 
1454
    }
 
1455
 
 
1456
    // Get the image width
 
1457
    function get_image_width() {
 
1458
        return (isset($this->data['info']['image']['width'])) ? $this->data['info']['image']['width'] : false;
 
1459
    }
 
1460
 
 
1461
    // Get the image height
 
1462
    function get_image_height() {
 
1463
        return (isset($this->data['info']['image']['height'])) ? $this->data['info']['image']['height'] : false;
 
1464
    }
 
1465
 
 
1466
 
 
1467
 
 
1468
 
 
1469
    /****************************************************
 
1470
    PARSE OUT ITEM-RELATED DATA
 
1471
    ****************************************************/
 
1472
    // Get the size of the array of items (for use in a for-loop)
 
1473
    function get_item_quantity($max=0) {
 
1474
        $qty = (isset($this->data['items'])) ? sizeof($this->data['items']) : 0;
 
1475
        if ($max != 0) return ($qty > $max) ? $max : $qty;
 
1476
        else return $qty;
 
1477
    }
 
1478
 
 
1479
    function get_item($key) {
 
1480
        return $this->data['items'][$key];
 
1481
    }
 
1482
 
 
1483
    function get_items($start = 0, $end = 0) {
 
1484
        return ($end == 0) ? array_slice($this->data['items'], $start) : array_slice($this->data['items'], $start, $end);
 
1485
    }
 
1486
 
 
1487
 
 
1488
 
 
1489
 
 
1490
    /****************************************************
 
1491
    FIX PROTOCOL
 
1492
    Convert feed:// and no-protocol URL's to http://
 
1493
    Feed is allowed to have no protocol.  Local files are toggled in init().
 
1494
    This is an internal function and is not intended to be used publically.
 
1495
 
 
1496
    $http=1, http://www.domain.com/feed.xml (absolute)
 
1497
    $http=2, feed://www.domain.com/feed.xml (absolute)
 
1498
    $http=3, podcast://www.domain.com/feed.xml (absolute)
 
1499
    ****************************************************/
 
1500
    function fix_protocol($mp_feed_proto, $http = 1) {
 
1501
        $url = $mp_feed_proto;
 
1502
 
 
1503
        $url = preg_replace('/feed:(\/\/)?(http:\/\/)?/i', 'http://', $url);
 
1504
        $url = preg_replace('/(feed:)?(\/\/)?https:\/\//i', 'https://', $url);
 
1505
        $url = preg_replace('/p(od)?cast:(\/\/)?(http:\/\/)?/i', 'http://', $url);
 
1506
        $url = preg_replace('/(p(od)?cast:)?(\/\/)?https:\/\//i', 'https://', $url);
 
1507
        if (!stristr($url, 'http://') && !stristr($url, 'https://') && !file_exists($url)) $url = "http://$url";
 
1508
 
 
1509
        if ($http == 1) return $url;
 
1510
        else if ($http == 2) {
 
1511
            if (strstr($url, 'http://')) {
 
1512
                $url = substr_replace($url, 'feed', 0, 4);
 
1513
                return $url;
 
1514
            }
 
1515
            else return $url;
 
1516
        }
 
1517
        else if ($http == 3) {
 
1518
            if (strstr($url, 'http://')) {
 
1519
                $url = substr_replace($url, 'podcast', 0, 4);
 
1520
                return $url;
 
1521
            }
 
1522
            else return $url;
 
1523
        }
 
1524
    }
 
1525
 
 
1526
 
 
1527
 
 
1528
 
 
1529
    /****************************************************
 
1530
    ULTRA-LIBERAL FEED LOCATOR
 
1531
    Based upon http://diveintomark.org/archives/2002/08/15/ultraliberal_rss_locator
 
1532
    This function enables support for RSS auto-discovery-on-crack.
 
1533
    ****************************************************/
 
1534
    function rss_locator($data, $url) {
 
1535
 
 
1536
        $this->url = $url;
 
1537
        $this->parsed_url = parse_url($url);
 
1538
        if (!isset($this->parsed_url['path'])) {
 
1539
            $this->parsed_url['path'] = '/';
 
1540
        }
 
1541
 
 
1542
        // Check is the URL we're given is a feed
 
1543
        if ($this->is_feed($data, false)) {
 
1544
            return $url;
 
1545
        }
 
1546
 
 
1547
        // Feeds pointed to by LINK tags in the header of the page (autodiscovery)
 
1548
        $stage1 = $this->check_link_elements($data);
 
1549
        if ($stage1) {
 
1550
            return $stage1;
 
1551
        }
 
1552
 
 
1553
        // Grab all the links in the page, and put them into two arrays (local, and external)
 
1554
        if ($this->get_links($data)) {
 
1555
 
 
1556
            // <A> links to feeds on the same server ending in ".rss", ".rdf", ".xml", or ".atom"
 
1557
            $stage2 = $this->check_link_extension($this->local);
 
1558
            if ($stage2) {
 
1559
                return $stage2;
 
1560
            }
 
1561
 
 
1562
            // <A> links to feeds on the same server containing "rss", "rdf", "xml", or "atom"
 
1563
            $stage3 = $this->check_link_body($this->local);
 
1564
            if ($stage3) {
 
1565
                return $stage3;
 
1566
            }
 
1567
 
 
1568
            // <A> links to feeds on external servers ending in ".rss", ".rdf", ".xml", or ".atom"
 
1569
            $stage4 = $this->check_link_extension($this->elsewhere);
 
1570
            if ($stage4) {
 
1571
                return $stage4;
 
1572
            }
 
1573
 
 
1574
            // <A> links to feeds on external servers containing "rss", "rdf", "xml", or "atom"
 
1575
            $stage5 = $this->check_link_body($this->elsewhere);
 
1576
            if ($stage5) {
 
1577
                return $stage5;
 
1578
            }
 
1579
        }
 
1580
 
 
1581
        return false;
 
1582
    }
 
1583
 
 
1584
    function check_link_elements($data) {
 
1585
        if (preg_match_all('/<link (.*)>/siU', $data, $matches)) {
 
1586
            foreach($matches[1] as $match) {
 
1587
                if (preg_match('/type=[\'|"]?(application\/rss\+xml|application\/atom\+xml|application\/rdf\+xml|application\/xml\+rss|application\/xml\+atom|application\/xml\+rdf|application\/xml|application\/x\.atom\+xml|text\/xml)[\'|"]?/iU', $match, $type)) {
 
1588
                    $href = $this->get_attribute($match, 'href');
 
1589
                    if (!empty($href[1])) {
 
1590
                        $href = $this->absolutize_url($href[1], $this->parsed_url);
 
1591
                        if ($this->is_feed($href)) {
 
1592
                            return $href;
 
1593
                        }
 
1594
                    }
 
1595
                }
 
1596
            }
 
1597
        } else return false;
 
1598
    }
 
1599
 
 
1600
    function check_link_extension($array) {
 
1601
        foreach ($array as $value) {
 
1602
            $parsed = @parse_url($value);
 
1603
            if (isset($parsed['path'])) {
 
1604
                $ext = strtolower(pathinfo($parsed['path'], PATHINFO_EXTENSION));
 
1605
                if (($ext == 'rss' || $ext == 'rdf' || $ext == 'xml' || $ext == 'atom') && $this->is_feed($value)) {
 
1606
                    return $this->absolutize_url($value, $this->parsed_url);
 
1607
                }
 
1608
            }
 
1609
        }
 
1610
        return false;
 
1611
    }
 
1612
 
 
1613
    function check_link_body($array) {
 
1614
        foreach ($array as $value) {
 
1615
            $value2 = @parse_url($value);
 
1616
            if (!empty($value2['path'])) {
 
1617
                if (strlen(pathinfo($value2['path'], PATHINFO_EXTENSION)) > 0) {
 
1618
                    $value3 = substr_replace($value, '', strpos($value, $value2['path'])+strpos($value2['path'], pathinfo($value2['path'], PATHINFO_EXTENSION))-1, strlen(pathinfo($value2['path'], PATHINFO_EXTENSION))+1);
 
1619
                } else {
 
1620
                    $value3 = $value;
 
1621
                }
 
1622
                if ((stristr($value3, 'rss') || stristr($value3, 'rdf') || stristr($value3, 'xml') || stristr($value3, 'atom') || stristr($value3, 'feed')) && $this->is_feed($value)) {
 
1623
                    return $this->absolutize_url($value, $this->parsed_url);
 
1624
                }
 
1625
            }
 
1626
        }
 
1627
        return false;
 
1628
    }
 
1629
 
 
1630
    function get_links($data) {
 
1631
        if (preg_match_all('/href="(.*)"/iU', $data, $matches)) {
 
1632
            $this->parse_links($matches);
 
1633
        }
 
1634
        if (preg_match_all('/href=\'(.*)\'/iU', $data, $matches)) {
 
1635
            $this->parse_links($matches);
 
1636
        }
 
1637
        if (preg_match_all('/href=(.*)[ |\/|>]/iU', $data, $matches)) {
 
1638
            foreach ($matches[1] as $key => $value) {
 
1639
                if (substr($value, 0, 1) == '"' || substr($value, 0, 1) == "'") {
 
1640
                    unset($matches[1][$key]);
 
1641
                }
 
1642
            }
 
1643
            $this->parse_links($matches);
 
1644
        }
 
1645
        if (!empty($this->local) || !empty($this->elsewhere)) {
 
1646
            $this->local = array_unique($this->local);
 
1647
            $this->elsewhere = array_unique($this->elsewhere);
 
1648
            return true;
 
1649
        } else return false;
 
1650
    }
 
1651
 
 
1652
    function parse_links($matches) {
 
1653
        foreach ($matches[1] as $match) {
 
1654
            if (strtolower(substr($match, 0, 11)) != 'javascript:') {
 
1655
                $parsed = @parse_url($match);
 
1656
                if (!isset($parsed['host']) || $parsed['host'] == $this->parsed_url['host']) {
 
1657
                    $this->local[] = $this->absolutize_url($match, $this->parsed_url);
 
1658
                } else {
 
1659
                    $this->elsewhere[] = $this->absolutize_url($match, $this->parsed_url);
 
1660
                }
 
1661
            }
 
1662
        }
 
1663
    }
 
1664
 
 
1665
    function is_feed($data, $is_url = true) {
 
1666
        if ($is_url) {
 
1667
            $data = $this->get_file($data);
 
1668
        }
 
1669
        if (stristr($data, '<!DOCTYPE HTML')) {
 
1670
            return false;
 
1671
        }
 
1672
        else if (stristr($data, '<rss') || stristr($data, '<rdf:RDF') || preg_match('/<([a-z0-9]+\:)?feed/mi', $data)) {
 
1673
            return true;
 
1674
        } else {
 
1675
            return false;
 
1676
        }
 
1677
    }
 
1678
 
 
1679
    function absolutize_url($href, $location) {
 
1680
        @$href_parts = parse_url($href);
 
1681
        if (!empty($href_parts['scheme'])) {
 
1682
            return $href;
 
1683
        } else {
 
1684
            if (isset($location['host'])) {
 
1685
                $full_url = $location['scheme'] . '://' . $location['host'];
 
1686
            } else {
 
1687
                $full_url = '';
 
1688
            }
 
1689
            if (isset($location['port'])) {
 
1690
                $full_url .= ':' . $location['port'];
 
1691
            }
 
1692
            if (!empty($href_parts['path'])) {
 
1693
                if (substr($href_parts['path'], 0, 1) == '/') {
 
1694
                    $full_url .= $href_parts['path'];
 
1695
                } else if (!empty($location['path'])) {
 
1696
                    $full_url .= dirname($location['path'] . 'a') . '/' . $href_parts['path'];
 
1697
                } else {
 
1698
                    $full_url .= $href_parts['path'];
 
1699
                }
 
1700
            } else if (!empty($location['path'])) {
 
1701
                $full_url .= $location['path'];
 
1702
            } else {
 
1703
                $full_url .= '/';
 
1704
            }
 
1705
            if (!empty($href_parts['query'])) {
 
1706
                $full_url .= '?' . $href_parts['query'];
 
1707
            } else if (!empty($location['query'])) {
 
1708
                $full_url .= '?' . $location['query'];
 
1709
            }
 
1710
            if (!empty($href_parts['fragment'])) {
 
1711
                $full_url .= '#' . $href_parts['fragment'];
 
1712
            } else if (!empty($location['fragment'])) {
 
1713
                $full_url .= '#' . $location['fragment'];
 
1714
            }
 
1715
            return $full_url;
 
1716
        }
 
1717
    }
 
1718
 
 
1719
 
 
1720
 
 
1721
 
 
1722
    /****************************************************
 
1723
    DISPLAY IMAGES
 
1724
    Some websites have a setting that blocks images from being loaded
 
1725
    into other pages.  This gets around those blocks by spoofing the referrer.
 
1726
    ****************************************************/
 
1727
    function display_image($image_url) {
 
1728
        $image = $this->get_file(urldecode($image_url));
 
1729
        $suffix = pathinfo($image_url, PATHINFO_EXTENSION);
 
1730
 
 
1731
        switch($suffix) {
 
1732
            case 'bmp':
 
1733
                $mime='image/bmp';
 
1734
                break;
 
1735
            case 'gif':
 
1736
                $mime='image/gif';
 
1737
                break;
 
1738
            case 'ico':
 
1739
                $mime='image/icon';
 
1740
                break;
 
1741
            case 'jpe':
 
1742
            case 'jpg':
 
1743
            case 'jpeg':
 
1744
                $mime='image/jpeg';
 
1745
                break;
 
1746
            case 'jfif':
 
1747
                $mime='image/pipeg';
 
1748
                break;
 
1749
            case 'png':
 
1750
                $mime='image/png';
 
1751
                break;
 
1752
            case 'tif':
 
1753
            case 'tiff':
 
1754
                $mime='image/tiff';
 
1755
                break;
 
1756
            default:
 
1757
                $mime='image';
 
1758
        }
 
1759
 
 
1760
        header('Content-type: ' . $mime);
 
1761
        echo $image;
 
1762
        //echo $image_url;
 
1763
        exit;
 
1764
    }
 
1765
 
 
1766
 
 
1767
 
 
1768
 
 
1769
    /****************************************************
 
1770
    DELETE OUTDATED CACHE FILES
 
1771
    Copyright 2004 by "adam at roomvoter dot com". This material
 
1772
    may be distributed only subject to the terms and conditions set
 
1773
    forth in the Open Publication License, v1.0 or later (the latest
 
1774
    version is presently available at http://www.opencontent.org/openpub/).
 
1775
    This function deletes cache files that have not been used in a hour.
 
1776
    ****************************************************/
 
1777
    function clear_cache($path, $max_minutes=60) {
 
1778
        if (is_dir($path) ) {
 
1779
            $handle = opendir($path);
 
1780
            while (false !== ($file = readdir($handle))) {
 
1781
                if ($file != '.' && $file != '..' && pathinfo($file, PATHINFO_EXTENSION) == 'spc') {
 
1782
                    $diff = (time() - filemtime("$path/$file"))/60;
 
1783
                    if ($diff > $max_minutes) unlink("$path/$file");
 
1784
                }
 
1785
            }
 
1786
            closedir($handle);
 
1787
        }
 
1788
    }
 
1789
 
 
1790
 
 
1791
 
 
1792
 
 
1793
    /****************************************************
 
1794
    OPENS A FILE, WITH EITHER FOPEN OR CURL
 
1795
    ****************************************************/
 
1796
    function get_file($url) {
 
1797
        if (substr($url, 0, 7) == 'http://' && extension_loaded('curl')) {
 
1798
            $gch = curl_init();
 
1799
            curl_setopt ($gch, CURLOPT_URL, $url);
 
1800
            curl_setopt ($gch, CURLOPT_HEADER, 0);
 
1801
            curl_setopt ($gch, CURLOPT_FOLLOWLOCATION, 1);
 
1802
            curl_setopt ($gch, CURLOPT_TIMEOUT, 10);
 
1803
            curl_setopt ($gch, CURLOPT_RETURNTRANSFER, 1);
 
1804
            curl_setopt ($gch, CURLOPT_REFERER, $url);
 
1805
            curl_setopt ($gch, CURLOPT_USERAGENT, $this->useragent);
 
1806
            $data = curl_exec ($gch);
 
1807
            curl_close ($gch);
 
1808
        } else {
 
1809
            $old_ua = ini_get('user_agent');
 
1810
            ini_set('user_agent', $this->useragent);
 
1811
            if ($fp = fopen($url, 'r')) {
 
1812
                stream_set_blocking($fp, false);
 
1813
                stream_set_timeout($fp, 10);
 
1814
                $status = socket_get_status($fp);
 
1815
                $data = '';
 
1816
                while (!feof($fp) && !$status['timed_out']) {
 
1817
                    $data .= fread($fp, 2048);
 
1818
                    $status = socket_get_status($fp);
 
1819
                }
 
1820
                if ($status['timed_out'])
 
1821
                    return false;
 
1822
                fclose($fp);
 
1823
            } else return false;
 
1824
            ini_set('user_agent', $old_ua);
 
1825
        }
 
1826
        return $data;
 
1827
    }
 
1828
 
 
1829
 
 
1830
 
 
1831
 
 
1832
    /****************************************************
 
1833
    CHECKS IF A FILE IS WRITEABLE, OR CREATEABLE
 
1834
    ****************************************************/
 
1835
    function is_writeable_createable($file) {
 
1836
        if (file_exists($file))
 
1837
            return is_writeable($file);
 
1838
        else
 
1839
            return is_writeable(dirname($file));
 
1840
    }
 
1841
 
 
1842
 
 
1843
 
 
1844
 
 
1845
    /****************************************************
 
1846
    GET ATTRIBUTE
 
1847
    ****************************************************/
 
1848
    function get_attribute($data, $attribute_name) {
 
1849
        if (preg_match("/$attribute_name='(.*)'/iU", $data, $match)) {
 
1850
            return $match;
 
1851
        } else if (preg_match("/$attribute_name=\"(.*)\"/iU", $data, $match)) {
 
1852
            return $match;
 
1853
        } else if (preg_match("/$attribute_name=(.*)[ |\/|>]/iU", $data, $match)) {
 
1854
            return $match;
 
1855
        }
 
1856
    }
 
1857
 
 
1858
 
 
1859
 
 
1860
 
 
1861
    /****************************************************
 
1862
    CALLBACK FUNCTION TO DEAL WITH CDATA WITHIN CDATA
 
1863
    ****************************************************/
 
1864
    function cdata_in_cdata($match) {
 
1865
        $match[3] = preg_replace_callback('/<!\[CDATA\[(.*)\]\]>/msiU', array(&$this, 'real_cdata_in_cdata'), $match[3]);
 
1866
        return "<$match[1]$match[2]><![CDATA[$match[3]]]></$match[1]>";
 
1867
    }
 
1868
 
 
1869
 
 
1870
 
 
1871
 
 
1872
    /****************************************************
 
1873
    CALLBACK FUNCTION TO REALLY DEAL WITH CDATA WITHIN CDATA
 
1874
    ****************************************************/
 
1875
    function real_cdata_in_cdata($match) {
 
1876
        return htmlentities($match[1], ENT_NOQUOTES, $this->encoding);
 
1877
    }
 
1878
 
 
1879
 
 
1880
 
 
1881
 
 
1882
    /****************************************************
 
1883
    ADD DATA TO XMLDATA
 
1884
    ****************************************************/
 
1885
    function do_add_content(&$array, $data) {
 
1886
        if ($this->is_first) {
 
1887
            $array['data'] = $data;
 
1888
            $array['attribs'] = $this->attribs;
 
1889
        } else $array['data'] .= $data;
 
1890
    }
 
1891
 
 
1892
 
 
1893
 
 
1894
 
 
1895
    /****************************************************
 
1896
    PARSE XMLDATA
 
1897
    ****************************************************/
 
1898
    function parse_xml_data_array() {
 
1899
        // Feed level xml:base
 
1900
        if (!empty($this->xmldata['feeddata']['attribs']['XML:BASE'])) {
 
1901
            $this->feed_xmlbase = parse_url($this->xmldata['feeddata']['attribs']['XML:BASE']);
 
1902
        }
 
1903
        else if (!empty($this->xmldata['feeddata']['attribs'][$this->namespaces['xml'] . ':BASE'])) {
 
1904
            $this->feed_xmlbase = parse_url($this->xmldata['feeddata']['attribs'][$this->namespaces['xml'] . ':BASE']);
 
1905
        }
 
1906
        else if (substr($this->rss_url, 0, 28) == 'http://feeds.feedburner.com/' && !empty($this->xmldata['info']['link'][0]['data'])) {
 
1907
            $this->feed_xmlbase = parse_url($this->xmldata['info']['link'][0]['data']);
 
1908
        } else {
 
1909
            $this->feed_xmlbase = $this->parsed_url;
 
1910
        }
 
1911
 
 
1912
        // Feed Info
 
1913
        if (isset($this->xmldata['feedinfo']['type'])) {
 
1914
            $this->data['feedinfo'] = $this->xmldata['feedinfo'];
 
1915
        }
 
1916
 
 
1917
        // Feed Title
 
1918
        if (!empty($this->xmldata['info']['title']['data'])) {
 
1919
            $this->data['info']['title'] = $this->sanitise($this->xmldata['info']['title']['data'], $this->xmldata['info']['title']['attribs']);
 
1920
        }
 
1921
 
 
1922
        // Feed Link(s)
 
1923
        if (!empty($this->xmldata['info']['link'])) {
 
1924
            foreach ($this->xmldata['info']['link'] as $num => $link) {
 
1925
                if (empty($link['attribs']['REL']) || $link['attribs']['REL'] == 'alternate') {
 
1926
                    if (empty($link['data'])) {
 
1927
                        $this->data['info']['link'][$num] = $this->sanitise($link['attribs']['HREF'], $link['attribs'], true);
 
1928
                    } else {
 
1929
                        $this->data['info']['link'][$num] = $this->sanitise($link['data'], $link['attribs'], true);
 
1930
                    }
 
1931
                }
 
1932
            }
 
1933
        }
 
1934
 
 
1935
        // Feed Description
 
1936
        if (!empty($this->xmldata['info']['description']['data'])) {
 
1937
            $this->data['info']['description'] = $this->sanitise($this->xmldata['info']['description']['data'], $this->xmldata['info']['description']['attribs']);
 
1938
        }
 
1939
        else if (!empty($this->xmldata['info']['dc:description']['data'])) {
 
1940
            $this->data['info']['description'] = $this->sanitise($this->xmldata['info']['dc:description']['data'], $this->xmldata['info']['dc:description']['attribs']);
 
1941
        }
 
1942
        else if (!empty($this->xmldata['info']['tagline']['data'])) {
 
1943
            $this->data['info']['description'] = $this->sanitise($this->xmldata['info']['tagline']['data'], $this->xmldata['info']['tagline']['attribs']);
 
1944
        }
 
1945
        else if (!empty($this->xmldata['info']['subtitle']['data'])) {
 
1946
            $this->data['info']['description'] = $this->sanitise($this->xmldata['info']['subtitle']['data'], $this->xmldata['info']['subtitle']['attribs']);
 
1947
        }
 
1948
 
 
1949
        // Feed Language
 
1950
        if (!empty($this->xmldata['info']['language']['data'])) {
 
1951
            $this->data['info']['language'] = $this->sanitise($this->xmldata['info']['language']['data'], $this->xmldata['info']['language']['attribs']);
 
1952
        }
 
1953
 
 
1954
        // Feed Copyright
 
1955
        if (!empty($this->xmldata['info']['copyright']['data'])) {
 
1956
            $this->data['info']['copyright'] = $this->sanitise($this->xmldata['info']['copyright']['data'], $this->xmldata['info']['copyright']['attribs']);
 
1957
        }
 
1958
 
 
1959
        // Feed Image
 
1960
        if (!empty($this->xmldata['info']['image']['title']['data'])) {
 
1961
            $this->data['info']['image']['title'] = $this->sanitise($this->xmldata['info']['image']['title']['data'], $this->xmldata['info']['image']['title']['attribs']);
 
1962
        }
 
1963
        if (!empty($this->xmldata['info']['image']['url']['data'])) {
 
1964
            $this->data['info']['image']['url'] = $this->sanitise($this->xmldata['info']['image']['url']['data'], $this->xmldata['info']['image']['url']['attribs'], true);
 
1965
        }
 
1966
        else if (!empty($this->xmldata['info']['logo']['data'])) {
 
1967
            $this->data['info']['image']['url'] = $this->sanitise($this->xmldata['info']['logo']['data'], $this->xmldata['info']['logo']['attribs'], true);
 
1968
        }
 
1969
        if (!empty($this->xmldata['info']['image']['link']['data'])) {
 
1970
            $this->data['info']['image']['link'] = $this->sanitise($this->xmldata['info']['image']['link']['data'], $this->xmldata['info']['image']['link']['attribs'], true);
 
1971
        }
 
1972
        if (!empty($this->xmldata['info']['image']['width']['data'])) {
 
1973
            $this->data['info']['image']['width'] = $this->sanitise($this->xmldata['info']['image']['width']['data'], $this->xmldata['info']['image']['width']['attribs']);
 
1974
        }
 
1975
        if (!empty($this->xmldata['info']['image']['height']['data'])) {
 
1976
            $this->data['info']['image']['height'] = $this->sanitise($this->xmldata['info']['image']['height']['data'], $this->xmldata['info']['image']['height']['attribs']);
 
1977
        }
 
1978
 
 
1979
        // Items
 
1980
        if (!empty($this->xmldata['items'])) {
 
1981
            foreach ($this->xmldata['items'] as $num => $item) {
 
1982
                // Item level xml:base
 
1983
                if (!empty($item['attribs']['XML:BASE'])) {
 
1984
                    $this->item_xmlbase = parse_url($this->absolutize_url($item['attribs']['XML:BASE'], $this->feed_xmlbase));
 
1985
                }
 
1986
                else if (!empty($item['attribs'][$this->namespaces['xml'] . ':BASE'])) {
 
1987
                    $this->item_xmlbase = parse_url($this->absolutize_url($item['attribs'][$this->namespaces['xml'] . ':BASE'], $this->feed_xmlbase));
 
1988
                }
 
1989
 
 
1990
                // Clear vars
 
1991
                $id = null;
 
1992
                $title = null;
 
1993
                $description = null;
 
1994
                $categories = array();
 
1995
                $author = array();
 
1996
                $date = null;
 
1997
                $links = array();
 
1998
                $enclosures = array();
 
1999
 
 
2000
                // Title
 
2001
                if (!empty($item['title']['data'])) {
 
2002
                    $title = $this->sanitise($item['title']['data'], $item['title']['attribs']);
 
2003
                }
 
2004
                else if (!empty($item['dc:title']['data'])) {
 
2005
                    $title = $this->sanitise($item['dc:title']['data'], $item['dc:title']['attribs']);
 
2006
                }
 
2007
 
 
2008
                // Description
 
2009
                if (!empty($item['content']['data'])) {
 
2010
                    $description = $this->sanitise($item['content']['data'], $item['content']['attribs']);
 
2011
                }
 
2012
                else if (!empty($item['encoded']['data'])) {
 
2013
                    $description = $this->sanitise($item['encoded']['data'], $item['encoded']['attribs']);
 
2014
                }
 
2015
                else if (!empty($item['summary']['data'])) {
 
2016
                    $description = $this->sanitise($item['summary']['data'], $item['summary']['attribs']);
 
2017
                }
 
2018
                else if (!empty($item['description']['data'])) {
 
2019
                    $description = $this->sanitise($item['description']['data'], $item['description']['attribs']);
 
2020
                }
 
2021
                else if (!empty($item['dc:description']['data'])) {
 
2022
                    $description = $this->sanitise($item['dc:description']['data'], $item['dc:description']['attribs']);
 
2023
                }
 
2024
                else if (!empty($item['longdesc']['data'])) {
 
2025
                    $description = $this->sanitise($item['longdesc']['data'], $item['longdesc']['attribs']);
 
2026
                }
 
2027
 
 
2028
                // Link
 
2029
                if (!empty($item['link'])) {
 
2030
                    foreach ($item['link'] as $link) {
 
2031
                        if (empty($link['attribs']['REL']) || $link['attribs']['REL'] == 'alternate') {
 
2032
                            if (empty($link['data'])) {
 
2033
                                $links[sizeof($links)] = $this->sanitise($link['attribs']['HREF'], $link['attribs'], true);
 
2034
                            } else {
 
2035
                                $links[sizeof($links)] = $this->sanitise($link['data'], $link['attribs'], true);
 
2036
                            }
 
2037
                        } else if ($link['attribs']['REL'] == 'enclosure' && !empty($link['attribs']['HREF'])) {
 
2038
                            $href = null;
 
2039
                            $type = null;
 
2040
                            $length = null;
 
2041
                            $href = $this->sanitise($link['attribs']['HREF'], $link['attribs'], true);
 
2042
                            if (!empty($link['attribs']['TYPE'])) {
 
2043
                                $type = $this->sanitise($link['attribs']['TYPE'], $link['attribs']);
 
2044
                            }
 
2045
                            if (!empty($link['attribs']['LENGTH'])) {
 
2046
                                $length = $this->sanitise($link['attribs']['LENGTH'], $link['attribs']);
 
2047
                            }
 
2048
                            $enclosures[] = new SimplePie_Enclosure($href, $type, $length);
 
2049
                        }
 
2050
                    }
 
2051
                }
 
2052
 
 
2053
                // Enclosures
 
2054
                if (!empty($item['enclosure'])) {
 
2055
                    foreach ($item['enclosure'] as $enclosure) {
 
2056
                        if (!empty($enclosure['attribs']['URL'])) {
 
2057
                            $href = null;
 
2058
                            $type = null;
 
2059
                            $length = null;
 
2060
                            $href = $this->sanitise($enclosure['attribs']['URL'], $enclosure['attribs'], true);
 
2061
                            if (!empty($enclosure['attribs']['TYPE'])) {
 
2062
                                $type = $this->sanitise($enclosure['attribs']['TYPE'], $enclosure['attribs']);
 
2063
                            }
 
2064
                            if (!empty($enclosure['attribs']['LENGTH'])) {
 
2065
                                $length = $this->sanitise($enclosure['attribs']['LENGTH'], $enclosure['attribs']);
 
2066
                            }
 
2067
                            $enclosures[] = new SimplePie_Enclosure($href, $type, $length);
 
2068
                        }
 
2069
                    }
 
2070
                }
 
2071
 
 
2072
                // ID
 
2073
                if (!empty($item['guid']['data'])) {
 
2074
                    if (empty($item['guid']['attribs']['ISPERMALINK']) || strtolower($item['guid']['attribs']['ISPERMALINK']) != 'false') {
 
2075
                        $links[sizeof($links)] = $this->sanitise($item['guid']['data'], $item['guid']['attribs']);
 
2076
                    }
 
2077
                    $id = $this->sanitise($item['guid']['data'], $item['guid']['attribs']);
 
2078
                }
 
2079
                else if (!empty($item['id']['data'])) {
 
2080
                    $id = $this->sanitise($item['id']['data'], $item['id']['attribs']);
 
2081
                }
 
2082
 
 
2083
                // Date
 
2084
                if (!empty($item['pubdate']['data'])) {
 
2085
                    $date = $this->parse_date($this->sanitise($item['pubdate']['data'], $item['pubdate']['attribs']));
 
2086
                }
 
2087
                else if (!empty($item['dc:date']['data'])) {
 
2088
                    $date = $this->parse_date($this->sanitise($item['dc:date']['data'], $item['dc:date']['attribs']));
 
2089
                }
 
2090
                else if (!empty($item['issued']['data'])) {
 
2091
                    $date = $this->parse_date($this->sanitise($item['issued']['data'], $item['issued']['attribs']));
 
2092
                }
 
2093
                else if (!empty($item['published']['data'])) {
 
2094
                    $date = $this->parse_date($this->sanitise($item['published']['data'], $item['published']['attribs']));
 
2095
                }
 
2096
                else if (!empty($item['modified']['data'])) {
 
2097
                    $date = $this->parse_date($this->sanitise($item['modified']['data'], $item['modified']['attribs']));
 
2098
                }
 
2099
                else if (!empty($item['updated']['data'])) {
 
2100
                    $date = $this->parse_date($this->sanitise($item['updated']['data'], $item['updated']['attribs']));
 
2101
                }
 
2102
 
 
2103
                // Categories
 
2104
                if (!empty($item['category'])) {
 
2105
                    foreach ($item['category'] as $category) {
 
2106
                        $categories[sizeof($categories)] = $this->sanitise($category['data'], $category['attribs']);
 
2107
                    }
 
2108
                }
 
2109
                if (!empty($item['subject'])) {
 
2110
                    foreach ($item['subject'] as $category) {
 
2111
                        $categories[sizeof($categories)] = $this->sanitise($category['data'], $category['attribs']);
 
2112
                    }
 
2113
                }
 
2114
 
 
2115
                // Author
 
2116
                $authors = array();
 
2117
                if (!empty($item['creator'])) {
 
2118
                    foreach($item['creator'] as $creator) {
 
2119
                        $authors[] = new SimplePie_Author($this->sanitise($creator['data'], $creator['attribs']), null, null);
 
2120
                    }
 
2121
                }
 
2122
                if (!empty($item['author'])) {
 
2123
                    foreach($item['author'] as $author) {
 
2124
                        $name = null;
 
2125
                        $link = null;
 
2126
                        $email = null;
 
2127
                        if (!empty($author['name'])) {
 
2128
                            $name = $this->sanitise($author['name']['data'], $author['name']['attribs']);
 
2129
                        }
 
2130
                        if (!empty($author['url'])) {
 
2131
                            $link = $this->sanitise($author['url']['data'], $author['url']['attribs'], true);
 
2132
                        }
 
2133
                        else if (!empty($author['uri'])) {
 
2134
                            $link = $this->sanitise($author['uri']['data'], $author['uri']['attribs'], true);
 
2135
                        }
 
2136
                        else if (!empty($author['homepage'])) {
 
2137
                            $link = $this->sanitise($author['homepage']['data'], $author['homepage']['attribs'], true);
 
2138
                        }
 
2139
                        if (!empty($author['email'])) {
 
2140
                            $email = $this->sanitise($author['email']['data'], $author['email']['attribs']);
 
2141
                        }
 
2142
                        if (!empty($author['rss'])) {
 
2143
                            $sane = $this->sanitise($author['rss']['data'], $author['rss']['attribs']);
 
2144
                            if (preg_match('/(.*)@(.*) \((.*)\)/msiU', $sane, $matches)) {
 
2145
                                $name = trim($matches[3]);
 
2146
                                $email = trim("$matches[1]@$matches[2]");
 
2147
                            } else {
 
2148
                                $email = $sane;
 
2149
                            }
 
2150
                        }
 
2151
                        $authors[] = new SimplePie_Author($name, $link, $email);
 
2152
                    }
 
2153
                }
 
2154
                $this->data['items'][] = new SimplePie_Item($id, $title, $description, array_unique($categories), array_unique($authors), $date, array_unique($links), array_unique($enclosures));
 
2155
            } // End Items
 
2156
        }
 
2157
        unset($this->xmldata);
 
2158
    } // End parse_xml_data_array();
 
2159
 
 
2160
    function sanitise($data, $attribs, $is_url = false) {
 
2161
        $this->attribs = $attribs;
 
2162
        if (isset($this->data['feedinfo']['type']) && $this->data['feedinfo']['type'] == 'Atom') {
 
2163
            if (!empty($attribs['MODE']) && $attribs['MODE'] == 'base64') {
 
2164
                $data = base64_decode($data);
 
2165
            } else if ((!empty($attribs['MODE']) && $attribs['MODE'] == 'escaped' || !empty($attribs['TYPE']) && ($attribs['TYPE'] == 'html' || $attribs['TYPE'] == 'text/html')) && (empty($attribs['SPENCODED']) || $attribs['SPENCODED'] != 'false')) {
 
2166
                $data = $this->entities_decode($data);
 
2167
            }
 
2168
            if (!empty($attribs['TYPE']) && ($attribs['TYPE'] == 'xhtml' || $attribs['TYPE'] == 'application/xhtml+xml')) {
 
2169
                if ($this->remove_div) {
 
2170
                    $data = preg_replace('/<div( .*)?>/msiU', '', strrev(preg_replace('/>vid\/</i', '', strrev($data), 1)), 1);
 
2171
                } else {
 
2172
                    $data = preg_replace('/<div( .*)?>/msiU', '<div>', $data, 1);
 
2173
                }
 
2174
                $data = preg_replace("/<(\/)?$this->xhtml_prefix:/msiU", '<\\1', $data);
 
2175
            }
 
2176
        } else {
 
2177
            if (empty($attribs['SPENCODED']) || $attribs['SPENCODED'] != 'false') {
 
2178
                $data = $this->entities_decode($data);
 
2179
            }
 
2180
        }
 
2181
        $data = trim($data);
 
2182
        $data = str_replace(' spencoded="false">', '>', $data);
 
2183
 
 
2184
        // Strip out HTML tags and attributes that might cause various security problems.
 
2185
        // Based on recommendations by Mark Pilgrim at:
 
2186
        // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
 
2187
        if ($this->strip_htmltags) {
 
2188
            $tags_to_strip = explode(',', $this->strip_htmltags);
 
2189
            foreach ($tags_to_strip as $tag) {
 
2190
                if ($this->encode_instead_of_strip) {
 
2191
                    // For encoded angled brackets (do these first)
 
2192
                    $data = preg_replace('/&lt;(!)?(\/)?'. trim($tag) .'(\w|\s|=|-|"|\'|&quot;|:|;|%|\/|\.|\?|&|,|#|!|\+|\(|\))*&gt;/i', '&amp;lt;\\0&amp;gt;', $data);
 
2193
                    $data = str_replace('&amp;lt;&lt;', '&amp;lt;', $data);
 
2194
                    $data = str_replace('&gt;&amp;gt;', '&amp;gt;', $data);
 
2195
 
 
2196
                    // For angled brackets
 
2197
                    $data = preg_replace('/<(!)?(\/)?'. trim($tag) .'(\w|\s|=|-|"|\'|&quot;|:|;|%|\/|\.|\?|&|,|#|!|\+|\(|\))*>/i', '&lt;\\0&gt;', $data);
 
2198
                    $data = str_replace('&lt;<', '&lt;', $data);
 
2199
                    $data = str_replace('>&gt;', '&gt;', $data);
 
2200
                }
 
2201
                else {
 
2202
                    $data = preg_replace('/(&lt;|<)(!)?(\/)?'. trim($tag) .'(\w|\s|=|-|"|\'|&quot;|:|;|%|\/|\.|\?|&|,|#|!|\+|\(|\))*(&gt;|>)/i', '', $data);
 
2203
                }
 
2204
            }
 
2205
        }
 
2206
 
 
2207
        if ($this->strip_attributes) {
 
2208
            $attribs_to_strip = explode(',', $this->strip_attributes);
 
2209
            foreach ($attribs_to_strip as $attrib) {
 
2210
                $data = preg_replace('/ '. trim($attrib) .'=(\'|&apos;|"|&quot;)?(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|\'|&apos;|<|>|\+|{|})*(\'|&apos;|"|&quot;)?/i', '', $data);
 
2211
            }
 
2212
        }
 
2213
 
 
2214
        // Replace H1, H2, and H3 tags with the less important H4 tags.
 
2215
        // This is because on a site, the more important headers might make sense,
 
2216
        // but it most likely doesn't fit in the context of RSS-in-a-webpage.
 
2217
        if ($this->replace_headers) {
 
2218
            $data = preg_replace('/<h[1-3]( .*)?>/msiU', '<h4>', $data);
 
2219
            $data = preg_replace('/<\/h[1-3]>/i', '</h4>', $data);
 
2220
        }
 
2221
 
 
2222
        // If Strip Ads is enabled, strip them.
 
2223
        if ($this->strip_ads) {
 
2224
            $data = preg_replace('/(&lt;|<)a(.*)href=(&quot;|")(.*)\\/\/(www\.)?pheedo.com\/(.*).phdo\?s=(.*)(&gt;|>)(\s*|.*)((&lt;|<).*(&gt;|>)|.*)(\s*|.*)(&lt;|<)\/a(&gt;|>)/i', '', $data); // Pheedo links (tested with Dooce.com)
 
2225
            $data = preg_replace('/(&lt;|<)a(\w|\s|\=|&quot;|")*href=(&quot;|")http:\/\/ad.doubleclick.net\/(.*)(&gt;|>)(\s*|.*)((&lt;|<).*(&gt;|>)|.*)(\s*|.*)(&lt;|<)\/a(&gt;|>)/i', '', $data); // Doubleclick links (tested with InfoWorld.com)
 
2226
            $data = preg_replace('/(&lt;|<)map(\w|\s|=|-|"|\'|&quot;)*name=(&quot;|\'|")google_ad_map(\w|\s|=|-)*(&quot;|\'|")(\w|\s|=|-|"|\'|&quot;)*(^gt;|>)(.*)(&lt;|<)\/map(&gt;|>)(&lt;|<)img(\w|\s|=|-|"|\'|&quot;)*usemap=(&quot;|\'|")#google_ad_map(\w|\s|=|-)*(&quot;|\'|")(\w|\s|=|-|"|\'|&quot;|:|;|\/|\.|\?|&)*(&gt;|>)/i', '', $data); // Google AdSense for Feeds (tested with tuaw.com).
 
2227
            // Feedflare, from Feedburner
 
2228
        }
 
2229
 
 
2230
        if ($is_url) {
 
2231
            $data = $this->replace_urls($data, true);
 
2232
        } else {
 
2233
            $data = preg_replace_callback('/<(.+)>/msiU', array(&$this, 'replace_urls'), $data);
 
2234
        }
 
2235
 
 
2236
        // If Bypass Image Hotlink is enabled, rewrite all the image tags.
 
2237
        if ($this->bypass_image_hotlink != false) {
 
2238
            $data = preg_replace_callback('/src=(&quot;|"|\'|&apos;)?(\w|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|\'|&apos;)*(&quot;|"|\'|&apos;)?/', create_function('$m', 'return "src=\"".rawurlencode(str_replace("\"", "", str_replace("src=", "", html_entity_decode($m[0]))))."\"";'), $data);
 
2239
 
 
2240
            if ($this->bypass_image_hotlink_page != false) {
 
2241
                $data = preg_replace('/<img(\w|\s|=|-|"|\'|&quot;|:|;|\/|\.|\?|&|,|#|!)*src=(&quot;|"|\')?/i', '\\0'.$this->bypass_image_hotlink_page.'?i=', $data);
 
2242
            }
 
2243
            else $data = preg_replace('/<img(\w|\s|=|-|"|\'|&quot;|:|;|\/|\.|\?|&|,|#|!)*src=(&quot;|"|\')?/i', '\\0?i=', $data);
 
2244
        }
 
2245
 
 
2246
        return $data;
 
2247
    }
 
2248
 
 
2249
    function replace_urls($data, $raw_url = false) {
 
2250
        if (!empty($this->attribs['XML:BASE'])) {
 
2251
            if (!empty($this->item_xmlbase)) {
 
2252
                $attrib_xmlbase = parse_url($this->absolutize_url($this->attribs['XML:BASE'], $this->item_xmlbase));
 
2253
            } else {
 
2254
                $attrib_xmlbase = parse_url($this->absolutize_url($this->attribs['XML:BASE'], $this->feed_xmlbase));
 
2255
            }
 
2256
        }
 
2257
        else if (!empty($this->attribs[$this->namespaces['xml'] . ':BASE'])) {
 
2258
            if (!empty($this->item_xmlbase)) {
 
2259
                $attrib_xmlbase = parse_url($this->absolutize_url($this->attribs[$this->namespaces['xml'] . ':BASE'], $this->item_xmlbase));
 
2260
            } else {
 
2261
                $attrib_xmlbase = parse_url($this->absolutize_url($this->attribs[$this->namespaces['xml'] . ':BASE'], $this->feed_xmlbase));
 
2262
            }
 
2263
        }
 
2264
        if (!empty($attrib_xmlbase)) {
 
2265
            $xmlbase = $attrib_xmlbase;
 
2266
        } else if (!empty($this->item_xmlbase)) {
 
2267
            $xmlbase = $this->item_xmlbase;
 
2268
        } else {
 
2269
            $xmlbase = $this->feed_xmlbase;
 
2270
        }
 
2271
        if ($raw_url) {
 
2272
            return $this->absolutize_url($data, $xmlbase);
 
2273
        } else {
 
2274
            $attributes = array(
 
2275
                'background',
 
2276
                'href',
 
2277
                'src',
 
2278
                'longdesc',
 
2279
                'usemap',
 
2280
                'codebase',
 
2281
                'data',
 
2282
                'classid',
 
2283
                'cite',
 
2284
                'action',
 
2285
                'profile',
 
2286
                'for'
 
2287
            );
 
2288
            foreach ($attributes as $attribute) {
 
2289
                $attrib = $this->get_attribute($data[0], $attribute);
 
2290
                $new_tag = str_replace($attrib[1], $this->absolutize_url($attrib[1], $xmlbase), $attrib[0]);
 
2291
                $data[0] = str_replace($attrib[0], $new_tag, $data[0]);
 
2292
            }
 
2293
            return $data[0];
 
2294
        }
 
2295
    }
 
2296
 
 
2297
    function entities_decode($data) {
 
2298
        return preg_replace_callback('/&(#)?(x)?([0-9a-z]+);/mi', array(&$this, 'do_entites_decode'), $data);
 
2299
    }
 
2300
 
 
2301
    function do_entites_decode($data)
 
2302
    {
 
2303
        $entity = "&$data[1]$data[2]$data[3];";
 
2304
        $entity_html = html_entity_decode($entity, ENT_QUOTES);
 
2305
        if ($entity == $entity_html) {
 
2306
            return preg_replace_callback('/&#([0-9a-fx]+);/mi', array(&$this, 'replace_num_entity'), $entity);
 
2307
        } else {
 
2308
            return $entity_html;
 
2309
        }
 
2310
    }
 
2311
 
 
2312
    /*
 
2313
     * Escape numeric entities
 
2314
     * From a PHP Manual note (on html_entity_decode())
 
2315
     * Copyright (c) 2005 by "php dot net at c dash ovidiu dot tk",
 
2316
     * "emilianomartinezluque at yahoo dot com" and "hurricane at cyberworldz dot org".
 
2317
     *
 
2318
     * This material may be distributed only subject to the terms and conditions set forth in
 
2319
     * the Open Publication License, v1.0 or later (the latest version is presently available at
 
2320
     * http://www.opencontent.org/openpub/).
 
2321
     */
 
2322
    function replace_num_entity($ord) {
 
2323
        $ord = $ord[1];
 
2324
        if (preg_match('/^x([0-9a-f]+)$/i', $ord, $match))
 
2325
            $ord = hexdec($match[1]);
 
2326
        else
 
2327
            $ord = intval($ord);
 
2328
        $no_bytes = 0;
 
2329
        $byte = array();
 
2330
        if ($ord < 128)
 
2331
            return chr($ord);
 
2332
        if ($ord < 2048)
 
2333
            $no_bytes = 2;
 
2334
        else if ($ord < 65536)
 
2335
            $no_bytes = 3;
 
2336
        else if ($ord < 1114112)
 
2337
            $no_bytes = 4;
 
2338
        else return;
 
2339
        switch ($no_bytes) {
 
2340
            case 2:
 
2341
                $prefix = array(31, 192);
 
2342
                break;
 
2343
 
 
2344
            case 3:
 
2345
                $prefix = array(15, 224);
 
2346
                break;
 
2347
 
 
2348
            case 4:
 
2349
            $prefix = array(7, 240);
 
2350
            break;
 
2351
        }
 
2352
        for ($i=0; $i < $no_bytes; ++$i)
 
2353
            $byte[$no_bytes-$i-1] = (($ord & (63 * pow(2,6*$i))) / pow(2,6*$i)) & 63 | 128;
 
2354
        $byte[0] = ($byte[0] & $prefix[0]) | $prefix[1];
 
2355
        $ret = '';
 
2356
        for ($i=0; $i < $no_bytes; ++$i)
 
2357
            $ret .= chr($byte[$i]);
 
2358
        return $ret;
 
2359
    }
 
2360
 
 
2361
    function parse_date($date) {
 
2362
        if (preg_match('/([0-9]{2,4})-([0-9][0-9])-([0-9][0-9])T([0-9][0-9]):([0-9][0-9]):([0-9][0-9])(\.[0-9][0-9])?Z/i', $date, $matches)) {
 
2363
            if (isset($matches[7]) && substr($matches[7], 1) >= 50)
 
2364
                $matches[6]++;
 
2365
            return strtotime("$matches[1]-$matches[2]-$matches[3] $matches[4]:$matches[5]:$matches[6] -0000");
 
2366
        } else if (preg_match('/([0-9]{2,4})-([0-9][0-9])-([0-9][0-9])T([0-9][0-9]):([0-9][0-9]):([0-9][0-9])(\.[0-9][0-9])?(\+|-)([0-9][0-9]):([0-9][0-9])/i', $date, $matches)) {
 
2367
            if (isset($matches[7]) && substr($matches[7], 1) >= 50)
 
2368
                $matches[6]++;
 
2369
            return strtotime("$matches[1]-$matches[2]-$matches[3] $matches[4]:$matches[5]:$matches[6] $matches[8]$matches[9]$matches[10]");
 
2370
        } else {
 
2371
            return strtotime($date);
 
2372
        }
 
2373
    }
 
2374
 
 
2375
 
 
2376
 
 
2377
 
 
2378
    /****************************************************
 
2379
    FUNCTIONS FOR XML_PARSE
 
2380
    ****************************************************/
 
2381
    function startHandler($parser, $name, $attribs) {
 
2382
        $this->tagName = $name;
 
2383
        $this->attribs = $attribs;
 
2384
        $this->is_first = true;
 
2385
        switch ($this->tagName) {
 
2386
            case 'ITEM':
 
2387
            case $this->namespaces['rss2'] . ':ITEM':
 
2388
            case $this->namespaces['rss1'] . ':ITEM':
 
2389
            case 'ENTRY':
 
2390
            case $this->namespaces['atom'] . ':ENTRY':
 
2391
                $this->insideItem = true;
 
2392
                $this->do_add_content($this->xmldata['items'][$this->itemNumber], '');
 
2393
                break;
 
2394
 
 
2395
            case 'CHANNEL':
 
2396
            case $this->namespaces['rss2'] . ':CHANNEL':
 
2397
            case $this->namespaces['rss1'] . ':CHANNEL':
 
2398
                $this->insideChannel = true;
 
2399
                break;
 
2400
 
 
2401
            case 'RSS':
 
2402
            case $this->namespaces['rss2'] . ':RSS':
 
2403
                $this->xmldata['feedinfo']['type'] = 'RSS';
 
2404
                $this->do_add_content($this->xmldata['feeddata'], '');
 
2405
                if (!empty($attribs['VERSION'])) {
 
2406
                    $this->xmldata['feedinfo']['version'] = trim($attribs['VERSION']);
 
2407
                }
 
2408
                break;
 
2409
 
 
2410
            case $this->namespaces['rdf'] . ':RDF':
 
2411
                $this->xmldata['feedinfo']['type'] = 'RSS';
 
2412
                $this->do_add_content($this->xmldata['feeddata'], '');
 
2413
                $this->xmldata['feedinfo']['version'] = 1;
 
2414
                break;
 
2415
 
 
2416
            case 'FEED':
 
2417
            case $this->namespaces['atom'] . ':FEED':
 
2418
                $this->xmldata['feedinfo']['type'] = 'Atom';
 
2419
                $this->do_add_content($this->xmldata['feeddata'], '');
 
2420
                if (!empty($attribs['VERSION'])) {
 
2421
                    $this->xmldata['feedinfo']['version'] = trim($attribs['VERSION']);
 
2422
                }
 
2423
                break;
 
2424
 
 
2425
            case 'IMAGE':
 
2426
            case $this->namespaces['rss2'] . ':IMAGE':
 
2427
            case $this->namespaces['rss1'] . ':IMAGE':
 
2428
                if ($this->insideChannel) $this->insideImage = true;
 
2429
                break;
 
2430
        }
 
2431
 
 
2432
        if (isset($this->xmldata['feedinfo']['type']) && $this->xmldata['feedinfo']['type'] == 'Atom') {
 
2433
            switch ($this->tagName) {
 
2434
                case 'AUTHOR':
 
2435
                case $this->namespaces['atom'] . ':AUTHOR':
 
2436
                    $this->insideAuthor = true;
 
2437
                    break;
 
2438
            }
 
2439
        }
 
2440
        $this->dataHandler($this->xml, '');
 
2441
    }
 
2442
 
 
2443
    function dataHandler($parser, $data) {
 
2444
        if ($this->insideItem) {
 
2445
            switch ($this->tagName) {
 
2446
                case 'TITLE':
 
2447
                case $this->namespaces['rss1'] . ':TITLE':
 
2448
                case $this->namespaces['rss2'] . ':TITLE':
 
2449
                case $this->namespaces['atom'] . ':TITLE':
 
2450
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['title'], $data);
 
2451
                    break;
 
2452
 
 
2453
                case $this->namespaces['dc'] . ':TITLE':
 
2454
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['dc:title'], $data);
 
2455
                    break;
 
2456
 
 
2457
                case 'CONTENT':
 
2458
                case $this->namespaces['atom'] . ':CONTENT':
 
2459
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['content'], $data);
 
2460
                    break;
 
2461
 
 
2462
                case $this->namespaces['content'] . ':ENCODED':
 
2463
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['encoded'], $data);
 
2464
                    break;
 
2465
 
 
2466
                case 'SUMMARY':
 
2467
                case $this->namespaces['atom'] . ':SUMMARY':
 
2468
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['summary'], $data);
 
2469
                    break;
 
2470
 
 
2471
                case 'LONGDESC':
 
2472
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['longdesc'], $data);
 
2473
                    break;
 
2474
 
 
2475
                case 'DESCRIPTION':
 
2476
                case $this->namespaces['rss1'] . ':DESCRIPTION':
 
2477
                case $this->namespaces['rss2'] . ':DESCRIPTION':
 
2478
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['description'], $data);
 
2479
                    break;
 
2480
 
 
2481
                case $this->namespaces['dc'] . ':DESCRIPTION':
 
2482
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['dc:description'], $data);
 
2483
                    break;
 
2484
 
 
2485
                case 'LINK':
 
2486
                case $this->namespaces['rss1'] . ':LINK':
 
2487
                case $this->namespaces['rss2'] . ':LINK':
 
2488
                case $this->namespaces['atom'] . ':LINK':
 
2489
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['link'][$this->itemLinkNumber], $data);
 
2490
                    break;
 
2491
 
 
2492
                case 'ENCLOSURE':
 
2493
                case $this->namespaces['rss1'] . ':ENCLOSURE':
 
2494
                case $this->namespaces['rss2'] . ':ENCLOSURE':
 
2495
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['enclosure'][$this->enclosureNumber], $data);
 
2496
                    break;
 
2497
 
 
2498
                case 'GUID':
 
2499
                case $this->namespaces['rss1'] . ':GUID':
 
2500
                case $this->namespaces['rss2'] . ':GUID':
 
2501
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['guid'], $data);
 
2502
                    break;
 
2503
 
 
2504
                case 'ID':
 
2505
                case $this->namespaces['atom'] . ':ID':
 
2506
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['id'], $data);
 
2507
                    break;
 
2508
 
 
2509
                case 'PUBDATE':
 
2510
                case $this->namespaces['rss1'] . ':PUBDATE':
 
2511
                case $this->namespaces['rss2'] . ':PUBDATE':
 
2512
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['pubdate'], $data);
 
2513
                    break;
 
2514
 
 
2515
                case $this->namespaces['dc'] . ':DATE':
 
2516
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['dc:date'], $data);
 
2517
                    break;
 
2518
 
 
2519
                case 'ISSUED':
 
2520
                case $this->namespaces['atom'] . ':ISSUED':
 
2521
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['issued'], $data);
 
2522
                    break;
 
2523
 
 
2524
                case 'PUBLISHED':
 
2525
                case $this->namespaces['atom'] . ':PUBLISHED':
 
2526
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['published'], $data);
 
2527
                    break;
 
2528
 
 
2529
                case 'MODIFIED':
 
2530
                case $this->namespaces['atom'] . ':MODIFIED':
 
2531
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['modified'], $data);
 
2532
                    break;
 
2533
 
 
2534
                case 'UPDATED':
 
2535
                case $this->namespaces['atom'] . ':UPDATED':
 
2536
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['updated'], $data);
 
2537
                    break;
 
2538
 
 
2539
                case 'CATEGORY':
 
2540
                case $this->namespaces['rss1'] . ':CATEGORY':
 
2541
                case $this->namespaces['rss2'] . ':CATEGORY':
 
2542
                case $this->namespaces['atom'] . ':CATEGORY':
 
2543
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['category'][$this->categoryNumber], $data);
 
2544
                    break;
 
2545
 
 
2546
                case $this->namespaces['dc'] . ':SUBJECT':
 
2547
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['subject'][$this->categoryNumber], $data);
 
2548
                    break;
 
2549
 
 
2550
                case $this->namespaces['dc'] . ':CREATOR':
 
2551
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['creator'][$this->authorNumber], $data);
 
2552
                    break;
 
2553
 
 
2554
                case 'AUTHOR':
 
2555
                case $this->namespaces['rss1'] . ':AUTHOR':
 
2556
                case $this->namespaces['rss2'] . ':AUTHOR':
 
2557
                    $this->do_add_content($this->xmldata['items'][$this->itemNumber]['author'][$this->authorNumber]['rss'], $data);
 
2558
                    break;
 
2559
            }
 
2560
 
 
2561
            if ($this->insideAuthor) {
 
2562
                switch ($this->tagName) {
 
2563
                    case 'NAME':
 
2564
                    case $this->namespaces['atom'] . ':NAME':
 
2565
                        $this->do_add_content($this->xmldata['items'][$this->itemNumber]['author'][$this->authorNumber]['name'], $data);
 
2566
                        break;
 
2567
 
 
2568
                    case 'URL':
 
2569
                    case $this->namespaces['atom'] . ':URL':
 
2570
                        $this->do_add_content($this->xmldata['items'][$this->itemNumber]['author'][$this->authorNumber]['url'], $data);
 
2571
                        break;
 
2572
 
 
2573
                    case 'URI':
 
2574
                    case $this->namespaces['atom'] . ':URI':
 
2575
                        $this->do_add_content($this->xmldata['items'][$this->itemNumber]['author'][$this->authorNumber]['uri'], $data);
 
2576
                        break;
 
2577
 
 
2578
                    case 'HOMEPAGE':
 
2579
                    case $this->namespaces['atom'] . ':HOMEPAGE':
 
2580
                        $this->do_add_content($this->xmldata['items'][$this->itemNumber]['author'][$this->authorNumber]['homepage'], $data);
 
2581
                        break;
 
2582
 
 
2583
                    case 'EMAIL':
 
2584
                    case $this->namespaces['atom'] . ':EMAIL':
 
2585
                        $this->do_add_content($this->xmldata['items'][$this->itemNumber]['author'][$this->authorNumber]['email'], $data);
 
2586
                        break;
 
2587
                }
 
2588
            }
 
2589
        }
 
2590
 
 
2591
        else if (($this->insideChannel && !$this->insideImage) || (isset($this->xmldata['feedinfo']['type']) && $this->xmldata['feedinfo']['type'] == 'Atom')) {
 
2592
            switch ($this->tagName) {
 
2593
                case 'TITLE':
 
2594
                case $this->namespaces['rss1'] . ':TITLE':
 
2595
                case $this->namespaces['rss2'] . ':TITLE':
 
2596
                case $this->namespaces['atom'] . ':TITLE':
 
2597
                    $this->do_add_content($this->xmldata['info']['title'], $data);
 
2598
                    break;
 
2599
 
 
2600
                case 'LINK':
 
2601
                case $this->namespaces['rss1'] . ':LINK':
 
2602
                case $this->namespaces['rss2'] . ':LINK':
 
2603
                case $this->namespaces['atom'] . ':LINK':
 
2604
                    $this->do_add_content($this->xmldata['info']['link'][$this->linkNumber], $data);
 
2605
                    break;
 
2606
 
 
2607
                case 'DESCRIPTION':
 
2608
                case $this->namespaces['rss1'] . ':DESCRIPTION':
 
2609
                case $this->namespaces['rss2'] . ':DESCRIPTION':
 
2610
                    $this->do_add_content($this->xmldata['info']['description'], $data);
 
2611
                    break;
 
2612
 
 
2613
                case $this->namespaces['dc'] . ':DESCRIPTION':
 
2614
                    $this->do_add_content($this->xmldata['info']['dc:description'], $data);
 
2615
                    break;
 
2616
 
 
2617
                case 'TAGLINE':
 
2618
                case $this->namespaces['atom'] . ':TAGLINE':
 
2619
                    $this->do_add_content($this->xmldata['info']['tagline'], $data);
 
2620
                    break;
 
2621
 
 
2622
                case 'SUBTITLE':
 
2623
                case $this->namespaces['atom'] . ':SUBTITLE':
 
2624
                    $this->do_add_content($this->xmldata['info']['subtitle'], $data);
 
2625
                    break;
 
2626
 
 
2627
                case 'COPYRIGHT':
 
2628
                case $this->namespaces['rss1'] . ':COPYRIGHT':
 
2629
                case $this->namespaces['rss2'] . ':COPYRIGHT':
 
2630
                case $this->namespaces['atom'] . ':COPYRIGHT':
 
2631
                    $this->do_add_content($this->xmldata['info']['copyright'], $data);
 
2632
                    break;
 
2633
 
 
2634
                case 'LANGUAGE':
 
2635
                case $this->namespaces['rss1'] . ':LANGUAGE':
 
2636
                case $this->namespaces['rss2'] . ':LANGUAGE':
 
2637
                    $this->do_add_content($this->xmldata['info']['language'], $data);
 
2638
                    break;
 
2639
 
 
2640
                case 'LOGO':
 
2641
                case $this->namespaces['atom'] . ':LOGO':
 
2642
                    $this->do_add_content($this->xmldata['info']['logo'], $data);
 
2643
                    break;
 
2644
 
 
2645
            }
 
2646
        }
 
2647
 
 
2648
        else if ($this->insideChannel && $this->insideImage) {
 
2649
            switch ($this->tagName) {
 
2650
                case 'TITLE':
 
2651
                case $this->namespaces['rss1'] . ':TITLE':
 
2652
                case $this->namespaces['rss2'] . ':TITLE':
 
2653
                    $this->do_add_content($this->xmldata['info']['image']['title'], $data);
 
2654
                    break;
 
2655
 
 
2656
                case 'URL':
 
2657
                case $this->namespaces['rss1'] . ':URL':
 
2658
                case $this->namespaces['rss2'] . ':URL':
 
2659
                    $this->do_add_content($this->xmldata['info']['image']['url'], $data);
 
2660
                    break;
 
2661
 
 
2662
                case 'LINK':
 
2663
                case $this->namespaces['rss1'] . ':LINK':
 
2664
                case $this->namespaces['rss2'] . ':LINK':
 
2665
                    $this->do_add_content($this->xmldata['info']['image']['link'], $data);
 
2666
                    break;
 
2667
 
 
2668
                case 'WIDTH':
 
2669
                case $this->namespaces['rss1'] . ':WIDTH':
 
2670
                case $this->namespaces['rss2'] . ':WIDTH':
 
2671
                    $this->do_add_content($this->xmldata['info']['image']['width'], $data);
 
2672
                    break;
 
2673
 
 
2674
                case 'HEIGHT':
 
2675
                case $this->namespaces['rss1'] . ':HEIGHT':
 
2676
                case $this->namespaces['rss2'] . ':HEIGHT':
 
2677
                    $this->do_add_content($this->xmldata['info']['image']['height'], $data);
 
2678
                    break;
 
2679
            }
 
2680
        }
 
2681
        $this->is_first = false;
 
2682
    }
 
2683
 
 
2684
    function endHandler($parser, $name) {
 
2685
        $this->tagName = '';
 
2686
        switch ($name) {
 
2687
            case 'ITEM':
 
2688
            case $this->namespaces['rss1'] . ':ITEM':
 
2689
            case $this->namespaces['rss2'] . ':ITEM':
 
2690
            case 'ENTRY':
 
2691
            case $this->namespaces['atom'] . ':ENTRY':
 
2692
                $this->insideItem = false;
 
2693
                $this->itemNumber++;
 
2694
                $this->authorNumber = 0;
 
2695
                $this->categoryNumber = 0;
 
2696
                $this->enclosureNumber = 0;
 
2697
                $this->itemLinkNumber = 0;
 
2698
                break;
 
2699
 
 
2700
            case 'CHANNEL':
 
2701
            case $this->namespaces['rss1'] . ':CHANNEL':
 
2702
            case $this->namespaces['rss2'] . ':CHANNEL':
 
2703
                $this->insideChannel = false;
 
2704
                break;
 
2705
 
 
2706
            case 'IMAGE':
 
2707
            case $this->namespaces['rss1'] . ':IMAGE':
 
2708
            case $this->namespaces['rss2'] . ':IMAGE':
 
2709
                if ($this->insideChannel) $this->insideImage = false;
 
2710
                break;
 
2711
 
 
2712
            case 'AUTHOR':
 
2713
            case $this->namespaces['rss1'] . ':AUTHOR':
 
2714
            case $this->namespaces['rss2'] . ':AUTHOR':
 
2715
            case $this->namespaces['atom'] . ':AUTHOR':
 
2716
                $this->authorNumber++;
 
2717
                if ($this->xmldata['feedinfo']['type'] == 'Atom') $this->insideAuthor = false;
 
2718
                break;
 
2719
 
 
2720
            case 'CATEGORY':
 
2721
            case $this->namespaces['rss1'] . ':CATEGORY':
 
2722
            case $this->namespaces['rss2'] . ':CATEGORY':
 
2723
            case $this->namespaces['atom'] . ':CATEGORY':
 
2724
            case $this->namespaces['dc'] . ':SUBJECT':
 
2725
                $this->categoryNumber++;
 
2726
                break;
 
2727
 
 
2728
            case 'ENCLOSURE':
 
2729
            case $this->namespaces['rss1'] . ':ENCLOSURE':
 
2730
            case $this->namespaces['rss2'] . ':ENCLOSURE':
 
2731
                $this->enclosureNumber++;
 
2732
                break;
 
2733
 
 
2734
            case 'LINK':
 
2735
            case $this->namespaces['rss1'] . ':LINK':
 
2736
            case $this->namespaces['rss2'] . ':LINK':
 
2737
            case $this->namespaces['atom'] . ':LINK':
 
2738
                if ($this->insideItem)
 
2739
                    $this->itemLinkNumber++;
 
2740
                else
 
2741
                    $this->linkNumber++;
 
2742
                break;
 
2743
        }
 
2744
    }
 
2745
 
 
2746
    function startNameSpace($parser, $prefix, $uri = null) {
 
2747
        $prefix = strtoupper($prefix);
 
2748
        $uri = strtoupper($uri);
 
2749
        if ($prefix == 'ATOM' || $uri == 'HTTP://WWW.W3.ORG/2005/ATOM' || $uri == 'HTTP://PURL.ORG/ATOM/NS#') {
 
2750
            $this->namespaces['atom'] = $uri;
 
2751
        }
 
2752
        else if ($prefix == 'RSS2' || $uri == 'HTTP://BACKEND.USERLAND.COM/RSS2') {
 
2753
            $this->namespaces['rss2'] = $uri;
 
2754
        }
 
2755
        else if ($prefix == 'RDF' || $uri == 'HTTP://WWW.W3.ORG/1999/02/22-RDF-SYNTAX-NS#') {
 
2756
            $this->namespaces['rdf'] = $uri;
 
2757
        }
 
2758
        else if ($prefix == 'RSS' || $uri == 'HTTP://PURL.ORG/RSS/1.0/') {
 
2759
            $this->namespaces['rss1'] = $uri;
 
2760
        }
 
2761
        else if ($prefix == 'DC' || $uri == 'HTTP://PURL.ORG/DC/ELEMENTS/1.1/') {
 
2762
            $this->namespaces['dc'] = $uri;
 
2763
        }
 
2764
        else if ($prefix == 'XHTML' || $uri == 'HTTP://WWW.W3.ORG/1999/XHTML') {
 
2765
            $this->namespaces['xhtml'] = $uri;
 
2766
            $this->xhtml_prefix = $prefix;
 
2767
        }
 
2768
        else if ($prefix == 'CONTENT' || $uri == 'HTTP://PURL.ORG/RSS/1.0/MODULES/CONTENT/') {
 
2769
            $this->namespaces['content'] = $uri;
 
2770
        }
 
2771
    }
 
2772
 
 
2773
    function endNameSpace($parser, $prefix) {
 
2774
        if ($key = array_search(strtoupper($prefix), $this->namespaces)) {
 
2775
            if ($key == 'atom') {
 
2776
                $this->namespaces['atom'] = 'ATOM';
 
2777
            }
 
2778
            else if ($key == 'rss2') {
 
2779
                $this->namespaces['rss2'] = 'RSS';
 
2780
            }
 
2781
            else if ($key == 'rdf') {
 
2782
                $this->namespaces['rdf'] = 'RDF';
 
2783
            }
 
2784
            else if ($key == 'rss1') {
 
2785
                $this->namespaces['rss1'] = 'RSS';
 
2786
            }
 
2787
            else if ($key == 'dc') {
 
2788
                $this->namespaces['dc'] = 'DC';
 
2789
            }
 
2790
            else if ($key == 'xhtml') {
 
2791
                $this->namespaces['xhtml'] = 'XHTML';
 
2792
                $this->xhtml_prefix = 'XHTML';
 
2793
            }
 
2794
            else if ($key == 'content') {
 
2795
                $this->namespaces['content'] = 'CONTENT';
 
2796
            }
 
2797
        }
 
2798
    }
 
2799
}
 
2800
 
 
2801
class SimplePie_Item
 
2802
{
 
2803
    function SimplePie_Item($id, $title, $description, $category, $author, $date, $links, $enclosure) {
 
2804
        $this->id = $id;
 
2805
        $this->title = $title;
 
2806
        $this->description = $description;
 
2807
        $this->category = $category;
 
2808
        $this->author = $author;
 
2809
        $this->date = $date;
 
2810
        $this->links = $links;
 
2811
        $this->enclosure = $enclosure;
 
2812
    }
 
2813
 
 
2814
    /****************************************************
 
2815
    PARSE OUT ITEM-RELATED DATA
 
2816
    ****************************************************/
 
2817
    // Get the id of the item
 
2818
    function get_id() {
 
2819
        return (empty($this->id)) ? false : $this->id;
 
2820
    }
 
2821
    // Get the title of the item
 
2822
    function get_title() {
 
2823
        return (empty($this->title)) ? false : $this->title;
 
2824
    }
 
2825
 
 
2826
    // Get the description of the item
 
2827
    function get_description() {
 
2828
        return (empty($this->description)) ? false : $this->description;
 
2829
    }
 
2830
 
 
2831
    // Get the category of the item
 
2832
    function get_category() {
 
2833
        return (empty($this->category)) ? false : $this->category;
 
2834
    }
 
2835
 
 
2836
    // Get the author of the item
 
2837
    function get_author($key) {
 
2838
        return (empty($this->author[$key])) ? false : $this->author[$key];
 
2839
    }
 
2840
 
 
2841
    // Get the author of the item
 
2842
    function get_authors() {
 
2843
        return (empty($this->author)) ? false : $this->author;
 
2844
    }
 
2845
 
 
2846
    // Get the date of the item
 
2847
    // Also, allow users to set the format of how dates are displayed on a webpage.
 
2848
    function get_date($date_format = 'j F Y, g:i a') {
 
2849
        return (empty($this->date)) ? false : date($date_format, $this->date);
 
2850
    }
 
2851
 
 
2852
    // Get the Permalink of the item
 
2853
    function get_permalink() {
 
2854
        // If there is a link, take it. Fine.
 
2855
        if (!empty($this->links[0])) {
 
2856
            return $this->links[0];
 
2857
        }
 
2858
 
 
2859
        // If there isn't, check for an enclosure, if that exists, give that.
 
2860
        else if ($this->get_enclosure(0)) {
 
2861
            return $this->get_enclosure(0);
 
2862
        }
 
2863
        else return false;
 
2864
    }
 
2865
 
 
2866
    // Get all links
 
2867
    function get_links() {
 
2868
        return (empty($this->links)) ? false : $this->links;
 
2869
    }
 
2870
 
 
2871
    // Get the enclosure of the item
 
2872
    function get_enclosure($key) {
 
2873
        return (empty($this->enclosure[$key])) ? false : $this->enclosure[$key];
 
2874
    }
 
2875
 
 
2876
    // Get the enclosure of the item
 
2877
    function get_enclosures() {
 
2878
        return (empty($this->enclosure)) ? false : $this->enclosure;
 
2879
    }
 
2880
 
 
2881
 
 
2882
 
 
2883
 
 
2884
    /****************************************************
 
2885
    "ADD TO" LINKS
 
2886
    Allows people to easily add news postings to social bookmarking sites.
 
2887
    ****************************************************/
 
2888
    function add_to_blinklist() {
 
2889
        return "http://www.blinklist.com/index.php?Action=Blink/addblink.php&amp;Description=&amp;Url=" . rawurlencode($this->get_permalink()) . "&amp;Title=" . rawurlencode($this->get_title());
 
2890
    }
 
2891
 
 
2892
    function add_to_delicious() {
 
2893
        return "http://del.icio.us/post/?v=3&amp;url=" . rawurlencode($this->get_permalink()) . "&amp;title=" . rawurlencode($this->get_title());
 
2894
    }
 
2895
 
 
2896
    function add_to_digg() {
 
2897
        return "http://digg.com/submit?phase=2&amp;URL=" . rawurlencode($this->get_permalink());
 
2898
    }
 
2899
 
 
2900
    function add_to_furl() {
 
2901
        return "http://www.furl.net/storeIt.jsp?u=" . rawurlencode($this->get_permalink()) . "&amp;t=" . rawurlencode($this->get_title());
 
2902
    }
 
2903
 
 
2904
    function add_to_magnolia() {
 
2905
        return "http://ma.gnolia.com/bookmarklet/add?url=" . rawurlencode($this->get_permalink()) . "&amp;title=" . rawurlencode($this->get_title());
 
2906
    }
 
2907
 
 
2908
    function add_to_myweb20() {
 
2909
        return "http://myweb2.search.yahoo.com/myresults/bookmarklet?u=" . rawurlencode($this->get_permalink()) . "&amp;t=" . rawurlencode($this->get_title());
 
2910
    }
 
2911
 
 
2912
    function add_to_newsvine() {
 
2913
        return "http://www.newsvine.com/_wine/save?u=" . rawurlencode($this->get_permalink()) . "&amp;h=" . rawurlencode($this->get_title());
 
2914
    }
 
2915
 
 
2916
    function add_to_reddit() {
 
2917
        return 'http://reddit.com/submit?url=' . rawurlencode($this->get_permalink()) . "&amp;title=" . rawurlencode($this->get_title());
 
2918
    }
 
2919
 
 
2920
    function add_to_spurl() {
 
2921
        return "http://www.spurl.net/spurl.php?v=3&amp;url=" . rawurlencode($this->get_permalink()) . "&amp;title=" . rawurlencode($this->get_title());
 
2922
    }
 
2923
 
 
2924
 
 
2925
 
 
2926
 
 
2927
    /****************************************************
 
2928
    SEARCHES
 
2929
    Metadata searches
 
2930
    ****************************************************/
 
2931
    function search_technorati() {
 
2932
        return 'http://www.technorati.com/search/' . rawurlencode($this->get_permalink());
 
2933
    }
 
2934
}
 
2935
 
 
2936
class SimplePie_Author
 
2937
{
 
2938
    var $name;
 
2939
    var $link;
 
2940
    var $email;
 
2941
 
 
2942
    // Constructor, used to input the data
 
2943
    function SimplePie_Author($name, $link, $email) {
 
2944
        $this->name = $name;
 
2945
        $this->link = $link;
 
2946
        $this->email = $email;
 
2947
    }
 
2948
 
 
2949
    function get_name() {
 
2950
        return (empty($this->name)) ? false : $this->name;
 
2951
    }
 
2952
 
 
2953
    function get_link() {
 
2954
        return (empty($this->link)) ? false : $this->link;
 
2955
    }
 
2956
 
 
2957
    function get_email() {
 
2958
        return (empty($this->email)) ? false : $this->email;
 
2959
    }
 
2960
}
 
2961
 
 
2962
class SimplePie_Enclosure
 
2963
{
 
2964
    var $link;
 
2965
    var $type;
 
2966
    var $length;
 
2967
 
 
2968
    // Constructor, used to input the data
 
2969
    function SimplePie_Enclosure($link, $type, $length) {
 
2970
        $this->link = $link;
 
2971
        $this->type = $type;
 
2972
        $this->length = $length;
 
2973
    }
 
2974
 
 
2975
    function get_link() {
 
2976
        return (empty($this->link)) ? false : $this->link;
 
2977
    }
 
2978
 
 
2979
    function get_extension() {
 
2980
        if (!empty($this->link)) {
 
2981
            return pathinfo($this->link, PATHINFO_EXTENSION);
 
2982
        } else {
 
2983
            return false;
 
2984
        }
 
2985
    }
 
2986
 
 
2987
    function get_type() {
 
2988
        return (empty($this->type)) ? false : $this->type;
 
2989
    }
 
2990
 
 
2991
    function get_length() {
 
2992
        return (empty($this->length)) ? false : $this->length;
 
2993
    }
 
2994
 
 
2995
    function get_size() {
 
2996
        return (empty($this->length)) ? false : round(($this->length/1048576), 2);
 
2997
    }
 
2998
 
 
2999
    function embed($options) {
 
3000
 
 
3001
        // Set up defaults
 
3002
        $audio='';
 
3003
        $video='';
 
3004
        $alt='';
 
3005
        $altclass='';
 
3006
        $loop='false';
 
3007
        $width='auto';
 
3008
        $height='auto';
 
3009
        $bgcolor='#ffffff';
 
3010
        $embed='';
 
3011
 
 
3012
        // Process options and reassign values as necessary
 
3013
        $options = explode(',', $options);
 
3014
        foreach($options as $option) {
 
3015
            $opt = explode(':', trim($option));
 
3016
            if ($opt[0] == 'audio') $audio=$opt[1];
 
3017
            else if ($opt[0] == 'video') $video=$opt[1];
 
3018
            else if ($opt[0] == 'alt') $alt=$opt[1];
 
3019
            else if ($opt[0] == 'altclass') $altclass=$opt[1];
 
3020
            else if ($opt[0] == 'loop') $loop=$opt[1];
 
3021
            else if ($opt[0] == 'width') $width=$opt[1];
 
3022
            else if ($opt[0] == 'height') $height=$opt[1];
 
3023
            else if ($opt[0] == 'bgcolor') $bgcolor=$opt[1];
 
3024
        }
 
3025
 
 
3026
        // Process values for 'auto'
 
3027
        if ($width == 'auto') {
 
3028
            if (stristr($this->type, 'audio/')) $width='100%';
 
3029
            else if (stristr($this->type, 'video/')) $width='320';
 
3030
            else $width='100%';
 
3031
        }
 
3032
        if ($height == 'auto') {
 
3033
            if (stristr($this->type, 'audio/')) $height=0;
 
3034
            else if (stristr($this->type, 'video/')) $height=240;
 
3035
            else $height=256;
 
3036
        }
 
3037
 
 
3038
        // Set proper placeholder value
 
3039
        if (stristr($this->type, 'audio/')) $placeholder=$audio;
 
3040
        else if (stristr($this->type, 'video/')) $placeholder=$video;
 
3041
 
 
3042
        // Make sure the JS library is included
 
3043
        // (I know it'll be included multiple times, but I can't think of a better way to do this automatically)
 
3044
        $embed.='<script type="text/javascript" src="?js"></script>';
 
3045
 
 
3046
        // Odeo Feed MP3's
 
3047
        if (substr(strtolower($this->link), 0, 15) == 'http://odeo.com') {
 
3048
            $embed.='<script type="text/javascript">embed_odeo("'.$this->link.'");</script>';
 
3049
        }
 
3050
 
 
3051
        // QuickTime 7 file types.  Need to test with QuickTime 6.
 
3052
        else if ($this->type == 'audio/3gpp' || $this->type == 'audio/3gpp2' || $this->type == 'audio/aac' || $this->type == 'audio/x-aac' || $this->type == 'audio/aiff' || $this->type == 'audio/x-aiff' || $this->type == 'audio/mid' || $this->type == 'audio/midi' || $this->type == 'audio/x-midi' || $this->type == 'audio/mpeg' || $this->type == 'audio/x-mpeg' || $this->type == 'audio/mp3' || $this->type == 'x-audio/mp3' || $this->type == 'audio/mp4' || $this->type == 'audio/m4a' || $this->type == 'audio/x-m4a' || $this->type == 'audio/wav' || $this->type == 'audio/x-wav' || $this->type == 'video/3gpp' || $this->type == 'video/3gpp2' || $this->type == 'video/m4v' || $this->type == 'video/x-m4v' || $this->type == 'video/mp4' || $this->type == 'video/mpeg' || $this->type == 'video/x-mpeg' || $this->type == 'video/quicktime' || $this->type == 'video/sd-video') {
 
3053
            $height+=16;
 
3054
            $embed.='<script type="text/javascript">embed_quicktime("'.$this->type.'", "'.$bgcolor.'", "'.$width.'", "'.$height.'", "'.$this->link.'", "'.$placeholder.'", "'.$loop.'");</script>';
 
3055
        }
 
3056
 
 
3057
        // Flash
 
3058
        else if ($this->type == 'application/x-shockwave-flash' || $this->type == 'application/futuresplash') {
 
3059
            $embed.='<script type="text/javascript">embed_flash("'.$bgcolor.'", "'.$width.'", "'.$height.'", "'.$this->link.'", "'.$loop.'", "'.$this->type.'");</script>';
 
3060
        }
 
3061
 
 
3062
        // Windows Media
 
3063
        else if ($this->type == 'application/asx' || $this->type == 'application/x-mplayer2' || $this->type == 'audio/x-ms-wma' || $this->type == 'audio/x-ms-wax' || $this->type == 'video/x-ms-asf-plugin' || $this->type == 'video/x-ms-asf' || $this->type == 'video/x-ms-wm' || $this->type == 'video/x-ms-wmv' || $this->type == 'video/x-ms-wvx') {
 
3064
            $height+=45;
 
3065
            $embed.='<script type="text/javascript">embed_wmedia("'.$width.'", "'.$height.'", "'.$this->link.'");</script>';
 
3066
        }
 
3067
 
 
3068
        // Everything else
 
3069
        else $embed.='<a href="' . $this->link . '" class="' . $altclass . '">' . $alt . '</a>';
 
3070
 
 
3071
        return $embed;
 
3072
    }
 
3073
}
 
3074
 
 
3075
?>