5 * A PHP-Based RSS and Atom Feed Framework.
6 * Takes the hard work out of managing a complete RSS/Atom solution.
8 * Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
11 * Redistribution and use in source and binary forms, with or without modification, are
12 * permitted provided that the following conditions are met:
14 * * Redistributions of source code must retain the above copyright notice, this list of
15 * conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above copyright notice, this list
18 * of conditions and the following disclaimer in the documentation and/or other materials
19 * provided with the distribution.
21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used
22 * to endorse or promote products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
37 * @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
39 * @author Geoffrey Sneddon
41 * @link http://simplepie.org/ SimplePie
42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43 * @todo phpDoc comments
49 public static function time_hms($seconds)
53 $hours = floor($seconds / 3600);
54 $remainder = $seconds %
3600;
60 $minutes = floor($remainder / 60);
61 $seconds = $remainder %
60;
62 if ($minutes < 10 && $hours > 0)
64 $minutes = '0' . $minutes;
68 $seconds = '0' . $seconds;
71 $time .= $minutes.':';
77 public static function absolutize_url($relative, $base)
79 $iri = SimplePie_IRI
::absolutize(new SimplePie_IRI($base), $relative);
80 return $iri->get_iri();
83 public static function remove_dot_segments($input)
86 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
88 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
89 if (strpos($input, '../') === 0)
91 $input = substr($input, 3);
93 elseif (strpos($input, './') === 0)
95 $input = substr($input, 2);
97 // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
98 elseif (strpos($input, '/./') === 0)
100 $input = substr_replace($input, '/', 0, 3);
102 elseif ($input === '/.')
106 // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
107 elseif (strpos($input, '/../') === 0)
109 $input = substr_replace($input, '/', 0, 4);
110 $output = substr_replace($output, '', strrpos($output, '/'));
112 elseif ($input === '/..')
115 $output = substr_replace($output, '', strrpos($output, '/'));
117 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
118 elseif ($input === '.' || $input === '..')
122 // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
123 elseif (($pos = strpos($input, '/', 1)) !== false)
125 $output .= substr($input, 0, $pos);
126 $input = substr_replace($input, '', 0, $pos);
134 return $output . $input;
137 public static function get_element($realname, $string)
140 $name = preg_quote($realname, '/');
141 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE
. "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER
| PREG_OFFSET_CAPTURE
))
143 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++
)
145 $return[$i]['tag'] = $realname;
146 $return[$i]['full'] = $matches[$i][0][0];
147 $return[$i]['offset'] = $matches[$i][0][1];
148 if (strlen($matches[$i][3][0]) <= 2)
150 $return[$i]['self_closing'] = true;
154 $return[$i]['self_closing'] = false;
155 $return[$i]['content'] = $matches[$i][4][0];
157 $return[$i]['attribs'] = array();
158 if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER
))
160 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++
)
162 if (count($attribs[$j]) === 2)
164 $attribs[$j][2] = $attribs[$j][1];
166 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc
::entities_decode(end($attribs[$j]), 'UTF-8');
174 public static function element_implode($element)
176 $full = "<$element[tag]";
177 foreach ($element['attribs'] as $key => $value)
179 $key = strtolower($key);
180 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
182 if ($element['self_closing'])
188 $full .= ">$element[content]</$element[tag]>";
193 public static function error($message, $level, $file, $line)
195 if ((ini_get('error_reporting') & $level) > 0)
203 $note = 'PHP Warning';
206 $note = 'PHP Notice';
209 $note = 'Unknown Error';
214 if (!function_exists('error_log'))
219 $log_file = @ini_get('error_log');
220 if (!empty($log_file) && ('syslog' !== $log_file) && !@is_writable($log_file))
227 @error_log("$note: $message in $file on line $line", 0);
234 public static function fix_protocol($url, $http = 1)
236 $url = SimplePie_Misc::normalize_url($url);
237 $parsed = SimplePie_Misc::parse_url($url);
238 if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
240 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
243 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
245 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
248 if ($http === 2 && $parsed['scheme'] !== '')
252 elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
254 return substr_replace($url, 'podcast', 0, 4);
256 elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
258 return substr_replace($url, 'itpc', 0, 4);
266 public static function parse_url($url)
268 $iri = new SimplePie_IRI($url);
270 'scheme' => (string) $iri->get_scheme(),
271 'authority' => (string) $iri->get_authority(),
272 'path' => (string) $iri->get_path(),
273 'query' => (string) $iri->get_query(),
274 'fragment' => (string) $iri->get_fragment()
278 public static function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
280 $iri = new SimplePie_IRI('');
281 $iri->set_scheme($scheme);
282 $iri->set_authority($authority);
283 $iri->set_path($path);
284 $iri->set_query($query);
285 $iri->set_fragment($fragment);
286 return $iri->get_iri();
289 public static function normalize_url($url)
291 $iri = new SimplePie_IRI($url);
292 return $iri->get_iri();
295 public static function percent_encoding_normalization($match)
297 $integer = hexdec($match[1]);
298 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
300 return chr($integer);
304 return strtoupper($match[0]);
309 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
312 * @param string $string Windows-1252 encoded string
313 * @return string UTF-8 encoded string
315 public static function windows_1252_to_utf8($string)
317 static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF");
319 return strtr($string, $convert_table);
323 * Change a string from one encoding to another
325 * @param string $data Raw data in $input encoding
326 * @param string $input Encoding of $data
327 * @param string $output Encoding you want
328 * @return string|boolean False if we can't convert it
330 public static function change_encoding($data, $input, $output)
332 $input = SimplePie_Misc
::encoding($input);
333 $output = SimplePie_Misc
::encoding($output);
335 // We fail to fail on non US-ASCII bytes
336 if ($input === 'US-ASCII')
338 static $non_ascii_octects = '';
339 if (!$non_ascii_octects)
341 for ($i = 0x80; $i <= 0xFF; $i++
)
343 $non_ascii_octects .= chr($i);
346 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
349 // This is first, as behaviour of this is completely predictable
350 if ($input === 'windows-1252' && $output === 'UTF-8')
352 return SimplePie_Misc
::windows_1252_to_utf8($data);
354 // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
355 elseif (function_exists('mb_convert_encoding') && ($return = SimplePie_Misc
::change_encoding_mbstring($data, $input, $output)))
359 // This is last, as behaviour of this varies with OS userland and PHP version
360 elseif (function_exists('iconv') && ($return = SimplePie_Misc
::change_encoding_iconv($data, $input, $output)))
364 // If we can't do anything, just fail
371 protected static function change_encoding_mbstring($data, $input, $output)
373 if ($input === 'windows-949')
377 if ($output === 'windows-949')
382 // Check that the encoding is supported
383 if (@mb_convert_encoding("\x80", 'UTF-16BE', $input) === "\x00\x80")
387 if (!in_array($input, mb_list_encodings()))
392 // Let's do some conversion
393 if ($return = @mb_convert_encoding($data, $output, $input))
401 protected static function change_encoding_iconv($data, $input, $output)
403 return @iconv($input, $output, $data);
407 * Normalize an encoding name
409 * This is automatically generated by create.php
411 * To generate it, run `php create.php` on the command line, and copy the
412 * output to replace this function.
414 * @param string $charset Character set to standardise
415 * @return string Standardised name
417 public static function encoding($charset)
419 // Normalization from UTS #22
420 switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
422 case 'adobestandardencoding':
423 case 'csadobestandardencoding':
424 return 'Adobe-Standard-Encoding';
426 case 'adobesymbolencoding':
428 return 'Adobe-Symbol-Encoding';
434 case 'ansix31101983':
436 case 'csiso99naplps':
439 return 'ANSI_X3.110-1983';
443 case 'csiso89asmo449':
464 case 'csiso4unitedkingdom':
472 case 'csiso47bsviewdata':
474 return 'BS_viewdata';
482 case 'csaz243419851':
483 case 'csiso121canadian1':
486 return 'CSA_Z243.4-1985-1';
489 case 'csaz243419852':
490 case 'csiso122canadian2':
493 return 'CSA_Z243.4-1985-2';
495 case 'csaz24341985gr':
496 case 'csiso123csaz24341985gr':
498 return 'CSA_Z243.4-1985-gr';
500 case 'csiso139csn369103':
510 case 'csiso21german':
521 case 'csiso646danish':
527 case 'csibmebcdicatde':
529 return 'EBCDIC-AT-DE';
531 case 'csebcdicatdea':
533 return 'EBCDIC-AT-DE-A';
537 return 'EBCDIC-CA-FR';
541 return 'EBCDIC-DK-NO';
543 case 'csebcdicdknoa':
545 return 'EBCDIC-DK-NO-A';
553 return 'EBCDIC-ES-A';
557 return 'EBCDIC-ES-S';
561 return 'EBCDIC-FI-SE';
563 case 'csebcdicfisea':
565 return 'EBCDIC-FI-SE-A';
587 case 'csiso111ecmacyrillic':
591 return 'ECMA-cyrillic';
593 case 'csiso17spanish':
599 case 'csiso85spanish2':
605 case 'cseucpkdfmtjapanese':
607 case 'extendedunixcodepackedformatforjapanese':
610 case 'cseucfixwidjapanese':
611 case 'extendedunixcodefixedwidthforjapanese':
612 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
620 case 'csiso58gb231280':
630 case 'csiso57gb1988':
636 case 'csiso153gost1976874':
640 return 'GOST_19768-74';
643 case 'csiso150greekccitt':
646 return 'greek-ccitt';
648 case 'csiso88greek7':
653 case 'csiso18greek7old':
685 return 'IBM-Symbols';
792 case 'cspc8codepage437':
804 case 'cspc775baltic':
810 case 'cspc850multilingual':
841 case 'pcmultilingual850euro':
859 case 'cspc862latinhebrew':
901 case 'ebcdiccproece':
914 case 'ebcdiccyrillic':
948 case 'ebcdiclatin9euro':
962 case 'ebcdicus37euro':
968 case 'ebcdicde273euro':
974 case 'ebcdicdk277euro':
975 case 'ebcdicno277euro':
981 case 'ebcdicfi278euro':
982 case 'ebcdicse278euro':
988 case 'ebcdicit280euro':
994 case 'ebcdices284euro':
1000 case 'ebcdicgb285euro':
1006 case 'ebcdicfr297euro':
1012 case 'ebcdicinternational500euro':
1018 case 'ebcdicis871euro':
1022 case 'csiso143iecp271':
1032 case 'csiso50inis8':
1037 case 'csiso51iniscyrillic':
1038 case 'iniscyrillic':
1040 return 'INIS-cyrillic';
1047 return 'ISO-2022-CN';
1049 case 'iso2022cnext':
1050 return 'ISO-2022-CN-EXT';
1054 return 'ISO-2022-JP';
1056 case 'csiso2022jp2':
1058 return 'ISO-2022-JP-2';
1062 return 'ISO-2022-KR';
1064 case 'cswindows30latin1':
1065 case 'iso88591windows30latin1':
1066 return 'ISO-8859-1-Windows-3.0-Latin-1';
1068 case 'cswindows31latin1':
1069 case 'iso88591windows31latin1':
1070 return 'ISO-8859-1-Windows-3.1-Latin-1';
1074 case 'iso885921987':
1078 return 'ISO-8859-2';
1080 case 'cswindows31latin2':
1081 case 'iso88592windowslatin2':
1082 return 'ISO-8859-2-Windows-Latin-2';
1086 case 'iso885931988':
1090 return 'ISO-8859-3';
1094 case 'iso885941988':
1098 return 'ISO-8859-4';
1100 case 'csisolatincyrillic':
1103 case 'iso885951988':
1105 return 'ISO-8859-5';
1109 case 'csisolatinarabic':
1112 case 'iso885961987':
1114 return 'ISO-8859-6';
1118 return 'ISO-8859-6-E';
1122 return 'ISO-8859-6-I';
1124 case 'csisolatingreek':
1130 case 'iso885971987':
1132 return 'ISO-8859-7';
1134 case 'csisolatinhebrew':
1137 case 'iso885981988':
1139 return 'ISO-8859-8';
1143 return 'ISO-8859-8-E';
1147 return 'ISO-8859-8-I';
1149 case 'cswindows31latin5':
1150 case 'iso88599windowslatin5':
1151 return 'ISO-8859-9-Windows-Latin-5';
1155 case 'iso8859101992':
1159 return 'ISO-8859-10';
1162 return 'ISO-8859-13';
1165 case 'iso8859141998':
1170 return 'ISO-8859-14';
1174 return 'ISO-8859-15';
1177 case 'iso8859162001':
1181 return 'ISO-8859-16';
1184 return 'ISO-10646-J-1';
1187 case 'iso10646ucs2':
1188 return 'ISO-10646-UCS-2';
1191 case 'iso10646ucs4':
1192 return 'ISO-10646-UCS-4';
1194 case 'csunicodeascii':
1195 case 'iso10646ucsbasic':
1196 return 'ISO-10646-UCS-Basic';
1198 case 'csunicodelatin1':
1200 case 'iso10646unicodelatin1':
1201 return 'ISO-10646-Unicode-Latin1';
1203 case 'csiso10646utf1':
1204 case 'iso10646utf1':
1205 return 'ISO-10646-UTF-1';
1210 return 'ISO-11548-1';
1216 case 'csunicodeibm1261':
1217 case 'isounicodeibm1261':
1218 return 'ISO-Unicode-IBM-1261';
1220 case 'csunicodeibm1264':
1221 case 'isounicodeibm1264':
1222 return 'ISO-Unicode-IBM-1264';
1224 case 'csunicodeibm1265':
1225 case 'isounicodeibm1265':
1226 return 'ISO-Unicode-IBM-1265';
1228 case 'csunicodeibm1268':
1229 case 'isounicodeibm1268':
1230 return 'ISO-Unicode-IBM-1268';
1232 case 'csunicodeibm1276':
1233 case 'isounicodeibm1276':
1234 return 'ISO-Unicode-IBM-1276';
1236 case 'csiso646basic1983':
1237 case 'iso646basic1983':
1239 return 'ISO_646.basic:1983';
1241 case 'csiso2intlrefversion':
1243 case 'iso646irv1983':
1245 return 'ISO_646.irv:1983';
1251 return 'ISO_2033-1983';
1253 case 'csiso5427cyrillic':
1258 case 'iso5427cyrillic1981':
1261 return 'ISO_5427:1981';
1263 case 'csiso5428greek':
1266 return 'ISO_5428:1980';
1268 case 'csiso6937add':
1271 return 'ISO_6937-2-25';
1273 case 'csisotextcomm':
1276 return 'ISO_6937-2-add';
1278 case 'csiso8859supp':
1282 return 'ISO_8859-supp';
1284 case 'csiso10367box':
1287 return 'ISO_10367-box';
1289 case 'csiso15italian':
1295 case 'csiso13jisc6220jp':
1297 case 'jisc62201969':
1298 case 'jisc62201969jp':
1301 return 'JIS_C6220-1969-jp';
1303 case 'csiso14jisc6220ro':
1306 case 'jisc62201969ro':
1308 return 'JIS_C6220-1969-ro';
1310 case 'csiso42jisc62261978':
1312 case 'jisc62261978':
1313 return 'JIS_C6226-1978';
1315 case 'csiso87jisx208':
1317 case 'jisc62261983':
1320 return 'JIS_C6226-1983';
1322 case 'csiso91jisc62291984a':
1324 case 'jisc62291984a':
1326 return 'JIS_C6229-1984-a';
1328 case 'csiso92jisc62991984b':
1329 case 'iso646jpocrb':
1331 case 'jisc62291984b':
1333 return 'JIS_C6229-1984-b';
1335 case 'csiso93jis62291984badd':
1337 case 'jisc62291984badd':
1339 return 'JIS_C6229-1984-b-add';
1341 case 'csiso94jis62291984hand':
1343 case 'jisc62291984hand':
1345 return 'JIS_C6229-1984-hand';
1347 case 'csiso95jis62291984handadd':
1349 case 'jisc62291984handadd':
1350 case 'jpocrhandadd':
1351 return 'JIS_C6229-1984-hand-add';
1353 case 'csiso96jisc62291984kana':
1355 case 'jisc62291984kana':
1356 return 'JIS_C6229-1984-kana';
1358 case 'csjisencoding':
1360 return 'JIS_Encoding';
1362 case 'cshalfwidthkatakana':
1367 case 'csiso159jisx2121990':
1371 return 'JIS_X0212-1990';
1373 case 'csiso141jusib1002':
1379 return 'JUS_I.B1.002';
1381 case 'csiso147macedonian':
1383 case 'jusib1003mac':
1385 return 'JUS_I.B1.003-mac';
1387 case 'csiso146serbian':
1389 case 'jusib1003serb':
1391 return 'JUS_I.B1.003-serb';
1393 case 'koi7switched':
1394 return 'KOI7-switched';
1411 case 'strk10482002':
1414 case 'csiso19latingreek':
1417 return 'latin-greek';
1419 case 'csiso27latingreek1':
1422 return 'Latin-greek-1';
1435 case 'csmicrosoftpublishing':
1436 case 'microsoftpublishing':
1437 return 'Microsoft-Publishing';
1447 case 'csiso86hungarian':
1452 return 'MSZ_7795.3';
1459 case 'csnatsdanoadd':
1462 return 'NATS-DANO-ADD';
1469 case 'csnatssefiadd':
1472 return 'NATS-SEFI-ADD';
1474 case 'csiso151cuba':
1479 return 'NC_NC00-10:81';
1481 case 'csiso69french':
1486 return 'NF_Z_62-010';
1488 case 'csiso25french':
1491 case 'nfz620101973':
1492 return 'NF_Z_62-010_(1973)';
1494 case 'csiso60danishnorwegian':
1495 case 'csiso60norwegian1':
1502 case 'csiso61norwegian2':
1509 case 'osdebcdicdf3irv':
1510 return 'OSD_EBCDIC_DF03_IRV';
1512 case 'osdebcdicdf41':
1513 return 'OSD_EBCDIC_DF04_1';
1515 case 'osdebcdicdf415':
1516 return 'OSD_EBCDIC_DF04_15';
1518 case 'cspc8danishnorwegian':
1519 case 'pc8danishnorwegian':
1520 return 'PC8-Danish-Norwegian';
1522 case 'cspc8turkish':
1524 return 'PC8-Turkish';
1526 case 'csiso16portuguese':
1532 case 'csiso84portuguese2':
1540 case 'cyrillicasian':
1548 case 'csiso10swedish':
1555 return 'SEN_850200_B';
1557 case 'csiso11swedishfornames':
1562 return 'SEN_850200_C';
1564 case 'csiso102t617bit':
1569 case 'csiso103t618bit':
1575 case 'csiso128t101g2':
1586 return 'UNICODE-1-1';
1588 case 'csunicode11utf7':
1589 case 'unicode11utf7':
1590 return 'UNICODE-1-1-UTF-7';
1592 case 'csunknown8bit':
1594 return 'UNKNOWN-8BIT';
1602 case 'iso646irv1991':
1637 case 'csventurainternational':
1638 case 'venturainternational':
1639 return 'Ventura-International';
1641 case 'csventuramath':
1643 return 'Ventura-Math';
1647 return 'Ventura-US';
1649 case 'csiso70videotexsupp1':
1651 case 'videotexsuppl':
1652 return 'videotex-suppl';
1663 case 'cswindows31j':
1668 //return 'Windows-31J';
1672 return 'windows-874';
1675 case 'csksc56011987':
1683 return 'windows-949';
1686 return 'windows-1250';
1689 return 'windows-1251';
1695 case 'iso885911987':
1700 return 'windows-1252';
1703 return 'windows-1253';
1707 case 'iso885991989':
1712 return 'windows-1254';
1715 return 'windows-1255';
1718 return 'windows-1256';
1721 return 'windows-1257';
1724 return 'windows-1258';
1731 public static function get_curl_version()
1733 if (is_array($curl = curl_version()))
1735 $curl = $curl['version'];
1737 elseif (substr($curl, 0, 5) === 'curl/')
1739 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
1741 elseif (substr($curl, 0, 8) === 'libcurl/')
1743 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
1752 public static function is_subclass_of($class1, $class2)
1754 if (func_num_args() !== 2)
1756 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING
);
1758 elseif (version_compare(PHP_VERSION
, '5.0.3', '>=') || is_object($class1))
1760 return is_subclass_of($class1, $class2);
1762 elseif (is_string($class1) && is_string($class2))
1764 if (class_exists($class1))
1766 if (class_exists($class2))
1768 $class2 = strtolower($class2);
1769 while ($class1 = strtolower(get_parent_class($class1)))
1771 if ($class1 === $class2)
1780 trigger_error('Unknown class passed as parameter', E_USER_WARNNG
);
1787 * Strip HTML comments
1789 * @param string $data Data to strip comments from
1790 * @return string Comment stripped string
1792 public static function strip_comments($data)
1795 while (($start = strpos($data, '<!--')) !== false)
1797 $output .= substr($data, 0, $start);
1798 if (($end = strpos($data, '-->', $start)) !== false)
1800 $data = substr_replace($data, '', 0, $end +
3);
1807 return $output . $data;
1810 public static function parse_date($dt)
1812 $parser = SimplePie_Parse_Date
::get();
1813 return $parser->parse($dt);
1817 * Decode HTML entities
1820 * @param string $data Input data
1821 * @return string Output data
1823 public static function entities_decode($data)
1825 $decoder = new SimplePie_Decode_HTML_Entities($data);
1826 return $decoder->parse();
1830 * Remove RFC822 comments
1832 * @param string $data Data to strip comments from
1833 * @return string Comment stripped string
1835 public static function uncomment_rfc822($string)
1837 $string = (string) $string;
1839 $length = strlen($string);
1844 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
1846 $output .= substr($string, $position, $pos - $position);
1847 $position = $pos +
1;
1848 if ($string[$pos - 1] !== '\\')
1851 while ($depth && $position < $length)
1853 $position +
= strcspn($string, '()', $position);
1854 if ($string[$position - 1] === '\\')
1859 elseif (isset($string[$position]))
1861 switch ($string[$position])
1884 $output .= substr($string, $position);
1889 public static function parse_mime($mime)
1891 if (($pos = strpos($mime, ';')) === false)
1897 return trim(substr($mime, 0, $pos));
1901 public static function htmlspecialchars_decode($string, $quote_style)
1903 if (function_exists('htmlspecialchars_decode'))
1905 return htmlspecialchars_decode($string, $quote_style);
1909 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS
, $quote_style)));
1913 public static function atom_03_construct_type($attribs)
1915 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
1917 $mode = SIMPLEPIE_CONSTRUCT_BASE64
;
1921 $mode = SIMPLEPIE_CONSTRUCT_NONE
;
1923 if (isset($attribs['']['type']))
1925 switch (strtolower(trim($attribs['']['type'])))
1929 return SIMPLEPIE_CONSTRUCT_TEXT
| $mode;
1933 return SIMPLEPIE_CONSTRUCT_HTML
| $mode;
1936 case 'application/xhtml+xml':
1937 return SIMPLEPIE_CONSTRUCT_XHTML
| $mode;
1940 return SIMPLEPIE_CONSTRUCT_NONE
| $mode;
1945 return SIMPLEPIE_CONSTRUCT_TEXT
| $mode;
1949 public static function atom_10_construct_type($attribs)
1951 if (isset($attribs['']['type']))
1953 switch (strtolower(trim($attribs['']['type'])))
1956 return SIMPLEPIE_CONSTRUCT_TEXT
;
1959 return SIMPLEPIE_CONSTRUCT_HTML
;
1962 return SIMPLEPIE_CONSTRUCT_XHTML
;
1965 return SIMPLEPIE_CONSTRUCT_NONE
;
1968 return SIMPLEPIE_CONSTRUCT_TEXT
;
1971 public static function atom_10_content_construct_type($attribs)
1973 if (isset($attribs['']['type']))
1975 $type = strtolower(trim($attribs['']['type']));
1979 return SIMPLEPIE_CONSTRUCT_TEXT
;
1982 return SIMPLEPIE_CONSTRUCT_HTML
;
1985 return SIMPLEPIE_CONSTRUCT_XHTML
;
1987 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
1989 return SIMPLEPIE_CONSTRUCT_NONE
;
1993 return SIMPLEPIE_CONSTRUCT_BASE64
;
1998 return SIMPLEPIE_CONSTRUCT_TEXT
;
2002 public static function is_isegment_nz_nc($string)
2004 return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string);
2007 public static function space_seperated_tokens($string)
2009 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
2010 $string_length = strlen($string);
2012 $position = strspn($string, $space_characters);
2015 while ($position < $string_length)
2017 $len = strcspn($string, $space_characters, $position);
2018 $tokens[] = substr($string, $position, $len);
2020 $position +
= strspn($string, $space_characters, $position);
2026 public static function array_unique($array)
2028 if (version_compare(PHP_VERSION
, '5.2', '>='))
2030 return array_unique($array);
2034 $array = (array) $array;
2035 $new_array = array();
2036 $new_array_strings = array();
2037 foreach ($array as $key => $value)
2039 if (is_object($value))
2041 if (method_exists($value, '__toString'))
2043 $cmp = $value->__toString();
2047 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR
);
2050 elseif (is_array($value))
2052 $cmp = (string) reset($value);
2056 $cmp = (string) $value;
2058 if (!in_array($cmp, $new_array_strings))
2060 $new_array[$key] = $value;
2061 $new_array_strings[] = $cmp;
2069 * Converts a unicode codepoint to a UTF-8 character
2072 * @param int $codepoint Unicode codepoint
2073 * @return string UTF-8 character
2075 public static function codepoint_to_utf8($codepoint)
2077 $codepoint = (int) $codepoint;
2082 else if ($codepoint <= 0x7f)
2084 return chr($codepoint);
2086 else if ($codepoint <= 0x7ff)
2088 return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
2090 else if ($codepoint <= 0xffff)
2092 return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
2094 else if ($codepoint <= 0x10ffff)
2096 return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
2100 // U+FFFD REPLACEMENT CHARACTER
2101 return "\xEF\xBF\xBD";
2106 * Similar to parse_str()
2108 * Returns an associative array of name/value pairs, where the value is an
2109 * array of values that have used the same name
2112 * @param string $str The input string.
2115 public static function parse_str($str)
2118 $str = explode('&', $str);
2120 foreach ($str as $section)
2122 if (strpos($section, '=') !== false)
2124 list($name, $value) = explode('=', $section, 2);
2125 $return[urldecode($name)][] = urldecode($value);
2129 $return[urldecode($section)][] = null;
2137 * Detect XML encoding, as per XML 1.0 Appendix F.1
2139 * @todo Add support for EBCDIC
2140 * @param string $data XML data
2141 * @return array Possible encodings
2143 public static function xml_encoding($data)
2145 // UTF-32 Big Endian BOM
2146 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
2148 $encoding[] = 'UTF-32BE';
2150 // UTF-32 Little Endian BOM
2151 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
2153 $encoding[] = 'UTF-32LE';
2155 // UTF-16 Big Endian BOM
2156 elseif (substr($data, 0, 2) === "\xFE\xFF")
2158 $encoding[] = 'UTF-16BE';
2160 // UTF-16 Little Endian BOM
2161 elseif (substr($data, 0, 2) === "\xFF\xFE")
2163 $encoding[] = 'UTF-16LE';
2166 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
2168 $encoding[] = 'UTF-8';
2170 // UTF-32 Big Endian Without BOM
2171 elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C")
2173 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
2175 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc
::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
2176 if ($parser->parse())
2178 $encoding[] = $parser->encoding
;
2181 $encoding[] = 'UTF-32BE';
2183 // UTF-32 Little Endian Without BOM
2184 elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00")
2186 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
2188 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc
::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
2189 if ($parser->parse())
2191 $encoding[] = $parser->encoding
;
2194 $encoding[] = 'UTF-32LE';
2196 // UTF-16 Big Endian Without BOM
2197 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
2199 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
2201 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc
::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
2202 if ($parser->parse())
2204 $encoding[] = $parser->encoding
;
2207 $encoding[] = 'UTF-16BE';
2209 // UTF-16 Little Endian Without BOM
2210 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
2212 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
2214 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc
::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
2215 if ($parser->parse())
2217 $encoding[] = $parser->encoding
;
2220 $encoding[] = 'UTF-16LE';
2222 // US-ASCII (or superset)
2223 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
2225 if ($pos = strpos($data, "\x3F\x3E"))
2227 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
2228 if ($parser->parse())
2230 $encoding[] = $parser->encoding
;
2233 $encoding[] = 'UTF-8';
2235 // Fallback to UTF-8
2238 $encoding[] = 'UTF-8';
2243 public static function output_javascript()
2245 if (function_exists('ob_gzhandler'))
2247 ob_start('ob_gzhandler');
2249 header('Content-type: text/javascript; charset: UTF-8');
2250 header('Cache-Control: must-revalidate');
2251 header('Expires: ' . gmdate('D, d M Y H:i:s', time() +
604800) . ' GMT'); // 7 days
2253 function embed_odeo(link
) {
2254 document
.writeln('<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url='+link+
'"></embed>');
2257 function embed_quicktime(type
, bgcolor
, width
, height
, link
, placeholder
, loop
) {
2258 if (placeholder
!= '') {
2259 document
.writeln('<embed type="'+type+
'" style="cursor:hand; cursor:pointer;" href="'+link+
'" src="'+placeholder+
'" width="'+width+
'" height="'+height+
'" autoplay="false" target="myself" controller="false" loop="'+loop+
'" scale="aspect" bgcolor="'+bgcolor+
'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
2262 document
.writeln('<embed type="'+type+
'" style="cursor:hand; cursor:pointer;" src="'+link+
'" width="'+width+
'" height="'+height+
'" autoplay="false" target="myself" controller="true" loop="'+loop+
'" scale="aspect" bgcolor="'+bgcolor+
'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
2266 function embed_flash(bgcolor
, width
, height
, link
, loop
, type
) {
2267 document
.writeln('<embed src="'+link+
'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="'+type+
'" quality="high" width="'+width+
'" height="'+height+
'" bgcolor="'+bgcolor+
'" loop="'+loop+
'"></embed>');
2270 function embed_flv(width
, height
, link
, placeholder
, loop
, player
) {
2271 document
.writeln('<embed src="'+player+
'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="'+width+
'" height="'+height+
'" wmode="transparent" flashvars="file='+link+
'&autostart=false&repeat='+loop+
'&showdigits=true&showfsbutton=false"></embed>');
2274 function embed_wmedia(width
, height
, link
) {
2275 document
.writeln('<embed type="application/x-mplayer2" src="'+link+
'" autosize="1" width="'+width+
'" height="'+height+
'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
2281 * Get the SimplePie build timestamp
2283 * Uses the git index if it exists, otherwise uses the modification time
2284 * of the newest file.
2286 public static function get_build()
2288 $root = dirname(dirname(__FILE__
));
2289 if (file_exists($root . '/.git/index'))
2291 return filemtime($root . '/.git/index');
2293 elseif (file_exists($root . '/SimplePie'))
2296 foreach (glob($root . '/SimplePie/*.php') as $file)
2298 if (($mtime = filemtime($file)) > $time)
2305 elseif (file_exists(dirname(__FILE__
) . '/Core.php'))
2307 return filemtime(dirname(__FILE__
) . '/Core.php');
2311 return filemtime(__FILE__
);
2316 * Format debugging information
2318 public static function debug(&$sp)
2320 $info = 'SimplePie ' . SIMPLEPIE_VERSION
. ' Build ' . SIMPLEPIE_BUILD
. "\n";
2321 $info .= 'PHP ' . PHP_VERSION
. "\n";
2322 if ($sp->error() !== null)
2324 $info .= 'Error occurred: ' . $sp->error() . "\n";
2328 $info .= "No error found.\n";
2330 $info .= "Extensions:\n";
2331 $extensions = array('pcre', 'curl', 'zlib', 'mbstring', 'iconv', 'xmlreader', 'xml');
2332 foreach ($extensions as $ext)
2334 if (extension_loaded($ext))
2336 $info .= " $ext loaded\n";
2340 $info .= ' Version ' . PCRE_VERSION
. "\n";
2343 $version = curl_version();
2344 $info .= ' Version ' . $version['version'] . "\n";
2347 $info .= ' Overloading: ' . mb_get_info('func_overload') . "\n";
2350 $info .= ' Version ' . ICONV_VERSION
. "\n";
2353 $info .= ' Version ' . LIBXML_DOTTED_VERSION
. "\n";
2359 $info .= " $ext not loaded\n";