PageRenderTime 75ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 2ms

/concrete/libraries/3rdparty/simplepie.php

https://bitbucket.org/seanom/concrete5
PHP | 13581 lines | 13015 code | 314 blank | 252 comment | 919 complexity | d734402dca4d59e8fe7bc9bb2f02fb97 MD5 | raw file
  1. <?php
  2. /**
  3. * SimplePie
  4. *
  5. * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without modification, are
  9. * permitted provided that the following conditions are met:
  10. *
  11. * * Redistributions of source code must retain the above copyright notice, this list of
  12. * conditions and the following disclaimer.
  13. *
  14. * * Redistributions in binary form must reproduce the above copyright notice, this list
  15. * of conditions and the following disclaimer in the documentation and/or other materials
  16. * provided with the distribution.
  17. *
  18. * * Neither the name of the SimplePie Team nor the names of its contributors may be used
  19. * to endorse or promote products derived from this software without specific prior
  20. * written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  23. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  24. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
  25. * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  26. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  27. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  29. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30. * POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. * @version 1.3
  33. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  34. */
  35. define('SIMPLEPIE_NAME', 'SimplePie');
  36. define('SIMPLEPIE_VERSION', '1.3');
  37. define('SIMPLEPIE_BUILD', '20120707113013');
  38. define('SIMPLEPIE_URL', 'http://simplepie.org');
  39. define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
  40. define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
  41. define('SIMPLEPIE_LOCATOR_NONE', 0);
  42. define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
  43. define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
  44. define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
  45. define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
  46. define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
  47. define('SIMPLEPIE_LOCATOR_ALL', 31);
  48. define('SIMPLEPIE_TYPE_NONE', 0);
  49. define('SIMPLEPIE_TYPE_RSS_090', 1);
  50. define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
  51. define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
  52. define('SIMPLEPIE_TYPE_RSS_091', 6);
  53. define('SIMPLEPIE_TYPE_RSS_092', 8);
  54. define('SIMPLEPIE_TYPE_RSS_093', 16);
  55. define('SIMPLEPIE_TYPE_RSS_094', 32);
  56. define('SIMPLEPIE_TYPE_RSS_10', 64);
  57. define('SIMPLEPIE_TYPE_RSS_20', 128);
  58. define('SIMPLEPIE_TYPE_RSS_RDF', 65);
  59. define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
  60. define('SIMPLEPIE_TYPE_RSS_ALL', 255);
  61. define('SIMPLEPIE_TYPE_ATOM_03', 256);
  62. define('SIMPLEPIE_TYPE_ATOM_10', 512);
  63. define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
  64. define('SIMPLEPIE_TYPE_ALL', 1023);
  65. define('SIMPLEPIE_CONSTRUCT_NONE', 0);
  66. define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
  67. define('SIMPLEPIE_CONSTRUCT_HTML', 2);
  68. define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
  69. define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
  70. define('SIMPLEPIE_CONSTRUCT_IRI', 16);
  71. define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
  72. define('SIMPLEPIE_CONSTRUCT_ALL', 63);
  73. define('SIMPLEPIE_SAME_CASE', 1);
  74. define('SIMPLEPIE_LOWERCASE', 2);
  75. define('SIMPLEPIE_UPPERCASE', 4);
  76. define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
  77. define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
  78. define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
  79. define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
  80. define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
  81. define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
  82. define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
  83. define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
  84. define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
  85. define('SIMPLEPIE_NAMESPACE_RSS_20', '');
  86. define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
  87. define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
  88. define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
  89. define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
  90. define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
  91. define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
  92. define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2', 'http://video.search.yahoo.com/mrss');
  93. define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3', 'http://video.search.yahoo.com/mrss/');
  94. define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4', 'http://www.rssboard.org/media-rss');
  95. define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5', 'http://www.rssboard.org/media-rss/');
  96. define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
  97. define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
  98. define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
  99. define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
  100. define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
  101. define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
  102. define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
  103. define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
  104. define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
  105. class SimplePie
  106. {
  107. public $data = array();
  108. public $error;
  109. public $sanitize;
  110. public $useragent = SIMPLEPIE_USERAGENT;
  111. public $feed_url;
  112. public $file;
  113. public $raw_data;
  114. public $timeout = 10;
  115. public $force_fsockopen = false;
  116. public $force_feed = false;
  117. public $cache = true;
  118. public $cache_duration = 3600;
  119. public $autodiscovery_cache_duration = 604800; // 7 Days.
  120. public $cache_location = './cache';
  121. public $cache_name_function = 'md5';
  122. public $order_by_date = true;
  123. public $input_encoding = false;
  124. public $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
  125. public $registry;
  126. public $max_checked_feeds = 10;
  127. public $all_discovered_feeds = array();
  128. public $image_handler = '';
  129. public $multifeed_url = array();
  130. public $multifeed_objects = array();
  131. public $config_settings = null;
  132. public $item_limit = 0;
  133. public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  134. public $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  135. public function __construct()
  136. {
  137. if (version_compare(PHP_VERSION, '5.2', '<'))
  138. {
  139. trigger_error('PHP 4.x, 5.0 and 5.1 are no longer supported. Please upgrade to PHP 5.2 or newer.');
  140. die();
  141. }
  142. // Other objects, instances created here so we can set options on them
  143. $this->sanitize = new SimplePie_Sanitize();
  144. $this->registry = new SimplePie_Registry();
  145. if (func_num_args() > 0)
  146. {
  147. trigger_error('Passing parameters to the constructor is no longer supported. Please use set_feed_url(), set_cache_location(), and set_cache_location() directly.');
  148. }
  149. }
  150. public function __toString()
  151. {
  152. return md5(serialize($this->data));
  153. }
  154. public function __destruct()
  155. {
  156. if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
  157. {
  158. if (!empty($this->data['items']))
  159. {
  160. foreach ($this->data['items'] as $item)
  161. {
  162. $item->__destruct();
  163. }
  164. unset($item, $this->data['items']);
  165. }
  166. if (!empty($this->data['ordered_items']))
  167. {
  168. foreach ($this->data['ordered_items'] as $item)
  169. {
  170. $item->__destruct();
  171. }
  172. unset($item, $this->data['ordered_items']);
  173. }
  174. }
  175. }
  176. public function force_feed($enable = false)
  177. {
  178. $this->force_feed = (bool) $enable;
  179. }
  180. public function set_feed_url($url)
  181. {
  182. $this->multifeed_url = array();
  183. if (is_array($url))
  184. {
  185. foreach ($url as $value)
  186. {
  187. $this->multifeed_url[] = $this->registry->call('Misc', 'fix_protocol', array($value, 1));
  188. }
  189. }
  190. else
  191. {
  192. $this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1));
  193. }
  194. }
  195. public function set_file(&$file)
  196. {
  197. if ($file instanceof SimplePie_File)
  198. {
  199. $this->feed_url = $file->url;
  200. $this->file =& $file;
  201. return true;
  202. }
  203. return false;
  204. }
  205. public function set_raw_data($data)
  206. {
  207. $this->raw_data = $data;
  208. }
  209. public function set_timeout($timeout = 10)
  210. {
  211. $this->timeout = (int) $timeout;
  212. }
  213. public function force_fsockopen($enable = false)
  214. {
  215. $this->force_fsockopen = (bool) $enable;
  216. }
  217. public function enable_cache($enable = true)
  218. {
  219. $this->cache = (bool) $enable;
  220. }
  221. public function set_cache_duration($seconds = 3600)
  222. {
  223. $this->cache_duration = (int) $seconds;
  224. }
  225. public function set_autodiscovery_cache_duration($seconds = 604800)
  226. {
  227. $this->autodiscovery_cache_duration = (int) $seconds;
  228. }
  229. public function set_cache_location($location = './cache')
  230. {
  231. $this->cache_location = (string) $location;
  232. }
  233. public function enable_order_by_date($enable = true)
  234. {
  235. $this->order_by_date = (bool) $enable;
  236. }
  237. public function set_input_encoding($encoding = false)
  238. {
  239. if ($encoding)
  240. {
  241. $this->input_encoding = (string) $encoding;
  242. }
  243. else
  244. {
  245. $this->input_encoding = false;
  246. }
  247. }
  248. public function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
  249. {
  250. $this->autodiscovery = (int) $level;
  251. }
  252. public function &get_registry()
  253. {
  254. return $this->registry;
  255. }
  256. /**
  257. * Set which class SimplePie uses for caching
  258. */
  259. public function set_cache_class($class = 'SimplePie_Cache')
  260. {
  261. return $this->registry->register('Cache', $class, true);
  262. }
  263. public function set_locator_class($class = 'SimplePie_Locator')
  264. {
  265. return $this->registry->register('Locator', $class, true);
  266. }
  267. public function set_parser_class($class = 'SimplePie_Parser')
  268. {
  269. return $this->registry->register('Parser', $class, true);
  270. }
  271. public function set_file_class($class = 'SimplePie_File')
  272. {
  273. return $this->registry->register('File', $class, true);
  274. }
  275. public function set_sanitize_class($class = 'SimplePie_Sanitize')
  276. {
  277. return $this->registry->register('Sanitize', $class, true);
  278. }
  279. public function set_item_class($class = 'SimplePie_Item')
  280. {
  281. return $this->registry->register('Item', $class, true);
  282. }
  283. public function set_author_class($class = 'SimplePie_Author')
  284. {
  285. return $this->registry->register('Author', $class, true);
  286. }
  287. public function set_category_class($class = 'SimplePie_Category')
  288. {
  289. return $this->registry->register('Category', $class, true);
  290. }
  291. public function set_enclosure_class($class = 'SimplePie_Enclosure')
  292. {
  293. return $this->registry->register('Enclosure', $class, true);
  294. }
  295. public function set_caption_class($class = 'SimplePie_Caption')
  296. {
  297. return $this->registry->register('Caption', $class, true);
  298. }
  299. public function set_copyright_class($class = 'SimplePie_Copyright')
  300. {
  301. return $this->registry->register('Copyright', $class, true);
  302. }
  303. public function set_credit_class($class = 'SimplePie_Credit')
  304. {
  305. return $this->registry->register('Credit', $class, true);
  306. }
  307. public function set_rating_class($class = 'SimplePie_Rating')
  308. {
  309. return $this->registry->register('Rating', $class, true);
  310. }
  311. public function set_restriction_class($class = 'SimplePie_Restriction')
  312. {
  313. return $this->registry->register('Restriction', $class, true);
  314. }
  315. public function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
  316. {
  317. return $this->registry->register('Content_Type_Sniffer', $class, true);
  318. }
  319. public function set_source_class($class = 'SimplePie_Source')
  320. {
  321. return $this->registry->register('Source', $class, true);
  322. }
  323. public function set_useragent($ua = SIMPLEPIE_USERAGENT)
  324. {
  325. $this->useragent = (string) $ua;
  326. }
  327. public function set_cache_name_function($function = 'md5')
  328. {
  329. if (is_callable($function))
  330. {
  331. $this->cache_name_function = $function;
  332. }
  333. }
  334. public function set_stupidly_fast($set = false)
  335. {
  336. if ($set)
  337. {
  338. $this->enable_order_by_date(false);
  339. $this->remove_div(false);
  340. $this->strip_comments(false);
  341. $this->strip_htmltags(false);
  342. $this->strip_attributes(false);
  343. $this->set_image_handler(false);
  344. }
  345. }
  346. public function set_max_checked_feeds($max = 10)
  347. {
  348. $this->max_checked_feeds = (int) $max;
  349. }
  350. public function remove_div($enable = true)
  351. {
  352. $this->sanitize->remove_div($enable);
  353. }
  354. public function strip_htmltags($tags = '', $encode = null)
  355. {
  356. if ($tags === '')
  357. {
  358. $tags = $this->strip_htmltags;
  359. }
  360. $this->sanitize->strip_htmltags($tags);
  361. if ($encode !== null)
  362. {
  363. $this->sanitize->encode_instead_of_strip($tags);
  364. }
  365. }
  366. public function encode_instead_of_strip($enable = true)
  367. {
  368. $this->sanitize->encode_instead_of_strip($enable);
  369. }
  370. public function strip_attributes($attribs = '')
  371. {
  372. if ($attribs === '')
  373. {
  374. $attribs = $this->strip_attributes;
  375. }
  376. $this->sanitize->strip_attributes($attribs);
  377. }
  378. public function set_output_encoding($encoding = 'UTF-8')
  379. {
  380. $this->sanitize->set_output_encoding($encoding);
  381. }
  382. public function strip_comments($strip = false)
  383. {
  384. $this->sanitize->strip_comments($strip);
  385. }
  386. public function set_url_replacements($element_attribute = null)
  387. {
  388. $this->sanitize->set_url_replacements($element_attribute);
  389. }
  390. public function set_image_handler($page = false, $qs = 'i')
  391. {
  392. if ($page !== false)
  393. {
  394. $this->sanitize->set_image_handler($page . '?' . $qs . '=');
  395. }
  396. else
  397. {
  398. $this->image_handler = '';
  399. }
  400. }
  401. public function set_item_limit($limit = 0)
  402. {
  403. $this->item_limit = (int) $limit;
  404. }
  405. public function init()
  406. {
  407. // Check absolute bare minimum requirements.
  408. if (!extension_loaded('xml') || !extension_loaded('pcre'))
  409. {
  410. return false;
  411. }
  412. // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader.
  413. elseif (!extension_loaded('xmlreader'))
  414. {
  415. static $xml_is_sane = null;
  416. if ($xml_is_sane === null)
  417. {
  418. $parser_check = xml_parser_create();
  419. xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
  420. xml_parser_free($parser_check);
  421. $xml_is_sane = isset($values[0]['value']);
  422. }
  423. if (!$xml_is_sane)
  424. {
  425. return false;
  426. }
  427. }
  428. if (method_exists($this->sanitize, 'set_registry'))
  429. {
  430. $this->sanitize->set_registry($this->registry);
  431. }
  432. // Pass whatever was set with config options over to the sanitizer.
  433. // Pass the classes in for legacy support; new classes should use the registry instead
  434. $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->registry->get_class('Cache'));
  435. $this->sanitize->pass_file_data($this->registry->get_class('File'), $this->timeout, $this->useragent, $this->force_fsockopen);
  436. if (!empty($this->multifeed_url))
  437. {
  438. $i = 0;
  439. $success = 0;
  440. $this->multifeed_objects = array();
  441. $this->error = array();
  442. foreach ($this->multifeed_url as $url)
  443. {
  444. $this->multifeed_objects[$i] = clone $this;
  445. $this->multifeed_objects[$i]->set_feed_url($url);
  446. $single_success = $this->multifeed_objects[$i]->init();
  447. $success |= $single_success;
  448. if (!$single_success)
  449. {
  450. $this->error[$i] = $this->multifeed_objects[$i]->error();
  451. }
  452. $i++;
  453. }
  454. return (bool) $success;
  455. }
  456. elseif ($this->feed_url === null && $this->raw_data === null)
  457. {
  458. return false;
  459. }
  460. $this->error = null;
  461. $this->data = array();
  462. $this->multifeed_objects = array();
  463. $cache = false;
  464. if ($this->feed_url !== null)
  465. {
  466. $parsed_feed_url = $this->registry->call('Misc', 'parse_url', array($this->feed_url));
  467. // Decide whether to enable caching
  468. if ($this->cache && $parsed_feed_url['scheme'] !== '')
  469. {
  470. $cache = $this->registry->call('Cache', 'create', array($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc'));
  471. }
  472. // Fetch the data via SimplePie_File into $this->raw_data
  473. if (($fetched = $this->fetch_data($cache)) === true)
  474. {
  475. return true;
  476. }
  477. elseif ($fetched === false) {
  478. return false;
  479. }
  480. list($headers, $sniffed) = $fetched;
  481. }
  482. // Set up array of possible encodings
  483. $encodings = array();
  484. // First check to see if input has been overridden.
  485. if ($this->input_encoding !== false)
  486. {
  487. $encodings[] = $this->input_encoding;
  488. }
  489. $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
  490. $text_types = array('text/xml', 'text/xml-external-parsed-entity');
  491. // RFC 3023 (only applies to sniffed content)
  492. if (isset($sniffed))
  493. {
  494. if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
  495. {
  496. if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  497. {
  498. $encodings[] = strtoupper($charset[1]);
  499. }
  500. $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
  501. $encodings[] = 'UTF-8';
  502. }
  503. elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
  504. {
  505. if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  506. {
  507. $encodings[] = $charset[1];
  508. }
  509. $encodings[] = 'US-ASCII';
  510. }
  511. // Text MIME-type default
  512. elseif (substr($sniffed, 0, 5) === 'text/')
  513. {
  514. $encodings[] = 'US-ASCII';
  515. }
  516. }
  517. // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
  518. $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
  519. $encodings[] = 'UTF-8';
  520. $encodings[] = 'ISO-8859-1';
  521. // There's no point in trying an encoding twice
  522. $encodings = array_unique($encodings);
  523. // Loop through each possible encoding, till we return something, or run out of possibilities
  524. foreach ($encodings as $encoding)
  525. {
  526. // Change the encoding to UTF-8 (as we always use UTF-8 internally)
  527. if ($utf8_data = $this->registry->call('Misc', 'change_encoding', array($this->raw_data, $encoding, 'UTF-8')))
  528. {
  529. // Create new parser
  530. $parser = $this->registry->create('Parser');
  531. // If it's parsed fine
  532. if ($parser->parse($utf8_data, 'UTF-8'))
  533. {
  534. $this->data = $parser->get_data();
  535. if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE))
  536. {
  537. $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
  538. $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
  539. return false;
  540. }
  541. if (isset($headers))
  542. {
  543. $this->data['headers'] = $headers;
  544. }
  545. $this->data['build'] = SIMPLEPIE_BUILD;
  546. // Cache the file if caching is enabled
  547. if ($cache && !$cache->save($this))
  548. {
  549. trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
  550. }
  551. return true;
  552. }
  553. }
  554. }
  555. if (isset($parser))
  556. {
  557. // We have an error, just set SimplePie_Misc::error to it and quit
  558. $this->error = sprintf('This XML document is invalid, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
  559. }
  560. else
  561. {
  562. $this->error = 'The data could not be converted to UTF-8. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.';
  563. }
  564. $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
  565. return false;
  566. }
  567. protected function fetch_data(&$cache)
  568. {
  569. // If it's enabled, use the cache
  570. if ($cache)
  571. {
  572. // Load the Cache
  573. $this->data = $cache->load();
  574. if (!empty($this->data))
  575. {
  576. // If the cache is for an outdated build of SimplePie
  577. if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
  578. {
  579. $cache->unlink();
  580. $this->data = array();
  581. }
  582. // If we've hit a collision just rerun it with caching disabled
  583. elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
  584. {
  585. $cache = false;
  586. $this->data = array();
  587. }
  588. // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
  589. elseif (isset($this->data['feed_url']))
  590. {
  591. // If the autodiscovery cache is still valid use it.
  592. if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
  593. {
  594. // Do not need to do feed autodiscovery yet.
  595. if ($this->data['feed_url'] !== $this->data['url'])
  596. {
  597. $this->set_feed_url($this->data['feed_url']);
  598. return $this->init();
  599. }
  600. $cache->unlink();
  601. $this->data = array();
  602. }
  603. }
  604. // Check if the cache has been updated
  605. elseif ($cache->mtime() + $this->cache_duration < time())
  606. {
  607. // If we have last-modified and/or etag set
  608. if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
  609. {
  610. $headers = array(
  611. 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
  612. );
  613. if (isset($this->data['headers']['last-modified']))
  614. {
  615. $headers['if-modified-since'] = $this->data['headers']['last-modified'];
  616. }
  617. if (isset($this->data['headers']['etag']))
  618. {
  619. $headers['if-none-match'] = $this->data['headers']['etag'];
  620. }
  621. $file = $this->registry->create('File', array($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen));
  622. if ($file->success)
  623. {
  624. if ($file->status_code === 304)
  625. {
  626. $cache->touch();
  627. return true;
  628. }
  629. }
  630. else
  631. {
  632. unset($file);
  633. }
  634. }
  635. }
  636. // If the cache is still valid, just return true
  637. else
  638. {
  639. $this->raw_data = false;
  640. return true;
  641. }
  642. }
  643. // If the cache is empty, delete it
  644. else
  645. {
  646. $cache->unlink();
  647. $this->data = array();
  648. }
  649. }
  650. // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
  651. if (!isset($file))
  652. {
  653. if ($this->file instanceof SimplePie_File && $this->file->url === $this->feed_url)
  654. {
  655. $file =& $this->file;
  656. }
  657. else
  658. {
  659. $headers = array(
  660. 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
  661. );
  662. $file = $this->registry->create('File', array($this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen));
  663. }
  664. }
  665. // If the file connection has an error, set SimplePie::error to that and quit
  666. if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
  667. {
  668. $this->error = $file->error;
  669. return !empty($this->data);
  670. }
  671. if (!$this->force_feed)
  672. {
  673. // Check if the supplied URL is a feed, if it isn't, look for it.
  674. $locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds));
  675. if (!$locate->is_feed($file))
  676. {
  677. // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
  678. unset($file);
  679. if (!($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds)))
  680. {
  681. $this->error = "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME . " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed.";
  682. $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
  683. return false;
  684. }
  685. if ($cache)
  686. {
  687. $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
  688. if (!$cache->save($this))
  689. {
  690. trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
  691. }
  692. $cache = $this->registry->call('Cache', 'create', array($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'));
  693. }
  694. $this->feed_url = $file->url;
  695. }
  696. $locate = null;
  697. }
  698. $this->raw_data = $file->body;
  699. $headers = $file->headers;
  700. $sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file));
  701. $sniffed = $sniffer->get_type();
  702. return array($headers, $sniffed);
  703. }
  704. public function error()
  705. {
  706. return $this->error;
  707. }
  708. public function get_raw_data()
  709. {
  710. return $this->raw_data;
  711. }
  712. public function get_encoding()
  713. {
  714. return $this->sanitize->output_encoding;
  715. }
  716. public function handle_content_type($mime = 'text/html')
  717. {
  718. if (!headers_sent())
  719. {
  720. $header = "Content-type: $mime;";
  721. if ($this->get_encoding())
  722. {
  723. $header .= ' charset=' . $this->get_encoding();
  724. }
  725. else
  726. {
  727. $header .= ' charset=UTF-8';
  728. }
  729. header($header);
  730. }
  731. }
  732. public function get_type()
  733. {
  734. if (!isset($this->data['type']))
  735. {
  736. $this->data['type'] = SIMPLEPIE_TYPE_ALL;
  737. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
  738. {
  739. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
  740. }
  741. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
  742. {
  743. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
  744. }
  745. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
  746. {
  747. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
  748. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
  749. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
  750. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
  751. {
  752. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
  753. }
  754. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
  755. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
  756. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
  757. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
  758. {
  759. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
  760. }
  761. }
  762. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
  763. {
  764. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
  765. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
  766. {
  767. switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
  768. {
  769. case '0.91':
  770. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
  771. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
  772. {
  773. switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
  774. {
  775. case '0':
  776. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
  777. break;
  778. case '24':
  779. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
  780. break;
  781. }
  782. }
  783. break;
  784. case '0.92':
  785. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
  786. break;
  787. case '0.93':
  788. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
  789. break;
  790. case '0.94':
  791. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
  792. break;
  793. case '2.0':
  794. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
  795. break;
  796. }
  797. }
  798. }
  799. else
  800. {
  801. $this->data['type'] = SIMPLEPIE_TYPE_NONE;
  802. }
  803. }
  804. return $this->data['type'];
  805. }
  806. public function subscribe_url()
  807. {
  808. if ($this->feed_url !== null)
  809. {
  810. return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
  811. }
  812. else
  813. {
  814. return null;
  815. }
  816. }
  817. public function get_feed_tags($namespace, $tag)
  818. {
  819. $type = $this->get_type();
  820. if ($type & SIMPLEPIE_TYPE_ATOM_10)
  821. {
  822. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
  823. {
  824. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
  825. }
  826. }
  827. if ($type & SIMPLEPIE_TYPE_ATOM_03)
  828. {
  829. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
  830. {
  831. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
  832. }
  833. }
  834. if ($type & SIMPLEPIE_TYPE_RSS_RDF)
  835. {
  836. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
  837. {
  838. return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
  839. }
  840. }
  841. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  842. {
  843. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
  844. {
  845. return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
  846. }
  847. }
  848. return null;
  849. }
  850. public function get_channel_tags($namespace, $tag)
  851. {
  852. $type = $this->get_type();
  853. if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
  854. {
  855. if ($return = $this->get_feed_tags($namespace, $tag))
  856. {
  857. return $return;
  858. }
  859. }
  860. if ($type & SIMPLEPIE_TYPE_RSS_10)
  861. {
  862. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
  863. {
  864. if (isset($channel[0]['child'][$namespace][$tag]))
  865. {
  866. return $channel[0]['child'][$namespace][$tag];
  867. }
  868. }
  869. }
  870. if ($type & SIMPLEPIE_TYPE_RSS_090)
  871. {
  872. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
  873. {
  874. if (isset($channel[0]['child'][$namespace][$tag]))
  875. {
  876. return $channel[0]['child'][$namespace][$tag];
  877. }
  878. }
  879. }
  880. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  881. {
  882. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
  883. {
  884. if (isset($channel[0]['child'][$namespace][$tag]))
  885. {
  886. return $channel[0]['child'][$namespace][$tag];
  887. }
  888. }
  889. }
  890. return null;
  891. }
  892. public function get_image_tags($namespace, $tag)
  893. {
  894. $type = $this->get_type();
  895. if ($type & SIMPLEPIE_TYPE_RSS_10)
  896. {
  897. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
  898. {
  899. if (isset($image[0]['child'][$namespace][$tag]))
  900. {
  901. return $image[0]['child'][$namespace][$tag];
  902. }
  903. }
  904. }
  905. if ($type & SIMPLEPIE_TYPE_RSS_090)
  906. {
  907. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
  908. {
  909. if (isset($image[0]['child'][$namespace][$tag]))
  910. {
  911. return $image[0]['child'][$namespace][$tag];
  912. }
  913. }
  914. }
  915. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  916. {
  917. if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
  918. {
  919. if (isset($image[0]['child'][$namespace][$tag]))
  920. {
  921. return $image[0]['child'][$namespace][$tag];
  922. }
  923. }
  924. }
  925. return null;
  926. }
  927. public function get_base($element = array())
  928. {
  929. if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
  930. {
  931. return $element['xml_base'];
  932. }
  933. elseif ($this->get_link() !== null)
  934. {
  935. return $this->get_link();
  936. }
  937. else
  938. {
  939. return $this->subscribe_url();
  940. }
  941. }
  942. public function sanitize($data, $type, $base = '')
  943. {
  944. return $this->sanitize->sanitize($data, $type, $base);
  945. }
  946. public function get_title()
  947. {
  948. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  949. {
  950. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  951. }
  952. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  953. {
  954. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  955. }
  956. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  957. {
  958. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  959. }
  960. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  961. {
  962. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  963. }
  964. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  965. {
  966. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  967. }
  968. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  969. {
  970. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  971. }
  972. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  973. {
  974. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  975. }
  976. else
  977. {
  978. return null;
  979. }
  980. }
  981. public function get_category($key = 0)
  982. {
  983. $categories = $this->get_categories();
  984. if (isset($categories[$key]))
  985. {
  986. return $categories[$key];
  987. }
  988. else
  989. {
  990. return null;
  991. }
  992. }
  993. public function get_categories()
  994. {
  995. $categories = array();
  996. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  997. {
  998. $term = null;
  999. $scheme = null;
  1000. $label = null;
  1001. if (isset($category['attribs']['']['term']))
  1002. {
  1003. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  1004. }
  1005. if (isset($category['attribs']['']['scheme']))
  1006. {
  1007. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  1008. }
  1009. if (isset($category['attribs']['']['label']))
  1010. {
  1011. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  1012. }
  1013. $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
  1014. }
  1015. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
  1016. {
  1017. // This is really the label, but keep this as the term also for BC.
  1018. // Label will also work on retrieving because that falls back to term.
  1019. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1020. if (isset($category['attribs']['']['domain']))
  1021. {
  1022. $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
  1023. }
  1024. else
  1025. {
  1026. $scheme = null;
  1027. }
  1028. $categories[] = $this->registry->create('Category', array($term, $scheme, null));
  1029. }
  1030. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  1031. {
  1032. $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  1033. }
  1034. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  1035. {
  1036. $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  1037. }
  1038. if (!empty($categories))
  1039. {
  1040. return array_unique($categories);
  1041. }
  1042. else
  1043. {
  1044. return null;
  1045. }
  1046. }
  1047. public function get_author($key = 0)
  1048. {
  1049. $authors = $this->get_authors();
  1050. if (isset($authors[$key]))
  1051. {
  1052. return $authors[$key];
  1053. }
  1054. else
  1055. {
  1056. return null;
  1057. }
  1058. }
  1059. public function get_authors()
  1060. {
  1061. $authors = array();
  1062. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  1063. {
  1064. $name = null;
  1065. $uri = null;
  1066. $email = null;
  1067. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  1068. {
  1069. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1070. }
  1071. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  1072. {
  1073. $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
  1074. }
  1075. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  1076. {
  1077. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1078. }
  1079. if ($name !== null || $email !== null || $uri !== null)
  1080. {
  1081. $authors[] = $this->registry->create('Author', array($name, $uri, $email));
  1082. }
  1083. }
  1084. if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  1085. {
  1086. $name = null;
  1087. $url = null;
  1088. $email = null;
  1089. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  1090. {
  1091. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1092. }
  1093. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  1094. {
  1095. $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
  1096. }
  1097. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  1098. {
  1099. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1100. }
  1101. if ($name !== null || $email !== null || $url !== null)
  1102. {
  1103. $authors[] = $this->registry->create('Author', array($name, $url, $email));
  1104. }
  1105. }
  1106. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  1107. {
  1108. $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  1109. }
  1110. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  1111. {
  1112. $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  1113. }
  1114. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  1115. {
  1116. $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  1117. }
  1118. if (!empty($authors))
  1119. {
  1120. return array_unique($authors);
  1121. }
  1122. else
  1123. {
  1124. return null;
  1125. }
  1126. }
  1127. public function get_contributor($key = 0)
  1128. {
  1129. $contributors = $this->get_contributors();
  1130. if (isset($contributors[$key]))
  1131. {
  1132. return $contributors[$key];
  1133. }
  1134. else
  1135. {
  1136. return null;
  1137. }
  1138. }
  1139. public function get_contributors()
  1140. {
  1141. $contributors = array();
  1142. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  1143. {
  1144. $name = null;
  1145. $uri = null;
  1146. $email = null;
  1147. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  1148. {
  1149. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1150. }
  1151. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  1152. {
  1153. $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
  1154. }
  1155. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  1156. {
  1157. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1158. }
  1159. if ($name !== null || $email !== null || $uri !== null)
  1160. {
  1161. $contributors[] = $this->registry->create('Author', array($name, $uri, $email));
  1162. }
  1163. }
  1164. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  1165. {
  1166. $name = null;
  1167. $url = null;
  1168. $email = null;
  1169. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  1170. {
  1171. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1172. }
  1173. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  1174. {
  1175. $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
  1176. }
  1177. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  1178. {
  1179. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1180. }
  1181. if ($name !== null || $email !== null || $url !== null)
  1182. {
  1183. $contributors[] = $this->registry->create('Author', array($name, $url, $email));
  1184. }
  1185. }
  1186. if (!empty($contributors))
  1187. {
  1188. return array_unique($contributors);
  1189. }
  1190. else
  1191. {
  1192. return null;
  1193. }
  1194. }
  1195. public function get_link($key = 0, $rel = 'alternate')
  1196. {
  1197. $links = $this->get_links($rel);
  1198. if (isset($links[$key]))
  1199. {
  1200. return $links[$key];
  1201. }
  1202. else
  1203. {
  1204. return null;
  1205. }
  1206. }
  1207. public function get_permalink()
  1208. {
  1209. return $this->get_link(0);
  1210. }
  1211. public function get_links($rel = 'alternate')
  1212. {
  1213. if (!isset($this->data['links']))
  1214. {
  1215. $this->data['links'] = array();
  1216. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  1217. {
  1218. foreach ($links as $link)
  1219. {
  1220. if (isset($link['attribs']['']['href']))
  1221. {
  1222. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  1223. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  1224. }
  1225. }
  1226. }
  1227. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  1228. {
  1229. foreach ($links as $link)
  1230. {
  1231. if (isset($link['attribs']['']['href']))
  1232. {
  1233. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  1234. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  1235. }
  1236. }
  1237. }
  1238. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  1239. {
  1240. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  1241. }
  1242. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  1243. {
  1244. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  1245. }
  1246. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  1247. {
  1248. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  1249. }
  1250. $keys = array_keys($this->data['links']);
  1251. foreach ($keys as $key)
  1252. {
  1253. if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
  1254. {
  1255. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  1256. {
  1257. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  1258. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  1259. }
  1260. else
  1261. {
  1262. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  1263. }
  1264. }
  1265. elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  1266. {
  1267. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  1268. }
  1269. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  1270. }
  1271. }
  1272. if (isset($this->data['links'][$rel]))
  1273. {
  1274. return $this->data['links'][$rel];
  1275. }
  1276. else
  1277. {
  1278. return null;
  1279. }
  1280. }
  1281. public function get_all_discovered_feeds()
  1282. {
  1283. return $this->all_discovered_feeds;
  1284. }
  1285. public function get_description()
  1286. {
  1287. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  1288. {
  1289. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  1290. }
  1291. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  1292. {
  1293. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  1294. }
  1295. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  1296. {
  1297. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  1298. }
  1299. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  1300. {
  1301. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  1302. }
  1303. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
  1304. {
  1305. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  1306. }
  1307. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  1308. {
  1309. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1310. }
  1311. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  1312. {
  1313. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1314. }
  1315. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  1316. {
  1317. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  1318. }
  1319. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  1320. {
  1321. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  1322. }
  1323. else
  1324. {
  1325. return null;
  1326. }
  1327. }
  1328. public function get_copyright()
  1329. {
  1330. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  1331. {
  1332. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  1333. }
  1334. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
  1335. {
  1336. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  1337. }
  1338. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
  1339. {
  1340. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1341. }
  1342. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  1343. {
  1344. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1345. }
  1346. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  1347. {
  1348. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1349. }
  1350. else
  1351. {
  1352. return null;
  1353. }
  1354. }
  1355. public function get_language()
  1356. {
  1357. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
  1358. {
  1359. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1360. }
  1361. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  1362. {
  1363. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1364. }
  1365. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  1366. {
  1367. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1368. }
  1369. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
  1370. {
  1371. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  1372. }
  1373. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
  1374. {
  1375. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  1376. }
  1377. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
  1378. {
  1379. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  1380. }
  1381. elseif (isset($this->data['headers']['content-language']))
  1382. {
  1383. return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
  1384. }
  1385. else
  1386. {
  1387. return null;
  1388. }
  1389. }
  1390. public function get_latitude()
  1391. {
  1392. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  1393. {
  1394. return (float) $return[0]['data'];
  1395. }
  1396. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  1397. {
  1398. return (float) $match[1];
  1399. }
  1400. else
  1401. {
  1402. return null;
  1403. }
  1404. }
  1405. public function get_longitude()
  1406. {
  1407. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  1408. {
  1409. return (float) $return[0]['data'];
  1410. }
  1411. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  1412. {
  1413. return (float) $return[0]['data'];
  1414. }
  1415. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  1416. {
  1417. return (float) $match[2];
  1418. }
  1419. else
  1420. {
  1421. return null;
  1422. }
  1423. }
  1424. public function get_image_title()
  1425. {
  1426. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  1427. {
  1428. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1429. }
  1430. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  1431. {
  1432. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1433. }
  1434. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  1435. {
  1436. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1437. }
  1438. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  1439. {
  1440. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1441. }
  1442. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  1443. {
  1444. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1445. }
  1446. else
  1447. {
  1448. return null;
  1449. }
  1450. }
  1451. public function get_image_url()
  1452. {
  1453. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  1454. {
  1455. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  1456. }
  1457. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  1458. {
  1459. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1460. }
  1461. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  1462. {
  1463. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1464. }
  1465. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
  1466. {
  1467. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1468. }
  1469. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
  1470. {
  1471. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1472. }
  1473. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  1474. {
  1475. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1476. }
  1477. else
  1478. {
  1479. return null;
  1480. }
  1481. }
  1482. public function get_image_link()
  1483. {
  1484. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  1485. {
  1486. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1487. }
  1488. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  1489. {
  1490. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1491. }
  1492. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  1493. {
  1494. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1495. }
  1496. else
  1497. {
  1498. return null;
  1499. }
  1500. }
  1501. public function get_image_width()
  1502. {
  1503. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
  1504. {
  1505. return round($return[0]['data']);
  1506. }
  1507. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  1508. {
  1509. return 88.0;
  1510. }
  1511. else
  1512. {
  1513. return null;
  1514. }
  1515. }
  1516. public function get_image_height()
  1517. {
  1518. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
  1519. {
  1520. return round($return[0]['data']);
  1521. }
  1522. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  1523. {
  1524. return 31.0;
  1525. }
  1526. else
  1527. {
  1528. return null;
  1529. }
  1530. }
  1531. public function get_item_quantity($max = 0)
  1532. {
  1533. $max = (int) $max;
  1534. $qty = count($this->get_items());
  1535. if ($max === 0)
  1536. {
  1537. return $qty;
  1538. }
  1539. else
  1540. {
  1541. return ($qty > $max) ? $max : $qty;
  1542. }
  1543. }
  1544. public function get_item($key = 0)
  1545. {
  1546. $items = $this->get_items();
  1547. if (isset($items[$key]))
  1548. {
  1549. return $items[$key];
  1550. }
  1551. else
  1552. {
  1553. return null;
  1554. }
  1555. }
  1556. public function get_items($start = 0, $end = 0)
  1557. {
  1558. if (!isset($this->data['items']))
  1559. {
  1560. if (!empty($this->multifeed_objects))
  1561. {
  1562. $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
  1563. }
  1564. else
  1565. {
  1566. $this->data['items'] = array();
  1567. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
  1568. {
  1569. $keys = array_keys($items);
  1570. foreach ($keys as $key)
  1571. {
  1572. $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  1573. }
  1574. }
  1575. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
  1576. {
  1577. $keys = array_keys($items);
  1578. foreach ($keys as $key)
  1579. {
  1580. $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  1581. }
  1582. }
  1583. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
  1584. {
  1585. $keys = array_keys($items);
  1586. foreach ($keys as $key)
  1587. {
  1588. $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  1589. }
  1590. }
  1591. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
  1592. {
  1593. $keys = array_keys($items);
  1594. foreach ($keys as $key)
  1595. {
  1596. $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  1597. }
  1598. }
  1599. if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
  1600. {
  1601. $keys = array_keys($items);
  1602. foreach ($keys as $key)
  1603. {
  1604. $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  1605. }
  1606. }
  1607. }
  1608. }
  1609. if (!empty($this->data['items']))
  1610. {
  1611. // If we want to order it by date, check if all items have a date, and then sort it
  1612. if ($this->order_by_date && empty($this->multifeed_objects))
  1613. {
  1614. if (!isset($this->data['ordered_items']))
  1615. {
  1616. $do_sort = true;
  1617. foreach ($this->data['items'] as $item)
  1618. {
  1619. if (!$item->get_date('U'))
  1620. {
  1621. $do_sort = false;
  1622. break;
  1623. }
  1624. }
  1625. $item = null;
  1626. $this->data['ordered_items'] = $this->data['items'];
  1627. if ($do_sort)
  1628. {
  1629. usort($this->data['ordered_items'], array(get_class($this), 'sort_items'));
  1630. }
  1631. }
  1632. $items = $this->data['ordered_items'];
  1633. }
  1634. else
  1635. {
  1636. $items = $this->data['items'];
  1637. }
  1638. // Slice the data as desired
  1639. if ($end === 0)
  1640. {
  1641. return array_slice($items, $start);
  1642. }
  1643. else
  1644. {
  1645. return array_slice($items, $start, $end);
  1646. }
  1647. }
  1648. else
  1649. {
  1650. return array();
  1651. }
  1652. }
  1653. public static function sort_items($a, $b)
  1654. {
  1655. return $a->get_date('U') <= $b->get_date('U');
  1656. }
  1657. public static function merge_items($urls, $start = 0, $end = 0, $limit = 0)
  1658. {
  1659. if (is_array($urls) && sizeof($urls) > 0)
  1660. {
  1661. $items = array();
  1662. foreach ($urls as $arg)
  1663. {
  1664. if ($arg instanceof SimplePie)
  1665. {
  1666. $items = array_merge($items, $arg->get_items(0, $limit));
  1667. }
  1668. else
  1669. {
  1670. trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
  1671. }
  1672. }
  1673. $do_sort = true;
  1674. foreach ($items as $item)
  1675. {
  1676. if (!$item->get_date('U'))
  1677. {
  1678. $do_sort = false;
  1679. break;
  1680. }
  1681. }
  1682. $item = null;
  1683. if ($do_sort)
  1684. {
  1685. usort($items, array(get_class($urls[0]), 'sort_items'));
  1686. }
  1687. if ($end === 0)
  1688. {
  1689. return array_slice($items, $start);
  1690. }
  1691. else
  1692. {
  1693. return array_slice($items, $start, $end);
  1694. }
  1695. }
  1696. else
  1697. {
  1698. trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
  1699. return array();
  1700. }
  1701. }
  1702. }
  1703. class SimplePie_Author
  1704. {
  1705. var $name;
  1706. var $link;
  1707. var $email;
  1708. public function __construct($name = null, $link = null, $email = null)
  1709. {
  1710. $this->name = $name;
  1711. $this->link = $link;
  1712. $this->email = $email;
  1713. }
  1714. public function __toString()
  1715. {
  1716. // There is no $this->data here
  1717. return md5(serialize($this));
  1718. }
  1719. public function get_name()
  1720. {
  1721. if ($this->name !== null)
  1722. {
  1723. return $this->name;
  1724. }
  1725. else
  1726. {
  1727. return null;
  1728. }
  1729. }
  1730. public function get_link()
  1731. {
  1732. if ($this->link !== null)
  1733. {
  1734. return $this->link;
  1735. }
  1736. else
  1737. {
  1738. return null;
  1739. }
  1740. }
  1741. public function get_email()
  1742. {
  1743. if ($this->email !== null)
  1744. {
  1745. return $this->email;
  1746. }
  1747. else
  1748. {
  1749. return null;
  1750. }
  1751. }
  1752. }
  1753. interface SimplePie_Cache_Base
  1754. {
  1755. const TYPE_FEED = 'spc';
  1756. const TYPE_IMAGE = 'spi';
  1757. public function __construct($location, $name, $type);
  1758. public function save($data);
  1759. public function load();
  1760. public function mtime();
  1761. public function touch();
  1762. public function unlink();
  1763. }
  1764. abstract class SimplePie_Cache_DB implements SimplePie_Cache_Base
  1765. {
  1766. protected static function prepare_simplepie_object_for_cache($data)
  1767. {
  1768. $items = $data->get_items();
  1769. $items_by_id = array();
  1770. if (!empty($items))
  1771. {
  1772. foreach ($items as $item)
  1773. {
  1774. $items_by_id[$item->get_id()] = $item;
  1775. }
  1776. if (count($items_by_id) !== count($items))
  1777. {
  1778. $items_by_id = array();
  1779. foreach ($items as $item)
  1780. {
  1781. $items_by_id[$item->get_id(true)] = $item;
  1782. }
  1783. }
  1784. if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
  1785. {
  1786. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
  1787. }
  1788. elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
  1789. {
  1790. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
  1791. }
  1792. elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
  1793. {
  1794. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
  1795. }
  1796. elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
  1797. {
  1798. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
  1799. }
  1800. else
  1801. {
  1802. $channel = null;
  1803. }
  1804. if ($channel !== null)
  1805. {
  1806. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
  1807. {
  1808. unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
  1809. }
  1810. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
  1811. {
  1812. unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
  1813. }
  1814. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
  1815. {
  1816. unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
  1817. }
  1818. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
  1819. {
  1820. unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
  1821. }
  1822. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
  1823. {
  1824. unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
  1825. }
  1826. }
  1827. if (isset($data->data['items']))
  1828. {
  1829. unset($data->data['items']);
  1830. }
  1831. if (isset($data->data['ordered_items']))
  1832. {
  1833. unset($data->data['ordered_items']);
  1834. }
  1835. }
  1836. return array(serialize($data->data), $items_by_id);
  1837. }
  1838. }
  1839. class SimplePie_Cache_File implements SimplePie_Cache_Base
  1840. {
  1841. protected $location;
  1842. protected $filename;
  1843. protected $extension;
  1844. protected $name;
  1845. public function __construct($location, $name, $type)
  1846. {
  1847. $this->location = $location;
  1848. $this->filename = $name;
  1849. $this->extension = $type;
  1850. $this->name = "$this->location/$this->filename.$this->extension";
  1851. }
  1852. public function save($data)
  1853. {
  1854. if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
  1855. {
  1856. if ($data instanceof SimplePie)
  1857. {
  1858. $data = $data->data;
  1859. }
  1860. $data = serialize($data);
  1861. return (bool) file_put_contents($this->name, $data);
  1862. }
  1863. return false;
  1864. }
  1865. public function load()
  1866. {
  1867. if (file_exists($this->name) && is_readable($this->name))
  1868. {
  1869. return unserialize(file_get_contents($this->name));
  1870. }
  1871. return false;
  1872. }
  1873. public function mtime()
  1874. {
  1875. if (file_exists($this->name))
  1876. {
  1877. return filemtime($this->name);
  1878. }
  1879. return false;
  1880. }
  1881. public function touch()
  1882. {
  1883. if (file_exists($this->name))
  1884. {
  1885. return touch($this->name);
  1886. }
  1887. return false;
  1888. }
  1889. public function unlink()
  1890. {
  1891. if (file_exists($this->name))
  1892. {
  1893. return unlink($this->name);
  1894. }
  1895. return false;
  1896. }
  1897. }
  1898. class SimplePie_Cache_Memcache implements SimplePie_Cache_Base
  1899. {
  1900. protected $cache;
  1901. protected $options;
  1902. protected $name;
  1903. public function __construct($location, $name, $type)
  1904. {
  1905. $this->options = array(
  1906. 'host' => '127.0.0.1',
  1907. 'port' => 11211,
  1908. 'extras' => array(
  1909. 'timeout' => 3600, // one hour
  1910. 'prefix' => 'simplepie_',
  1911. ),
  1912. );
  1913. $parsed = SimplePie_Cache::parse_URL($location);
  1914. $this->options['host'] = empty($parsed['host']) ? $this->options['host'] : $parsed['host'];
  1915. $this->options['port'] = empty($parsed['port']) ? $this->options['port'] : $parsed['port'];
  1916. $this->options['extras'] = array_merge($this->options['extras'], $parsed['extras']);
  1917. $this->name = $this->options['extras']['prefix'] . md5("$name:$type");
  1918. $this->cache = new Memcache();
  1919. $this->cache->addServer($this->options['host'], (int) $this->options['port']);
  1920. }
  1921. public function save($data)
  1922. {
  1923. if ($data instanceof SimplePie)
  1924. {
  1925. $data = $data->data;
  1926. }
  1927. return $this->cache->set($this->name, serialize($data), MEMCACHE_COMPRESSED, (int) $this->options['extras']['timeout']);
  1928. }
  1929. public function load()
  1930. {
  1931. $data = $this->cache->get($this->name);
  1932. if ($data !== false)
  1933. {
  1934. return unserialize($data);
  1935. }
  1936. return false;
  1937. }
  1938. public function mtime()
  1939. {
  1940. $data = $this->cache->get($this->name);
  1941. if ($data !== false)
  1942. {
  1943. // essentially ignore the mtime because Memcache expires on it's own
  1944. return time();
  1945. }
  1946. return false;
  1947. }
  1948. public function touch()
  1949. {
  1950. $data = $this->cache->get($this->name);
  1951. if ($data !== false)
  1952. {
  1953. return $this->cache->set($this->name, $data, MEMCACHE_COMPRESSED, (int) $this->duration);
  1954. }
  1955. return false;
  1956. }
  1957. public function unlink()
  1958. {
  1959. return $this->cache->delete($this->name, 0);
  1960. }
  1961. }
  1962. class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
  1963. {
  1964. protected $mysql;
  1965. protected $options;
  1966. protected $id;
  1967. public function __construct($location, $name, $type)
  1968. {
  1969. $this->options = array(
  1970. 'user' => null,
  1971. 'pass' => null,
  1972. 'host' => '127.0.0.1',
  1973. 'port' => '3306',
  1974. 'path' => '',
  1975. 'extras' => array(
  1976. 'prefix' => '',
  1977. ),
  1978. );
  1979. $this->options = array_merge_recursive($this->options, SimplePie_Cache::parse_URL($location));
  1980. // Path is prefixed with a "/"
  1981. $this->options['dbname'] = substr($this->options['path'], 1);
  1982. try
  1983. {
  1984. $this->mysql = new PDO("mysql:dbname={$this->options['dbname']};host={$this->options['host']};port={$this->options['port']}", $this->options['user'], $this->options['pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
  1985. }
  1986. catch (PDOException $e)
  1987. {
  1988. $this->mysql = null;
  1989. return;
  1990. }
  1991. $this->id = $name . $type;
  1992. if (!$query = $this->mysql->query('SHOW TABLES'))
  1993. {
  1994. $this->mysql = null;
  1995. return;
  1996. }
  1997. $db = array();
  1998. while ($row = $query->fetchColumn())
  1999. {
  2000. $db[] = $row;
  2001. }
  2002. if (!in_array($this->options['extras']['prefix'] . 'cache_data', $db))
  2003. {
  2004. $query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))');
  2005. if ($query === false)
  2006. {
  2007. $this->mysql = null;
  2008. }
  2009. }
  2010. if (!in_array($this->options['extras']['prefix'] . 'items', $db))
  2011. {
  2012. $query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))');
  2013. if ($query === false)
  2014. {
  2015. $this->mysql = null;
  2016. }
  2017. }
  2018. }
  2019. public function save($data)
  2020. {
  2021. if ($this->mysql === null)
  2022. {
  2023. return false;
  2024. }
  2025. if ($data instanceof SimplePie)
  2026. {
  2027. $data = clone $data;
  2028. $prepared = self::prepare_simplepie_object_for_cache($data);
  2029. $query = $this->mysql->prepare('SELECT COUNT(*) FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
  2030. $query->bindValue(':feed', $this->id);
  2031. if ($query->execute())
  2032. {
  2033. if ($query->fetchColumn() > 0)
  2034. {
  2035. $items = count($prepared[1]);
  2036. if ($items)
  2037. {
  2038. $sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = :items, `data` = :data, `mtime` = :time WHERE `id` = :feed';
  2039. $query = $this->mysql->prepare($sql);
  2040. $query->bindValue(':items', $items);
  2041. }
  2042. else
  2043. {
  2044. $sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `data` = :data, `mtime` = :time WHERE `id` = :feed';
  2045. $query = $this->mysql->prepare($sql);
  2046. }
  2047. $query->bindValue(':data', $prepared[0]);
  2048. $query->bindValue(':time', time());
  2049. $query->bindValue(':feed', $this->id);
  2050. if (!$query->execute())
  2051. {
  2052. return false;
  2053. }
  2054. }
  2055. else
  2056. {
  2057. $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:feed, :count, :data, :time)');
  2058. $query->bindValue(':feed', $this->id);
  2059. $query->bindValue(':count', count($prepared[1]));
  2060. $query->bindValue(':data', $prepared[0]);
  2061. $query->bindValue(':time', time());
  2062. if (!$query->execute())
  2063. {
  2064. return false;
  2065. }
  2066. }
  2067. $ids = array_keys($prepared[1]);
  2068. if (!empty($ids))
  2069. {
  2070. foreach ($ids as $id)
  2071. {
  2072. $database_ids[] = $this->mysql->quote($id);
  2073. }
  2074. $query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `id` = ' . implode(' OR `id` = ', $database_ids) . ' AND `feed_id` = :feed');
  2075. $query->bindValue(':feed', $this->id);
  2076. if ($query->execute())
  2077. {
  2078. $existing_ids = array();
  2079. while ($row = $query->fetchColumn())
  2080. {
  2081. $existing_ids[] = $row;
  2082. }
  2083. $new_ids = array_diff($ids, $existing_ids);
  2084. foreach ($new_ids as $new_id)
  2085. {
  2086. if (!($date = $prepared[1][$new_id]->get_date('U')))
  2087. {
  2088. $date = time();
  2089. }
  2090. $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(:feed, :id, :data, :date)');
  2091. $query->bindValue(':feed', $this->id);
  2092. $query->bindValue(':id', $new_id);
  2093. $query->bindValue(':data', serialize($prepared[1][$new_id]->data));
  2094. $query->bindValue(':date', $date);
  2095. if (!$query->execute())
  2096. {
  2097. return false;
  2098. }
  2099. }
  2100. return true;
  2101. }
  2102. }
  2103. else
  2104. {
  2105. return true;
  2106. }
  2107. }
  2108. }
  2109. else
  2110. {
  2111. $query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
  2112. $query->bindValue(':feed', $this->id);
  2113. if ($query->execute())
  2114. {
  2115. if ($query->rowCount() > 0)
  2116. {
  2117. $query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = 0, `data` = :data, `mtime` = :time WHERE `id` = :feed');
  2118. $query->bindValue(':data', serialize($data));
  2119. $query->bindValue(':time', time());
  2120. $query->bindValue(':feed', $this->id);
  2121. if ($this->execute())
  2122. {
  2123. return true;
  2124. }
  2125. }
  2126. else
  2127. {
  2128. $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:id, 0, :data, :time)');
  2129. $query->bindValue(':id', $this->id);
  2130. $query->bindValue(':data', serialize($data));
  2131. $query->bindValue(':time', time());
  2132. if ($query->execute())
  2133. {
  2134. return true;
  2135. }
  2136. }
  2137. }
  2138. }
  2139. return false;
  2140. }
  2141. public function load()
  2142. {
  2143. if ($this->mysql === null)
  2144. {
  2145. return false;
  2146. }
  2147. $query = $this->mysql->prepare('SELECT `items`, `data` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
  2148. $query->bindValue(':id', $this->id);
  2149. if ($query->execute() && ($row = $query->fetch()))
  2150. {
  2151. $data = unserialize($row[1]);
  2152. if (isset($this->options['items'][0]))
  2153. {
  2154. $items = (int) $this->options['items'][0];
  2155. }
  2156. else
  2157. {
  2158. $items = (int) $row[0];
  2159. }
  2160. if ($items !== 0)
  2161. {
  2162. if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
  2163. {
  2164. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
  2165. }
  2166. elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
  2167. {
  2168. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
  2169. }
  2170. elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
  2171. {
  2172. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
  2173. }
  2174. elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
  2175. {
  2176. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
  2177. }
  2178. else
  2179. {
  2180. $feed = null;
  2181. }
  2182. if ($feed !== null)
  2183. {
  2184. $sql = 'SELECT `data` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :feed ORDER BY `posted` DESC';
  2185. if ($items > 0)
  2186. {
  2187. $sql .= ' LIMIT ' . $items;
  2188. }
  2189. $query = $this->mysql->prepare($sql);
  2190. $query->bindValue(':feed', $this->id);
  2191. if ($query->execute())
  2192. {
  2193. while ($row = $query->fetchColumn())
  2194. {
  2195. $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row);
  2196. }
  2197. }
  2198. else
  2199. {
  2200. return false;
  2201. }
  2202. }
  2203. }
  2204. return $data;
  2205. }
  2206. return false;
  2207. }
  2208. public function mtime()
  2209. {
  2210. if ($this->mysql === null)
  2211. {
  2212. return false;
  2213. }
  2214. $query = $this->mysql->prepare('SELECT `mtime` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
  2215. $query->bindValue(':id', $this->id);
  2216. if ($query->execute() && ($time = $query->fetchColumn()))
  2217. {
  2218. return $time;
  2219. }
  2220. else
  2221. {
  2222. return false;
  2223. }
  2224. }
  2225. public function touch()
  2226. {
  2227. if ($this->mysql === null)
  2228. {
  2229. return false;
  2230. }
  2231. $query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `mtime` = :time WHERE `id` = :id');
  2232. $query->bindValue(':time', time());
  2233. $query->bindValue(':id', $this->id);
  2234. if ($query->execute() && $query->rowCount() > 0)
  2235. {
  2236. return true;
  2237. }
  2238. else
  2239. {
  2240. return false;
  2241. }
  2242. }
  2243. public function unlink()
  2244. {
  2245. if ($this->mysql === null)
  2246. {
  2247. return false;
  2248. }
  2249. $query = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
  2250. $query->bindValue(':id', $this->id);
  2251. $query2 = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :id');
  2252. $query2->bindValue(':id', $this->id);
  2253. if ($query->execute() && $query2->execute())
  2254. {
  2255. return true;
  2256. }
  2257. else
  2258. {
  2259. return false;
  2260. }
  2261. }
  2262. }
  2263. class SimplePie_Cache
  2264. {
  2265. protected static $handlers = array(
  2266. 'mysql' => 'SimplePie_Cache_MySQL',
  2267. 'memcache' => 'SimplePie_Cache_Memcache',
  2268. );
  2269. private function __construct() { }
  2270. public static function create($location, $filename, $extension)
  2271. {
  2272. $type = explode(':', $location, 2);
  2273. $type = $type[0];
  2274. if (!empty(self::$handlers[$type]))
  2275. {
  2276. $class = self::$handlers[$type];
  2277. return new $class($location, $filename, $extension);
  2278. }
  2279. return new SimplePie_Cache_File($location, $filename, $extension);
  2280. }
  2281. public static function register($type, $class)
  2282. {
  2283. self::$handlers[$type] = $class;
  2284. }
  2285. public static function parse_URL($url)
  2286. {
  2287. $params = parse_url($url);
  2288. $params['extras'] = array();
  2289. if (isset($params['query']))
  2290. {
  2291. parse_str($params['query'], $params['extras']);
  2292. }
  2293. return $params;
  2294. }
  2295. }
  2296. class SimplePie_Caption
  2297. {
  2298. var $type;
  2299. var $lang;
  2300. var $startTime;
  2301. var $endTime;
  2302. var $text;
  2303. public function __construct($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
  2304. {
  2305. $this->type = $type;
  2306. $this->lang = $lang;
  2307. $this->startTime = $startTime;
  2308. $this->endTime = $endTime;
  2309. $this->text = $text;
  2310. }
  2311. public function __toString()
  2312. {
  2313. // There is no $this->data here
  2314. return md5(serialize($this));
  2315. }
  2316. public function get_endtime()
  2317. {
  2318. if ($this->endTime !== null)
  2319. {
  2320. return $this->endTime;
  2321. }
  2322. else
  2323. {
  2324. return null;
  2325. }
  2326. }
  2327. public function get_language()
  2328. {
  2329. if ($this->lang !== null)
  2330. {
  2331. return $this->lang;
  2332. }
  2333. else
  2334. {
  2335. return null;
  2336. }
  2337. }
  2338. public function get_starttime()
  2339. {
  2340. if ($this->startTime !== null)
  2341. {
  2342. return $this->startTime;
  2343. }
  2344. else
  2345. {
  2346. return null;
  2347. }
  2348. }
  2349. public function get_text()
  2350. {
  2351. if ($this->text !== null)
  2352. {
  2353. return $this->text;
  2354. }
  2355. else
  2356. {
  2357. return null;
  2358. }
  2359. }
  2360. public function get_type()
  2361. {
  2362. if ($this->type !== null)
  2363. {
  2364. return $this->type;
  2365. }
  2366. else
  2367. {
  2368. return null;
  2369. }
  2370. }
  2371. }
  2372. class SimplePie_Category
  2373. {
  2374. var $term;
  2375. var $scheme;
  2376. var $label;
  2377. public function __construct($term = null, $scheme = null, $label = null)
  2378. {
  2379. $this->term = $term;
  2380. $this->scheme = $scheme;
  2381. $this->label = $label;
  2382. }
  2383. public function __toString()
  2384. {
  2385. // There is no $this->data here
  2386. return md5(serialize($this));
  2387. }
  2388. public function get_term()
  2389. {
  2390. if ($this->term !== null)
  2391. {
  2392. return $this->term;
  2393. }
  2394. else
  2395. {
  2396. return null;
  2397. }
  2398. }
  2399. public function get_scheme()
  2400. {
  2401. if ($this->scheme !== null)
  2402. {
  2403. return $this->scheme;
  2404. }
  2405. else
  2406. {
  2407. return null;
  2408. }
  2409. }
  2410. public function get_label()
  2411. {
  2412. if ($this->label !== null)
  2413. {
  2414. return $this->label;
  2415. }
  2416. else
  2417. {
  2418. return $this->get_term();
  2419. }
  2420. }
  2421. }
  2422. class SimplePie_Content_Type_Sniffer
  2423. {
  2424. var $file;
  2425. public function __construct($file)
  2426. {
  2427. $this->file = $file;
  2428. }
  2429. public function get_type()
  2430. {
  2431. if (isset($this->file->headers['content-type']))
  2432. {
  2433. if (!isset($this->file->headers['content-encoding'])
  2434. && ($this->file->headers['content-type'] === 'text/plain'
  2435. || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
  2436. || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'
  2437. || $this->file->headers['content-type'] === 'text/plain; charset=UTF-8'))
  2438. {
  2439. return $this->text_or_binary();
  2440. }
  2441. if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
  2442. {
  2443. $official = substr($this->file->headers['content-type'], 0, $pos);
  2444. }
  2445. else
  2446. {
  2447. $official = $this->file->headers['content-type'];
  2448. }
  2449. $official = trim(strtolower($official));
  2450. if ($official === 'unknown/unknown'
  2451. || $official === 'application/unknown')
  2452. {
  2453. return $this->unknown();
  2454. }
  2455. elseif (substr($official, -4) === '+xml'
  2456. || $official === 'text/xml'
  2457. || $official === 'application/xml')
  2458. {
  2459. return $official;
  2460. }
  2461. elseif (substr($official, 0, 6) === 'image/')
  2462. {
  2463. if ($return = $this->image())
  2464. {
  2465. return $return;
  2466. }
  2467. else
  2468. {
  2469. return $official;
  2470. }
  2471. }
  2472. elseif ($official === 'text/html')
  2473. {
  2474. return $this->feed_or_html();
  2475. }
  2476. else
  2477. {
  2478. return $official;
  2479. }
  2480. }
  2481. else
  2482. {
  2483. return $this->unknown();
  2484. }
  2485. }
  2486. public function text_or_binary()
  2487. {
  2488. if (substr($this->file->body, 0, 2) === "\xFE\xFF"
  2489. || substr($this->file->body, 0, 2) === "\xFF\xFE"
  2490. || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
  2491. || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
  2492. {
  2493. return 'text/plain';
  2494. }
  2495. elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
  2496. {
  2497. return 'application/octect-stream';
  2498. }
  2499. else
  2500. {
  2501. return 'text/plain';
  2502. }
  2503. }
  2504. public function unknown()
  2505. {
  2506. $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
  2507. if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
  2508. || strtolower(substr($this->file->body, $ws, 5)) === '<html'
  2509. || strtolower(substr($this->file->body, $ws, 7)) === '<script')
  2510. {
  2511. return 'text/html';
  2512. }
  2513. elseif (substr($this->file->body, 0, 5) === '%PDF-')
  2514. {
  2515. return 'application/pdf';
  2516. }
  2517. elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
  2518. {
  2519. return 'application/postscript';
  2520. }
  2521. elseif (substr($this->file->body, 0, 6) === 'GIF87a'
  2522. || substr($this->file->body, 0, 6) === 'GIF89a')
  2523. {
  2524. return 'image/gif';
  2525. }
  2526. elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
  2527. {
  2528. return 'image/png';
  2529. }
  2530. elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
  2531. {
  2532. return 'image/jpeg';
  2533. }
  2534. elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
  2535. {
  2536. return 'image/bmp';
  2537. }
  2538. elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00")
  2539. {
  2540. return 'image/vnd.microsoft.icon';
  2541. }
  2542. else
  2543. {
  2544. return $this->text_or_binary();
  2545. }
  2546. }
  2547. public function image()
  2548. {
  2549. if (substr($this->file->body, 0, 6) === 'GIF87a'
  2550. || substr($this->file->body, 0, 6) === 'GIF89a')
  2551. {
  2552. return 'image/gif';
  2553. }
  2554. elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
  2555. {
  2556. return 'image/png';
  2557. }
  2558. elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
  2559. {
  2560. return 'image/jpeg';
  2561. }
  2562. elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
  2563. {
  2564. return 'image/bmp';
  2565. }
  2566. elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00")
  2567. {
  2568. return 'image/vnd.microsoft.icon';
  2569. }
  2570. else
  2571. {
  2572. return false;
  2573. }
  2574. }
  2575. public function feed_or_html()
  2576. {
  2577. $len = strlen($this->file->body);
  2578. $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
  2579. while ($pos < $len)
  2580. {
  2581. switch ($this->file->body[$pos])
  2582. {
  2583. case "\x09":
  2584. case "\x0A":
  2585. case "\x0D":
  2586. case "\x20":
  2587. $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
  2588. continue 2;
  2589. case '<':
  2590. $pos++;
  2591. break;
  2592. default:
  2593. return 'text/html';
  2594. }
  2595. if (substr($this->file->body, $pos, 3) === '!--')
  2596. {
  2597. $pos += 3;
  2598. if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
  2599. {
  2600. $pos += 3;
  2601. }
  2602. else
  2603. {
  2604. return 'text/html';
  2605. }
  2606. }
  2607. elseif (substr($this->file->body, $pos, 1) === '!')
  2608. {
  2609. if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
  2610. {
  2611. $pos++;
  2612. }
  2613. else
  2614. {
  2615. return 'text/html';
  2616. }
  2617. }
  2618. elseif (substr($this->file->body, $pos, 1) === '?')
  2619. {
  2620. if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
  2621. {
  2622. $pos += 2;
  2623. }
  2624. else
  2625. {
  2626. return 'text/html';
  2627. }
  2628. }
  2629. elseif (substr($this->file->body, $pos, 3) === 'rss'
  2630. || substr($this->file->body, $pos, 7) === 'rdf:RDF')
  2631. {
  2632. return 'application/rss+xml';
  2633. }
  2634. elseif (substr($this->file->body, $pos, 4) === 'feed')
  2635. {
  2636. return 'application/atom+xml';
  2637. }
  2638. else
  2639. {
  2640. return 'text/html';
  2641. }
  2642. }
  2643. return 'text/html';
  2644. }
  2645. }
  2646. class SimplePie_Copyright
  2647. {
  2648. var $url;
  2649. var $label;
  2650. public function __construct($url = null, $label = null)
  2651. {
  2652. $this->url = $url;
  2653. $this->label = $label;
  2654. }
  2655. public function __toString()
  2656. {
  2657. // There is no $this->data here
  2658. return md5(serialize($this));
  2659. }
  2660. public function get_url()
  2661. {
  2662. if ($this->url !== null)
  2663. {
  2664. return $this->url;
  2665. }
  2666. else
  2667. {
  2668. return null;
  2669. }
  2670. }
  2671. public function get_attribution()
  2672. {
  2673. if ($this->label !== null)
  2674. {
  2675. return $this->label;
  2676. }
  2677. else
  2678. {
  2679. return null;
  2680. }
  2681. }
  2682. }
  2683. class SimplePie_Core extends SimplePie
  2684. {
  2685. }
  2686. class SimplePie_Credit
  2687. {
  2688. var $role;
  2689. var $scheme;
  2690. var $name;
  2691. public function __construct($role = null, $scheme = null, $name = null)
  2692. {
  2693. $this->role = $role;
  2694. $this->scheme = $scheme;
  2695. $this->name = $name;
  2696. }
  2697. public function __toString()
  2698. {
  2699. // There is no $this->data here
  2700. return md5(serialize($this));
  2701. }
  2702. public function get_role()
  2703. {
  2704. if ($this->role !== null)
  2705. {
  2706. return $this->role;
  2707. }
  2708. else
  2709. {
  2710. return null;
  2711. }
  2712. }
  2713. public function get_scheme()
  2714. {
  2715. if ($this->scheme !== null)
  2716. {
  2717. return $this->scheme;
  2718. }
  2719. else
  2720. {
  2721. return null;
  2722. }
  2723. }
  2724. public function get_name()
  2725. {
  2726. if ($this->name !== null)
  2727. {
  2728. return $this->name;
  2729. }
  2730. else
  2731. {
  2732. return null;
  2733. }
  2734. }
  2735. }
  2736. class SimplePie_Decode_HTML_Entities
  2737. {
  2738. var $data = '';
  2739. var $consumed = '';
  2740. var $position = 0;
  2741. public function __construct($data)
  2742. {
  2743. $this->data = $data;
  2744. }
  2745. public function parse()
  2746. {
  2747. while (($this->position = strpos($this->data, '&', $this->position)) !== false)
  2748. {
  2749. $this->consume();
  2750. $this->entity();
  2751. $this->consumed = '';
  2752. }
  2753. return $this->data;
  2754. }
  2755. public function consume()
  2756. {
  2757. if (isset($this->data[$this->position]))
  2758. {
  2759. $this->consumed .= $this->data[$this->position];
  2760. return $this->data[$this->position++];
  2761. }
  2762. else
  2763. {
  2764. return false;
  2765. }
  2766. }
  2767. public function consume_range($chars)
  2768. {
  2769. if ($len = strspn($this->data, $chars, $this->position))
  2770. {
  2771. $data = substr($this->data, $this->position, $len);
  2772. $this->consumed .= $data;
  2773. $this->position += $len;
  2774. return $data;
  2775. }
  2776. else
  2777. {
  2778. return false;
  2779. }
  2780. }
  2781. public function unconsume()
  2782. {
  2783. $this->consumed = substr($this->consumed, 0, -1);
  2784. $this->position--;
  2785. }
  2786. public function entity()
  2787. {
  2788. switch ($this->consume())
  2789. {
  2790. case "\x09":
  2791. case "\x0A":
  2792. case "\x0B":
  2793. case "\x0B":
  2794. case "\x0C":
  2795. case "\x20":
  2796. case "\x3C":
  2797. case "\x26":
  2798. case false:
  2799. break;
  2800. case "\x23":
  2801. switch ($this->consume())
  2802. {
  2803. case "\x78":
  2804. case "\x58":
  2805. $range = '0123456789ABCDEFabcdef';
  2806. $hex = true;
  2807. break;
  2808. default:
  2809. $range = '0123456789';
  2810. $hex = false;
  2811. $this->unconsume();
  2812. break;
  2813. }
  2814. if ($codepoint = $this->consume_range($range))
  2815. {
  2816. static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8");
  2817. if ($hex)
  2818. {
  2819. $codepoint = hexdec($codepoint);
  2820. }
  2821. else
  2822. {
  2823. $codepoint = intval($codepoint);
  2824. }
  2825. if (isset($windows_1252_specials[$codepoint]))
  2826. {
  2827. $replacement = $windows_1252_specials[$codepoint];
  2828. }
  2829. else
  2830. {
  2831. $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
  2832. }
  2833. if (!in_array($this->consume(), array(';', false), true))
  2834. {
  2835. $this->unconsume();
  2836. }
  2837. $consumed_length = strlen($this->consumed);
  2838. $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
  2839. $this->position += strlen($replacement) - $consumed_length;
  2840. }
  2841. break;
  2842. default:
  2843. static $entities = array(
  2844. 'Aacute' => "\xC3\x81",
  2845. 'aacute' => "\xC3\xA1",
  2846. 'Aacute;' => "\xC3\x81",
  2847. 'aacute;' => "\xC3\xA1",
  2848. 'Acirc' => "\xC3\x82",
  2849. 'acirc' => "\xC3\xA2",
  2850. 'Acirc;' => "\xC3\x82",
  2851. 'acirc;' => "\xC3\xA2",
  2852. 'acute' => "\xC2\xB4",
  2853. 'acute;' => "\xC2\xB4",
  2854. 'AElig' => "\xC3\x86",
  2855. 'aelig' => "\xC3\xA6",
  2856. 'AElig;' => "\xC3\x86",
  2857. 'aelig;' => "\xC3\xA6",
  2858. 'Agrave' => "\xC3\x80",
  2859. 'agrave' => "\xC3\xA0",
  2860. 'Agrave;' => "\xC3\x80",
  2861. 'agrave;' => "\xC3\xA0",
  2862. 'alefsym;' => "\xE2\x84\xB5",
  2863. 'Alpha;' => "\xCE\x91",
  2864. 'alpha;' => "\xCE\xB1",
  2865. 'AMP' => "\x26",
  2866. 'amp' => "\x26",
  2867. 'AMP;' => "\x26",
  2868. 'amp;' => "\x26",
  2869. 'and;' => "\xE2\x88\xA7",
  2870. 'ang;' => "\xE2\x88\xA0",
  2871. 'apos;' => "\x27",
  2872. 'Aring' => "\xC3\x85",
  2873. 'aring' => "\xC3\xA5",
  2874. 'Aring;' => "\xC3\x85",
  2875. 'aring;' => "\xC3\xA5",
  2876. 'asymp;' => "\xE2\x89\x88",
  2877. 'Atilde' => "\xC3\x83",
  2878. 'atilde' => "\xC3\xA3",
  2879. 'Atilde;' => "\xC3\x83",
  2880. 'atilde;' => "\xC3\xA3",
  2881. 'Auml' => "\xC3\x84",
  2882. 'auml' => "\xC3\xA4",
  2883. 'Auml;' => "\xC3\x84",
  2884. 'auml;' => "\xC3\xA4",
  2885. 'bdquo;' => "\xE2\x80\x9E",
  2886. 'Beta;' => "\xCE\x92",
  2887. 'beta;' => "\xCE\xB2",
  2888. 'brvbar' => "\xC2\xA6",
  2889. 'brvbar;' => "\xC2\xA6",
  2890. 'bull;' => "\xE2\x80\xA2",
  2891. 'cap;' => "\xE2\x88\xA9",
  2892. 'Ccedil' => "\xC3\x87",
  2893. 'ccedil' => "\xC3\xA7",
  2894. 'Ccedil;' => "\xC3\x87",
  2895. 'ccedil;' => "\xC3\xA7",
  2896. 'cedil' => "\xC2\xB8",
  2897. 'cedil;' => "\xC2\xB8",
  2898. 'cent' => "\xC2\xA2",
  2899. 'cent;' => "\xC2\xA2",
  2900. 'Chi;' => "\xCE\xA7",
  2901. 'chi;' => "\xCF\x87",
  2902. 'circ;' => "\xCB\x86",
  2903. 'clubs;' => "\xE2\x99\xA3",
  2904. 'cong;' => "\xE2\x89\x85",
  2905. 'COPY' => "\xC2\xA9",
  2906. 'copy' => "\xC2\xA9",
  2907. 'COPY;' => "\xC2\xA9",
  2908. 'copy;' => "\xC2\xA9",
  2909. 'crarr;' => "\xE2\x86\xB5",
  2910. 'cup;' => "\xE2\x88\xAA",
  2911. 'curren' => "\xC2\xA4",
  2912. 'curren;' => "\xC2\xA4",
  2913. 'Dagger;' => "\xE2\x80\xA1",
  2914. 'dagger;' => "\xE2\x80\xA0",
  2915. 'dArr;' => "\xE2\x87\x93",
  2916. 'darr;' => "\xE2\x86\x93",
  2917. 'deg' => "\xC2\xB0",
  2918. 'deg;' => "\xC2\xB0",
  2919. 'Delta;' => "\xCE\x94",
  2920. 'delta;' => "\xCE\xB4",
  2921. 'diams;' => "\xE2\x99\xA6",
  2922. 'divide' => "\xC3\xB7",
  2923. 'divide;' => "\xC3\xB7",
  2924. 'Eacute' => "\xC3\x89",
  2925. 'eacute' => "\xC3\xA9",
  2926. 'Eacute;' => "\xC3\x89",
  2927. 'eacute;' => "\xC3\xA9",
  2928. 'Ecirc' => "\xC3\x8A",
  2929. 'ecirc' => "\xC3\xAA",
  2930. 'Ecirc;' => "\xC3\x8A",
  2931. 'ecirc;' => "\xC3\xAA",
  2932. 'Egrave' => "\xC3\x88",
  2933. 'egrave' => "\xC3\xA8",
  2934. 'Egrave;' => "\xC3\x88",
  2935. 'egrave;' => "\xC3\xA8",
  2936. 'empty;' => "\xE2\x88\x85",
  2937. 'emsp;' => "\xE2\x80\x83",
  2938. 'ensp;' => "\xE2\x80\x82",
  2939. 'Epsilon;' => "\xCE\x95",
  2940. 'epsilon;' => "\xCE\xB5",
  2941. 'equiv;' => "\xE2\x89\xA1",
  2942. 'Eta;' => "\xCE\x97",
  2943. 'eta;' => "\xCE\xB7",
  2944. 'ETH' => "\xC3\x90",
  2945. 'eth' => "\xC3\xB0",
  2946. 'ETH;' => "\xC3\x90",
  2947. 'eth;' => "\xC3\xB0",
  2948. 'Euml' => "\xC3\x8B",
  2949. 'euml' => "\xC3\xAB",
  2950. 'Euml;' => "\xC3\x8B",
  2951. 'euml;' => "\xC3\xAB",
  2952. 'euro;' => "\xE2\x82\xAC",
  2953. 'exist;' => "\xE2\x88\x83",
  2954. 'fnof;' => "\xC6\x92",
  2955. 'forall;' => "\xE2\x88\x80",
  2956. 'frac12' => "\xC2\xBD",
  2957. 'frac12;' => "\xC2\xBD",
  2958. 'frac14' => "\xC2\xBC",
  2959. 'frac14;' => "\xC2\xBC",
  2960. 'frac34' => "\xC2\xBE",
  2961. 'frac34;' => "\xC2\xBE",
  2962. 'frasl;' => "\xE2\x81\x84",
  2963. 'Gamma;' => "\xCE\x93",
  2964. 'gamma;' => "\xCE\xB3",
  2965. 'ge;' => "\xE2\x89\xA5",
  2966. 'GT' => "\x3E",
  2967. 'gt' => "\x3E",
  2968. 'GT;' => "\x3E",
  2969. 'gt;' => "\x3E",
  2970. 'hArr;' => "\xE2\x87\x94",
  2971. 'harr;' => "\xE2\x86\x94",
  2972. 'hearts;' => "\xE2\x99\xA5",
  2973. 'hellip;' => "\xE2\x80\xA6",
  2974. 'Iacute' => "\xC3\x8D",
  2975. 'iacute' => "\xC3\xAD",
  2976. 'Iacute;' => "\xC3\x8D",
  2977. 'iacute;' => "\xC3\xAD",
  2978. 'Icirc' => "\xC3\x8E",
  2979. 'icirc' => "\xC3\xAE",
  2980. 'Icirc;' => "\xC3\x8E",
  2981. 'icirc;' => "\xC3\xAE",
  2982. 'iexcl' => "\xC2\xA1",
  2983. 'iexcl;' => "\xC2\xA1",
  2984. 'Igrave' => "\xC3\x8C",
  2985. 'igrave' => "\xC3\xAC",
  2986. 'Igrave;' => "\xC3\x8C",
  2987. 'igrave;' => "\xC3\xAC",
  2988. 'image;' => "\xE2\x84\x91",
  2989. 'infin;' => "\xE2\x88\x9E",
  2990. 'int;' => "\xE2\x88\xAB",
  2991. 'Iota;' => "\xCE\x99",
  2992. 'iota;' => "\xCE\xB9",
  2993. 'iquest' => "\xC2\xBF",
  2994. 'iquest;' => "\xC2\xBF",
  2995. 'isin;' => "\xE2\x88\x88",
  2996. 'Iuml' => "\xC3\x8F",
  2997. 'iuml' => "\xC3\xAF",
  2998. 'Iuml;' => "\xC3\x8F",
  2999. 'iuml;' => "\xC3\xAF",
  3000. 'Kappa;' => "\xCE\x9A",
  3001. 'kappa;' => "\xCE\xBA",
  3002. 'Lambda;' => "\xCE\x9B",
  3003. 'lambda;' => "\xCE\xBB",
  3004. 'lang;' => "\xE3\x80\x88",
  3005. 'laquo' => "\xC2\xAB",
  3006. 'laquo;' => "\xC2\xAB",
  3007. 'lArr;' => "\xE2\x87\x90",
  3008. 'larr;' => "\xE2\x86\x90",
  3009. 'lceil;' => "\xE2\x8C\x88",
  3010. 'ldquo;' => "\xE2\x80\x9C",
  3011. 'le;' => "\xE2\x89\xA4",
  3012. 'lfloor;' => "\xE2\x8C\x8A",
  3013. 'lowast;' => "\xE2\x88\x97",
  3014. 'loz;' => "\xE2\x97\x8A",
  3015. 'lrm;' => "\xE2\x80\x8E",
  3016. 'lsaquo;' => "\xE2\x80\xB9",
  3017. 'lsquo;' => "\xE2\x80\x98",
  3018. 'LT' => "\x3C",
  3019. 'lt' => "\x3C",
  3020. 'LT;' => "\x3C",
  3021. 'lt;' => "\x3C",
  3022. 'macr' => "\xC2\xAF",
  3023. 'macr;' => "\xC2\xAF",
  3024. 'mdash;' => "\xE2\x80\x94",
  3025. 'micro' => "\xC2\xB5",
  3026. 'micro;' => "\xC2\xB5",
  3027. 'middot' => "\xC2\xB7",
  3028. 'middot;' => "\xC2\xB7",
  3029. 'minus;' => "\xE2\x88\x92",
  3030. 'Mu;' => "\xCE\x9C",
  3031. 'mu;' => "\xCE\xBC",
  3032. 'nabla;' => "\xE2\x88\x87",
  3033. 'nbsp' => "\xC2\xA0",
  3034. 'nbsp;' => "\xC2\xA0",
  3035. 'ndash;' => "\xE2\x80\x93",
  3036. 'ne;' => "\xE2\x89\xA0",
  3037. 'ni;' => "\xE2\x88\x8B",
  3038. 'not' => "\xC2\xAC",
  3039. 'not;' => "\xC2\xAC",
  3040. 'notin;' => "\xE2\x88\x89",
  3041. 'nsub;' => "\xE2\x8A\x84",
  3042. 'Ntilde' => "\xC3\x91",
  3043. 'ntilde' => "\xC3\xB1",
  3044. 'Ntilde;' => "\xC3\x91",
  3045. 'ntilde;' => "\xC3\xB1",
  3046. 'Nu;' => "\xCE\x9D",
  3047. 'nu;' => "\xCE\xBD",
  3048. 'Oacute' => "\xC3\x93",
  3049. 'oacute' => "\xC3\xB3",
  3050. 'Oacute;' => "\xC3\x93",
  3051. 'oacute;' => "\xC3\xB3",
  3052. 'Ocirc' => "\xC3\x94",
  3053. 'ocirc' => "\xC3\xB4",
  3054. 'Ocirc;' => "\xC3\x94",
  3055. 'ocirc;' => "\xC3\xB4",
  3056. 'OElig;' => "\xC5\x92",
  3057. 'oelig;' => "\xC5\x93",
  3058. 'Ograve' => "\xC3\x92",
  3059. 'ograve' => "\xC3\xB2",
  3060. 'Ograve;' => "\xC3\x92",
  3061. 'ograve;' => "\xC3\xB2",
  3062. 'oline;' => "\xE2\x80\xBE",
  3063. 'Omega;' => "\xCE\xA9",
  3064. 'omega;' => "\xCF\x89",
  3065. 'Omicron;' => "\xCE\x9F",
  3066. 'omicron;' => "\xCE\xBF",
  3067. 'oplus;' => "\xE2\x8A\x95",
  3068. 'or;' => "\xE2\x88\xA8",
  3069. 'ordf' => "\xC2\xAA",
  3070. 'ordf;' => "\xC2\xAA",
  3071. 'ordm' => "\xC2\xBA",
  3072. 'ordm;' => "\xC2\xBA",
  3073. 'Oslash' => "\xC3\x98",
  3074. 'oslash' => "\xC3\xB8",
  3075. 'Oslash;' => "\xC3\x98",
  3076. 'oslash;' => "\xC3\xB8",
  3077. 'Otilde' => "\xC3\x95",
  3078. 'otilde' => "\xC3\xB5",
  3079. 'Otilde;' => "\xC3\x95",
  3080. 'otilde;' => "\xC3\xB5",
  3081. 'otimes;' => "\xE2\x8A\x97",
  3082. 'Ouml' => "\xC3\x96",
  3083. 'ouml' => "\xC3\xB6",
  3084. 'Ouml;' => "\xC3\x96",
  3085. 'ouml;' => "\xC3\xB6",
  3086. 'para' => "\xC2\xB6",
  3087. 'para;' => "\xC2\xB6",
  3088. 'part;' => "\xE2\x88\x82",
  3089. 'permil;' => "\xE2\x80\xB0",
  3090. 'perp;' => "\xE2\x8A\xA5",
  3091. 'Phi;' => "\xCE\xA6",
  3092. 'phi;' => "\xCF\x86",
  3093. 'Pi;' => "\xCE\xA0",
  3094. 'pi;' => "\xCF\x80",
  3095. 'piv;' => "\xCF\x96",
  3096. 'plusmn' => "\xC2\xB1",
  3097. 'plusmn;' => "\xC2\xB1",
  3098. 'pound' => "\xC2\xA3",
  3099. 'pound;' => "\xC2\xA3",
  3100. 'Prime;' => "\xE2\x80\xB3",
  3101. 'prime;' => "\xE2\x80\xB2",
  3102. 'prod;' => "\xE2\x88\x8F",
  3103. 'prop;' => "\xE2\x88\x9D",
  3104. 'Psi;' => "\xCE\xA8",
  3105. 'psi;' => "\xCF\x88",
  3106. 'QUOT' => "\x22",
  3107. 'quot' => "\x22",
  3108. 'QUOT;' => "\x22",
  3109. 'quot;' => "\x22",
  3110. 'radic;' => "\xE2\x88\x9A",
  3111. 'rang;' => "\xE3\x80\x89",
  3112. 'raquo' => "\xC2\xBB",
  3113. 'raquo;' => "\xC2\xBB",
  3114. 'rArr;' => "\xE2\x87\x92",
  3115. 'rarr;' => "\xE2\x86\x92",
  3116. 'rceil;' => "\xE2\x8C\x89",
  3117. 'rdquo;' => "\xE2\x80\x9D",
  3118. 'real;' => "\xE2\x84\x9C",
  3119. 'REG' => "\xC2\xAE",
  3120. 'reg' => "\xC2\xAE",
  3121. 'REG;' => "\xC2\xAE",
  3122. 'reg;' => "\xC2\xAE",
  3123. 'rfloor;' => "\xE2\x8C\x8B",
  3124. 'Rho;' => "\xCE\xA1",
  3125. 'rho;' => "\xCF\x81",
  3126. 'rlm;' => "\xE2\x80\x8F",
  3127. 'rsaquo;' => "\xE2\x80\xBA",
  3128. 'rsquo;' => "\xE2\x80\x99",
  3129. 'sbquo;' => "\xE2\x80\x9A",
  3130. 'Scaron;' => "\xC5\xA0",
  3131. 'scaron;' => "\xC5\xA1",
  3132. 'sdot;' => "\xE2\x8B\x85",
  3133. 'sect' => "\xC2\xA7",
  3134. 'sect;' => "\xC2\xA7",
  3135. 'shy' => "\xC2\xAD",
  3136. 'shy;' => "\xC2\xAD",
  3137. 'Sigma;' => "\xCE\xA3",
  3138. 'sigma;' => "\xCF\x83",
  3139. 'sigmaf;' => "\xCF\x82",
  3140. 'sim;' => "\xE2\x88\xBC",
  3141. 'spades;' => "\xE2\x99\xA0",
  3142. 'sub;' => "\xE2\x8A\x82",
  3143. 'sube;' => "\xE2\x8A\x86",
  3144. 'sum;' => "\xE2\x88\x91",
  3145. 'sup;' => "\xE2\x8A\x83",
  3146. 'sup1' => "\xC2\xB9",
  3147. 'sup1;' => "\xC2\xB9",
  3148. 'sup2' => "\xC2\xB2",
  3149. 'sup2;' => "\xC2\xB2",
  3150. 'sup3' => "\xC2\xB3",
  3151. 'sup3;' => "\xC2\xB3",
  3152. 'supe;' => "\xE2\x8A\x87",
  3153. 'szlig' => "\xC3\x9F",
  3154. 'szlig;' => "\xC3\x9F",
  3155. 'Tau;' => "\xCE\xA4",
  3156. 'tau;' => "\xCF\x84",
  3157. 'there4;' => "\xE2\x88\xB4",
  3158. 'Theta;' => "\xCE\x98",
  3159. 'theta;' => "\xCE\xB8",
  3160. 'thetasym;' => "\xCF\x91",
  3161. 'thinsp;' => "\xE2\x80\x89",
  3162. 'THORN' => "\xC3\x9E",
  3163. 'thorn' => "\xC3\xBE",
  3164. 'THORN;' => "\xC3\x9E",
  3165. 'thorn;' => "\xC3\xBE",
  3166. 'tilde;' => "\xCB\x9C",
  3167. 'times' => "\xC3\x97",
  3168. 'times;' => "\xC3\x97",
  3169. 'TRADE;' => "\xE2\x84\xA2",
  3170. 'trade;' => "\xE2\x84\xA2",
  3171. 'Uacute' => "\xC3\x9A",
  3172. 'uacute' => "\xC3\xBA",
  3173. 'Uacute;' => "\xC3\x9A",
  3174. 'uacute;' => "\xC3\xBA",
  3175. 'uArr;' => "\xE2\x87\x91",
  3176. 'uarr;' => "\xE2\x86\x91",
  3177. 'Ucirc' => "\xC3\x9B",
  3178. 'ucirc' => "\xC3\xBB",
  3179. 'Ucirc;' => "\xC3\x9B",
  3180. 'ucirc;' => "\xC3\xBB",
  3181. 'Ugrave' => "\xC3\x99",
  3182. 'ugrave' => "\xC3\xB9",
  3183. 'Ugrave;' => "\xC3\x99",
  3184. 'ugrave;' => "\xC3\xB9",
  3185. 'uml' => "\xC2\xA8",
  3186. 'uml;' => "\xC2\xA8",
  3187. 'upsih;' => "\xCF\x92",
  3188. 'Upsilon;' => "\xCE\xA5",
  3189. 'upsilon;' => "\xCF\x85",
  3190. 'Uuml' => "\xC3\x9C",
  3191. 'uuml' => "\xC3\xBC",
  3192. 'Uuml;' => "\xC3\x9C",
  3193. 'uuml;' => "\xC3\xBC",
  3194. 'weierp;' => "\xE2\x84\x98",
  3195. 'Xi;' => "\xCE\x9E",
  3196. 'xi;' => "\xCE\xBE",
  3197. 'Yacute' => "\xC3\x9D",
  3198. 'yacute' => "\xC3\xBD",
  3199. 'Yacute;' => "\xC3\x9D",
  3200. 'yacute;' => "\xC3\xBD",
  3201. 'yen' => "\xC2\xA5",
  3202. 'yen;' => "\xC2\xA5",
  3203. 'yuml' => "\xC3\xBF",
  3204. 'Yuml;' => "\xC5\xB8",
  3205. 'yuml;' => "\xC3\xBF",
  3206. 'Zeta;' => "\xCE\x96",
  3207. 'zeta;' => "\xCE\xB6",
  3208. 'zwj;' => "\xE2\x80\x8D",
  3209. 'zwnj;' => "\xE2\x80\x8C"
  3210. );
  3211. for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
  3212. {
  3213. $consumed = substr($this->consumed, 1);
  3214. if (isset($entities[$consumed]))
  3215. {
  3216. $match = $consumed;
  3217. }
  3218. }
  3219. if ($match !== null)
  3220. {
  3221. $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
  3222. $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
  3223. }
  3224. break;
  3225. }
  3226. }
  3227. }
  3228. class SimplePie_Enclosure
  3229. {
  3230. var $bitrate;
  3231. var $captions;
  3232. var $categories;
  3233. var $channels;
  3234. var $copyright;
  3235. var $credits;
  3236. var $description;
  3237. var $duration;
  3238. var $expression;
  3239. var $framerate;
  3240. var $handler;
  3241. var $hashes;
  3242. var $height;
  3243. var $javascript;
  3244. var $keywords;
  3245. var $lang;
  3246. var $length;
  3247. var $link;
  3248. var $medium;
  3249. var $player;
  3250. var $ratings;
  3251. var $restrictions;
  3252. var $samplingrate;
  3253. var $thumbnails;
  3254. var $title;
  3255. var $type;
  3256. var $width;
  3257. public function __construct($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)
  3258. {
  3259. $this->bitrate = $bitrate;
  3260. $this->captions = $captions;
  3261. $this->categories = $categories;
  3262. $this->channels = $channels;
  3263. $this->copyright = $copyright;
  3264. $this->credits = $credits;
  3265. $this->description = $description;
  3266. $this->duration = $duration;
  3267. $this->expression = $expression;
  3268. $this->framerate = $framerate;
  3269. $this->hashes = $hashes;
  3270. $this->height = $height;
  3271. $this->keywords = $keywords;
  3272. $this->lang = $lang;
  3273. $this->length = $length;
  3274. $this->link = $link;
  3275. $this->medium = $medium;
  3276. $this->player = $player;
  3277. $this->ratings = $ratings;
  3278. $this->restrictions = $restrictions;
  3279. $this->samplingrate = $samplingrate;
  3280. $this->thumbnails = $thumbnails;
  3281. $this->title = $title;
  3282. $this->type = $type;
  3283. $this->width = $width;
  3284. if (class_exists('idna_convert'))
  3285. {
  3286. $idn = new idna_convert();
  3287. $parsed = SimplePie_Misc::parse_url($link);
  3288. $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  3289. }
  3290. $this->handler = $this->get_handler(); // Needs to load last
  3291. }
  3292. public function __toString()
  3293. {
  3294. // There is no $this->data here
  3295. return md5(serialize($this));
  3296. }
  3297. public function get_bitrate()
  3298. {
  3299. if ($this->bitrate !== null)
  3300. {
  3301. return $this->bitrate;
  3302. }
  3303. else
  3304. {
  3305. return null;
  3306. }
  3307. }
  3308. public function get_caption($key = 0)
  3309. {
  3310. $captions = $this->get_captions();
  3311. if (isset($captions[$key]))
  3312. {
  3313. return $captions[$key];
  3314. }
  3315. else
  3316. {
  3317. return null;
  3318. }
  3319. }
  3320. public function get_captions()
  3321. {
  3322. if ($this->captions !== null)
  3323. {
  3324. return $this->captions;
  3325. }
  3326. else
  3327. {
  3328. return null;
  3329. }
  3330. }
  3331. public function get_category($key = 0)
  3332. {
  3333. $categories = $this->get_categories();
  3334. if (isset($categories[$key]))
  3335. {
  3336. return $categories[$key];
  3337. }
  3338. else
  3339. {
  3340. return null;
  3341. }
  3342. }
  3343. public function get_categories()
  3344. {
  3345. if ($this->categories !== null)
  3346. {
  3347. return $this->categories;
  3348. }
  3349. else
  3350. {
  3351. return null;
  3352. }
  3353. }
  3354. public function get_channels()
  3355. {
  3356. if ($this->channels !== null)
  3357. {
  3358. return $this->channels;
  3359. }
  3360. else
  3361. {
  3362. return null;
  3363. }
  3364. }
  3365. public function get_copyright()
  3366. {
  3367. if ($this->copyright !== null)
  3368. {
  3369. return $this->copyright;
  3370. }
  3371. else
  3372. {
  3373. return null;
  3374. }
  3375. }
  3376. public function get_credit($key = 0)
  3377. {
  3378. $credits = $this->get_credits();
  3379. if (isset($credits[$key]))
  3380. {
  3381. return $credits[$key];
  3382. }
  3383. else
  3384. {
  3385. return null;
  3386. }
  3387. }
  3388. public function get_credits()
  3389. {
  3390. if ($this->credits !== null)
  3391. {
  3392. return $this->credits;
  3393. }
  3394. else
  3395. {
  3396. return null;
  3397. }
  3398. }
  3399. public function get_description()
  3400. {
  3401. if ($this->description !== null)
  3402. {
  3403. return $this->description;
  3404. }
  3405. else
  3406. {
  3407. return null;
  3408. }
  3409. }
  3410. public function get_duration($convert = false)
  3411. {
  3412. if ($this->duration !== null)
  3413. {
  3414. if ($convert)
  3415. {
  3416. $time = SimplePie_Misc::time_hms($this->duration);
  3417. return $time;
  3418. }
  3419. else
  3420. {
  3421. return $this->duration;
  3422. }
  3423. }
  3424. else
  3425. {
  3426. return null;
  3427. }
  3428. }
  3429. public function get_expression()
  3430. {
  3431. if ($this->expression !== null)
  3432. {
  3433. return $this->expression;
  3434. }
  3435. else
  3436. {
  3437. return 'full';
  3438. }
  3439. }
  3440. public function get_extension()
  3441. {
  3442. if ($this->link !== null)
  3443. {
  3444. $url = SimplePie_Misc::parse_url($this->link);
  3445. if ($url['path'] !== '')
  3446. {
  3447. return pathinfo($url['path'], PATHINFO_EXTENSION);
  3448. }
  3449. }
  3450. return null;
  3451. }
  3452. public function get_framerate()
  3453. {
  3454. if ($this->framerate !== null)
  3455. {
  3456. return $this->framerate;
  3457. }
  3458. else
  3459. {
  3460. return null;
  3461. }
  3462. }
  3463. public function get_handler()
  3464. {
  3465. return $this->get_real_type(true);
  3466. }
  3467. public function get_hash($key = 0)
  3468. {
  3469. $hashes = $this->get_hashes();
  3470. if (isset($hashes[$key]))
  3471. {
  3472. return $hashes[$key];
  3473. }
  3474. else
  3475. {
  3476. return null;
  3477. }
  3478. }
  3479. public function get_hashes()
  3480. {
  3481. if ($this->hashes !== null)
  3482. {
  3483. return $this->hashes;
  3484. }
  3485. else
  3486. {
  3487. return null;
  3488. }
  3489. }
  3490. public function get_height()
  3491. {
  3492. if ($this->height !== null)
  3493. {
  3494. return $this->height;
  3495. }
  3496. else
  3497. {
  3498. return null;
  3499. }
  3500. }
  3501. public function get_language()
  3502. {
  3503. if ($this->lang !== null)
  3504. {
  3505. return $this->lang;
  3506. }
  3507. else
  3508. {
  3509. return null;
  3510. }
  3511. }
  3512. public function get_keyword($key = 0)
  3513. {
  3514. $keywords = $this->get_keywords();
  3515. if (isset($keywords[$key]))
  3516. {
  3517. return $keywords[$key];
  3518. }
  3519. else
  3520. {
  3521. return null;
  3522. }
  3523. }
  3524. public function get_keywords()
  3525. {
  3526. if ($this->keywords !== null)
  3527. {
  3528. return $this->keywords;
  3529. }
  3530. else
  3531. {
  3532. return null;
  3533. }
  3534. }
  3535. public function get_length()
  3536. {
  3537. if ($this->length !== null)
  3538. {
  3539. return $this->length;
  3540. }
  3541. else
  3542. {
  3543. return null;
  3544. }
  3545. }
  3546. public function get_link()
  3547. {
  3548. if ($this->link !== null)
  3549. {
  3550. return urldecode($this->link);
  3551. }
  3552. else
  3553. {
  3554. return null;
  3555. }
  3556. }
  3557. public function get_medium()
  3558. {
  3559. if ($this->medium !== null)
  3560. {
  3561. return $this->medium;
  3562. }
  3563. else
  3564. {
  3565. return null;
  3566. }
  3567. }
  3568. public function get_player()
  3569. {
  3570. if ($this->player !== null)
  3571. {
  3572. return $this->player;
  3573. }
  3574. else
  3575. {
  3576. return null;
  3577. }
  3578. }
  3579. public function get_rating($key = 0)
  3580. {
  3581. $ratings = $this->get_ratings();
  3582. if (isset($ratings[$key]))
  3583. {
  3584. return $ratings[$key];
  3585. }
  3586. else
  3587. {
  3588. return null;
  3589. }
  3590. }
  3591. public function get_ratings()
  3592. {
  3593. if ($this->ratings !== null)
  3594. {
  3595. return $this->ratings;
  3596. }
  3597. else
  3598. {
  3599. return null;
  3600. }
  3601. }
  3602. public function get_restriction($key = 0)
  3603. {
  3604. $restrictions = $this->get_restrictions();
  3605. if (isset($restrictions[$key]))
  3606. {
  3607. return $restrictions[$key];
  3608. }
  3609. else
  3610. {
  3611. return null;
  3612. }
  3613. }
  3614. public function get_restrictions()
  3615. {
  3616. if ($this->restrictions !== null)
  3617. {
  3618. return $this->restrictions;
  3619. }
  3620. else
  3621. {
  3622. return null;
  3623. }
  3624. }
  3625. public function get_sampling_rate()
  3626. {
  3627. if ($this->samplingrate !== null)
  3628. {
  3629. return $this->samplingrate;
  3630. }
  3631. else
  3632. {
  3633. return null;
  3634. }
  3635. }
  3636. public function get_size()
  3637. {
  3638. $length = $this->get_length();
  3639. if ($length !== null)
  3640. {
  3641. return round($length/1048576, 2);
  3642. }
  3643. else
  3644. {
  3645. return null;
  3646. }
  3647. }
  3648. public function get_thumbnail($key = 0)
  3649. {
  3650. $thumbnails = $this->get_thumbnails();
  3651. if (isset($thumbnails[$key]))
  3652. {
  3653. return $thumbnails[$key];
  3654. }
  3655. else
  3656. {
  3657. return null;
  3658. }
  3659. }
  3660. public function get_thumbnails()
  3661. {
  3662. if ($this->thumbnails !== null)
  3663. {
  3664. return $this->thumbnails;
  3665. }
  3666. else
  3667. {
  3668. return null;
  3669. }
  3670. }
  3671. public function get_title()
  3672. {
  3673. if ($this->title !== null)
  3674. {
  3675. return $this->title;
  3676. }
  3677. else
  3678. {
  3679. return null;
  3680. }
  3681. }
  3682. public function get_type()
  3683. {
  3684. if ($this->type !== null)
  3685. {
  3686. return $this->type;
  3687. }
  3688. else
  3689. {
  3690. return null;
  3691. }
  3692. }
  3693. public function get_width()
  3694. {
  3695. if ($this->width !== null)
  3696. {
  3697. return $this->width;
  3698. }
  3699. else
  3700. {
  3701. return null;
  3702. }
  3703. }
  3704. public function native_embed($options='')
  3705. {
  3706. return $this->embed($options, true);
  3707. }
  3708. public function embed($options = '', $native = false)
  3709. {
  3710. // Set up defaults
  3711. $audio = '';
  3712. $video = '';
  3713. $alt = '';
  3714. $altclass = '';
  3715. $loop = 'false';
  3716. $width = 'auto';
  3717. $height = 'auto';
  3718. $bgcolor = '#ffffff';
  3719. $mediaplayer = '';
  3720. $widescreen = false;
  3721. $handler = $this->get_handler();
  3722. $type = $this->get_real_type();
  3723. // Process options and reassign values as necessary
  3724. if (is_array($options))
  3725. {
  3726. extract($options);
  3727. }
  3728. else
  3729. {
  3730. $options = explode(',', $options);
  3731. foreach($options as $option)
  3732. {
  3733. $opt = explode(':', $option, 2);
  3734. if (isset($opt[0], $opt[1]))
  3735. {
  3736. $opt[0] = trim($opt[0]);
  3737. $opt[1] = trim($opt[1]);
  3738. switch ($opt[0])
  3739. {
  3740. case 'audio':
  3741. $audio = $opt[1];
  3742. break;
  3743. case 'video':
  3744. $video = $opt[1];
  3745. break;
  3746. case 'alt':
  3747. $alt = $opt[1];
  3748. break;
  3749. case 'altclass':
  3750. $altclass = $opt[1];
  3751. break;
  3752. case 'loop':
  3753. $loop = $opt[1];
  3754. break;
  3755. case 'width':
  3756. $width = $opt[1];
  3757. break;
  3758. case 'height':
  3759. $height = $opt[1];
  3760. break;
  3761. case 'bgcolor':
  3762. $bgcolor = $opt[1];
  3763. break;
  3764. case 'mediaplayer':
  3765. $mediaplayer = $opt[1];
  3766. break;
  3767. case 'widescreen':
  3768. $widescreen = $opt[1];
  3769. break;
  3770. }
  3771. }
  3772. }
  3773. }
  3774. $mime = explode('/', $type, 2);
  3775. $mime = $mime[0];
  3776. // Process values for 'auto'
  3777. if ($width === 'auto')
  3778. {
  3779. if ($mime === 'video')
  3780. {
  3781. if ($height === 'auto')
  3782. {
  3783. $width = 480;
  3784. }
  3785. elseif ($widescreen)
  3786. {
  3787. $width = round((intval($height)/9)*16);
  3788. }
  3789. else
  3790. {
  3791. $width = round((intval($height)/3)*4);
  3792. }
  3793. }
  3794. else
  3795. {
  3796. $width = '100%';
  3797. }
  3798. }
  3799. if ($height === 'auto')
  3800. {
  3801. if ($mime === 'audio')
  3802. {
  3803. $height = 0;
  3804. }
  3805. elseif ($mime === 'video')
  3806. {
  3807. if ($width === 'auto')
  3808. {
  3809. if ($widescreen)
  3810. {
  3811. $height = 270;
  3812. }
  3813. else
  3814. {
  3815. $height = 360;
  3816. }
  3817. }
  3818. elseif ($widescreen)
  3819. {
  3820. $height = round((intval($width)/16)*9);
  3821. }
  3822. else
  3823. {
  3824. $height = round((intval($width)/4)*3);
  3825. }
  3826. }
  3827. else
  3828. {
  3829. $height = 376;
  3830. }
  3831. }
  3832. elseif ($mime === 'audio')
  3833. {
  3834. $height = 0;
  3835. }
  3836. // Set proper placeholder value
  3837. if ($mime === 'audio')
  3838. {
  3839. $placeholder = $audio;
  3840. }
  3841. elseif ($mime === 'video')
  3842. {
  3843. $placeholder = $video;
  3844. }
  3845. $embed = '';
  3846. // Flash
  3847. if ($handler === 'flash')
  3848. {
  3849. if ($native)
  3850. {
  3851. $embed .= "<embed src=\"" . $this->get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\"></embed>";
  3852. }
  3853. else
  3854. {
  3855. $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
  3856. }
  3857. }
  3858. // Flash Media Player file types.
  3859. // Preferred handler for MP3 file types.
  3860. elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
  3861. {
  3862. $height += 20;
  3863. if ($native)
  3864. {
  3865. $embed .= "<embed src=\"$mediaplayer\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" quality=\"high\" width=\"$width\" height=\"$height\" wmode=\"transparent\" flashvars=\"file=" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\"></embed>";
  3866. }
  3867. else
  3868. {
  3869. $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
  3870. }
  3871. }
  3872. // QuickTime 7 file types. Need to test with QuickTime 6.
  3873. // Only handle MP3's if the Flash Media Player is not present.
  3874. elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
  3875. {
  3876. $height += 16;
  3877. if ($native)
  3878. {
  3879. if ($placeholder !== '')
  3880. {
  3881. $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" href=\"" . $this->get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
  3882. }
  3883. else
  3884. {
  3885. $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" src=\"" . $this->get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
  3886. }
  3887. }
  3888. else
  3889. {
  3890. $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
  3891. }
  3892. }
  3893. // Windows Media
  3894. elseif ($handler === 'wmedia')
  3895. {
  3896. $height += 45;
  3897. if ($native)
  3898. {
  3899. $embed .= "<embed type=\"application/x-mplayer2\" src=\"" . $this->get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\"></embed>";
  3900. }
  3901. else
  3902. {
  3903. $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
  3904. }
  3905. }
  3906. // Everything else
  3907. else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
  3908. return $embed;
  3909. }
  3910. public function get_real_type($find_handler = false)
  3911. {
  3912. // Mime-types by handler.
  3913. $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
  3914. $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
  3915. $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime
  3916. $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media
  3917. $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
  3918. if ($this->get_type() !== null)
  3919. {
  3920. $type = strtolower($this->type);
  3921. }
  3922. else
  3923. {
  3924. $type = null;
  3925. }
  3926. // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
  3927. if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
  3928. {
  3929. switch (strtolower($this->get_extension()))
  3930. {
  3931. // Audio mime-types
  3932. case 'aac':
  3933. case 'adts':
  3934. $type = 'audio/acc';
  3935. break;
  3936. case 'aif':
  3937. case 'aifc':
  3938. case 'aiff':
  3939. case 'cdda':
  3940. $type = 'audio/aiff';
  3941. break;
  3942. case 'bwf':
  3943. $type = 'audio/wav';
  3944. break;
  3945. case 'kar':
  3946. case 'mid':
  3947. case 'midi':
  3948. case 'smf':
  3949. $type = 'audio/midi';
  3950. break;
  3951. case 'm4a':
  3952. $type = 'audio/x-m4a';
  3953. break;
  3954. case 'mp3':
  3955. case 'swa':
  3956. $type = 'audio/mp3';
  3957. break;
  3958. case 'wav':
  3959. $type = 'audio/wav';
  3960. break;
  3961. case 'wax':
  3962. $type = 'audio/x-ms-wax';
  3963. break;
  3964. case 'wma':
  3965. $type = 'audio/x-ms-wma';
  3966. break;
  3967. // Video mime-types
  3968. case '3gp':
  3969. case '3gpp':
  3970. $type = 'video/3gpp';
  3971. break;
  3972. case '3g2':
  3973. case '3gp2':
  3974. $type = 'video/3gpp2';
  3975. break;
  3976. case 'asf':
  3977. $type = 'video/x-ms-asf';
  3978. break;
  3979. case 'flv':
  3980. $type = 'video/x-flv';
  3981. break;
  3982. case 'm1a':
  3983. case 'm1s':
  3984. case 'm1v':
  3985. case 'm15':
  3986. case 'm75':
  3987. case 'mp2':
  3988. case 'mpa':
  3989. case 'mpeg':
  3990. case 'mpg':
  3991. case 'mpm':
  3992. case 'mpv':
  3993. $type = 'video/mpeg';
  3994. break;
  3995. case 'm4v':
  3996. $type = 'video/x-m4v';
  3997. break;
  3998. case 'mov':
  3999. case 'qt':
  4000. $type = 'video/quicktime';
  4001. break;
  4002. case 'mp4':
  4003. case 'mpg4':
  4004. $type = 'video/mp4';
  4005. break;
  4006. case 'sdv':
  4007. $type = 'video/sd-video';
  4008. break;
  4009. case 'wm':
  4010. $type = 'video/x-ms-wm';
  4011. break;
  4012. case 'wmv':
  4013. $type = 'video/x-ms-wmv';
  4014. break;
  4015. case 'wvx':
  4016. $type = 'video/x-ms-wvx';
  4017. break;
  4018. // Flash mime-types
  4019. case 'spl':
  4020. $type = 'application/futuresplash';
  4021. break;
  4022. case 'swf':
  4023. $type = 'application/x-shockwave-flash';
  4024. break;
  4025. }
  4026. }
  4027. if ($find_handler)
  4028. {
  4029. if (in_array($type, $types_flash))
  4030. {
  4031. return 'flash';
  4032. }
  4033. elseif (in_array($type, $types_fmedia))
  4034. {
  4035. return 'fmedia';
  4036. }
  4037. elseif (in_array($type, $types_quicktime))
  4038. {
  4039. return 'quicktime';
  4040. }
  4041. elseif (in_array($type, $types_wmedia))
  4042. {
  4043. return 'wmedia';
  4044. }
  4045. elseif (in_array($type, $types_mp3))
  4046. {
  4047. return 'mp3';
  4048. }
  4049. else
  4050. {
  4051. return null;
  4052. }
  4053. }
  4054. else
  4055. {
  4056. return $type;
  4057. }
  4058. }
  4059. }
  4060. class SimplePie_File
  4061. {
  4062. var $url;
  4063. var $useragent;
  4064. var $success = true;
  4065. var $headers = array();
  4066. var $body;
  4067. var $status_code;
  4068. var $redirects = 0;
  4069. var $error;
  4070. var $method = SIMPLEPIE_FILE_SOURCE_NONE;
  4071. public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
  4072. {
  4073. if (class_exists('idna_convert'))
  4074. {
  4075. $idn = new idna_convert();
  4076. $parsed = SimplePie_Misc::parse_url($url);
  4077. $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  4078. }
  4079. $this->url = $url;
  4080. $this->useragent = $useragent;
  4081. if (preg_match('/^http(s)?:\/\//i', $url))
  4082. {
  4083. if ($useragent === null)
  4084. {
  4085. $useragent = ini_get('user_agent');
  4086. $this->useragent = $useragent;
  4087. }
  4088. if (!is_array($headers))
  4089. {
  4090. $headers = array();
  4091. }
  4092. if (!$force_fsockopen && function_exists('curl_exec'))
  4093. {
  4094. $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
  4095. $fp = curl_init();
  4096. $headers2 = array();
  4097. foreach ($headers as $key => $value)
  4098. {
  4099. $headers2[] = "$key: $value";
  4100. }
  4101. if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
  4102. {
  4103. curl_setopt($fp, CURLOPT_ENCODING, '');
  4104. }
  4105. curl_setopt($fp, CURLOPT_URL, $url);
  4106. curl_setopt($fp, CURLOPT_HEADER, 1);
  4107. curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
  4108. curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
  4109. curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
  4110. curl_setopt($fp, CURLOPT_REFERER, $url);
  4111. curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
  4112. curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
  4113. if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
  4114. {
  4115. curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
  4116. curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
  4117. }
  4118. $this->headers = curl_exec($fp);
  4119. if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
  4120. {
  4121. curl_setopt($fp, CURLOPT_ENCODING, 'none');
  4122. $this->headers = curl_exec($fp);
  4123. }
  4124. if (curl_errno($fp))
  4125. {
  4126. $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
  4127. $this->success = false;
  4128. }
  4129. else
  4130. {
  4131. $info = curl_getinfo($fp);
  4132. curl_close($fp);
  4133. $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
  4134. $this->headers = array_pop($this->headers);
  4135. $parser = new SimplePie_HTTP_Parser($this->headers);
  4136. if ($parser->parse())
  4137. {
  4138. $this->headers = $parser->headers;
  4139. $this->body = $parser->body;
  4140. $this->status_code = $parser->status_code;
  4141. if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  4142. {
  4143. $this->redirects++;
  4144. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  4145. return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  4146. }
  4147. }
  4148. }
  4149. }
  4150. else
  4151. {
  4152. $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
  4153. $url_parts = parse_url($url);
  4154. $socket_host = $url_parts['host'];
  4155. if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
  4156. {
  4157. $socket_host = "ssl://$url_parts[host]";
  4158. $url_parts['port'] = 443;
  4159. }
  4160. if (!isset($url_parts['port']))
  4161. {
  4162. $url_parts['port'] = 80;
  4163. }
  4164. $fp = @fsockopen($socket_host, $url_parts['port'], $errno, $errstr, $timeout);
  4165. if (!$fp)
  4166. {
  4167. $this->error = 'fsockopen error: ' . $errstr;
  4168. $this->success = false;
  4169. }
  4170. else
  4171. {
  4172. stream_set_timeout($fp, $timeout);
  4173. if (isset($url_parts['path']))
  4174. {
  4175. if (isset($url_parts['query']))
  4176. {
  4177. $get = "$url_parts[path]?$url_parts[query]";
  4178. }
  4179. else
  4180. {
  4181. $get = $url_parts['path'];
  4182. }
  4183. }
  4184. else
  4185. {
  4186. $get = '/';
  4187. }
  4188. $out = "GET $get HTTP/1.1\r\n";
  4189. $out .= "Host: $url_parts[host]\r\n";
  4190. $out .= "User-Agent: $useragent\r\n";
  4191. if (extension_loaded('zlib'))
  4192. {
  4193. $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
  4194. }
  4195. if (isset($url_parts['user']) && isset($url_parts['pass']))
  4196. {
  4197. $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
  4198. }
  4199. foreach ($headers as $key => $value)
  4200. {
  4201. $out .= "$key: $value\r\n";
  4202. }
  4203. $out .= "Connection: Close\r\n\r\n";
  4204. fwrite($fp, $out);
  4205. $info = stream_get_meta_data($fp);
  4206. $this->headers = '';
  4207. while (!$info['eof'] && !$info['timed_out'])
  4208. {
  4209. $this->headers .= fread($fp, 1160);
  4210. $info = stream_get_meta_data($fp);
  4211. }
  4212. if (!$info['timed_out'])
  4213. {
  4214. $parser = new SimplePie_HTTP_Parser($this->headers);
  4215. if ($parser->parse())
  4216. {
  4217. $this->headers = $parser->headers;
  4218. $this->body = $parser->body;
  4219. $this->status_code = $parser->status_code;
  4220. if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  4221. {
  4222. $this->redirects++;
  4223. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  4224. return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  4225. }
  4226. if (isset($this->headers['content-encoding']))
  4227. {
  4228. // Hey, we act dumb elsewhere, so let's do that here too
  4229. switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
  4230. {
  4231. case 'gzip':
  4232. case 'x-gzip':
  4233. $decoder = new SimplePie_gzdecode($this->body);
  4234. if (!$decoder->parse())
  4235. {
  4236. $this->error = 'Unable to decode HTTP "gzip" stream';
  4237. $this->success = false;
  4238. }
  4239. else
  4240. {
  4241. $this->body = $decoder->data;
  4242. }
  4243. break;
  4244. case 'deflate':
  4245. if (($decompressed = gzinflate($this->body)) !== false)
  4246. {
  4247. $this->body = $decompressed;
  4248. }
  4249. else if (($decompressed = gzuncompress($this->body)) !== false)
  4250. {
  4251. $this->body = $decompressed;
  4252. }
  4253. else if (function_exists('gzdecode') && ($decompressed = gzdecode($this->body)) !== false)
  4254. {
  4255. $this->body = $decompressed;
  4256. }
  4257. else
  4258. {
  4259. $this->error = 'Unable to decode HTTP "deflate" stream';
  4260. $this->success = false;
  4261. }
  4262. break;
  4263. default:
  4264. $this->error = 'Unknown content coding';
  4265. $this->success = false;
  4266. }
  4267. }
  4268. }
  4269. }
  4270. else
  4271. {
  4272. $this->error = 'fsocket timed out';
  4273. $this->success = false;
  4274. }
  4275. fclose($fp);
  4276. }
  4277. }
  4278. }
  4279. else
  4280. {
  4281. $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
  4282. if (!$this->body = file_get_contents($url))
  4283. {
  4284. $this->error = 'file_get_contents could not read the file';
  4285. $this->success = false;
  4286. }
  4287. }
  4288. }
  4289. }
  4290. class SimplePie_gzdecode
  4291. {
  4292. var $compressed_data;
  4293. var $compressed_size;
  4294. var $min_compressed_size = 18;
  4295. var $position = 0;
  4296. var $flags;
  4297. var $data;
  4298. var $MTIME;
  4299. var $XFL;
  4300. var $OS;
  4301. var $SI1;
  4302. var $SI2;
  4303. var $extra_field;
  4304. var $filename;
  4305. var $comment;
  4306. public function __set($name, $value)
  4307. {
  4308. trigger_error("Cannot write property $name", E_USER_ERROR);
  4309. }
  4310. public function __construct($data)
  4311. {
  4312. $this->compressed_data = $data;
  4313. $this->compressed_size = strlen($data);
  4314. }
  4315. public function parse()
  4316. {
  4317. if ($this->compressed_size >= $this->min_compressed_size)
  4318. {
  4319. // Check ID1, ID2, and CM
  4320. if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
  4321. {
  4322. return false;
  4323. }
  4324. // Get the FLG (FLaGs)
  4325. $this->flags = ord($this->compressed_data[3]);
  4326. // FLG bits above (1 << 4) are reserved
  4327. if ($this->flags > 0x1F)
  4328. {
  4329. return false;
  4330. }
  4331. // Advance the pointer after the above
  4332. $this->position += 4;
  4333. // MTIME
  4334. $mtime = substr($this->compressed_data, $this->position, 4);
  4335. // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
  4336. if (current(unpack('S', "\x00\x01")) === 1)
  4337. {
  4338. $mtime = strrev($mtime);
  4339. }
  4340. $this->MTIME = current(unpack('l', $mtime));
  4341. $this->position += 4;
  4342. // Get the XFL (eXtra FLags)
  4343. $this->XFL = ord($this->compressed_data[$this->position++]);
  4344. // Get the OS (Operating System)
  4345. $this->OS = ord($this->compressed_data[$this->position++]);
  4346. // Parse the FEXTRA
  4347. if ($this->flags & 4)
  4348. {
  4349. // Read subfield IDs
  4350. $this->SI1 = $this->compressed_data[$this->position++];
  4351. $this->SI2 = $this->compressed_data[$this->position++];
  4352. // SI2 set to zero is reserved for future use
  4353. if ($this->SI2 === "\x00")
  4354. {
  4355. return false;
  4356. }
  4357. // Get the length of the extra field
  4358. $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
  4359. $this->position += 2;
  4360. // Check the length of the string is still valid
  4361. $this->min_compressed_size += $len + 4;
  4362. if ($this->compressed_size >= $this->min_compressed_size)
  4363. {
  4364. // Set the extra field to the given data
  4365. $this->extra_field = substr($this->compressed_data, $this->position, $len);
  4366. $this->position += $len;
  4367. }
  4368. else
  4369. {
  4370. return false;
  4371. }
  4372. }
  4373. // Parse the FNAME
  4374. if ($this->flags & 8)
  4375. {
  4376. // Get the length of the filename
  4377. $len = strcspn($this->compressed_data, "\x00", $this->position);
  4378. // Check the length of the string is still valid
  4379. $this->min_compressed_size += $len + 1;
  4380. if ($this->compressed_size >= $this->min_compressed_size)
  4381. {
  4382. // Set the original filename to the given string
  4383. $this->filename = substr($this->compressed_data, $this->position, $len);
  4384. $this->position += $len + 1;
  4385. }
  4386. else
  4387. {
  4388. return false;
  4389. }
  4390. }
  4391. // Parse the FCOMMENT
  4392. if ($this->flags & 16)
  4393. {
  4394. // Get the length of the comment
  4395. $len = strcspn($this->compressed_data, "\x00", $this->position);
  4396. // Check the length of the string is still valid
  4397. $this->min_compressed_size += $len + 1;
  4398. if ($this->compressed_size >= $this->min_compressed_size)
  4399. {
  4400. // Set the original comment to the given string
  4401. $this->comment = substr($this->compressed_data, $this->position, $len);
  4402. $this->position += $len + 1;
  4403. }
  4404. else
  4405. {
  4406. return false;
  4407. }
  4408. }
  4409. // Parse the FHCRC
  4410. if ($this->flags & 2)
  4411. {
  4412. // Check the length of the string is still valid
  4413. $this->min_compressed_size += $len + 2;
  4414. if ($this->compressed_size >= $this->min_compressed_size)
  4415. {
  4416. // Read the CRC
  4417. $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
  4418. // Check the CRC matches
  4419. if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
  4420. {
  4421. $this->position += 2;
  4422. }
  4423. else
  4424. {
  4425. return false;
  4426. }
  4427. }
  4428. else
  4429. {
  4430. return false;
  4431. }
  4432. }
  4433. // Decompress the actual data
  4434. if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
  4435. {
  4436. return false;
  4437. }
  4438. else
  4439. {
  4440. $this->position = $this->compressed_size - 8;
  4441. }
  4442. // Check CRC of data
  4443. $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
  4444. $this->position += 4;
  4445. /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
  4446. {
  4447. return false;
  4448. }*/
  4449. // Check ISIZE of data
  4450. $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
  4451. $this->position += 4;
  4452. if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
  4453. {
  4454. return false;
  4455. }
  4456. // Wow, against all odds, we've actually got a valid gzip string
  4457. return true;
  4458. }
  4459. else
  4460. {
  4461. return false;
  4462. }
  4463. }
  4464. }
  4465. class SimplePie_HTTP_Parser
  4466. {
  4467. public $http_version = 0.0;
  4468. public $status_code = 0;
  4469. public $reason = '';
  4470. public $headers = array();
  4471. public $body = '';
  4472. protected $state = 'http_version';
  4473. protected $data = '';
  4474. protected $data_length = 0;
  4475. protected $position = 0;
  4476. protected $name = '';
  4477. protected $value = '';
  4478. public function __construct($data)
  4479. {
  4480. $this->data = $data;
  4481. $this->data_length = strlen($this->data);
  4482. }
  4483. public function parse()
  4484. {
  4485. while ($this->state && $this->state !== 'emit' && $this->has_data())
  4486. {
  4487. $state = $this->state;
  4488. $this->$state();
  4489. }
  4490. $this->data = '';
  4491. if ($this->state === 'emit' || $this->state === 'body')
  4492. {
  4493. return true;
  4494. }
  4495. else
  4496. {
  4497. $this->http_version = '';
  4498. $this->status_code = '';
  4499. $this->reason = '';
  4500. $this->headers = array();
  4501. $this->body = '';
  4502. return false;
  4503. }
  4504. }
  4505. protected function has_data()
  4506. {
  4507. return (bool) ($this->position < $this->data_length);
  4508. }
  4509. protected function is_linear_whitespace()
  4510. {
  4511. return (bool) ($this->data[$this->position] === "\x09"
  4512. || $this->data[$this->position] === "\x20"
  4513. || ($this->data[$this->position] === "\x0A"
  4514. && isset($this->data[$this->position + 1])
  4515. && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
  4516. }
  4517. protected function http_version()
  4518. {
  4519. if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
  4520. {
  4521. $len = strspn($this->data, '0123456789.', 5);
  4522. $this->http_version = substr($this->data, 5, $len);
  4523. $this->position += 5 + $len;
  4524. if (substr_count($this->http_version, '.') <= 1)
  4525. {
  4526. $this->http_version = (float) $this->http_version;
  4527. $this->position += strspn($this->data, "\x09\x20", $this->position);
  4528. $this->state = 'status';
  4529. }
  4530. else
  4531. {
  4532. $this->state = false;
  4533. }
  4534. }
  4535. else
  4536. {
  4537. $this->state = false;
  4538. }
  4539. }
  4540. protected function status()
  4541. {
  4542. if ($len = strspn($this->data, '0123456789', $this->position))
  4543. {
  4544. $this->status_code = (int) substr($this->data, $this->position, $len);
  4545. $this->position += $len;
  4546. $this->state = 'reason';
  4547. }
  4548. else
  4549. {
  4550. $this->state = false;
  4551. }
  4552. }
  4553. protected function reason()
  4554. {
  4555. $len = strcspn($this->data, "\x0A", $this->position);
  4556. $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
  4557. $this->position += $len + 1;
  4558. $this->state = 'new_line';
  4559. }
  4560. protected function new_line()
  4561. {
  4562. $this->value = trim($this->value, "\x0D\x20");
  4563. if ($this->name !== '' && $this->value !== '')
  4564. {
  4565. $this->name = strtolower($this->name);
  4566. // We should only use the last Content-Type header. c.f. issue #1
  4567. if (isset($this->headers[$this->name]) && $this->name !== 'content-type')
  4568. {
  4569. $this->headers[$this->name] .= ', ' . $this->value;
  4570. }
  4571. else
  4572. {
  4573. $this->headers[$this->name] = $this->value;
  4574. }
  4575. }
  4576. $this->name = '';
  4577. $this->value = '';
  4578. if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
  4579. {
  4580. $this->position += 2;
  4581. $this->state = 'body';
  4582. }
  4583. elseif ($this->data[$this->position] === "\x0A")
  4584. {
  4585. $this->position++;
  4586. $this->state = 'body';
  4587. }
  4588. else
  4589. {
  4590. $this->state = 'name';
  4591. }
  4592. }
  4593. protected function name()
  4594. {
  4595. $len = strcspn($this->data, "\x0A:", $this->position);
  4596. if (isset($this->data[$this->position + $len]))
  4597. {
  4598. if ($this->data[$this->position + $len] === "\x0A")
  4599. {
  4600. $this->position += $len;
  4601. $this->state = 'new_line';
  4602. }
  4603. else
  4604. {
  4605. $this->name = substr($this->data, $this->position, $len);
  4606. $this->position += $len + 1;
  4607. $this->state = 'value';
  4608. }
  4609. }
  4610. else
  4611. {
  4612. $this->state = false;
  4613. }
  4614. }
  4615. protected function linear_whitespace()
  4616. {
  4617. do
  4618. {
  4619. if (substr($this->data, $this->position, 2) === "\x0D\x0A")
  4620. {
  4621. $this->position += 2;
  4622. }
  4623. elseif ($this->data[$this->position] === "\x0A")
  4624. {
  4625. $this->position++;
  4626. }
  4627. $this->position += strspn($this->data, "\x09\x20", $this->position);
  4628. } while ($this->has_data() && $this->is_linear_whitespace());
  4629. $this->value .= "\x20";
  4630. }
  4631. protected function value()
  4632. {
  4633. if ($this->is_linear_whitespace())
  4634. {
  4635. $this->linear_whitespace();
  4636. }
  4637. else
  4638. {
  4639. switch ($this->data[$this->position])
  4640. {
  4641. case '"':
  4642. // Workaround for ETags: we have to include the quotes as
  4643. // part of the tag.
  4644. if (strtolower($this->name) === 'etag')
  4645. {
  4646. $this->value .= '"';
  4647. $this->position++;
  4648. $this->state = 'value_char';
  4649. break;
  4650. }
  4651. $this->position++;
  4652. $this->state = 'quote';
  4653. break;
  4654. case "\x0A":
  4655. $this->position++;
  4656. $this->state = 'new_line';
  4657. break;
  4658. default:
  4659. $this->state = 'value_char';
  4660. break;
  4661. }
  4662. }
  4663. }
  4664. protected function value_char()
  4665. {
  4666. $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
  4667. $this->value .= substr($this->data, $this->position, $len);
  4668. $this->position += $len;
  4669. $this->state = 'value';
  4670. }
  4671. protected function quote()
  4672. {
  4673. if ($this->is_linear_whitespace())
  4674. {
  4675. $this->linear_whitespace();
  4676. }
  4677. else
  4678. {
  4679. switch ($this->data[$this->position])
  4680. {
  4681. case '"':
  4682. $this->position++;
  4683. $this->state = 'value';
  4684. break;
  4685. case "\x0A":
  4686. $this->position++;
  4687. $this->state = 'new_line';
  4688. break;
  4689. case '\\':
  4690. $this->position++;
  4691. $this->state = 'quote_escaped';
  4692. break;
  4693. default:
  4694. $this->state = 'quote_char';
  4695. break;
  4696. }
  4697. }
  4698. }
  4699. protected function quote_char()
  4700. {
  4701. $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
  4702. $this->value .= substr($this->data, $this->position, $len);
  4703. $this->position += $len;
  4704. $this->state = 'value';
  4705. }
  4706. protected function quote_escaped()
  4707. {
  4708. $this->value .= $this->data[$this->position];
  4709. $this->position++;
  4710. $this->state = 'quote';
  4711. }
  4712. protected function body()
  4713. {
  4714. $this->body = substr($this->data, $this->position);
  4715. if (!empty($this->headers['transfer-encoding']))
  4716. {
  4717. unset($this->headers['transfer-encoding']);
  4718. $this->state = 'chunked';
  4719. }
  4720. else
  4721. {
  4722. $this->state = 'emit';
  4723. }
  4724. }
  4725. protected function chunked()
  4726. {
  4727. if (!preg_match('/^([0-9a-f]+)[^\r\n]*\r\n/i', trim($this->body)))
  4728. {
  4729. $this->state = 'emit';
  4730. return;
  4731. }
  4732. $decoded = '';
  4733. $encoded = $this->body;
  4734. while (true)
  4735. {
  4736. $is_chunked = (bool) preg_match( '/^([0-9a-f]+)[^\r\n]*\r\n/i', $encoded, $matches );
  4737. if (!$is_chunked)
  4738. {
  4739. // Looks like it's not chunked after all
  4740. $this->state = 'emit';
  4741. return;
  4742. }
  4743. $length = hexdec(trim($matches[1]));
  4744. if ($length === 0)
  4745. {
  4746. // Ignore trailer headers
  4747. $this->state = 'emit';
  4748. $this->body = $decoded;
  4749. return;
  4750. }
  4751. $chunk_length = strlen($matches[0]);
  4752. $decoded .= $part = substr($encoded, $chunk_length, $length);
  4753. $encoded = substr($encoded, $chunk_length + $length + 2);
  4754. if (trim($encoded) === '0' || empty($encoded))
  4755. {
  4756. $this->state = 'emit';
  4757. $this->body = $decoded;
  4758. return;
  4759. }
  4760. }
  4761. }
  4762. }
  4763. class SimplePie_IRI
  4764. {
  4765. protected $scheme = null;
  4766. protected $iuserinfo = null;
  4767. protected $ihost = null;
  4768. protected $port = null;
  4769. protected $ipath = '';
  4770. protected $iquery = null;
  4771. protected $ifragment = null;
  4772. protected $normalization = array(
  4773. 'acap' => array(
  4774. 'port' => 674
  4775. ),
  4776. 'dict' => array(
  4777. 'port' => 2628
  4778. ),
  4779. 'file' => array(
  4780. 'ihost' => 'localhost'
  4781. ),
  4782. 'http' => array(
  4783. 'port' => 80,
  4784. 'ipath' => '/'
  4785. ),
  4786. 'https' => array(
  4787. 'port' => 443,
  4788. 'ipath' => '/'
  4789. ),
  4790. );
  4791. public function __toString()
  4792. {
  4793. return $this->get_iri();
  4794. }
  4795. public function __set($name, $value)
  4796. {
  4797. if (method_exists($this, 'set_' . $name))
  4798. {
  4799. call_user_func(array($this, 'set_' . $name), $value);
  4800. }
  4801. elseif (
  4802. $name === 'iauthority'
  4803. || $name === 'iuserinfo'
  4804. || $name === 'ihost'
  4805. || $name === 'ipath'
  4806. || $name === 'iquery'
  4807. || $name === 'ifragment'
  4808. )
  4809. {
  4810. call_user_func(array($this, 'set_' . substr($name, 1)), $value);
  4811. }
  4812. }
  4813. public function __get($name)
  4814. {
  4815. // isset() returns false for null, we don't want to do that
  4816. // Also why we use array_key_exists below instead of isset()
  4817. $props = get_object_vars($this);
  4818. if (
  4819. $name === 'iri' ||
  4820. $name === 'uri' ||
  4821. $name === 'iauthority' ||
  4822. $name === 'authority'
  4823. )
  4824. {
  4825. $return = $this->{"get_$name"}();
  4826. }
  4827. elseif (array_key_exists($name, $props))
  4828. {
  4829. $return = $this->$name;
  4830. }
  4831. // host -> ihost
  4832. elseif (($prop = 'i' . $name) && array_key_exists($prop, $props))
  4833. {
  4834. $name = $prop;
  4835. $return = $this->$prop;
  4836. }
  4837. // ischeme -> scheme
  4838. elseif (($prop = substr($name, 1)) && array_key_exists($prop, $props))
  4839. {
  4840. $name = $prop;
  4841. $return = $this->$prop;
  4842. }
  4843. else
  4844. {
  4845. trigger_error('Undefined property: ' . get_class($this) . '::' . $name, E_USER_NOTICE);
  4846. $return = null;
  4847. }
  4848. if ($return === null && isset($this->normalization[$this->scheme][$name]))
  4849. {
  4850. return $this->normalization[$this->scheme][$name];
  4851. }
  4852. else
  4853. {
  4854. return $return;
  4855. }
  4856. }
  4857. public function __isset($name)
  4858. {
  4859. if (method_exists($this, 'get_' . $name) || isset($this->$name))
  4860. {
  4861. return true;
  4862. }
  4863. else
  4864. {
  4865. return false;
  4866. }
  4867. }
  4868. public function __unset($name)
  4869. {
  4870. if (method_exists($this, 'set_' . $name))
  4871. {
  4872. call_user_func(array($this, 'set_' . $name), '');
  4873. }
  4874. }
  4875. public function __construct($iri = null)
  4876. {
  4877. $this->set_iri($iri);
  4878. }
  4879. public static function absolutize($base, $relative)
  4880. {
  4881. if (!($relative instanceof SimplePie_IRI))
  4882. {
  4883. $relative = new SimplePie_IRI($relative);
  4884. }
  4885. if (!$relative->is_valid())
  4886. {
  4887. return false;
  4888. }
  4889. elseif ($relative->scheme !== null)
  4890. {
  4891. return clone $relative;
  4892. }
  4893. else
  4894. {
  4895. if (!($base instanceof SimplePie_IRI))
  4896. {
  4897. $base = new SimplePie_IRI($base);
  4898. }
  4899. if ($base->scheme !== null && $base->is_valid())
  4900. {
  4901. if ($relative->get_iri() !== '')
  4902. {
  4903. if ($relative->iuserinfo !== null || $relative->ihost !== null || $relative->port !== null)
  4904. {
  4905. $target = clone $relative;
  4906. $target->scheme = $base->scheme;
  4907. }
  4908. else
  4909. {
  4910. $target = new SimplePie_IRI;
  4911. $target->scheme = $base->scheme;
  4912. $target->iuserinfo = $base->iuserinfo;
  4913. $target->ihost = $base->ihost;
  4914. $target->port = $base->port;
  4915. if ($relative->ipath !== '')
  4916. {
  4917. if ($relative->ipath[0] === '/')
  4918. {
  4919. $target->ipath = $relative->ipath;
  4920. }
  4921. elseif (($base->iuserinfo !== null || $base->ihost !== null || $base->port !== null) && $base->ipath === '')
  4922. {
  4923. $target->ipath = '/' . $relative->ipath;
  4924. }
  4925. elseif (($last_segment = strrpos($base->ipath, '/')) !== false)
  4926. {
  4927. $target->ipath = substr($base->ipath, 0, $last_segment + 1) . $relative->ipath;
  4928. }
  4929. else
  4930. {
  4931. $target->ipath = $relative->ipath;
  4932. }
  4933. $target->ipath = $target->remove_dot_segments($target->ipath);
  4934. $target->iquery = $relative->iquery;
  4935. }
  4936. else
  4937. {
  4938. $target->ipath = $base->ipath;
  4939. if ($relative->iquery !== null)
  4940. {
  4941. $target->iquery = $relative->iquery;
  4942. }
  4943. elseif ($base->iquery !== null)
  4944. {
  4945. $target->iquery = $base->iquery;
  4946. }
  4947. }
  4948. $target->ifragment = $relative->ifragment;
  4949. }
  4950. }
  4951. else
  4952. {
  4953. $target = clone $base;
  4954. $target->ifragment = null;
  4955. }
  4956. $target->scheme_normalization();
  4957. return $target;
  4958. }
  4959. else
  4960. {
  4961. return false;
  4962. }
  4963. }
  4964. }
  4965. protected function parse_iri($iri)
  4966. {
  4967. $iri = trim($iri, "\x20\x09\x0A\x0C\x0D");
  4968. if (preg_match('/^((?P<scheme>[^:\/?#]+):)?(\/\/(?P<authority>[^\/?#]*))?(?P<path>[^?#]*)(\?(?P<query>[^#]*))?(#(?P<fragment>.*))?$/', $iri, $match))
  4969. {
  4970. if ($match[1] === '')
  4971. {
  4972. $match['scheme'] = null;
  4973. }
  4974. if (!isset($match[3]) || $match[3] === '')
  4975. {
  4976. $match['authority'] = null;
  4977. }
  4978. if (!isset($match[5]))
  4979. {
  4980. $match['path'] = '';
  4981. }
  4982. if (!isset($match[6]) || $match[6] === '')
  4983. {
  4984. $match['query'] = null;
  4985. }
  4986. if (!isset($match[8]) || $match[8] === '')
  4987. {
  4988. $match['fragment'] = null;
  4989. }
  4990. return $match;
  4991. }
  4992. else
  4993. {
  4994. trigger_error('This should never happen', E_USER_ERROR);
  4995. die;
  4996. }
  4997. }
  4998. protected function remove_dot_segments($input)
  4999. {
  5000. $output = '';
  5001. while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
  5002. {
  5003. // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
  5004. if (strpos($input, '../') === 0)
  5005. {
  5006. $input = substr($input, 3);
  5007. }
  5008. elseif (strpos($input, './') === 0)
  5009. {
  5010. $input = substr($input, 2);
  5011. }
  5012. // 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,
  5013. elseif (strpos($input, '/./') === 0)
  5014. {
  5015. $input = substr($input, 2);
  5016. }
  5017. elseif ($input === '/.')
  5018. {
  5019. $input = '/';
  5020. }
  5021. // 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,
  5022. elseif (strpos($input, '/../') === 0)
  5023. {
  5024. $input = substr($input, 3);
  5025. $output = substr_replace($output, '', strrpos($output, '/'));
  5026. }
  5027. elseif ($input === '/..')
  5028. {
  5029. $input = '/';
  5030. $output = substr_replace($output, '', strrpos($output, '/'));
  5031. }
  5032. // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
  5033. elseif ($input === '.' || $input === '..')
  5034. {
  5035. $input = '';
  5036. }
  5037. // 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
  5038. elseif (($pos = strpos($input, '/', 1)) !== false)
  5039. {
  5040. $output .= substr($input, 0, $pos);
  5041. $input = substr_replace($input, '', 0, $pos);
  5042. }
  5043. else
  5044. {
  5045. $output .= $input;
  5046. $input = '';
  5047. }
  5048. }
  5049. return $output . $input;
  5050. }
  5051. protected function replace_invalid_with_pct_encoding($string, $extra_chars, $iprivate = false)
  5052. {
  5053. // Normalize as many pct-encoded sections as possible
  5054. $string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array($this, 'remove_iunreserved_percent_encoded'), $string);
  5055. // Replace invalid percent characters
  5056. $string = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $string);
  5057. // Add unreserved and % to $extra_chars (the latter is safe because all
  5058. // pct-encoded sections are now valid).
  5059. $extra_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';
  5060. // Now replace any bytes that aren't allowed with their pct-encoded versions
  5061. $position = 0;
  5062. $strlen = strlen($string);
  5063. while (($position += strspn($string, $extra_chars, $position)) < $strlen)
  5064. {
  5065. $value = ord($string[$position]);
  5066. // Start position
  5067. $start = $position;
  5068. // By default we are valid
  5069. $valid = true;
  5070. // No one byte sequences are valid due to the while.
  5071. // Two byte sequence:
  5072. if (($value & 0xE0) === 0xC0)
  5073. {
  5074. $character = ($value & 0x1F) << 6;
  5075. $length = 2;
  5076. $remaining = 1;
  5077. }
  5078. // Three byte sequence:
  5079. elseif (($value & 0xF0) === 0xE0)
  5080. {
  5081. $character = ($value & 0x0F) << 12;
  5082. $length = 3;
  5083. $remaining = 2;
  5084. }
  5085. // Four byte sequence:
  5086. elseif (($value & 0xF8) === 0xF0)
  5087. {
  5088. $character = ($value & 0x07) << 18;
  5089. $length = 4;
  5090. $remaining = 3;
  5091. }
  5092. // Invalid byte:
  5093. else
  5094. {
  5095. $valid = false;
  5096. $length = 1;
  5097. $remaining = 0;
  5098. }
  5099. if ($remaining)
  5100. {
  5101. if ($position + $length <= $strlen)
  5102. {
  5103. for ($position++; $remaining; $position++)
  5104. {
  5105. $value = ord($string[$position]);
  5106. // Check that the byte is valid, then add it to the character:
  5107. if (($value & 0xC0) === 0x80)
  5108. {
  5109. $character |= ($value & 0x3F) << (--$remaining * 6);
  5110. }
  5111. // If it is invalid, count the sequence as invalid and reprocess the current byte:
  5112. else
  5113. {
  5114. $valid = false;
  5115. $position--;
  5116. break;
  5117. }
  5118. }
  5119. }
  5120. else
  5121. {
  5122. $position = $strlen - 1;
  5123. $valid = false;
  5124. }
  5125. }
  5126. // Percent encode anything invalid or not in ucschar
  5127. if (
  5128. // Invalid sequences
  5129. !$valid
  5130. // Non-shortest form sequences are invalid
  5131. || $length > 1 && $character <= 0x7F
  5132. || $length > 2 && $character <= 0x7FF
  5133. || $length > 3 && $character <= 0xFFFF
  5134. // Outside of range of ucschar codepoints
  5135. // Noncharacters
  5136. || ($character & 0xFFFE) === 0xFFFE
  5137. || $character >= 0xFDD0 && $character <= 0xFDEF
  5138. || (
  5139. // Everything else not in ucschar
  5140. $character > 0xD7FF && $character < 0xF900
  5141. || $character < 0xA0
  5142. || $character > 0xEFFFD
  5143. )
  5144. && (
  5145. // Everything not in iprivate, if it applies
  5146. !$iprivate
  5147. || $character < 0xE000
  5148. || $character > 0x10FFFD
  5149. )
  5150. )
  5151. {
  5152. // If we were a character, pretend we weren't, but rather an error.
  5153. if ($valid)
  5154. $position--;
  5155. for ($j = $start; $j <= $position; $j++)
  5156. {
  5157. $string = substr_replace($string, sprintf('%%%02X', ord($string[$j])), $j, 1);
  5158. $j += 2;
  5159. $position += 2;
  5160. $strlen += 2;
  5161. }
  5162. }
  5163. }
  5164. return $string;
  5165. }
  5166. protected function remove_iunreserved_percent_encoded($match)
  5167. {
  5168. // As we just have valid percent encoded sequences we can just explode
  5169. // and ignore the first member of the returned array (an empty string).
  5170. $bytes = explode('%', $match[0]);
  5171. // Initialize the new string (this is what will be returned) and that
  5172. // there are no bytes remaining in the current sequence (unsurprising
  5173. // at the first byte!).
  5174. $string = '';
  5175. $remaining = 0;
  5176. // Loop over each and every byte, and set $value to its value
  5177. for ($i = 1, $len = count($bytes); $i < $len; $i++)
  5178. {
  5179. $value = hexdec($bytes[$i]);
  5180. // If we're the first byte of sequence:
  5181. if (!$remaining)
  5182. {
  5183. // Start position
  5184. $start = $i;
  5185. // By default we are valid
  5186. $valid = true;
  5187. // One byte sequence:
  5188. if ($value <= 0x7F)
  5189. {
  5190. $character = $value;
  5191. $length = 1;
  5192. }
  5193. // Two byte sequence:
  5194. elseif (($value & 0xE0) === 0xC0)
  5195. {
  5196. $character = ($value & 0x1F) << 6;
  5197. $length = 2;
  5198. $remaining = 1;
  5199. }
  5200. // Three byte sequence:
  5201. elseif (($value & 0xF0) === 0xE0)
  5202. {
  5203. $character = ($value & 0x0F) << 12;
  5204. $length = 3;
  5205. $remaining = 2;
  5206. }
  5207. // Four byte sequence:
  5208. elseif (($value & 0xF8) === 0xF0)
  5209. {
  5210. $character = ($value & 0x07) << 18;
  5211. $length = 4;
  5212. $remaining = 3;
  5213. }
  5214. // Invalid byte:
  5215. else
  5216. {
  5217. $valid = false;
  5218. $remaining = 0;
  5219. }
  5220. }
  5221. // Continuation byte:
  5222. else
  5223. {
  5224. // Check that the byte is valid, then add it to the character:
  5225. if (($value & 0xC0) === 0x80)
  5226. {
  5227. $remaining--;
  5228. $character |= ($value & 0x3F) << ($remaining * 6);
  5229. }
  5230. // If it is invalid, count the sequence as invalid and reprocess the current byte as the start of a sequence:
  5231. else
  5232. {
  5233. $valid = false;
  5234. $remaining = 0;
  5235. $i--;
  5236. }
  5237. }
  5238. // If we've reached the end of the current byte sequence, append it to Unicode::$data
  5239. if (!$remaining)
  5240. {
  5241. // Percent encode anything invalid or not in iunreserved
  5242. if (
  5243. // Invalid sequences
  5244. !$valid
  5245. // Non-shortest form sequences are invalid
  5246. || $length > 1 && $character <= 0x7F
  5247. || $length > 2 && $character <= 0x7FF
  5248. || $length > 3 && $character <= 0xFFFF
  5249. // Outside of range of iunreserved codepoints
  5250. || $character < 0x2D
  5251. || $character > 0xEFFFD
  5252. // Noncharacters
  5253. || ($character & 0xFFFE) === 0xFFFE
  5254. || $character >= 0xFDD0 && $character <= 0xFDEF
  5255. // Everything else not in iunreserved (this is all BMP)
  5256. || $character === 0x2F
  5257. || $character > 0x39 && $character < 0x41
  5258. || $character > 0x5A && $character < 0x61
  5259. || $character > 0x7A && $character < 0x7E
  5260. || $character > 0x7E && $character < 0xA0
  5261. || $character > 0xD7FF && $character < 0xF900
  5262. )
  5263. {
  5264. for ($j = $start; $j <= $i; $j++)
  5265. {
  5266. $string .= '%' . strtoupper($bytes[$j]);
  5267. }
  5268. }
  5269. else
  5270. {
  5271. for ($j = $start; $j <= $i; $j++)
  5272. {
  5273. $string .= chr(hexdec($bytes[$j]));
  5274. }
  5275. }
  5276. }
  5277. }
  5278. // If we have any bytes left over they are invalid (i.e., we are
  5279. // mid-way through a multi-byte sequence)
  5280. if ($remaining)
  5281. {
  5282. for ($j = $start; $j < $len; $j++)
  5283. {
  5284. $string .= '%' . strtoupper($bytes[$j]);
  5285. }
  5286. }
  5287. return $string;
  5288. }
  5289. protected function scheme_normalization()
  5290. {
  5291. if (isset($this->normalization[$this->scheme]['iuserinfo']) && $this->iuserinfo === $this->normalization[$this->scheme]['iuserinfo'])
  5292. {
  5293. $this->iuserinfo = null;
  5294. }
  5295. if (isset($this->normalization[$this->scheme]['ihost']) && $this->ihost === $this->normalization[$this->scheme]['ihost'])
  5296. {
  5297. $this->ihost = null;
  5298. }
  5299. if (isset($this->normalization[$this->scheme]['port']) && $this->port === $this->normalization[$this->scheme]['port'])
  5300. {
  5301. $this->port = null;
  5302. }
  5303. if (isset($this->normalization[$this->scheme]['ipath']) && $this->ipath === $this->normalization[$this->scheme]['ipath'])
  5304. {
  5305. $this->ipath = '';
  5306. }
  5307. if (isset($this->normalization[$this->scheme]['iquery']) && $this->iquery === $this->normalization[$this->scheme]['iquery'])
  5308. {
  5309. $this->iquery = null;
  5310. }
  5311. if (isset($this->normalization[$this->scheme]['ifragment']) && $this->ifragment === $this->normalization[$this->scheme]['ifragment'])
  5312. {
  5313. $this->ifragment = null;
  5314. }
  5315. }
  5316. public function is_valid()
  5317. {
  5318. $isauthority = $this->iuserinfo !== null || $this->ihost !== null || $this->port !== null;
  5319. if ($this->ipath !== '' &&
  5320. (
  5321. $isauthority && (
  5322. $this->ipath[0] !== '/' ||
  5323. substr($this->ipath, 0, 2) === '//'
  5324. ) ||
  5325. (
  5326. $this->scheme === null &&
  5327. !$isauthority &&
  5328. strpos($this->ipath, ':') !== false &&
  5329. (strpos($this->ipath, '/') === false ? true : strpos($this->ipath, ':') < strpos($this->ipath, '/'))
  5330. )
  5331. )
  5332. )
  5333. {
  5334. return false;
  5335. }
  5336. return true;
  5337. }
  5338. public function set_iri($iri)
  5339. {
  5340. static $cache;
  5341. if (!$cache)
  5342. {
  5343. $cache = array();
  5344. }
  5345. if ($iri === null)
  5346. {
  5347. return true;
  5348. }
  5349. elseif (isset($cache[$iri]))
  5350. {
  5351. list($this->scheme,
  5352. $this->iuserinfo,
  5353. $this->ihost,
  5354. $this->port,
  5355. $this->ipath,
  5356. $this->iquery,
  5357. $this->ifragment,
  5358. $return) = $cache[$iri];
  5359. return $return;
  5360. }
  5361. else
  5362. {
  5363. $parsed = $this->parse_iri((string) $iri);
  5364. $return = $this->set_scheme($parsed['scheme'])
  5365. && $this->set_authority($parsed['authority'])
  5366. && $this->set_path($parsed['path'])
  5367. && $this->set_query($parsed['query'])
  5368. && $this->set_fragment($parsed['fragment']);
  5369. $cache[$iri] = array($this->scheme,
  5370. $this->iuserinfo,
  5371. $this->ihost,
  5372. $this->port,
  5373. $this->ipath,
  5374. $this->iquery,
  5375. $this->ifragment,
  5376. $return);
  5377. return $return;
  5378. }
  5379. }
  5380. public function set_scheme($scheme)
  5381. {
  5382. if ($scheme === null)
  5383. {
  5384. $this->scheme = null;
  5385. }
  5386. elseif (!preg_match('/^[A-Za-z][0-9A-Za-z+\-.]*$/', $scheme))
  5387. {
  5388. $this->scheme = null;
  5389. return false;
  5390. }
  5391. else
  5392. {
  5393. $this->scheme = strtolower($scheme);
  5394. }
  5395. return true;
  5396. }
  5397. public function set_authority($authority)
  5398. {
  5399. static $cache;
  5400. if (!$cache)
  5401. $cache = array();
  5402. if ($authority === null)
  5403. {
  5404. $this->iuserinfo = null;
  5405. $this->ihost = null;
  5406. $this->port = null;
  5407. return true;
  5408. }
  5409. elseif (isset($cache[$authority]))
  5410. {
  5411. list($this->iuserinfo,
  5412. $this->ihost,
  5413. $this->port,
  5414. $return) = $cache[$authority];
  5415. return $return;
  5416. }
  5417. else
  5418. {
  5419. $remaining = $authority;
  5420. if (($iuserinfo_end = strrpos($remaining, '@')) !== false)
  5421. {
  5422. $iuserinfo = substr($remaining, 0, $iuserinfo_end);
  5423. $remaining = substr($remaining, $iuserinfo_end + 1);
  5424. }
  5425. else
  5426. {
  5427. $iuserinfo = null;
  5428. }
  5429. if (($port_start = strpos($remaining, ':', strpos($remaining, ']'))) !== false)
  5430. {
  5431. if (($port = substr($remaining, $port_start + 1)) === false)
  5432. {
  5433. $port = null;
  5434. }
  5435. $remaining = substr($remaining, 0, $port_start);
  5436. }
  5437. else
  5438. {
  5439. $port = null;
  5440. }
  5441. $return = $this->set_userinfo($iuserinfo) &&
  5442. $this->set_host($remaining) &&
  5443. $this->set_port($port);
  5444. $cache[$authority] = array($this->iuserinfo,
  5445. $this->ihost,
  5446. $this->port,
  5447. $return);
  5448. return $return;
  5449. }
  5450. }
  5451. public function set_userinfo($iuserinfo)
  5452. {
  5453. if ($iuserinfo === null)
  5454. {
  5455. $this->iuserinfo = null;
  5456. }
  5457. else
  5458. {
  5459. $this->iuserinfo = $this->replace_invalid_with_pct_encoding($iuserinfo, '!$&\'()*+,;=:');
  5460. $this->scheme_normalization();
  5461. }
  5462. return true;
  5463. }
  5464. public function set_host($ihost)
  5465. {
  5466. if ($ihost === null)
  5467. {
  5468. $this->ihost = null;
  5469. return true;
  5470. }
  5471. elseif (substr($ihost, 0, 1) === '[' && substr($ihost, -1) === ']')
  5472. {
  5473. if (SimplePie_Net_IPv6::check_ipv6(substr($ihost, 1, -1)))
  5474. {
  5475. $this->ihost = '[' . SimplePie_Net_IPv6::compress(substr($ihost, 1, -1)) . ']';
  5476. }
  5477. else
  5478. {
  5479. $this->ihost = null;
  5480. return false;
  5481. }
  5482. }
  5483. else
  5484. {
  5485. $ihost = $this->replace_invalid_with_pct_encoding($ihost, '!$&\'()*+,;=');
  5486. // Lowercase, but ignore pct-encoded sections (as they should
  5487. // remain uppercase). This must be done after the previous step
  5488. // as that can add unescaped characters.
  5489. $position = 0;
  5490. $strlen = strlen($ihost);
  5491. while (($position += strcspn($ihost, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ%', $position)) < $strlen)
  5492. {
  5493. if ($ihost[$position] === '%')
  5494. {
  5495. $position += 3;
  5496. }
  5497. else
  5498. {
  5499. $ihost[$position] = strtolower($ihost[$position]);
  5500. $position++;
  5501. }
  5502. }
  5503. $this->ihost = $ihost;
  5504. }
  5505. $this->scheme_normalization();
  5506. return true;
  5507. }
  5508. public function set_port($port)
  5509. {
  5510. if ($port === null)
  5511. {
  5512. $this->port = null;
  5513. return true;
  5514. }
  5515. elseif (strspn($port, '0123456789') === strlen($port))
  5516. {
  5517. $this->port = (int) $port;
  5518. $this->scheme_normalization();
  5519. return true;
  5520. }
  5521. else
  5522. {
  5523. $this->port = null;
  5524. return false;
  5525. }
  5526. }
  5527. public function set_path($ipath)
  5528. {
  5529. static $cache;
  5530. if (!$cache)
  5531. {
  5532. $cache = array();
  5533. }
  5534. $ipath = (string) $ipath;
  5535. if (isset($cache[$ipath]))
  5536. {
  5537. $this->ipath = $cache[$ipath][(int) ($this->scheme !== null)];
  5538. }
  5539. else
  5540. {
  5541. $valid = $this->replace_invalid_with_pct_encoding($ipath, '!$&\'()*+,;=@:/');
  5542. $removed = $this->remove_dot_segments($valid);
  5543. $cache[$ipath] = array($valid, $removed);
  5544. $this->ipath = ($this->scheme !== null) ? $removed : $valid;
  5545. }
  5546. $this->scheme_normalization();
  5547. return true;
  5548. }
  5549. public function set_query($iquery)
  5550. {
  5551. if ($iquery === null)
  5552. {
  5553. $this->iquery = null;
  5554. }
  5555. else
  5556. {
  5557. $this->iquery = $this->replace_invalid_with_pct_encoding($iquery, '!$&\'()*+,;=:@/?', true);
  5558. $this->scheme_normalization();
  5559. }
  5560. return true;
  5561. }
  5562. public function set_fragment($ifragment)
  5563. {
  5564. if ($ifragment === null)
  5565. {
  5566. $this->ifragment = null;
  5567. }
  5568. else
  5569. {
  5570. $this->ifragment = $this->replace_invalid_with_pct_encoding($ifragment, '!$&\'()*+,;=:@/?');
  5571. $this->scheme_normalization();
  5572. }
  5573. return true;
  5574. }
  5575. public function to_uri($string)
  5576. {
  5577. static $non_ascii;
  5578. if (!$non_ascii)
  5579. {
  5580. $non_ascii = implode('', range("\x80", "\xFF"));
  5581. }
  5582. $position = 0;
  5583. $strlen = strlen($string);
  5584. while (($position += strcspn($string, $non_ascii, $position)) < $strlen)
  5585. {
  5586. $string = substr_replace($string, sprintf('%%%02X', ord($string[$position])), $position, 1);
  5587. $position += 3;
  5588. $strlen += 2;
  5589. }
  5590. return $string;
  5591. }
  5592. public function get_iri()
  5593. {
  5594. if (!$this->is_valid())
  5595. {
  5596. return false;
  5597. }
  5598. $iri = '';
  5599. if ($this->scheme !== null)
  5600. {
  5601. $iri .= $this->scheme . ':';
  5602. }
  5603. if (($iauthority = $this->get_iauthority()) !== null)
  5604. {
  5605. $iri .= '//' . $iauthority;
  5606. }
  5607. if ($this->ipath !== '')
  5608. {
  5609. $iri .= $this->ipath;
  5610. }
  5611. elseif (!empty($this->normalization[$this->scheme]['ipath']) && $iauthority !== null && $iauthority !== '')
  5612. {
  5613. $iri .= $this->normalization[$this->scheme]['ipath'];
  5614. }
  5615. if ($this->iquery !== null)
  5616. {
  5617. $iri .= '?' . $this->iquery;
  5618. }
  5619. if ($this->ifragment !== null)
  5620. {
  5621. $iri .= '#' . $this->ifragment;
  5622. }
  5623. return $iri;
  5624. }
  5625. public function get_uri()
  5626. {
  5627. return $this->to_uri($this->get_iri());
  5628. }
  5629. protected function get_iauthority()
  5630. {
  5631. if ($this->iuserinfo !== null || $this->ihost !== null || $this->port !== null)
  5632. {
  5633. $iauthority = '';
  5634. if ($this->iuserinfo !== null)
  5635. {
  5636. $iauthority .= $this->iuserinfo . '@';
  5637. }
  5638. if ($this->ihost !== null)
  5639. {
  5640. $iauthority .= $this->ihost;
  5641. }
  5642. if ($this->port !== null)
  5643. {
  5644. $iauthority .= ':' . $this->port;
  5645. }
  5646. return $iauthority;
  5647. }
  5648. else
  5649. {
  5650. return null;
  5651. }
  5652. }
  5653. protected function get_authority()
  5654. {
  5655. $iauthority = $this->get_iauthority();
  5656. if (is_string($iauthority))
  5657. return $this->to_uri($iauthority);
  5658. else
  5659. return $iauthority;
  5660. }
  5661. }
  5662. class SimplePie_Item
  5663. {
  5664. var $feed;
  5665. var $data = array();
  5666. protected $registry;
  5667. public function __construct($feed, $data)
  5668. {
  5669. $this->feed = $feed;
  5670. $this->data = $data;
  5671. }
  5672. public function set_registry(SimplePie_Registry $registry)
  5673. {
  5674. $this->registry = $registry;
  5675. }
  5676. public function __toString()
  5677. {
  5678. return md5(serialize($this->data));
  5679. }
  5680. public function __destruct()
  5681. {
  5682. if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
  5683. {
  5684. unset($this->feed);
  5685. }
  5686. }
  5687. public function get_item_tags($namespace, $tag)
  5688. {
  5689. if (isset($this->data['child'][$namespace][$tag]))
  5690. {
  5691. return $this->data['child'][$namespace][$tag];
  5692. }
  5693. else
  5694. {
  5695. return null;
  5696. }
  5697. }
  5698. public function get_base($element = array())
  5699. {
  5700. return $this->feed->get_base($element);
  5701. }
  5702. public function sanitize($data, $type, $base = '')
  5703. {
  5704. return $this->feed->sanitize($data, $type, $base);
  5705. }
  5706. public function get_feed()
  5707. {
  5708. return $this->feed;
  5709. }
  5710. public function get_id($hash = false)
  5711. {
  5712. if (!$hash)
  5713. {
  5714. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
  5715. {
  5716. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5717. }
  5718. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
  5719. {
  5720. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5721. }
  5722. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
  5723. {
  5724. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5725. }
  5726. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
  5727. {
  5728. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5729. }
  5730. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
  5731. {
  5732. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5733. }
  5734. elseif (isset($this->data['attribs'][SIMPLEPIE_NAMESPACE_RDF]['about']))
  5735. {
  5736. return $this->sanitize($this->data['attribs'][SIMPLEPIE_NAMESPACE_RDF]['about'], SIMPLEPIE_CONSTRUCT_TEXT);
  5737. }
  5738. elseif (($return = $this->get_permalink()) !== null)
  5739. {
  5740. return $return;
  5741. }
  5742. elseif (($return = $this->get_title()) !== null)
  5743. {
  5744. return $return;
  5745. }
  5746. }
  5747. if ($this->get_permalink() !== null || $this->get_title() !== null)
  5748. {
  5749. return md5($this->get_permalink() . $this->get_title());
  5750. }
  5751. else
  5752. {
  5753. return md5(serialize($this->data));
  5754. }
  5755. }
  5756. public function get_title()
  5757. {
  5758. if (!isset($this->data['title']))
  5759. {
  5760. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  5761. {
  5762. $this->data['title'] = $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  5763. }
  5764. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  5765. {
  5766. $this->data['title'] = $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  5767. }
  5768. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  5769. {
  5770. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5771. }
  5772. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  5773. {
  5774. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5775. }
  5776. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  5777. {
  5778. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5779. }
  5780. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  5781. {
  5782. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5783. }
  5784. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  5785. {
  5786. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5787. }
  5788. else
  5789. {
  5790. $this->data['title'] = null;
  5791. }
  5792. }
  5793. return $this->data['title'];
  5794. }
  5795. public function get_description($description_only = false)
  5796. {
  5797. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
  5798. {
  5799. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  5800. }
  5801. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
  5802. {
  5803. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  5804. }
  5805. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  5806. {
  5807. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5808. }
  5809. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
  5810. {
  5811. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5812. }
  5813. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  5814. {
  5815. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5816. }
  5817. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  5818. {
  5819. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5820. }
  5821. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  5822. {
  5823. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5824. }
  5825. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  5826. {
  5827. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5828. }
  5829. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  5830. {
  5831. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
  5832. }
  5833. elseif (!$description_only)
  5834. {
  5835. return $this->get_content(true);
  5836. }
  5837. else
  5838. {
  5839. return null;
  5840. }
  5841. }
  5842. public function get_content($content_only = false)
  5843. {
  5844. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
  5845. {
  5846. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_content_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  5847. }
  5848. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
  5849. {
  5850. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  5851. }
  5852. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
  5853. {
  5854. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5855. }
  5856. elseif (!$content_only)
  5857. {
  5858. return $this->get_description(true);
  5859. }
  5860. else
  5861. {
  5862. return null;
  5863. }
  5864. }
  5865. public function get_category($key = 0)
  5866. {
  5867. $categories = $this->get_categories();
  5868. if (isset($categories[$key]))
  5869. {
  5870. return $categories[$key];
  5871. }
  5872. else
  5873. {
  5874. return null;
  5875. }
  5876. }
  5877. public function get_categories()
  5878. {
  5879. $categories = array();
  5880. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  5881. {
  5882. $term = null;
  5883. $scheme = null;
  5884. $label = null;
  5885. if (isset($category['attribs']['']['term']))
  5886. {
  5887. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  5888. }
  5889. if (isset($category['attribs']['']['scheme']))
  5890. {
  5891. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  5892. }
  5893. if (isset($category['attribs']['']['label']))
  5894. {
  5895. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  5896. }
  5897. $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
  5898. }
  5899. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
  5900. {
  5901. // This is really the label, but keep this as the term also for BC.
  5902. // Label will also work on retrieving because that falls back to term.
  5903. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5904. if (isset($category['attribs']['']['domain']))
  5905. {
  5906. $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
  5907. }
  5908. else
  5909. {
  5910. $scheme = null;
  5911. }
  5912. $categories[] = $this->registry->create('Category', array($term, $scheme, null));
  5913. }
  5914. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  5915. {
  5916. $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  5917. }
  5918. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  5919. {
  5920. $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  5921. }
  5922. if (!empty($categories))
  5923. {
  5924. return array_unique($categories);
  5925. }
  5926. else
  5927. {
  5928. return null;
  5929. }
  5930. }
  5931. public function get_author($key = 0)
  5932. {
  5933. $authors = $this->get_authors();
  5934. if (isset($authors[$key]))
  5935. {
  5936. return $authors[$key];
  5937. }
  5938. else
  5939. {
  5940. return null;
  5941. }
  5942. }
  5943. public function get_contributor($key = 0)
  5944. {
  5945. $contributors = $this->get_contributors();
  5946. if (isset($contributors[$key]))
  5947. {
  5948. return $contributors[$key];
  5949. }
  5950. else
  5951. {
  5952. return null;
  5953. }
  5954. }
  5955. public function get_contributors()
  5956. {
  5957. $contributors = array();
  5958. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  5959. {
  5960. $name = null;
  5961. $uri = null;
  5962. $email = null;
  5963. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  5964. {
  5965. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5966. }
  5967. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  5968. {
  5969. $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
  5970. }
  5971. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  5972. {
  5973. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5974. }
  5975. if ($name !== null || $email !== null || $uri !== null)
  5976. {
  5977. $contributors[] = $this->registry->create('Author', array($name, $uri, $email));
  5978. }
  5979. }
  5980. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  5981. {
  5982. $name = null;
  5983. $url = null;
  5984. $email = null;
  5985. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  5986. {
  5987. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5988. }
  5989. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  5990. {
  5991. $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
  5992. }
  5993. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  5994. {
  5995. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5996. }
  5997. if ($name !== null || $email !== null || $url !== null)
  5998. {
  5999. $contributors[] = $this->registry->create('Author', array($name, $url, $email));
  6000. }
  6001. }
  6002. if (!empty($contributors))
  6003. {
  6004. return array_unique($contributors);
  6005. }
  6006. else
  6007. {
  6008. return null;
  6009. }
  6010. }
  6011. public function get_authors()
  6012. {
  6013. $authors = array();
  6014. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  6015. {
  6016. $name = null;
  6017. $uri = null;
  6018. $email = null;
  6019. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  6020. {
  6021. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6022. }
  6023. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  6024. {
  6025. $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
  6026. }
  6027. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  6028. {
  6029. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6030. }
  6031. if ($name !== null || $email !== null || $uri !== null)
  6032. {
  6033. $authors[] = $this->registry->create('Author', array($name, $uri, $email));
  6034. }
  6035. }
  6036. if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  6037. {
  6038. $name = null;
  6039. $url = null;
  6040. $email = null;
  6041. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  6042. {
  6043. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6044. }
  6045. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  6046. {
  6047. $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
  6048. }
  6049. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  6050. {
  6051. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6052. }
  6053. if ($name !== null || $email !== null || $url !== null)
  6054. {
  6055. $authors[] = $this->registry->create('Author', array($name, $url, $email));
  6056. }
  6057. }
  6058. if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
  6059. {
  6060. $authors[] = $this->registry->create('Author', array(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)));
  6061. }
  6062. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  6063. {
  6064. $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  6065. }
  6066. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  6067. {
  6068. $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  6069. }
  6070. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  6071. {
  6072. $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  6073. }
  6074. if (!empty($authors))
  6075. {
  6076. return array_unique($authors);
  6077. }
  6078. elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
  6079. {
  6080. return $authors;
  6081. }
  6082. elseif ($authors = $this->feed->get_authors())
  6083. {
  6084. return $authors;
  6085. }
  6086. else
  6087. {
  6088. return null;
  6089. }
  6090. }
  6091. public function get_copyright()
  6092. {
  6093. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  6094. {
  6095. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  6096. }
  6097. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  6098. {
  6099. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6100. }
  6101. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  6102. {
  6103. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6104. }
  6105. else
  6106. {
  6107. return null;
  6108. }
  6109. }
  6110. public function get_date($date_format = 'j F Y, g:i a')
  6111. {
  6112. if (!isset($this->data['date']))
  6113. {
  6114. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
  6115. {
  6116. $this->data['date']['raw'] = $return[0]['data'];
  6117. }
  6118. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
  6119. {
  6120. $this->data['date']['raw'] = $return[0]['data'];
  6121. }
  6122. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
  6123. {
  6124. $this->data['date']['raw'] = $return[0]['data'];
  6125. }
  6126. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
  6127. {
  6128. $this->data['date']['raw'] = $return[0]['data'];
  6129. }
  6130. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
  6131. {
  6132. $this->data['date']['raw'] = $return[0]['data'];
  6133. }
  6134. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
  6135. {
  6136. $this->data['date']['raw'] = $return[0]['data'];
  6137. }
  6138. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
  6139. {
  6140. $this->data['date']['raw'] = $return[0]['data'];
  6141. }
  6142. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
  6143. {
  6144. $this->data['date']['raw'] = $return[0]['data'];
  6145. }
  6146. if (!empty($this->data['date']['raw']))
  6147. {
  6148. $parser = $this->registry->call('Parse_Date', 'get');
  6149. $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
  6150. }
  6151. else
  6152. {
  6153. $this->data['date'] = null;
  6154. }
  6155. }
  6156. if ($this->data['date'])
  6157. {
  6158. $date_format = (string) $date_format;
  6159. switch ($date_format)
  6160. {
  6161. case '':
  6162. return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
  6163. case 'U':
  6164. return $this->data['date']['parsed'];
  6165. default:
  6166. return date($date_format, $this->data['date']['parsed']);
  6167. }
  6168. }
  6169. else
  6170. {
  6171. return null;
  6172. }
  6173. }
  6174. public function get_updated_date($date_format = 'j F Y, g:i a')
  6175. {
  6176. if (!isset($this->data['updated']))
  6177. {
  6178. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
  6179. {
  6180. $this->data['updated']['raw'] = $return[0]['data'];
  6181. }
  6182. if (!empty($this->data['updated']['raw']))
  6183. {
  6184. $parser = $this->registry->call('Parse_Date', 'get');
  6185. $this->data['updated']['parsed'] = $parser->parse($this->data['date']['raw']);
  6186. }
  6187. else
  6188. {
  6189. $this->data['updated'] = null;
  6190. }
  6191. }
  6192. if ($this->data['updated'])
  6193. {
  6194. $date_format = (string) $date_format;
  6195. switch ($date_format)
  6196. {
  6197. case '':
  6198. return $this->sanitize($this->data['updated']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
  6199. case 'U':
  6200. return $this->data['updated']['parsed'];
  6201. default:
  6202. return date($date_format, $this->data['updated']['parsed']);
  6203. }
  6204. }
  6205. else
  6206. {
  6207. return null;
  6208. }
  6209. }
  6210. public function get_local_date($date_format = '%c')
  6211. {
  6212. if (!$date_format)
  6213. {
  6214. return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
  6215. }
  6216. elseif (($date = $this->get_date('U')) !== null && $date !== false)
  6217. {
  6218. return strftime($date_format, $date);
  6219. }
  6220. else
  6221. {
  6222. return null;
  6223. }
  6224. }
  6225. public function get_gmdate($date_format = 'j F Y, g:i a')
  6226. {
  6227. $date = $this->get_date('U');
  6228. if ($date === null)
  6229. {
  6230. return null;
  6231. }
  6232. return gmdate($date_format, $date);
  6233. }
  6234. public function get_updated_gmdate($date_format = 'j F Y, g:i a')
  6235. {
  6236. $date = $this->get_updated_date('U');
  6237. if ($date === null)
  6238. {
  6239. return null;
  6240. }
  6241. return gmdate($date_format, $date);
  6242. }
  6243. public function get_permalink()
  6244. {
  6245. $link = $this->get_link();
  6246. $enclosure = $this->get_enclosure(0);
  6247. if ($link !== null)
  6248. {
  6249. return $link;
  6250. }
  6251. elseif ($enclosure !== null)
  6252. {
  6253. return $enclosure->get_link();
  6254. }
  6255. else
  6256. {
  6257. return null;
  6258. }
  6259. }
  6260. public function get_link($key = 0, $rel = 'alternate')
  6261. {
  6262. $links = $this->get_links($rel);
  6263. if ($links[$key] !== null)
  6264. {
  6265. return $links[$key];
  6266. }
  6267. else
  6268. {
  6269. return null;
  6270. }
  6271. }
  6272. public function get_links($rel = 'alternate')
  6273. {
  6274. if (!isset($this->data['links']))
  6275. {
  6276. $this->data['links'] = array();
  6277. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  6278. {
  6279. if (isset($link['attribs']['']['href']))
  6280. {
  6281. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  6282. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  6283. }
  6284. }
  6285. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  6286. {
  6287. if (isset($link['attribs']['']['href']))
  6288. {
  6289. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  6290. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  6291. }
  6292. }
  6293. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  6294. {
  6295. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  6296. }
  6297. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  6298. {
  6299. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  6300. }
  6301. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  6302. {
  6303. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  6304. }
  6305. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
  6306. {
  6307. if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')
  6308. {
  6309. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  6310. }
  6311. }
  6312. $keys = array_keys($this->data['links']);
  6313. foreach ($keys as $key)
  6314. {
  6315. if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
  6316. {
  6317. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  6318. {
  6319. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  6320. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  6321. }
  6322. else
  6323. {
  6324. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  6325. }
  6326. }
  6327. elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  6328. {
  6329. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  6330. }
  6331. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  6332. }
  6333. }
  6334. if (isset($this->data['links'][$rel]))
  6335. {
  6336. return $this->data['links'][$rel];
  6337. }
  6338. else
  6339. {
  6340. return null;
  6341. }
  6342. }
  6343. public function get_enclosure($key = 0, $prefer = null)
  6344. {
  6345. $enclosures = $this->get_enclosures();
  6346. if (isset($enclosures[$key]))
  6347. {
  6348. return $enclosures[$key];
  6349. }
  6350. else
  6351. {
  6352. return null;
  6353. }
  6354. }
  6355. public function get_enclosures()
  6356. {
  6357. if (!isset($this->data['enclosures']))
  6358. {
  6359. $this->data['enclosures'] = array();
  6360. // Elements
  6361. $captions_parent = null;
  6362. $categories_parent = null;
  6363. $copyrights_parent = null;
  6364. $credits_parent = null;
  6365. $description_parent = null;
  6366. $duration_parent = null;
  6367. $hashes_parent = null;
  6368. $keywords_parent = null;
  6369. $player_parent = null;
  6370. $ratings_parent = null;
  6371. $restrictions_parent = null;
  6372. $thumbnails_parent = null;
  6373. $title_parent = null;
  6374. // Let's do the channel and item-level ones first, and just re-use them if we need to.
  6375. $parent = $this->get_feed();
  6376. // CAPTIONS
  6377. if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  6378. {
  6379. foreach ($captions as $caption)
  6380. {
  6381. $caption_type = null;
  6382. $caption_lang = null;
  6383. $caption_startTime = null;
  6384. $caption_endTime = null;
  6385. $caption_text = null;
  6386. if (isset($caption['attribs']['']['type']))
  6387. {
  6388. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  6389. }
  6390. if (isset($caption['attribs']['']['lang']))
  6391. {
  6392. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  6393. }
  6394. if (isset($caption['attribs']['']['start']))
  6395. {
  6396. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  6397. }
  6398. if (isset($caption['attribs']['']['end']))
  6399. {
  6400. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  6401. }
  6402. if (isset($caption['data']))
  6403. {
  6404. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6405. }
  6406. $captions_parent[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
  6407. }
  6408. }
  6409. elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  6410. {
  6411. foreach ($captions as $caption)
  6412. {
  6413. $caption_type = null;
  6414. $caption_lang = null;
  6415. $caption_startTime = null;
  6416. $caption_endTime = null;
  6417. $caption_text = null;
  6418. if (isset($caption['attribs']['']['type']))
  6419. {
  6420. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  6421. }
  6422. if (isset($caption['attribs']['']['lang']))
  6423. {
  6424. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  6425. }
  6426. if (isset($caption['attribs']['']['start']))
  6427. {
  6428. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  6429. }
  6430. if (isset($caption['attribs']['']['end']))
  6431. {
  6432. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  6433. }
  6434. if (isset($caption['data']))
  6435. {
  6436. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6437. }
  6438. $captions_parent[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
  6439. }
  6440. }
  6441. if (is_array($captions_parent))
  6442. {
  6443. $captions_parent = array_values(array_unique($captions_parent));
  6444. }
  6445. // CATEGORIES
  6446. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  6447. {
  6448. $term = null;
  6449. $scheme = null;
  6450. $label = null;
  6451. if (isset($category['data']))
  6452. {
  6453. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6454. }
  6455. if (isset($category['attribs']['']['scheme']))
  6456. {
  6457. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  6458. }
  6459. else
  6460. {
  6461. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  6462. }
  6463. if (isset($category['attribs']['']['label']))
  6464. {
  6465. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  6466. }
  6467. $categories_parent[] = $this->registry->create('Category', array($term, $scheme, $label));
  6468. }
  6469. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  6470. {
  6471. $term = null;
  6472. $scheme = null;
  6473. $label = null;
  6474. if (isset($category['data']))
  6475. {
  6476. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6477. }
  6478. if (isset($category['attribs']['']['scheme']))
  6479. {
  6480. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  6481. }
  6482. else
  6483. {
  6484. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  6485. }
  6486. if (isset($category['attribs']['']['label']))
  6487. {
  6488. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  6489. }
  6490. $categories_parent[] = $this->registry->create('Category', array($term, $scheme, $label));
  6491. }
  6492. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
  6493. {
  6494. $term = null;
  6495. $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
  6496. $label = null;
  6497. if (isset($category['attribs']['']['text']))
  6498. {
  6499. $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  6500. }
  6501. $categories_parent[] = $this->registry->create('Category', array($term, $scheme, $label));
  6502. if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
  6503. {
  6504. foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
  6505. {
  6506. if (isset($subcategory['attribs']['']['text']))
  6507. {
  6508. $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  6509. }
  6510. $categories_parent[] = $this->registry->create('Category', array($term, $scheme, $label));
  6511. }
  6512. }
  6513. }
  6514. if (is_array($categories_parent))
  6515. {
  6516. $categories_parent = array_values(array_unique($categories_parent));
  6517. }
  6518. // COPYRIGHT
  6519. if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  6520. {
  6521. $copyright_url = null;
  6522. $copyright_label = null;
  6523. if (isset($copyright[0]['attribs']['']['url']))
  6524. {
  6525. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  6526. }
  6527. if (isset($copyright[0]['data']))
  6528. {
  6529. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6530. }
  6531. $copyrights_parent = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
  6532. }
  6533. elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  6534. {
  6535. $copyright_url = null;
  6536. $copyright_label = null;
  6537. if (isset($copyright[0]['attribs']['']['url']))
  6538. {
  6539. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  6540. }
  6541. if (isset($copyright[0]['data']))
  6542. {
  6543. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6544. }
  6545. $copyrights_parent = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
  6546. }
  6547. // CREDITS
  6548. if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  6549. {
  6550. foreach ($credits as $credit)
  6551. {
  6552. $credit_role = null;
  6553. $credit_scheme = null;
  6554. $credit_name = null;
  6555. if (isset($credit['attribs']['']['role']))
  6556. {
  6557. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  6558. }
  6559. if (isset($credit['attribs']['']['scheme']))
  6560. {
  6561. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  6562. }
  6563. else
  6564. {
  6565. $credit_scheme = 'urn:ebu';
  6566. }
  6567. if (isset($credit['data']))
  6568. {
  6569. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6570. }
  6571. $credits_parent[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
  6572. }
  6573. }
  6574. elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  6575. {
  6576. foreach ($credits as $credit)
  6577. {
  6578. $credit_role = null;
  6579. $credit_scheme = null;
  6580. $credit_name = null;
  6581. if (isset($credit['attribs']['']['role']))
  6582. {
  6583. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  6584. }
  6585. if (isset($credit['attribs']['']['scheme']))
  6586. {
  6587. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  6588. }
  6589. else
  6590. {
  6591. $credit_scheme = 'urn:ebu';
  6592. }
  6593. if (isset($credit['data']))
  6594. {
  6595. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6596. }
  6597. $credits_parent[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
  6598. }
  6599. }
  6600. if (is_array($credits_parent))
  6601. {
  6602. $credits_parent = array_values(array_unique($credits_parent));
  6603. }
  6604. // DESCRIPTION
  6605. if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  6606. {
  6607. if (isset($description_parent[0]['data']))
  6608. {
  6609. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6610. }
  6611. }
  6612. elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  6613. {
  6614. if (isset($description_parent[0]['data']))
  6615. {
  6616. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6617. }
  6618. }
  6619. // DURATION
  6620. if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
  6621. {
  6622. $seconds = null;
  6623. $minutes = null;
  6624. $hours = null;
  6625. if (isset($duration_parent[0]['data']))
  6626. {
  6627. $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  6628. if (sizeof($temp) > 0)
  6629. {
  6630. $seconds = (int) array_pop($temp);
  6631. }
  6632. if (sizeof($temp) > 0)
  6633. {
  6634. $minutes = (int) array_pop($temp);
  6635. $seconds += $minutes * 60;
  6636. }
  6637. if (sizeof($temp) > 0)
  6638. {
  6639. $hours = (int) array_pop($temp);
  6640. $seconds += $hours * 3600;
  6641. }
  6642. unset($temp);
  6643. $duration_parent = $seconds;
  6644. }
  6645. }
  6646. // HASHES
  6647. if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  6648. {
  6649. foreach ($hashes_iterator as $hash)
  6650. {
  6651. $value = null;
  6652. $algo = null;
  6653. if (isset($hash['data']))
  6654. {
  6655. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6656. }
  6657. if (isset($hash['attribs']['']['algo']))
  6658. {
  6659. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  6660. }
  6661. else
  6662. {
  6663. $algo = 'md5';
  6664. }
  6665. $hashes_parent[] = $algo.':'.$value;
  6666. }
  6667. }
  6668. elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  6669. {
  6670. foreach ($hashes_iterator as $hash)
  6671. {
  6672. $value = null;
  6673. $algo = null;
  6674. if (isset($hash['data']))
  6675. {
  6676. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6677. }
  6678. if (isset($hash['attribs']['']['algo']))
  6679. {
  6680. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  6681. }
  6682. else
  6683. {
  6684. $algo = 'md5';
  6685. }
  6686. $hashes_parent[] = $algo.':'.$value;
  6687. }
  6688. }
  6689. if (is_array($hashes_parent))
  6690. {
  6691. $hashes_parent = array_values(array_unique($hashes_parent));
  6692. }
  6693. // KEYWORDS
  6694. if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  6695. {
  6696. if (isset($keywords[0]['data']))
  6697. {
  6698. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  6699. foreach ($temp as $word)
  6700. {
  6701. $keywords_parent[] = trim($word);
  6702. }
  6703. }
  6704. unset($temp);
  6705. }
  6706. elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  6707. {
  6708. if (isset($keywords[0]['data']))
  6709. {
  6710. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  6711. foreach ($temp as $word)
  6712. {
  6713. $keywords_parent[] = trim($word);
  6714. }
  6715. }
  6716. unset($temp);
  6717. }
  6718. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  6719. {
  6720. if (isset($keywords[0]['data']))
  6721. {
  6722. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  6723. foreach ($temp as $word)
  6724. {
  6725. $keywords_parent[] = trim($word);
  6726. }
  6727. }
  6728. unset($temp);
  6729. }
  6730. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  6731. {
  6732. if (isset($keywords[0]['data']))
  6733. {
  6734. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  6735. foreach ($temp as $word)
  6736. {
  6737. $keywords_parent[] = trim($word);
  6738. }
  6739. }
  6740. unset($temp);
  6741. }
  6742. if (is_array($keywords_parent))
  6743. {
  6744. $keywords_parent = array_values(array_unique($keywords_parent));
  6745. }
  6746. // PLAYER
  6747. if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  6748. {
  6749. if (isset($player_parent[0]['attribs']['']['url']))
  6750. {
  6751. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  6752. }
  6753. }
  6754. elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  6755. {
  6756. if (isset($player_parent[0]['attribs']['']['url']))
  6757. {
  6758. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  6759. }
  6760. }
  6761. // RATINGS
  6762. if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  6763. {
  6764. foreach ($ratings as $rating)
  6765. {
  6766. $rating_scheme = null;
  6767. $rating_value = null;
  6768. if (isset($rating['attribs']['']['scheme']))
  6769. {
  6770. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  6771. }
  6772. else
  6773. {
  6774. $rating_scheme = 'urn:simple';
  6775. }
  6776. if (isset($rating['data']))
  6777. {
  6778. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6779. }
  6780. $ratings_parent[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
  6781. }
  6782. }
  6783. elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  6784. {
  6785. foreach ($ratings as $rating)
  6786. {
  6787. $rating_scheme = 'urn:itunes';
  6788. $rating_value = null;
  6789. if (isset($rating['data']))
  6790. {
  6791. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6792. }
  6793. $ratings_parent[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
  6794. }
  6795. }
  6796. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  6797. {
  6798. foreach ($ratings as $rating)
  6799. {
  6800. $rating_scheme = null;
  6801. $rating_value = null;
  6802. if (isset($rating['attribs']['']['scheme']))
  6803. {
  6804. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  6805. }
  6806. else
  6807. {
  6808. $rating_scheme = 'urn:simple';
  6809. }
  6810. if (isset($rating['data']))
  6811. {
  6812. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6813. }
  6814. $ratings_parent[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
  6815. }
  6816. }
  6817. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  6818. {
  6819. foreach ($ratings as $rating)
  6820. {
  6821. $rating_scheme = 'urn:itunes';
  6822. $rating_value = null;
  6823. if (isset($rating['data']))
  6824. {
  6825. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6826. }
  6827. $ratings_parent[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
  6828. }
  6829. }
  6830. if (is_array($ratings_parent))
  6831. {
  6832. $ratings_parent = array_values(array_unique($ratings_parent));
  6833. }
  6834. // RESTRICTIONS
  6835. if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  6836. {
  6837. foreach ($restrictions as $restriction)
  6838. {
  6839. $restriction_relationship = null;
  6840. $restriction_type = null;
  6841. $restriction_value = null;
  6842. if (isset($restriction['attribs']['']['relationship']))
  6843. {
  6844. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  6845. }
  6846. if (isset($restriction['attribs']['']['type']))
  6847. {
  6848. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  6849. }
  6850. if (isset($restriction['data']))
  6851. {
  6852. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6853. }
  6854. $restrictions_parent[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
  6855. }
  6856. }
  6857. elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  6858. {
  6859. foreach ($restrictions as $restriction)
  6860. {
  6861. $restriction_relationship = 'allow';
  6862. $restriction_type = null;
  6863. $restriction_value = 'itunes';
  6864. if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
  6865. {
  6866. $restriction_relationship = 'deny';
  6867. }
  6868. $restrictions_parent[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
  6869. }
  6870. }
  6871. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  6872. {
  6873. foreach ($restrictions as $restriction)
  6874. {
  6875. $restriction_relationship = null;
  6876. $restriction_type = null;
  6877. $restriction_value = null;
  6878. if (isset($restriction['attribs']['']['relationship']))
  6879. {
  6880. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  6881. }
  6882. if (isset($restriction['attribs']['']['type']))
  6883. {
  6884. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  6885. }
  6886. if (isset($restriction['data']))
  6887. {
  6888. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6889. }
  6890. $restrictions_parent[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
  6891. }
  6892. }
  6893. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  6894. {
  6895. foreach ($restrictions as $restriction)
  6896. {
  6897. $restriction_relationship = 'allow';
  6898. $restriction_type = null;
  6899. $restriction_value = 'itunes';
  6900. if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
  6901. {
  6902. $restriction_relationship = 'deny';
  6903. }
  6904. $restrictions_parent[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
  6905. }
  6906. }
  6907. if (is_array($restrictions_parent))
  6908. {
  6909. $restrictions_parent = array_values(array_unique($restrictions_parent));
  6910. }
  6911. else
  6912. {
  6913. $restrictions_parent = array(new SimplePie_Restriction('allow', null, 'default'));
  6914. }
  6915. // THUMBNAILS
  6916. if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  6917. {
  6918. foreach ($thumbnails as $thumbnail)
  6919. {
  6920. if (isset($thumbnail['attribs']['']['url']))
  6921. {
  6922. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  6923. }
  6924. }
  6925. }
  6926. elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  6927. {
  6928. foreach ($thumbnails as $thumbnail)
  6929. {
  6930. if (isset($thumbnail['attribs']['']['url']))
  6931. {
  6932. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  6933. }
  6934. }
  6935. }
  6936. // TITLES
  6937. if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  6938. {
  6939. if (isset($title_parent[0]['data']))
  6940. {
  6941. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6942. }
  6943. }
  6944. elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  6945. {
  6946. if (isset($title_parent[0]['data']))
  6947. {
  6948. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  6949. }
  6950. }
  6951. // Clear the memory
  6952. unset($parent);
  6953. // Attributes
  6954. $bitrate = null;
  6955. $channels = null;
  6956. $duration = null;
  6957. $expression = null;
  6958. $framerate = null;
  6959. $height = null;
  6960. $javascript = null;
  6961. $lang = null;
  6962. $length = null;
  6963. $medium = null;
  6964. $samplingrate = null;
  6965. $type = null;
  6966. $url = null;
  6967. $width = null;
  6968. // Elements
  6969. $captions = null;
  6970. $categories = null;
  6971. $copyrights = null;
  6972. $credits = null;
  6973. $description = null;
  6974. $hashes = null;
  6975. $keywords = null;
  6976. $player = null;
  6977. $ratings = null;
  6978. $restrictions = null;
  6979. $thumbnails = null;
  6980. $title = null;
  6981. // If we have media:group tags, loop through them.
  6982. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
  6983. {
  6984. if(isset($group['child']) && isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
  6985. {
  6986. // If we have media:content tags, loop through them.
  6987. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  6988. {
  6989. if (isset($content['attribs']['']['url']))
  6990. {
  6991. // Attributes
  6992. $bitrate = null;
  6993. $channels = null;
  6994. $duration = null;
  6995. $expression = null;
  6996. $framerate = null;
  6997. $height = null;
  6998. $javascript = null;
  6999. $lang = null;
  7000. $length = null;
  7001. $medium = null;
  7002. $samplingrate = null;
  7003. $type = null;
  7004. $url = null;
  7005. $width = null;
  7006. // Elements
  7007. $captions = null;
  7008. $categories = null;
  7009. $copyrights = null;
  7010. $credits = null;
  7011. $description = null;
  7012. $hashes = null;
  7013. $keywords = null;
  7014. $player = null;
  7015. $ratings = null;
  7016. $restrictions = null;
  7017. $thumbnails = null;
  7018. $title = null;
  7019. // Start checking the attributes of media:content
  7020. if (isset($content['attribs']['']['bitrate']))
  7021. {
  7022. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  7023. }
  7024. if (isset($content['attribs']['']['channels']))
  7025. {
  7026. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  7027. }
  7028. if (isset($content['attribs']['']['duration']))
  7029. {
  7030. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  7031. }
  7032. else
  7033. {
  7034. $duration = $duration_parent;
  7035. }
  7036. if (isset($content['attribs']['']['expression']))
  7037. {
  7038. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  7039. }
  7040. if (isset($content['attribs']['']['framerate']))
  7041. {
  7042. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  7043. }
  7044. if (isset($content['attribs']['']['height']))
  7045. {
  7046. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  7047. }
  7048. if (isset($content['attribs']['']['lang']))
  7049. {
  7050. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  7051. }
  7052. if (isset($content['attribs']['']['fileSize']))
  7053. {
  7054. $length = ceil($content['attribs']['']['fileSize']);
  7055. }
  7056. if (isset($content['attribs']['']['medium']))
  7057. {
  7058. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  7059. }
  7060. if (isset($content['attribs']['']['samplingrate']))
  7061. {
  7062. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  7063. }
  7064. if (isset($content['attribs']['']['type']))
  7065. {
  7066. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  7067. }
  7068. if (isset($content['attribs']['']['width']))
  7069. {
  7070. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  7071. }
  7072. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  7073. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  7074. // CAPTIONS
  7075. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  7076. {
  7077. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  7078. {
  7079. $caption_type = null;
  7080. $caption_lang = null;
  7081. $caption_startTime = null;
  7082. $caption_endTime = null;
  7083. $caption_text = null;
  7084. if (isset($caption['attribs']['']['type']))
  7085. {
  7086. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  7087. }
  7088. if (isset($caption['attribs']['']['lang']))
  7089. {
  7090. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  7091. }
  7092. if (isset($caption['attribs']['']['start']))
  7093. {
  7094. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  7095. }
  7096. if (isset($caption['attribs']['']['end']))
  7097. {
  7098. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  7099. }
  7100. if (isset($caption['data']))
  7101. {
  7102. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7103. }
  7104. $captions[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
  7105. }
  7106. if (is_array($captions))
  7107. {
  7108. $captions = array_values(array_unique($captions));
  7109. }
  7110. }
  7111. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  7112. {
  7113. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  7114. {
  7115. $caption_type = null;
  7116. $caption_lang = null;
  7117. $caption_startTime = null;
  7118. $caption_endTime = null;
  7119. $caption_text = null;
  7120. if (isset($caption['attribs']['']['type']))
  7121. {
  7122. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  7123. }
  7124. if (isset($caption['attribs']['']['lang']))
  7125. {
  7126. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  7127. }
  7128. if (isset($caption['attribs']['']['start']))
  7129. {
  7130. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  7131. }
  7132. if (isset($caption['attribs']['']['end']))
  7133. {
  7134. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  7135. }
  7136. if (isset($caption['data']))
  7137. {
  7138. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7139. }
  7140. $captions[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
  7141. }
  7142. if (is_array($captions))
  7143. {
  7144. $captions = array_values(array_unique($captions));
  7145. }
  7146. }
  7147. else
  7148. {
  7149. $captions = $captions_parent;
  7150. }
  7151. // CATEGORIES
  7152. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  7153. {
  7154. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  7155. {
  7156. $term = null;
  7157. $scheme = null;
  7158. $label = null;
  7159. if (isset($category['data']))
  7160. {
  7161. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7162. }
  7163. if (isset($category['attribs']['']['scheme']))
  7164. {
  7165. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  7166. }
  7167. else
  7168. {
  7169. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  7170. }
  7171. if (isset($category['attribs']['']['label']))
  7172. {
  7173. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  7174. }
  7175. $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
  7176. }
  7177. }
  7178. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  7179. {
  7180. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  7181. {
  7182. $term = null;
  7183. $scheme = null;
  7184. $label = null;
  7185. if (isset($category['data']))
  7186. {
  7187. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7188. }
  7189. if (isset($category['attribs']['']['scheme']))
  7190. {
  7191. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  7192. }
  7193. else
  7194. {
  7195. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  7196. }
  7197. if (isset($category['attribs']['']['label']))
  7198. {
  7199. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  7200. }
  7201. $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
  7202. }
  7203. }
  7204. if (is_array($categories) && is_array($categories_parent))
  7205. {
  7206. $categories = array_values(array_unique(array_merge($categories, $categories_parent)));
  7207. }
  7208. elseif (is_array($categories))
  7209. {
  7210. $categories = array_values(array_unique($categories));
  7211. }
  7212. elseif (is_array($categories_parent))
  7213. {
  7214. $categories = array_values(array_unique($categories_parent));
  7215. }
  7216. // COPYRIGHTS
  7217. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  7218. {
  7219. $copyright_url = null;
  7220. $copyright_label = null;
  7221. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  7222. {
  7223. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  7224. }
  7225. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  7226. {
  7227. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7228. }
  7229. $copyrights = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
  7230. }
  7231. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  7232. {
  7233. $copyright_url = null;
  7234. $copyright_label = null;
  7235. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  7236. {
  7237. $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  7238. }
  7239. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  7240. {
  7241. $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7242. }
  7243. $copyrights = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
  7244. }
  7245. else
  7246. {
  7247. $copyrights = $copyrights_parent;
  7248. }
  7249. // CREDITS
  7250. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  7251. {
  7252. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  7253. {
  7254. $credit_role = null;
  7255. $credit_scheme = null;
  7256. $credit_name = null;
  7257. if (isset($credit['attribs']['']['role']))
  7258. {
  7259. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  7260. }
  7261. if (isset($credit['attribs']['']['scheme']))
  7262. {
  7263. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  7264. }
  7265. else
  7266. {
  7267. $credit_scheme = 'urn:ebu';
  7268. }
  7269. if (isset($credit['data']))
  7270. {
  7271. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7272. }
  7273. $credits[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
  7274. }
  7275. if (is_array($credits))
  7276. {
  7277. $credits = array_values(array_unique($credits));
  7278. }
  7279. }
  7280. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  7281. {
  7282. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  7283. {
  7284. $credit_role = null;
  7285. $credit_scheme = null;
  7286. $credit_name = null;
  7287. if (isset($credit['attribs']['']['role']))
  7288. {
  7289. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  7290. }
  7291. if (isset($credit['attribs']['']['scheme']))
  7292. {
  7293. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  7294. }
  7295. else
  7296. {
  7297. $credit_scheme = 'urn:ebu';
  7298. }
  7299. if (isset($credit['data']))
  7300. {
  7301. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7302. }
  7303. $credits[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
  7304. }
  7305. if (is_array($credits))
  7306. {
  7307. $credits = array_values(array_unique($credits));
  7308. }
  7309. }
  7310. else
  7311. {
  7312. $credits = $credits_parent;
  7313. }
  7314. // DESCRIPTION
  7315. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  7316. {
  7317. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7318. }
  7319. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  7320. {
  7321. $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7322. }
  7323. else
  7324. {
  7325. $description = $description_parent;
  7326. }
  7327. // HASHES
  7328. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  7329. {
  7330. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  7331. {
  7332. $value = null;
  7333. $algo = null;
  7334. if (isset($hash['data']))
  7335. {
  7336. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7337. }
  7338. if (isset($hash['attribs']['']['algo']))
  7339. {
  7340. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  7341. }
  7342. else
  7343. {
  7344. $algo = 'md5';
  7345. }
  7346. $hashes[] = $algo.':'.$value;
  7347. }
  7348. if (is_array($hashes))
  7349. {
  7350. $hashes = array_values(array_unique($hashes));
  7351. }
  7352. }
  7353. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  7354. {
  7355. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  7356. {
  7357. $value = null;
  7358. $algo = null;
  7359. if (isset($hash['data']))
  7360. {
  7361. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7362. }
  7363. if (isset($hash['attribs']['']['algo']))
  7364. {
  7365. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  7366. }
  7367. else
  7368. {
  7369. $algo = 'md5';
  7370. }
  7371. $hashes[] = $algo.':'.$value;
  7372. }
  7373. if (is_array($hashes))
  7374. {
  7375. $hashes = array_values(array_unique($hashes));
  7376. }
  7377. }
  7378. else
  7379. {
  7380. $hashes = $hashes_parent;
  7381. }
  7382. // KEYWORDS
  7383. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  7384. {
  7385. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  7386. {
  7387. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  7388. foreach ($temp as $word)
  7389. {
  7390. $keywords[] = trim($word);
  7391. }
  7392. unset($temp);
  7393. }
  7394. if (is_array($keywords))
  7395. {
  7396. $keywords = array_values(array_unique($keywords));
  7397. }
  7398. }
  7399. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  7400. {
  7401. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  7402. {
  7403. $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  7404. foreach ($temp as $word)
  7405. {
  7406. $keywords[] = trim($word);
  7407. }
  7408. unset($temp);
  7409. }
  7410. if (is_array($keywords))
  7411. {
  7412. $keywords = array_values(array_unique($keywords));
  7413. }
  7414. }
  7415. else
  7416. {
  7417. $keywords = $keywords_parent;
  7418. }
  7419. // PLAYER
  7420. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  7421. {
  7422. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  7423. }
  7424. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  7425. {
  7426. $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  7427. }
  7428. else
  7429. {
  7430. $player = $player_parent;
  7431. }
  7432. // RATINGS
  7433. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  7434. {
  7435. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  7436. {
  7437. $rating_scheme = null;
  7438. $rating_value = null;
  7439. if (isset($rating['attribs']['']['scheme']))
  7440. {
  7441. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  7442. }
  7443. else
  7444. {
  7445. $rating_scheme = 'urn:simple';
  7446. }
  7447. if (isset($rating['data']))
  7448. {
  7449. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7450. }
  7451. $ratings[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
  7452. }
  7453. if (is_array($ratings))
  7454. {
  7455. $ratings = array_values(array_unique($ratings));
  7456. }
  7457. }
  7458. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  7459. {
  7460. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  7461. {
  7462. $rating_scheme = null;
  7463. $rating_value = null;
  7464. if (isset($rating['attribs']['']['scheme']))
  7465. {
  7466. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  7467. }
  7468. else
  7469. {
  7470. $rating_scheme = 'urn:simple';
  7471. }
  7472. if (isset($rating['data']))
  7473. {
  7474. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7475. }
  7476. $ratings[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
  7477. }
  7478. if (is_array($ratings))
  7479. {
  7480. $ratings = array_values(array_unique($ratings));
  7481. }
  7482. }
  7483. else
  7484. {
  7485. $ratings = $ratings_parent;
  7486. }
  7487. // RESTRICTIONS
  7488. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  7489. {
  7490. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  7491. {
  7492. $restriction_relationship = null;
  7493. $restriction_type = null;
  7494. $restriction_value = null;
  7495. if (isset($restriction['attribs']['']['relationship']))
  7496. {
  7497. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  7498. }
  7499. if (isset($restriction['attribs']['']['type']))
  7500. {
  7501. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  7502. }
  7503. if (isset($restriction['data']))
  7504. {
  7505. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7506. }
  7507. $restrictions[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
  7508. }
  7509. if (is_array($restrictions))
  7510. {
  7511. $restrictions = array_values(array_unique($restrictions));
  7512. }
  7513. }
  7514. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  7515. {
  7516. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  7517. {
  7518. $restriction_relationship = null;
  7519. $restriction_type = null;
  7520. $restriction_value = null;
  7521. if (isset($restriction['attribs']['']['relationship']))
  7522. {
  7523. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  7524. }
  7525. if (isset($restriction['attribs']['']['type']))
  7526. {
  7527. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  7528. }
  7529. if (isset($restriction['data']))
  7530. {
  7531. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7532. }
  7533. $restrictions[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
  7534. }
  7535. if (is_array($restrictions))
  7536. {
  7537. $restrictions = array_values(array_unique($restrictions));
  7538. }
  7539. }
  7540. else
  7541. {
  7542. $restrictions = $restrictions_parent;
  7543. }
  7544. // THUMBNAILS
  7545. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  7546. {
  7547. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  7548. {
  7549. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  7550. }
  7551. if (is_array($thumbnails))
  7552. {
  7553. $thumbnails = array_values(array_unique($thumbnails));
  7554. }
  7555. }
  7556. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  7557. {
  7558. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  7559. {
  7560. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  7561. }
  7562. if (is_array($thumbnails))
  7563. {
  7564. $thumbnails = array_values(array_unique($thumbnails));
  7565. }
  7566. }
  7567. else
  7568. {
  7569. $thumbnails = $thumbnails_parent;
  7570. }
  7571. // TITLES
  7572. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  7573. {
  7574. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7575. }
  7576. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  7577. {
  7578. $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7579. }
  7580. else
  7581. {
  7582. $title = $title_parent;
  7583. }
  7584. $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width));
  7585. }
  7586. }
  7587. }
  7588. }
  7589. // If we have standalone media:content tags, loop through them.
  7590. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
  7591. {
  7592. foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  7593. {
  7594. if (isset($content['attribs']['']['url']) || isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  7595. {
  7596. // Attributes
  7597. $bitrate = null;
  7598. $channels = null;
  7599. $duration = null;
  7600. $expression = null;
  7601. $framerate = null;
  7602. $height = null;
  7603. $javascript = null;
  7604. $lang = null;
  7605. $length = null;
  7606. $medium = null;
  7607. $samplingrate = null;
  7608. $type = null;
  7609. $url = null;
  7610. $width = null;
  7611. // Elements
  7612. $captions = null;
  7613. $categories = null;
  7614. $copyrights = null;
  7615. $credits = null;
  7616. $description = null;
  7617. $hashes = null;
  7618. $keywords = null;
  7619. $player = null;
  7620. $ratings = null;
  7621. $restrictions = null;
  7622. $thumbnails = null;
  7623. $title = null;
  7624. // Start checking the attributes of media:content
  7625. if (isset($content['attribs']['']['bitrate']))
  7626. {
  7627. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  7628. }
  7629. if (isset($content['attribs']['']['channels']))
  7630. {
  7631. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  7632. }
  7633. if (isset($content['attribs']['']['duration']))
  7634. {
  7635. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  7636. }
  7637. else
  7638. {
  7639. $duration = $duration_parent;
  7640. }
  7641. if (isset($content['attribs']['']['expression']))
  7642. {
  7643. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  7644. }
  7645. if (isset($content['attribs']['']['framerate']))
  7646. {
  7647. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  7648. }
  7649. if (isset($content['attribs']['']['height']))
  7650. {
  7651. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  7652. }
  7653. if (isset($content['attribs']['']['lang']))
  7654. {
  7655. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  7656. }
  7657. if (isset($content['attribs']['']['fileSize']))
  7658. {
  7659. $length = ceil($content['attribs']['']['fileSize']);
  7660. }
  7661. if (isset($content['attribs']['']['medium']))
  7662. {
  7663. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  7664. }
  7665. if (isset($content['attribs']['']['samplingrate']))
  7666. {
  7667. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  7668. }
  7669. if (isset($content['attribs']['']['type']))
  7670. {
  7671. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  7672. }
  7673. if (isset($content['attribs']['']['width']))
  7674. {
  7675. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  7676. }
  7677. if (isset($content['attribs']['']['url']))
  7678. {
  7679. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  7680. }
  7681. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  7682. // CAPTIONS
  7683. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  7684. {
  7685. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  7686. {
  7687. $caption_type = null;
  7688. $caption_lang = null;
  7689. $caption_startTime = null;
  7690. $caption_endTime = null;
  7691. $caption_text = null;
  7692. if (isset($caption['attribs']['']['type']))
  7693. {
  7694. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  7695. }
  7696. if (isset($caption['attribs']['']['lang']))
  7697. {
  7698. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  7699. }
  7700. if (isset($caption['attribs']['']['start']))
  7701. {
  7702. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  7703. }
  7704. if (isset($caption['attribs']['']['end']))
  7705. {
  7706. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  7707. }
  7708. if (isset($caption['data']))
  7709. {
  7710. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7711. }
  7712. $captions[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
  7713. }
  7714. if (is_array($captions))
  7715. {
  7716. $captions = array_values(array_unique($captions));
  7717. }
  7718. }
  7719. else
  7720. {
  7721. $captions = $captions_parent;
  7722. }
  7723. // CATEGORIES
  7724. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  7725. {
  7726. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  7727. {
  7728. $term = null;
  7729. $scheme = null;
  7730. $label = null;
  7731. if (isset($category['data']))
  7732. {
  7733. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7734. }
  7735. if (isset($category['attribs']['']['scheme']))
  7736. {
  7737. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  7738. }
  7739. else
  7740. {
  7741. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  7742. }
  7743. if (isset($category['attribs']['']['label']))
  7744. {
  7745. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  7746. }
  7747. $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
  7748. }
  7749. }
  7750. if (is_array($categories) && is_array($categories_parent))
  7751. {
  7752. $categories = array_values(array_unique(array_merge($categories, $categories_parent)));
  7753. }
  7754. elseif (is_array($categories))
  7755. {
  7756. $categories = array_values(array_unique($categories));
  7757. }
  7758. elseif (is_array($categories_parent))
  7759. {
  7760. $categories = array_values(array_unique($categories_parent));
  7761. }
  7762. else
  7763. {
  7764. $categories = null;
  7765. }
  7766. // COPYRIGHTS
  7767. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  7768. {
  7769. $copyright_url = null;
  7770. $copyright_label = null;
  7771. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  7772. {
  7773. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  7774. }
  7775. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  7776. {
  7777. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7778. }
  7779. $copyrights = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
  7780. }
  7781. else
  7782. {
  7783. $copyrights = $copyrights_parent;
  7784. }
  7785. // CREDITS
  7786. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  7787. {
  7788. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  7789. {
  7790. $credit_role = null;
  7791. $credit_scheme = null;
  7792. $credit_name = null;
  7793. if (isset($credit['attribs']['']['role']))
  7794. {
  7795. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  7796. }
  7797. if (isset($credit['attribs']['']['scheme']))
  7798. {
  7799. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  7800. }
  7801. else
  7802. {
  7803. $credit_scheme = 'urn:ebu';
  7804. }
  7805. if (isset($credit['data']))
  7806. {
  7807. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7808. }
  7809. $credits[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
  7810. }
  7811. if (is_array($credits))
  7812. {
  7813. $credits = array_values(array_unique($credits));
  7814. }
  7815. }
  7816. else
  7817. {
  7818. $credits = $credits_parent;
  7819. }
  7820. // DESCRIPTION
  7821. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  7822. {
  7823. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7824. }
  7825. else
  7826. {
  7827. $description = $description_parent;
  7828. }
  7829. // HASHES
  7830. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  7831. {
  7832. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  7833. {
  7834. $value = null;
  7835. $algo = null;
  7836. if (isset($hash['data']))
  7837. {
  7838. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7839. }
  7840. if (isset($hash['attribs']['']['algo']))
  7841. {
  7842. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  7843. }
  7844. else
  7845. {
  7846. $algo = 'md5';
  7847. }
  7848. $hashes[] = $algo.':'.$value;
  7849. }
  7850. if (is_array($hashes))
  7851. {
  7852. $hashes = array_values(array_unique($hashes));
  7853. }
  7854. }
  7855. else
  7856. {
  7857. $hashes = $hashes_parent;
  7858. }
  7859. // KEYWORDS
  7860. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  7861. {
  7862. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  7863. {
  7864. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  7865. foreach ($temp as $word)
  7866. {
  7867. $keywords[] = trim($word);
  7868. }
  7869. unset($temp);
  7870. }
  7871. if (is_array($keywords))
  7872. {
  7873. $keywords = array_values(array_unique($keywords));
  7874. }
  7875. }
  7876. else
  7877. {
  7878. $keywords = $keywords_parent;
  7879. }
  7880. // PLAYER
  7881. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  7882. {
  7883. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  7884. }
  7885. else
  7886. {
  7887. $player = $player_parent;
  7888. }
  7889. // RATINGS
  7890. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  7891. {
  7892. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  7893. {
  7894. $rating_scheme = null;
  7895. $rating_value = null;
  7896. if (isset($rating['attribs']['']['scheme']))
  7897. {
  7898. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  7899. }
  7900. else
  7901. {
  7902. $rating_scheme = 'urn:simple';
  7903. }
  7904. if (isset($rating['data']))
  7905. {
  7906. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7907. }
  7908. $ratings[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
  7909. }
  7910. if (is_array($ratings))
  7911. {
  7912. $ratings = array_values(array_unique($ratings));
  7913. }
  7914. }
  7915. else
  7916. {
  7917. $ratings = $ratings_parent;
  7918. }
  7919. // RESTRICTIONS
  7920. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  7921. {
  7922. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  7923. {
  7924. $restriction_relationship = null;
  7925. $restriction_type = null;
  7926. $restriction_value = null;
  7927. if (isset($restriction['attribs']['']['relationship']))
  7928. {
  7929. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  7930. }
  7931. if (isset($restriction['attribs']['']['type']))
  7932. {
  7933. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  7934. }
  7935. if (isset($restriction['data']))
  7936. {
  7937. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7938. }
  7939. $restrictions[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
  7940. }
  7941. if (is_array($restrictions))
  7942. {
  7943. $restrictions = array_values(array_unique($restrictions));
  7944. }
  7945. }
  7946. else
  7947. {
  7948. $restrictions = $restrictions_parent;
  7949. }
  7950. // THUMBNAILS
  7951. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  7952. {
  7953. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  7954. {
  7955. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  7956. }
  7957. if (is_array($thumbnails))
  7958. {
  7959. $thumbnails = array_values(array_unique($thumbnails));
  7960. }
  7961. }
  7962. else
  7963. {
  7964. $thumbnails = $thumbnails_parent;
  7965. }
  7966. // TITLES
  7967. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  7968. {
  7969. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  7970. }
  7971. else
  7972. {
  7973. $title = $title_parent;
  7974. }
  7975. $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width));
  7976. }
  7977. }
  7978. }
  7979. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  7980. {
  7981. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
  7982. {
  7983. // Attributes
  7984. $bitrate = null;
  7985. $channels = null;
  7986. $duration = null;
  7987. $expression = null;
  7988. $framerate = null;
  7989. $height = null;
  7990. $javascript = null;
  7991. $lang = null;
  7992. $length = null;
  7993. $medium = null;
  7994. $samplingrate = null;
  7995. $type = null;
  7996. $url = null;
  7997. $width = null;
  7998. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  7999. if (isset($link['attribs']['']['type']))
  8000. {
  8001. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  8002. }
  8003. if (isset($link['attribs']['']['length']))
  8004. {
  8005. $length = ceil($link['attribs']['']['length']);
  8006. }
  8007. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  8008. $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width));
  8009. }
  8010. }
  8011. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  8012. {
  8013. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
  8014. {
  8015. // Attributes
  8016. $bitrate = null;
  8017. $channels = null;
  8018. $duration = null;
  8019. $expression = null;
  8020. $framerate = null;
  8021. $height = null;
  8022. $javascript = null;
  8023. $lang = null;
  8024. $length = null;
  8025. $medium = null;
  8026. $samplingrate = null;
  8027. $type = null;
  8028. $url = null;
  8029. $width = null;
  8030. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  8031. if (isset($link['attribs']['']['type']))
  8032. {
  8033. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  8034. }
  8035. if (isset($link['attribs']['']['length']))
  8036. {
  8037. $length = ceil($link['attribs']['']['length']);
  8038. }
  8039. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  8040. $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width));
  8041. }
  8042. }
  8043. if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure'))
  8044. {
  8045. if (isset($enclosure[0]['attribs']['']['url']))
  8046. {
  8047. // Attributes
  8048. $bitrate = null;
  8049. $channels = null;
  8050. $duration = null;
  8051. $expression = null;
  8052. $framerate = null;
  8053. $height = null;
  8054. $javascript = null;
  8055. $lang = null;
  8056. $length = null;
  8057. $medium = null;
  8058. $samplingrate = null;
  8059. $type = null;
  8060. $url = null;
  8061. $width = null;
  8062. $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
  8063. if (isset($enclosure[0]['attribs']['']['type']))
  8064. {
  8065. $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  8066. }
  8067. if (isset($enclosure[0]['attribs']['']['length']))
  8068. {
  8069. $length = ceil($enclosure[0]['attribs']['']['length']);
  8070. }
  8071. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  8072. $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width));
  8073. }
  8074. }
  8075. if (sizeof($this->data['enclosures']) === 0 && ($url || $type || $length || $bitrate || $captions_parent || $categories_parent || $channels || $copyrights_parent || $credits_parent || $description_parent || $duration_parent || $expression || $framerate || $hashes_parent || $height || $keywords_parent || $lang || $medium || $player_parent || $ratings_parent || $restrictions_parent || $samplingrate || $thumbnails_parent || $title_parent || $width))
  8076. {
  8077. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  8078. $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width));
  8079. }
  8080. $this->data['enclosures'] = array_values(array_unique($this->data['enclosures']));
  8081. }
  8082. if (!empty($this->data['enclosures']))
  8083. {
  8084. return $this->data['enclosures'];
  8085. }
  8086. else
  8087. {
  8088. return null;
  8089. }
  8090. }
  8091. public function get_latitude()
  8092. {
  8093. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  8094. {
  8095. return (float) $return[0]['data'];
  8096. }
  8097. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  8098. {
  8099. return (float) $match[1];
  8100. }
  8101. else
  8102. {
  8103. return null;
  8104. }
  8105. }
  8106. public function get_longitude()
  8107. {
  8108. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  8109. {
  8110. return (float) $return[0]['data'];
  8111. }
  8112. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  8113. {
  8114. return (float) $return[0]['data'];
  8115. }
  8116. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  8117. {
  8118. return (float) $match[2];
  8119. }
  8120. else
  8121. {
  8122. return null;
  8123. }
  8124. }
  8125. public function get_source()
  8126. {
  8127. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
  8128. {
  8129. return $this->registry->create('Source', array($this, $return[0]));
  8130. }
  8131. else
  8132. {
  8133. return null;
  8134. }
  8135. }
  8136. }
  8137. class SimplePie_Locator
  8138. {
  8139. var $useragent;
  8140. var $timeout;
  8141. var $file;
  8142. var $local = array();
  8143. var $elsewhere = array();
  8144. var $cached_entities = array();
  8145. var $http_base;
  8146. var $base;
  8147. var $base_location = 0;
  8148. var $checked_feeds = 0;
  8149. var $max_checked_feeds = 10;
  8150. protected $registry;
  8151. public function __construct(SimplePie_File $file, $timeout = 10, $useragent = null, $max_checked_feeds = 10)
  8152. {
  8153. $this->file = $file;
  8154. $this->useragent = $useragent;
  8155. $this->timeout = $timeout;
  8156. $this->max_checked_feeds = $max_checked_feeds;
  8157. $this->dom = new DOMDocument();
  8158. set_error_handler(array('SimplePie_Misc', 'silence_errors'));
  8159. $this->dom->loadHTML($this->file->body);
  8160. restore_error_handler();
  8161. }
  8162. public function set_registry(SimplePie_Registry $registry)
  8163. {
  8164. $this->registry = $registry;
  8165. }
  8166. public function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
  8167. {
  8168. if ($this->is_feed($this->file))
  8169. {
  8170. return $this->file;
  8171. }
  8172. if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
  8173. {
  8174. $sniffer = $this->registry->create('Content_Type_Sniffer', array($this->file));
  8175. if ($sniffer->get_type() !== 'text/html')
  8176. {
  8177. return null;
  8178. }
  8179. }
  8180. if ($type & ~SIMPLEPIE_LOCATOR_NONE)
  8181. {
  8182. $this->get_base();
  8183. }
  8184. if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
  8185. {
  8186. return $working[0];
  8187. }
  8188. if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
  8189. {
  8190. if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
  8191. {
  8192. return $working;
  8193. }
  8194. if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
  8195. {
  8196. return $working;
  8197. }
  8198. if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
  8199. {
  8200. return $working;
  8201. }
  8202. if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
  8203. {
  8204. return $working;
  8205. }
  8206. }
  8207. return null;
  8208. }
  8209. public function is_feed($file)
  8210. {
  8211. if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
  8212. {
  8213. $sniffer = $this->registry->create('Content_Type_Sniffer', array($file));
  8214. $sniffed = $sniffer->get_type();
  8215. if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
  8216. {
  8217. return true;
  8218. }
  8219. else
  8220. {
  8221. return false;
  8222. }
  8223. }
  8224. elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
  8225. {
  8226. return true;
  8227. }
  8228. else
  8229. {
  8230. return false;
  8231. }
  8232. }
  8233. public function get_base()
  8234. {
  8235. $this->http_base = $this->file->url;
  8236. $this->base = $this->http_base;
  8237. $elements = $this->dom->getElementsByTagName('base');
  8238. foreach ($elements as $element)
  8239. {
  8240. if ($element->hasAttribute('href'))
  8241. {
  8242. $this->base = $this->registry->call('Misc', 'absolutize_url', array(trim($element->getAttribute('href')), $this->http_base));
  8243. $this->base_location = method_exists($element, 'getLineNo') ? $element->getLineNo() : 0;
  8244. break;
  8245. }
  8246. }
  8247. }
  8248. public function autodiscovery()
  8249. {
  8250. $done = array();
  8251. $feeds = array();
  8252. $feeds = array_merge($feeds, $this->search_elements_by_tag('link', $done, $feeds));
  8253. $feeds = array_merge($feeds, $this->search_elements_by_tag('a', $done, $feeds));
  8254. $feeds = array_merge($feeds, $this->search_elements_by_tag('area', $done, $feeds));
  8255. if (!empty($feeds))
  8256. {
  8257. return array_values($feeds);
  8258. }
  8259. else
  8260. {
  8261. return null;
  8262. }
  8263. }
  8264. protected function search_elements_by_tag($name, &$done, $feeds)
  8265. {
  8266. $links = $this->dom->getElementsByTagName($name);
  8267. foreach ($links as $link)
  8268. {
  8269. if ($this->checked_feeds === $this->max_checked_feeds)
  8270. {
  8271. break;
  8272. }
  8273. if ($link->hasAttribute('href') && $link->hasAttribute('rel'))
  8274. {
  8275. $rel = array_unique($this->registry->call('Misc', 'space_seperated_tokens', array(strtolower($link->getAttribute('rel')))));
  8276. $line = method_exists($link, 'getLineNo') ? $link->getLineNo() : 1;
  8277. if ($this->base_location < $line)
  8278. {
  8279. $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base));
  8280. }
  8281. else
  8282. {
  8283. $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base));
  8284. }
  8285. if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !in_array('stylesheet', $rel) && $link->hasAttribute('type') && in_array(strtolower($this->registry->call('Misc', 'parse_mime', array($link->getAttribute('type')))), array('application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href]))
  8286. {
  8287. $this->checked_feeds++;
  8288. $headers = array(
  8289. 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
  8290. );
  8291. $feed = $this->registry->create('File', array($href, $this->timeout, 5, $headers, $this->useragent));
  8292. if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
  8293. {
  8294. $feeds[$href] = $feed;
  8295. }
  8296. }
  8297. $done[] = $href;
  8298. }
  8299. }
  8300. return $feeds;
  8301. }
  8302. public function get_links()
  8303. {
  8304. $links = $this->dom->getElementsByTagName('a');
  8305. foreach ($links as $link)
  8306. {
  8307. if ($link->hasAttribute('href'))
  8308. {
  8309. $href = trim($link->getAttribute('href'));
  8310. $parsed = $this->registry->call('Misc', 'parse_url', array($href));
  8311. if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
  8312. {
  8313. if ($this->base_location < $link->getLineNo())
  8314. {
  8315. $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base));
  8316. }
  8317. else
  8318. {
  8319. $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base));
  8320. }
  8321. $current = $this->registry->call('Misc', 'parse_url', array($this->file->url));
  8322. if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
  8323. {
  8324. $this->local[] = $href;
  8325. }
  8326. else
  8327. {
  8328. $this->elsewhere[] = $href;
  8329. }
  8330. }
  8331. }
  8332. }
  8333. $this->local = array_unique($this->local);
  8334. $this->elsewhere = array_unique($this->elsewhere);
  8335. if (!empty($this->local) || !empty($this->elsewhere))
  8336. {
  8337. return true;
  8338. }
  8339. return null;
  8340. }
  8341. public function extension(&$array)
  8342. {
  8343. foreach ($array as $key => $value)
  8344. {
  8345. if ($this->checked_feeds === $this->max_checked_feeds)
  8346. {
  8347. break;
  8348. }
  8349. if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
  8350. {
  8351. $this->checked_feeds++;
  8352. $headers = array(
  8353. 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
  8354. );
  8355. $feed = $this->registry->create('File', array($value, $this->timeout, 5, $headers, $this->useragent));
  8356. if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
  8357. {
  8358. return $feed;
  8359. }
  8360. else
  8361. {
  8362. unset($array[$key]);
  8363. }
  8364. }
  8365. }
  8366. return null;
  8367. }
  8368. public function body(&$array)
  8369. {
  8370. foreach ($array as $key => $value)
  8371. {
  8372. if ($this->checked_feeds === $this->max_checked_feeds)
  8373. {
  8374. break;
  8375. }
  8376. if (preg_match('/(rss|rdf|atom|xml)/i', $value))
  8377. {
  8378. $this->checked_feeds++;
  8379. $headers = array(
  8380. 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
  8381. );
  8382. $feed = $this->registry->create('File', array($value, $this->timeout, 5, null, $this->useragent));
  8383. if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
  8384. {
  8385. return $feed;
  8386. }
  8387. else
  8388. {
  8389. unset($array[$key]);
  8390. }
  8391. }
  8392. }
  8393. return null;
  8394. }
  8395. }
  8396. class SimplePie_Misc
  8397. {
  8398. public static function time_hms($seconds)
  8399. {
  8400. $time = '';
  8401. $hours = floor($seconds / 3600);
  8402. $remainder = $seconds % 3600;
  8403. if ($hours > 0)
  8404. {
  8405. $time .= $hours.':';
  8406. }
  8407. $minutes = floor($remainder / 60);
  8408. $seconds = $remainder % 60;
  8409. if ($minutes < 10 && $hours > 0)
  8410. {
  8411. $minutes = '0' . $minutes;
  8412. }
  8413. if ($seconds < 10)
  8414. {
  8415. $seconds = '0' . $seconds;
  8416. }
  8417. $time .= $minutes.':';
  8418. $time .= $seconds;
  8419. return $time;
  8420. }
  8421. public static function absolutize_url($relative, $base)
  8422. {
  8423. $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);
  8424. return $iri->get_uri();
  8425. }
  8426. public static function get_element($realname, $string)
  8427. {
  8428. $return = array();
  8429. $name = preg_quote($realname, '/');
  8430. if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
  8431. {
  8432. for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
  8433. {
  8434. $return[$i]['tag'] = $realname;
  8435. $return[$i]['full'] = $matches[$i][0][0];
  8436. $return[$i]['offset'] = $matches[$i][0][1];
  8437. if (strlen($matches[$i][3][0]) <= 2)
  8438. {
  8439. $return[$i]['self_closing'] = true;
  8440. }
  8441. else
  8442. {
  8443. $return[$i]['self_closing'] = false;
  8444. $return[$i]['content'] = $matches[$i][4][0];
  8445. }
  8446. $return[$i]['attribs'] = array();
  8447. 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))
  8448. {
  8449. for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
  8450. {
  8451. if (count($attribs[$j]) === 2)
  8452. {
  8453. $attribs[$j][2] = $attribs[$j][1];
  8454. }
  8455. $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
  8456. }
  8457. }
  8458. }
  8459. }
  8460. return $return;
  8461. }
  8462. public static function element_implode($element)
  8463. {
  8464. $full = "<$element[tag]";
  8465. foreach ($element['attribs'] as $key => $value)
  8466. {
  8467. $key = strtolower($key);
  8468. $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
  8469. }
  8470. if ($element['self_closing'])
  8471. {
  8472. $full .= ' />';
  8473. }
  8474. else
  8475. {
  8476. $full .= ">$element[content]</$element[tag]>";
  8477. }
  8478. return $full;
  8479. }
  8480. public static function error($message, $level, $file, $line)
  8481. {
  8482. if ((ini_get('error_reporting') & $level) > 0)
  8483. {
  8484. switch ($level)
  8485. {
  8486. case E_USER_ERROR:
  8487. $note = 'PHP Error';
  8488. break;
  8489. case E_USER_WARNING:
  8490. $note = 'PHP Warning';
  8491. break;
  8492. case E_USER_NOTICE:
  8493. $note = 'PHP Notice';
  8494. break;
  8495. default:
  8496. $note = 'Unknown Error';
  8497. break;
  8498. }
  8499. $log_error = true;
  8500. if (!function_exists('error_log'))
  8501. {
  8502. $log_error = false;
  8503. }
  8504. $log_file = @ini_get('error_log');
  8505. if (!empty($log_file) && ('syslog' !== $log_file) && !@is_writable($log_file))
  8506. {
  8507. $log_error = false;
  8508. }
  8509. if ($log_error)
  8510. {
  8511. @error_log("$note: $message in $file on line $line", 0);
  8512. }
  8513. }
  8514. return $message;
  8515. }
  8516. public static function fix_protocol($url, $http = 1)
  8517. {
  8518. $url = SimplePie_Misc::normalize_url($url);
  8519. $parsed = SimplePie_Misc::parse_url($url);
  8520. if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
  8521. {
  8522. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
  8523. }
  8524. if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
  8525. {
  8526. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
  8527. }
  8528. if ($http === 2 && $parsed['scheme'] !== '')
  8529. {
  8530. return "feed:$url";
  8531. }
  8532. elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
  8533. {
  8534. return substr_replace($url, 'podcast', 0, 4);
  8535. }
  8536. elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
  8537. {
  8538. return substr_replace($url, 'itpc', 0, 4);
  8539. }
  8540. else
  8541. {
  8542. return $url;
  8543. }
  8544. }
  8545. public static function parse_url($url)
  8546. {
  8547. $iri = new SimplePie_IRI($url);
  8548. return array(
  8549. 'scheme' => (string) $iri->scheme,
  8550. 'authority' => (string) $iri->authority,
  8551. 'path' => (string) $iri->path,
  8552. 'query' => (string) $iri->query,
  8553. 'fragment' => (string) $iri->fragment
  8554. );
  8555. }
  8556. public static function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
  8557. {
  8558. $iri = new SimplePie_IRI('');
  8559. $iri->scheme = $scheme;
  8560. $iri->authority = $authority;
  8561. $iri->path = $path;
  8562. $iri->query = $query;
  8563. $iri->fragment = $fragment;
  8564. return $iri->get_uri();
  8565. }
  8566. public static function normalize_url($url)
  8567. {
  8568. $iri = new SimplePie_IRI($url);
  8569. return $iri->get_uri();
  8570. }
  8571. public static function percent_encoding_normalization($match)
  8572. {
  8573. $integer = hexdec($match[1]);
  8574. if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
  8575. {
  8576. return chr($integer);
  8577. }
  8578. else
  8579. {
  8580. return strtoupper($match[0]);
  8581. }
  8582. }
  8583. public static function windows_1252_to_utf8($string)
  8584. {
  8585. 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");
  8586. return strtr($string, $convert_table);
  8587. }
  8588. public static function change_encoding($data, $input, $output)
  8589. {
  8590. $input = SimplePie_Misc::encoding($input);
  8591. $output = SimplePie_Misc::encoding($output);
  8592. // We fail to fail on non US-ASCII bytes
  8593. if ($input === 'US-ASCII')
  8594. {
  8595. static $non_ascii_octects = '';
  8596. if (!$non_ascii_octects)
  8597. {
  8598. for ($i = 0x80; $i <= 0xFF; $i++)
  8599. {
  8600. $non_ascii_octects .= chr($i);
  8601. }
  8602. }
  8603. $data = substr($data, 0, strcspn($data, $non_ascii_octects));
  8604. }
  8605. // This is first, as behaviour of this is completely predictable
  8606. if ($input === 'windows-1252' && $output === 'UTF-8')
  8607. {
  8608. return SimplePie_Misc::windows_1252_to_utf8($data);
  8609. }
  8610. // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
  8611. elseif (function_exists('mb_convert_encoding') && ($return = SimplePie_Misc::change_encoding_mbstring($data, $input, $output)))
  8612. {
  8613. return $return;
  8614. }
  8615. // This is last, as behaviour of this varies with OS userland and PHP version
  8616. elseif (function_exists('iconv') && ($return = SimplePie_Misc::change_encoding_iconv($data, $input, $output)))
  8617. {
  8618. return $return;
  8619. }
  8620. // If we can't do anything, just fail
  8621. else
  8622. {
  8623. return false;
  8624. }
  8625. }
  8626. protected static function change_encoding_mbstring($data, $input, $output)
  8627. {
  8628. if ($input === 'windows-949')
  8629. {
  8630. $input = 'EUC-KR';
  8631. }
  8632. if ($output === 'windows-949')
  8633. {
  8634. $output = 'EUC-KR';
  8635. }
  8636. if ($input === 'Windows-31J')
  8637. {
  8638. $input = 'SJIS';
  8639. }
  8640. if ($output === 'Windows-31J')
  8641. {
  8642. $output = 'SJIS';
  8643. }
  8644. // Check that the encoding is supported
  8645. if (@mb_convert_encoding("\x80", 'UTF-16BE', $input) === "\x00\x80")
  8646. {
  8647. return false;
  8648. }
  8649. if (!in_array($input, mb_list_encodings()))
  8650. {
  8651. return false;
  8652. }
  8653. // Let's do some conversion
  8654. if ($return = @mb_convert_encoding($data, $output, $input))
  8655. {
  8656. return $return;
  8657. }
  8658. return false;
  8659. }
  8660. protected static function change_encoding_iconv($data, $input, $output)
  8661. {
  8662. return @iconv($input, $output, $data);
  8663. }
  8664. public static function encoding($charset)
  8665. {
  8666. // Normalization from UTS #22
  8667. switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
  8668. {
  8669. case 'adobestandardencoding':
  8670. case 'csadobestandardencoding':
  8671. return 'Adobe-Standard-Encoding';
  8672. case 'adobesymbolencoding':
  8673. case 'cshppsmath':
  8674. return 'Adobe-Symbol-Encoding';
  8675. case 'ami1251':
  8676. case 'amiga1251':
  8677. return 'Amiga-1251';
  8678. case 'ansix31101983':
  8679. case 'csat5001983':
  8680. case 'csiso99naplps':
  8681. case 'isoir99':
  8682. case 'naplps':
  8683. return 'ANSI_X3.110-1983';
  8684. case 'arabic7':
  8685. case 'asmo449':
  8686. case 'csiso89asmo449':
  8687. case 'iso9036':
  8688. case 'isoir89':
  8689. return 'ASMO_449';
  8690. case 'big5':
  8691. case 'csbig5':
  8692. return 'Big5';
  8693. case 'big5hkscs':
  8694. return 'Big5-HKSCS';
  8695. case 'bocu1':
  8696. case 'csbocu1':
  8697. return 'BOCU-1';
  8698. case 'brf':
  8699. case 'csbrf':
  8700. return 'BRF';
  8701. case 'bs4730':
  8702. case 'csiso4unitedkingdom':
  8703. case 'gb':
  8704. case 'iso646gb':
  8705. case 'isoir4':
  8706. case 'uk':
  8707. return 'BS_4730';
  8708. case 'bsviewdata':
  8709. case 'csiso47bsviewdata':
  8710. case 'isoir47':
  8711. return 'BS_viewdata';
  8712. case 'cesu8':
  8713. case 'cscesu8':
  8714. return 'CESU-8';
  8715. case 'ca':
  8716. case 'csa71':
  8717. case 'csaz243419851':
  8718. case 'csiso121canadian1':
  8719. case 'iso646ca':
  8720. case 'isoir121':
  8721. return 'CSA_Z243.4-1985-1';
  8722. case 'csa72':
  8723. case 'csaz243419852':
  8724. case 'csiso122canadian2':
  8725. case 'iso646ca2':
  8726. case 'isoir122':
  8727. return 'CSA_Z243.4-1985-2';
  8728. case 'csaz24341985gr':
  8729. case 'csiso123csaz24341985gr':
  8730. case 'isoir123':
  8731. return 'CSA_Z243.4-1985-gr';
  8732. case 'csiso139csn369103':
  8733. case 'csn369103':
  8734. case 'isoir139':
  8735. return 'CSN_369103';
  8736. case 'csdecmcs':
  8737. case 'dec':
  8738. case 'decmcs':
  8739. return 'DEC-MCS';
  8740. case 'csiso21german':
  8741. case 'de':
  8742. case 'din66003':
  8743. case 'iso646de':
  8744. case 'isoir21':
  8745. return 'DIN_66003';
  8746. case 'csdkus':
  8747. case 'dkus':
  8748. return 'dk-us';
  8749. case 'csiso646danish':
  8750. case 'dk':
  8751. case 'ds2089':
  8752. case 'iso646dk':
  8753. return 'DS_2089';
  8754. case 'csibmebcdicatde':
  8755. case 'ebcdicatde':
  8756. return 'EBCDIC-AT-DE';
  8757. case 'csebcdicatdea':
  8758. case 'ebcdicatdea':
  8759. return 'EBCDIC-AT-DE-A';
  8760. case 'csebcdiccafr':
  8761. case 'ebcdiccafr':
  8762. return 'EBCDIC-CA-FR';
  8763. case 'csebcdicdkno':
  8764. case 'ebcdicdkno':
  8765. return 'EBCDIC-DK-NO';
  8766. case 'csebcdicdknoa':
  8767. case 'ebcdicdknoa':
  8768. return 'EBCDIC-DK-NO-A';
  8769. case 'csebcdices':
  8770. case 'ebcdices':
  8771. return 'EBCDIC-ES';
  8772. case 'csebcdicesa':
  8773. case 'ebcdicesa':
  8774. return 'EBCDIC-ES-A';
  8775. case 'csebcdicess':
  8776. case 'ebcdicess':
  8777. return 'EBCDIC-ES-S';
  8778. case 'csebcdicfise':
  8779. case 'ebcdicfise':
  8780. return 'EBCDIC-FI-SE';
  8781. case 'csebcdicfisea':
  8782. case 'ebcdicfisea':
  8783. return 'EBCDIC-FI-SE-A';
  8784. case 'csebcdicfr':
  8785. case 'ebcdicfr':
  8786. return 'EBCDIC-FR';
  8787. case 'csebcdicit':
  8788. case 'ebcdicit':
  8789. return 'EBCDIC-IT';
  8790. case 'csebcdicpt':
  8791. case 'ebcdicpt':
  8792. return 'EBCDIC-PT';
  8793. case 'csebcdicuk':
  8794. case 'ebcdicuk':
  8795. return 'EBCDIC-UK';
  8796. case 'csebcdicus':
  8797. case 'ebcdicus':
  8798. return 'EBCDIC-US';
  8799. case 'csiso111ecmacyrillic':
  8800. case 'ecmacyrillic':
  8801. case 'isoir111':
  8802. case 'koi8e':
  8803. return 'ECMA-cyrillic';
  8804. case 'csiso17spanish':
  8805. case 'es':
  8806. case 'iso646es':
  8807. case 'isoir17':
  8808. return 'ES';
  8809. case 'csiso85spanish2':
  8810. case 'es2':
  8811. case 'iso646es2':
  8812. case 'isoir85':
  8813. return 'ES2';
  8814. case 'cseucpkdfmtjapanese':
  8815. case 'eucjp':
  8816. case 'extendedunixcodepackedformatforjapanese':
  8817. return 'EUC-JP';
  8818. case 'cseucfixwidjapanese':
  8819. case 'extendedunixcodefixedwidthforjapanese':
  8820. return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
  8821. case 'gb18030':
  8822. return 'GB18030';
  8823. case 'chinese':
  8824. case 'cp936':
  8825. case 'csgb2312':
  8826. case 'csiso58gb231280':
  8827. case 'gb2312':
  8828. case 'gb231280':
  8829. case 'gbk':
  8830. case 'isoir58':
  8831. case 'ms936':
  8832. case 'windows936':
  8833. return 'GBK';
  8834. case 'cn':
  8835. case 'csiso57gb1988':
  8836. case 'gb198880':
  8837. case 'iso646cn':
  8838. case 'isoir57':
  8839. return 'GB_1988-80';
  8840. case 'csiso153gost1976874':
  8841. case 'gost1976874':
  8842. case 'isoir153':
  8843. case 'stsev35888':
  8844. return 'GOST_19768-74';
  8845. case 'csiso150':
  8846. case 'csiso150greekccitt':
  8847. case 'greekccitt':
  8848. case 'isoir150':
  8849. return 'greek-ccitt';
  8850. case 'csiso88greek7':
  8851. case 'greek7':
  8852. case 'isoir88':
  8853. return 'greek7';
  8854. case 'csiso18greek7old':
  8855. case 'greek7old':
  8856. case 'isoir18':
  8857. return 'greek7-old';
  8858. case 'cshpdesktop':
  8859. case 'hpdesktop':
  8860. return 'HP-DeskTop';
  8861. case 'cshplegal':
  8862. case 'hplegal':
  8863. return 'HP-Legal';
  8864. case 'cshpmath8':
  8865. case 'hpmath8':
  8866. return 'HP-Math8';
  8867. case 'cshppifont':
  8868. case 'hppifont':
  8869. return 'HP-Pi-font';
  8870. case 'cshproman8':
  8871. case 'hproman8':
  8872. case 'r8':
  8873. case 'roman8':
  8874. return 'hp-roman8';
  8875. case 'hzgb2312':
  8876. return 'HZ-GB-2312';
  8877. case 'csibmsymbols':
  8878. case 'ibmsymbols':
  8879. return 'IBM-Symbols';
  8880. case 'csibmthai':
  8881. case 'ibmthai':
  8882. return 'IBM-Thai';
  8883. case 'cp37':
  8884. case 'csibm37':
  8885. case 'ebcdiccpca':
  8886. case 'ebcdiccpnl':
  8887. case 'ebcdiccpus':
  8888. case 'ebcdiccpwt':
  8889. case 'ibm37':
  8890. return 'IBM037';
  8891. case 'cp38':
  8892. case 'csibm38':
  8893. case 'ebcdicint':
  8894. case 'ibm38':
  8895. return 'IBM038';
  8896. case 'cp273':
  8897. case 'csibm273':
  8898. case 'ibm273':
  8899. return 'IBM273';
  8900. case 'cp274':
  8901. case 'csibm274':
  8902. case 'ebcdicbe':
  8903. case 'ibm274':
  8904. return 'IBM274';
  8905. case 'cp275':
  8906. case 'csibm275':
  8907. case 'ebcdicbr':
  8908. case 'ibm275':
  8909. return 'IBM275';
  8910. case 'csibm277':
  8911. case 'ebcdiccpdk':
  8912. case 'ebcdiccpno':
  8913. case 'ibm277':
  8914. return 'IBM277';
  8915. case 'cp278':
  8916. case 'csibm278':
  8917. case 'ebcdiccpfi':
  8918. case 'ebcdiccpse':
  8919. case 'ibm278':
  8920. return 'IBM278';
  8921. case 'cp280':
  8922. case 'csibm280':
  8923. case 'ebcdiccpit':
  8924. case 'ibm280':
  8925. return 'IBM280';
  8926. case 'cp281':
  8927. case 'csibm281':
  8928. case 'ebcdicjpe':
  8929. case 'ibm281':
  8930. return 'IBM281';
  8931. case 'cp284':
  8932. case 'csibm284':
  8933. case 'ebcdiccpes':
  8934. case 'ibm284':
  8935. return 'IBM284';
  8936. case 'cp285':
  8937. case 'csibm285':
  8938. case 'ebcdiccpgb':
  8939. case 'ibm285':
  8940. return 'IBM285';
  8941. case 'cp290':
  8942. case 'csibm290':
  8943. case 'ebcdicjpkana':
  8944. case 'ibm290':
  8945. return 'IBM290';
  8946. case 'cp297':
  8947. case 'csibm297':
  8948. case 'ebcdiccpfr':
  8949. case 'ibm297':
  8950. return 'IBM297';
  8951. case 'cp420':
  8952. case 'csibm420':
  8953. case 'ebcdiccpar1':
  8954. case 'ibm420':
  8955. return 'IBM420';
  8956. case 'cp423':
  8957. case 'csibm423':
  8958. case 'ebcdiccpgr':
  8959. case 'ibm423':
  8960. return 'IBM423';
  8961. case 'cp424':
  8962. case 'csibm424':
  8963. case 'ebcdiccphe':
  8964. case 'ibm424':
  8965. return 'IBM424';
  8966. case '437':
  8967. case 'cp437':
  8968. case 'cspc8codepage437':
  8969. case 'ibm437':
  8970. return 'IBM437';
  8971. case 'cp500':
  8972. case 'csibm500':
  8973. case 'ebcdiccpbe':
  8974. case 'ebcdiccpch':
  8975. case 'ibm500':
  8976. return 'IBM500';
  8977. case 'cp775':
  8978. case 'cspc775baltic':
  8979. case 'ibm775':
  8980. return 'IBM775';
  8981. case '850':
  8982. case 'cp850':
  8983. case 'cspc850multilingual':
  8984. case 'ibm850':
  8985. return 'IBM850';
  8986. case '851':
  8987. case 'cp851':
  8988. case 'csibm851':
  8989. case 'ibm851':
  8990. return 'IBM851';
  8991. case '852':
  8992. case 'cp852':
  8993. case 'cspcp852':
  8994. case 'ibm852':
  8995. return 'IBM852';
  8996. case '855':
  8997. case 'cp855':
  8998. case 'csibm855':
  8999. case 'ibm855':
  9000. return 'IBM855';
  9001. case '857':
  9002. case 'cp857':
  9003. case 'csibm857':
  9004. case 'ibm857':
  9005. return 'IBM857';
  9006. case 'ccsid858':
  9007. case 'cp858':
  9008. case 'ibm858':
  9009. case 'pcmultilingual850euro':
  9010. return 'IBM00858';
  9011. case '860':
  9012. case 'cp860':
  9013. case 'csibm860':
  9014. case 'ibm860':
  9015. return 'IBM860';
  9016. case '861':
  9017. case 'cp861':
  9018. case 'cpis':
  9019. case 'csibm861':
  9020. case 'ibm861':
  9021. return 'IBM861';
  9022. case '862':
  9023. case 'cp862':
  9024. case 'cspc862latinhebrew':
  9025. case 'ibm862':
  9026. return 'IBM862';
  9027. case '863':
  9028. case 'cp863':
  9029. case 'csibm863':
  9030. case 'ibm863':
  9031. return 'IBM863';
  9032. case 'cp864':
  9033. case 'csibm864':
  9034. case 'ibm864':
  9035. return 'IBM864';
  9036. case '865':
  9037. case 'cp865':
  9038. case 'csibm865':
  9039. case 'ibm865':
  9040. return 'IBM865';
  9041. case '866':
  9042. case 'cp866':
  9043. case 'csibm866':
  9044. case 'ibm866':
  9045. return 'IBM866';
  9046. case 'cp868':
  9047. case 'cpar':
  9048. case 'csibm868':
  9049. case 'ibm868':
  9050. return 'IBM868';
  9051. case '869':
  9052. case 'cp869':
  9053. case 'cpgr':
  9054. case 'csibm869':
  9055. case 'ibm869':
  9056. return 'IBM869';
  9057. case 'cp870':
  9058. case 'csibm870':
  9059. case 'ebcdiccproece':
  9060. case 'ebcdiccpyu':
  9061. case 'ibm870':
  9062. return 'IBM870';
  9063. case 'cp871':
  9064. case 'csibm871':
  9065. case 'ebcdiccpis':
  9066. case 'ibm871':
  9067. return 'IBM871';
  9068. case 'cp880':
  9069. case 'csibm880':
  9070. case 'ebcdiccyrillic':
  9071. case 'ibm880':
  9072. return 'IBM880';
  9073. case 'cp891':
  9074. case 'csibm891':
  9075. case 'ibm891':
  9076. return 'IBM891';
  9077. case 'cp903':
  9078. case 'csibm903':
  9079. case 'ibm903':
  9080. return 'IBM903';
  9081. case '904':
  9082. case 'cp904':
  9083. case 'csibbm904':
  9084. case 'ibm904':
  9085. return 'IBM904';
  9086. case 'cp905':
  9087. case 'csibm905':
  9088. case 'ebcdiccptr':
  9089. case 'ibm905':
  9090. return 'IBM905';
  9091. case 'cp918':
  9092. case 'csibm918':
  9093. case 'ebcdiccpar2':
  9094. case 'ibm918':
  9095. return 'IBM918';
  9096. case 'ccsid924':
  9097. case 'cp924':
  9098. case 'ebcdiclatin9euro':
  9099. case 'ibm924':
  9100. return 'IBM00924';
  9101. case 'cp1026':
  9102. case 'csibm1026':
  9103. case 'ibm1026':
  9104. return 'IBM1026';
  9105. case 'ibm1047':
  9106. return 'IBM1047';
  9107. case 'ccsid1140':
  9108. case 'cp1140':
  9109. case 'ebcdicus37euro':
  9110. case 'ibm1140':
  9111. return 'IBM01140';
  9112. case 'ccsid1141':
  9113. case 'cp1141':
  9114. case 'ebcdicde273euro':
  9115. case 'ibm1141':
  9116. return 'IBM01141';
  9117. case 'ccsid1142':
  9118. case 'cp1142':
  9119. case 'ebcdicdk277euro':
  9120. case 'ebcdicno277euro':
  9121. case 'ibm1142':
  9122. return 'IBM01142';
  9123. case 'ccsid1143':
  9124. case 'cp1143':
  9125. case 'ebcdicfi278euro':
  9126. case 'ebcdicse278euro':
  9127. case 'ibm1143':
  9128. return 'IBM01143';
  9129. case 'ccsid1144':
  9130. case 'cp1144':
  9131. case 'ebcdicit280euro':
  9132. case 'ibm1144':
  9133. return 'IBM01144';
  9134. case 'ccsid1145':
  9135. case 'cp1145':
  9136. case 'ebcdices284euro':
  9137. case 'ibm1145':
  9138. return 'IBM01145';
  9139. case 'ccsid1146':
  9140. case 'cp1146':
  9141. case 'ebcdicgb285euro':
  9142. case 'ibm1146':
  9143. return 'IBM01146';
  9144. case 'ccsid1147':
  9145. case 'cp1147':
  9146. case 'ebcdicfr297euro':
  9147. case 'ibm1147':
  9148. return 'IBM01147';
  9149. case 'ccsid1148':
  9150. case 'cp1148':
  9151. case 'ebcdicinternational500euro':
  9152. case 'ibm1148':
  9153. return 'IBM01148';
  9154. case 'ccsid1149':
  9155. case 'cp1149':
  9156. case 'ebcdicis871euro':
  9157. case 'ibm1149':
  9158. return 'IBM01149';
  9159. case 'csiso143iecp271':
  9160. case 'iecp271':
  9161. case 'isoir143':
  9162. return 'IEC_P27-1';
  9163. case 'csiso49inis':
  9164. case 'inis':
  9165. case 'isoir49':
  9166. return 'INIS';
  9167. case 'csiso50inis8':
  9168. case 'inis8':
  9169. case 'isoir50':
  9170. return 'INIS-8';
  9171. case 'csiso51iniscyrillic':
  9172. case 'iniscyrillic':
  9173. case 'isoir51':
  9174. return 'INIS-cyrillic';
  9175. case 'csinvariant':
  9176. case 'invariant':
  9177. return 'INVARIANT';
  9178. case 'iso2022cn':
  9179. return 'ISO-2022-CN';
  9180. case 'iso2022cnext':
  9181. return 'ISO-2022-CN-EXT';
  9182. case 'csiso2022jp':
  9183. case 'iso2022jp':
  9184. return 'ISO-2022-JP';
  9185. case 'csiso2022jp2':
  9186. case 'iso2022jp2':
  9187. return 'ISO-2022-JP-2';
  9188. case 'csiso2022kr':
  9189. case 'iso2022kr':
  9190. return 'ISO-2022-KR';
  9191. case 'cswindows30latin1':
  9192. case 'iso88591windows30latin1':
  9193. return 'ISO-8859-1-Windows-3.0-Latin-1';
  9194. case 'cswindows31latin1':
  9195. case 'iso88591windows31latin1':
  9196. return 'ISO-8859-1-Windows-3.1-Latin-1';
  9197. case 'csisolatin2':
  9198. case 'iso88592':
  9199. case 'iso885921987':
  9200. case 'isoir101':
  9201. case 'l2':
  9202. case 'latin2':
  9203. return 'ISO-8859-2';
  9204. case 'cswindows31latin2':
  9205. case 'iso88592windowslatin2':
  9206. return 'ISO-8859-2-Windows-Latin-2';
  9207. case 'csisolatin3':
  9208. case 'iso88593':
  9209. case 'iso885931988':
  9210. case 'isoir109':
  9211. case 'l3':
  9212. case 'latin3':
  9213. return 'ISO-8859-3';
  9214. case 'csisolatin4':
  9215. case 'iso88594':
  9216. case 'iso885941988':
  9217. case 'isoir110':
  9218. case 'l4':
  9219. case 'latin4':
  9220. return 'ISO-8859-4';
  9221. case 'csisolatincyrillic':
  9222. case 'cyrillic':
  9223. case 'iso88595':
  9224. case 'iso885951988':
  9225. case 'isoir144':
  9226. return 'ISO-8859-5';
  9227. case 'arabic':
  9228. case 'asmo708':
  9229. case 'csisolatinarabic':
  9230. case 'ecma114':
  9231. case 'iso88596':
  9232. case 'iso885961987':
  9233. case 'isoir127':
  9234. return 'ISO-8859-6';
  9235. case 'csiso88596e':
  9236. case 'iso88596e':
  9237. return 'ISO-8859-6-E';
  9238. case 'csiso88596i':
  9239. case 'iso88596i':
  9240. return 'ISO-8859-6-I';
  9241. case 'csisolatingreek':
  9242. case 'ecma118':
  9243. case 'elot928':
  9244. case 'greek':
  9245. case 'greek8':
  9246. case 'iso88597':
  9247. case 'iso885971987':
  9248. case 'isoir126':
  9249. return 'ISO-8859-7';
  9250. case 'csisolatinhebrew':
  9251. case 'hebrew':
  9252. case 'iso88598':
  9253. case 'iso885981988':
  9254. case 'isoir138':
  9255. return 'ISO-8859-8';
  9256. case 'csiso88598e':
  9257. case 'iso88598e':
  9258. return 'ISO-8859-8-E';
  9259. case 'csiso88598i':
  9260. case 'iso88598i':
  9261. return 'ISO-8859-8-I';
  9262. case 'cswindows31latin5':
  9263. case 'iso88599windowslatin5':
  9264. return 'ISO-8859-9-Windows-Latin-5';
  9265. case 'csisolatin6':
  9266. case 'iso885910':
  9267. case 'iso8859101992':
  9268. case 'isoir157':
  9269. case 'l6':
  9270. case 'latin6':
  9271. return 'ISO-8859-10';
  9272. case 'iso885913':
  9273. return 'ISO-8859-13';
  9274. case 'iso885914':
  9275. case 'iso8859141998':
  9276. case 'isoceltic':
  9277. case 'isoir199':
  9278. case 'l8':
  9279. case 'latin8':
  9280. return 'ISO-8859-14';
  9281. case 'iso885915':
  9282. case 'latin9':
  9283. return 'ISO-8859-15';
  9284. case 'iso885916':
  9285. case 'iso8859162001':
  9286. case 'isoir226':
  9287. case 'l10':
  9288. case 'latin10':
  9289. return 'ISO-8859-16';
  9290. case 'iso10646j1':
  9291. return 'ISO-10646-J-1';
  9292. case 'csunicode':
  9293. case 'iso10646ucs2':
  9294. return 'ISO-10646-UCS-2';
  9295. case 'csucs4':
  9296. case 'iso10646ucs4':
  9297. return 'ISO-10646-UCS-4';
  9298. case 'csunicodeascii':
  9299. case 'iso10646ucsbasic':
  9300. return 'ISO-10646-UCS-Basic';
  9301. case 'csunicodelatin1':
  9302. case 'iso10646':
  9303. case 'iso10646unicodelatin1':
  9304. return 'ISO-10646-Unicode-Latin1';
  9305. case 'csiso10646utf1':
  9306. case 'iso10646utf1':
  9307. return 'ISO-10646-UTF-1';
  9308. case 'csiso115481':
  9309. case 'iso115481':
  9310. case 'isotr115481':
  9311. return 'ISO-11548-1';
  9312. case 'csiso90':
  9313. case 'isoir90':
  9314. return 'iso-ir-90';
  9315. case 'csunicodeibm1261':
  9316. case 'isounicodeibm1261':
  9317. return 'ISO-Unicode-IBM-1261';
  9318. case 'csunicodeibm1264':
  9319. case 'isounicodeibm1264':
  9320. return 'ISO-Unicode-IBM-1264';
  9321. case 'csunicodeibm1265':
  9322. case 'isounicodeibm1265':
  9323. return 'ISO-Unicode-IBM-1265';
  9324. case 'csunicodeibm1268':
  9325. case 'isounicodeibm1268':
  9326. return 'ISO-Unicode-IBM-1268';
  9327. case 'csunicodeibm1276':
  9328. case 'isounicodeibm1276':
  9329. return 'ISO-Unicode-IBM-1276';
  9330. case 'csiso646basic1983':
  9331. case 'iso646basic1983':
  9332. case 'ref':
  9333. return 'ISO_646.basic:1983';
  9334. case 'csiso2intlrefversion':
  9335. case 'irv':
  9336. case 'iso646irv1983':
  9337. case 'isoir2':
  9338. return 'ISO_646.irv:1983';
  9339. case 'csiso2033':
  9340. case 'e13b':
  9341. case 'iso20331983':
  9342. case 'isoir98':
  9343. return 'ISO_2033-1983';
  9344. case 'csiso5427cyrillic':
  9345. case 'iso5427':
  9346. case 'isoir37':
  9347. return 'ISO_5427';
  9348. case 'iso5427cyrillic1981':
  9349. case 'iso54271981':
  9350. case 'isoir54':
  9351. return 'ISO_5427:1981';
  9352. case 'csiso5428greek':
  9353. case 'iso54281980':
  9354. case 'isoir55':
  9355. return 'ISO_5428:1980';
  9356. case 'csiso6937add':
  9357. case 'iso6937225':
  9358. case 'isoir152':
  9359. return 'ISO_6937-2-25';
  9360. case 'csisotextcomm':
  9361. case 'iso69372add':
  9362. case 'isoir142':
  9363. return 'ISO_6937-2-add';
  9364. case 'csiso8859supp':
  9365. case 'iso8859supp':
  9366. case 'isoir154':
  9367. case 'latin125':
  9368. return 'ISO_8859-supp';
  9369. case 'csiso10367box':
  9370. case 'iso10367box':
  9371. case 'isoir155':
  9372. return 'ISO_10367-box';
  9373. case 'csiso15italian':
  9374. case 'iso646it':
  9375. case 'isoir15':
  9376. case 'it':
  9377. return 'IT';
  9378. case 'csiso13jisc6220jp':
  9379. case 'isoir13':
  9380. case 'jisc62201969':
  9381. case 'jisc62201969jp':
  9382. case 'katakana':
  9383. case 'x2017':
  9384. return 'JIS_C6220-1969-jp';
  9385. case 'csiso14jisc6220ro':
  9386. case 'iso646jp':
  9387. case 'isoir14':
  9388. case 'jisc62201969ro':
  9389. case 'jp':
  9390. return 'JIS_C6220-1969-ro';
  9391. case 'csiso42jisc62261978':
  9392. case 'isoir42':
  9393. case 'jisc62261978':
  9394. return 'JIS_C6226-1978';
  9395. case 'csiso87jisx208':
  9396. case 'isoir87':
  9397. case 'jisc62261983':
  9398. case 'jisx2081983':
  9399. case 'x208':
  9400. return 'JIS_C6226-1983';
  9401. case 'csiso91jisc62291984a':
  9402. case 'isoir91':
  9403. case 'jisc62291984a':
  9404. case 'jpocra':
  9405. return 'JIS_C6229-1984-a';
  9406. case 'csiso92jisc62991984b':
  9407. case 'iso646jpocrb':
  9408. case 'isoir92':
  9409. case 'jisc62291984b':
  9410. case 'jpocrb':
  9411. return 'JIS_C6229-1984-b';
  9412. case 'csiso93jis62291984badd':
  9413. case 'isoir93':
  9414. case 'jisc62291984badd':
  9415. case 'jpocrbadd':
  9416. return 'JIS_C6229-1984-b-add';
  9417. case 'csiso94jis62291984hand':
  9418. case 'isoir94':
  9419. case 'jisc62291984hand':
  9420. case 'jpocrhand':
  9421. return 'JIS_C6229-1984-hand';
  9422. case 'csiso95jis62291984handadd':
  9423. case 'isoir95':
  9424. case 'jisc62291984handadd':
  9425. case 'jpocrhandadd':
  9426. return 'JIS_C6229-1984-hand-add';
  9427. case 'csiso96jisc62291984kana':
  9428. case 'isoir96':
  9429. case 'jisc62291984kana':
  9430. return 'JIS_C6229-1984-kana';
  9431. case 'csjisencoding':
  9432. case 'jisencoding':
  9433. return 'JIS_Encoding';
  9434. case 'cshalfwidthkatakana':
  9435. case 'jisx201':
  9436. case 'x201':
  9437. return 'JIS_X0201';
  9438. case 'csiso159jisx2121990':
  9439. case 'isoir159':
  9440. case 'jisx2121990':
  9441. case 'x212':
  9442. return 'JIS_X0212-1990';
  9443. case 'csiso141jusib1002':
  9444. case 'iso646yu':
  9445. case 'isoir141':
  9446. case 'js':
  9447. case 'jusib1002':
  9448. case 'yu':
  9449. return 'JUS_I.B1.002';
  9450. case 'csiso147macedonian':
  9451. case 'isoir147':
  9452. case 'jusib1003mac':
  9453. case 'macedonian':
  9454. return 'JUS_I.B1.003-mac';
  9455. case 'csiso146serbian':
  9456. case 'isoir146':
  9457. case 'jusib1003serb':
  9458. case 'serbian':
  9459. return 'JUS_I.B1.003-serb';
  9460. case 'koi7switched':
  9461. return 'KOI7-switched';
  9462. case 'cskoi8r':
  9463. case 'koi8r':
  9464. return 'KOI8-R';
  9465. case 'koi8u':
  9466. return 'KOI8-U';
  9467. case 'csksc5636':
  9468. case 'iso646kr':
  9469. case 'ksc5636':
  9470. return 'KSC5636';
  9471. case 'cskz1048':
  9472. case 'kz1048':
  9473. case 'rk1048':
  9474. case 'strk10482002':
  9475. return 'KZ-1048';
  9476. case 'csiso19latingreek':
  9477. case 'isoir19':
  9478. case 'latingreek':
  9479. return 'latin-greek';
  9480. case 'csiso27latingreek1':
  9481. case 'isoir27':
  9482. case 'latingreek1':
  9483. return 'Latin-greek-1';
  9484. case 'csiso158lap':
  9485. case 'isoir158':
  9486. case 'lap':
  9487. case 'latinlap':
  9488. return 'latin-lap';
  9489. case 'csmacintosh':
  9490. case 'mac':
  9491. case 'macintosh':
  9492. return 'macintosh';
  9493. case 'csmicrosoftpublishing':
  9494. case 'microsoftpublishing':
  9495. return 'Microsoft-Publishing';
  9496. case 'csmnem':
  9497. case 'mnem':
  9498. return 'MNEM';
  9499. case 'csmnemonic':
  9500. case 'mnemonic':
  9501. return 'MNEMONIC';
  9502. case 'csiso86hungarian':
  9503. case 'hu':
  9504. case 'iso646hu':
  9505. case 'isoir86':
  9506. case 'msz77953':
  9507. return 'MSZ_7795.3';
  9508. case 'csnatsdano':
  9509. case 'isoir91':
  9510. case 'natsdano':
  9511. return 'NATS-DANO';
  9512. case 'csnatsdanoadd':
  9513. case 'isoir92':
  9514. case 'natsdanoadd':
  9515. return 'NATS-DANO-ADD';
  9516. case 'csnatssefi':
  9517. case 'isoir81':
  9518. case 'natssefi':
  9519. return 'NATS-SEFI';
  9520. case 'csnatssefiadd':
  9521. case 'isoir82':
  9522. case 'natssefiadd':
  9523. return 'NATS-SEFI-ADD';
  9524. case 'csiso151cuba':
  9525. case 'cuba':
  9526. case 'iso646cu':
  9527. case 'isoir151':
  9528. case 'ncnc1081':
  9529. return 'NC_NC00-10:81';
  9530. case 'csiso69french':
  9531. case 'fr':
  9532. case 'iso646fr':
  9533. case 'isoir69':
  9534. case 'nfz62010':
  9535. return 'NF_Z_62-010';
  9536. case 'csiso25french':
  9537. case 'iso646fr1':
  9538. case 'isoir25':
  9539. case 'nfz620101973':
  9540. return 'NF_Z_62-010_(1973)';
  9541. case 'csiso60danishnorwegian':
  9542. case 'csiso60norwegian1':
  9543. case 'iso646no':
  9544. case 'isoir60':
  9545. case 'no':
  9546. case 'ns45511':
  9547. return 'NS_4551-1';
  9548. case 'csiso61norwegian2':
  9549. case 'iso646no2':
  9550. case 'isoir61':
  9551. case 'no2':
  9552. case 'ns45512':
  9553. return 'NS_4551-2';
  9554. case 'osdebcdicdf3irv':
  9555. return 'OSD_EBCDIC_DF03_IRV';
  9556. case 'osdebcdicdf41':
  9557. return 'OSD_EBCDIC_DF04_1';
  9558. case 'osdebcdicdf415':
  9559. return 'OSD_EBCDIC_DF04_15';
  9560. case 'cspc8danishnorwegian':
  9561. case 'pc8danishnorwegian':
  9562. return 'PC8-Danish-Norwegian';
  9563. case 'cspc8turkish':
  9564. case 'pc8turkish':
  9565. return 'PC8-Turkish';
  9566. case 'csiso16portuguese':
  9567. case 'iso646pt':
  9568. case 'isoir16':
  9569. case 'pt':
  9570. return 'PT';
  9571. case 'csiso84portuguese2':
  9572. case 'iso646pt2':
  9573. case 'isoir84':
  9574. case 'pt2':
  9575. return 'PT2';
  9576. case 'cp154':
  9577. case 'csptcp154':
  9578. case 'cyrillicasian':
  9579. case 'pt154':
  9580. case 'ptcp154':
  9581. return 'PTCP154';
  9582. case 'scsu':
  9583. return 'SCSU';
  9584. case 'csiso10swedish':
  9585. case 'fi':
  9586. case 'iso646fi':
  9587. case 'iso646se':
  9588. case 'isoir10':
  9589. case 'se':
  9590. case 'sen850200b':
  9591. return 'SEN_850200_B';
  9592. case 'csiso11swedishfornames':
  9593. case 'iso646se2':
  9594. case 'isoir11':
  9595. case 'se2':
  9596. case 'sen850200c':
  9597. return 'SEN_850200_C';
  9598. case 'csiso102t617bit':
  9599. case 'isoir102':
  9600. case 't617bit':
  9601. return 'T.61-7bit';
  9602. case 'csiso103t618bit':
  9603. case 'isoir103':
  9604. case 't61':
  9605. case 't618bit':
  9606. return 'T.61-8bit';
  9607. case 'csiso128t101g2':
  9608. case 'isoir128':
  9609. case 't101g2':
  9610. return 'T.101-G2';
  9611. case 'cstscii':
  9612. case 'tscii':
  9613. return 'TSCII';
  9614. case 'csunicode11':
  9615. case 'unicode11':
  9616. return 'UNICODE-1-1';
  9617. case 'csunicode11utf7':
  9618. case 'unicode11utf7':
  9619. return 'UNICODE-1-1-UTF-7';
  9620. case 'csunknown8bit':
  9621. case 'unknown8bit':
  9622. return 'UNKNOWN-8BIT';
  9623. case 'ansix341968':
  9624. case 'ansix341986':
  9625. case 'ascii':
  9626. case 'cp367':
  9627. case 'csascii':
  9628. case 'ibm367':
  9629. case 'iso646irv1991':
  9630. case 'iso646us':
  9631. case 'isoir6':
  9632. case 'us':
  9633. case 'usascii':
  9634. return 'US-ASCII';
  9635. case 'csusdk':
  9636. case 'usdk':
  9637. return 'us-dk';
  9638. case 'utf7':
  9639. return 'UTF-7';
  9640. case 'utf8':
  9641. return 'UTF-8';
  9642. case 'utf16':
  9643. return 'UTF-16';
  9644. case 'utf16be':
  9645. return 'UTF-16BE';
  9646. case 'utf16le':
  9647. return 'UTF-16LE';
  9648. case 'utf32':
  9649. return 'UTF-32';
  9650. case 'utf32be':
  9651. return 'UTF-32BE';
  9652. case 'utf32le':
  9653. return 'UTF-32LE';
  9654. case 'csventurainternational':
  9655. case 'venturainternational':
  9656. return 'Ventura-International';
  9657. case 'csventuramath':
  9658. case 'venturamath':
  9659. return 'Ventura-Math';
  9660. case 'csventuraus':
  9661. case 'venturaus':
  9662. return 'Ventura-US';
  9663. case 'csiso70videotexsupp1':
  9664. case 'isoir70':
  9665. case 'videotexsuppl':
  9666. return 'videotex-suppl';
  9667. case 'csviqr':
  9668. case 'viqr':
  9669. return 'VIQR';
  9670. case 'csviscii':
  9671. case 'viscii':
  9672. return 'VISCII';
  9673. case 'csshiftjis':
  9674. case 'cswindows31j':
  9675. case 'mskanji':
  9676. case 'shiftjis':
  9677. case 'windows31j':
  9678. return 'Windows-31J';
  9679. case 'iso885911':
  9680. case 'tis620':
  9681. return 'windows-874';
  9682. case 'cseuckr':
  9683. case 'csksc56011987':
  9684. case 'euckr':
  9685. case 'isoir149':
  9686. case 'korean':
  9687. case 'ksc5601':
  9688. case 'ksc56011987':
  9689. case 'ksc56011989':
  9690. case 'windows949':
  9691. return 'windows-949';
  9692. case 'windows1250':
  9693. return 'windows-1250';
  9694. case 'windows1251':
  9695. return 'windows-1251';
  9696. case 'cp819':
  9697. case 'csisolatin1':
  9698. case 'ibm819':
  9699. case 'iso88591':
  9700. case 'iso885911987':
  9701. case 'isoir100':
  9702. case 'l1':
  9703. case 'latin1':
  9704. case 'windows1252':
  9705. return 'windows-1252';
  9706. case 'windows1253':
  9707. return 'windows-1253';
  9708. case 'csisolatin5':
  9709. case 'iso88599':
  9710. case 'iso885991989':
  9711. case 'isoir148':
  9712. case 'l5':
  9713. case 'latin5':
  9714. case 'windows1254':
  9715. return 'windows-1254';
  9716. case 'windows1255':
  9717. return 'windows-1255';
  9718. case 'windows1256':
  9719. return 'windows-1256';
  9720. case 'windows1257':
  9721. return 'windows-1257';
  9722. case 'windows1258':
  9723. return 'windows-1258';
  9724. default:
  9725. return $charset;
  9726. }
  9727. }
  9728. public static function get_curl_version()
  9729. {
  9730. if (is_array($curl = curl_version()))
  9731. {
  9732. $curl = $curl['version'];
  9733. }
  9734. elseif (substr($curl, 0, 5) === 'curl/')
  9735. {
  9736. $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
  9737. }
  9738. elseif (substr($curl, 0, 8) === 'libcurl/')
  9739. {
  9740. $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
  9741. }
  9742. else
  9743. {
  9744. $curl = 0;
  9745. }
  9746. return $curl;
  9747. }
  9748. public static function strip_comments($data)
  9749. {
  9750. $output = '';
  9751. while (($start = strpos($data, '<!--')) !== false)
  9752. {
  9753. $output .= substr($data, 0, $start);
  9754. if (($end = strpos($data, '-->', $start)) !== false)
  9755. {
  9756. $data = substr_replace($data, '', 0, $end + 3);
  9757. }
  9758. else
  9759. {
  9760. $data = '';
  9761. }
  9762. }
  9763. return $output . $data;
  9764. }
  9765. public static function parse_date($dt)
  9766. {
  9767. $parser = SimplePie_Parse_Date::get();
  9768. return $parser->parse($dt);
  9769. }
  9770. public static function entities_decode($data)
  9771. {
  9772. $decoder = new SimplePie_Decode_HTML_Entities($data);
  9773. return $decoder->parse();
  9774. }
  9775. public static function uncomment_rfc822($string)
  9776. {
  9777. $string = (string) $string;
  9778. $position = 0;
  9779. $length = strlen($string);
  9780. $depth = 0;
  9781. $output = '';
  9782. while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
  9783. {
  9784. $output .= substr($string, $position, $pos - $position);
  9785. $position = $pos + 1;
  9786. if ($string[$pos - 1] !== '\\')
  9787. {
  9788. $depth++;
  9789. while ($depth && $position < $length)
  9790. {
  9791. $position += strcspn($string, '()', $position);
  9792. if ($string[$position - 1] === '\\')
  9793. {
  9794. $position++;
  9795. continue;
  9796. }
  9797. elseif (isset($string[$position]))
  9798. {
  9799. switch ($string[$position])
  9800. {
  9801. case '(':
  9802. $depth++;
  9803. break;
  9804. case ')':
  9805. $depth--;
  9806. break;
  9807. }
  9808. $position++;
  9809. }
  9810. else
  9811. {
  9812. break;
  9813. }
  9814. }
  9815. }
  9816. else
  9817. {
  9818. $output .= '(';
  9819. }
  9820. }
  9821. $output .= substr($string, $position);
  9822. return $output;
  9823. }
  9824. public static function parse_mime($mime)
  9825. {
  9826. if (($pos = strpos($mime, ';')) === false)
  9827. {
  9828. return trim($mime);
  9829. }
  9830. else
  9831. {
  9832. return trim(substr($mime, 0, $pos));
  9833. }
  9834. }
  9835. public static function atom_03_construct_type($attribs)
  9836. {
  9837. if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
  9838. {
  9839. $mode = SIMPLEPIE_CONSTRUCT_BASE64;
  9840. }
  9841. else
  9842. {
  9843. $mode = SIMPLEPIE_CONSTRUCT_NONE;
  9844. }
  9845. if (isset($attribs['']['type']))
  9846. {
  9847. switch (strtolower(trim($attribs['']['type'])))
  9848. {
  9849. case 'text':
  9850. case 'text/plain':
  9851. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  9852. case 'html':
  9853. case 'text/html':
  9854. return SIMPLEPIE_CONSTRUCT_HTML | $mode;
  9855. case 'xhtml':
  9856. case 'application/xhtml+xml':
  9857. return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
  9858. default:
  9859. return SIMPLEPIE_CONSTRUCT_NONE | $mode;
  9860. }
  9861. }
  9862. else
  9863. {
  9864. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  9865. }
  9866. }
  9867. public static function atom_10_construct_type($attribs)
  9868. {
  9869. if (isset($attribs['']['type']))
  9870. {
  9871. switch (strtolower(trim($attribs['']['type'])))
  9872. {
  9873. case 'text':
  9874. return SIMPLEPIE_CONSTRUCT_TEXT;
  9875. case 'html':
  9876. return SIMPLEPIE_CONSTRUCT_HTML;
  9877. case 'xhtml':
  9878. return SIMPLEPIE_CONSTRUCT_XHTML;
  9879. default:
  9880. return SIMPLEPIE_CONSTRUCT_NONE;
  9881. }
  9882. }
  9883. return SIMPLEPIE_CONSTRUCT_TEXT;
  9884. }
  9885. public static function atom_10_content_construct_type($attribs)
  9886. {
  9887. if (isset($attribs['']['type']))
  9888. {
  9889. $type = strtolower(trim($attribs['']['type']));
  9890. switch ($type)
  9891. {
  9892. case 'text':
  9893. return SIMPLEPIE_CONSTRUCT_TEXT;
  9894. case 'html':
  9895. return SIMPLEPIE_CONSTRUCT_HTML;
  9896. case 'xhtml':
  9897. return SIMPLEPIE_CONSTRUCT_XHTML;
  9898. }
  9899. if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
  9900. {
  9901. return SIMPLEPIE_CONSTRUCT_NONE;
  9902. }
  9903. else
  9904. {
  9905. return SIMPLEPIE_CONSTRUCT_BASE64;
  9906. }
  9907. }
  9908. else
  9909. {
  9910. return SIMPLEPIE_CONSTRUCT_TEXT;
  9911. }
  9912. }
  9913. public static function is_isegment_nz_nc($string)
  9914. {
  9915. 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);
  9916. }
  9917. public static function space_seperated_tokens($string)
  9918. {
  9919. $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
  9920. $string_length = strlen($string);
  9921. $position = strspn($string, $space_characters);
  9922. $tokens = array();
  9923. while ($position < $string_length)
  9924. {
  9925. $len = strcspn($string, $space_characters, $position);
  9926. $tokens[] = substr($string, $position, $len);
  9927. $position += $len;
  9928. $position += strspn($string, $space_characters, $position);
  9929. }
  9930. return $tokens;
  9931. }
  9932. public static function codepoint_to_utf8($codepoint)
  9933. {
  9934. $codepoint = (int) $codepoint;
  9935. if ($codepoint < 0)
  9936. {
  9937. return false;
  9938. }
  9939. else if ($codepoint <= 0x7f)
  9940. {
  9941. return chr($codepoint);
  9942. }
  9943. else if ($codepoint <= 0x7ff)
  9944. {
  9945. return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
  9946. }
  9947. else if ($codepoint <= 0xffff)
  9948. {
  9949. return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  9950. }
  9951. else if ($codepoint <= 0x10ffff)
  9952. {
  9953. return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  9954. }
  9955. else
  9956. {
  9957. // U+FFFD REPLACEMENT CHARACTER
  9958. return "\xEF\xBF\xBD";
  9959. }
  9960. }
  9961. public static function parse_str($str)
  9962. {
  9963. $return = array();
  9964. $str = explode('&', $str);
  9965. foreach ($str as $section)
  9966. {
  9967. if (strpos($section, '=') !== false)
  9968. {
  9969. list($name, $value) = explode('=', $section, 2);
  9970. $return[urldecode($name)][] = urldecode($value);
  9971. }
  9972. else
  9973. {
  9974. $return[urldecode($section)][] = null;
  9975. }
  9976. }
  9977. return $return;
  9978. }
  9979. public static function xml_encoding($data, $registry)
  9980. {
  9981. // UTF-32 Big Endian BOM
  9982. if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
  9983. {
  9984. $encoding[] = 'UTF-32BE';
  9985. }
  9986. // UTF-32 Little Endian BOM
  9987. elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
  9988. {
  9989. $encoding[] = 'UTF-32LE';
  9990. }
  9991. // UTF-16 Big Endian BOM
  9992. elseif (substr($data, 0, 2) === "\xFE\xFF")
  9993. {
  9994. $encoding[] = 'UTF-16BE';
  9995. }
  9996. // UTF-16 Little Endian BOM
  9997. elseif (substr($data, 0, 2) === "\xFF\xFE")
  9998. {
  9999. $encoding[] = 'UTF-16LE';
  10000. }
  10001. // UTF-8 BOM
  10002. elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
  10003. {
  10004. $encoding[] = 'UTF-8';
  10005. }
  10006. // UTF-32 Big Endian Without BOM
  10007. 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")
  10008. {
  10009. if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
  10010. {
  10011. $parser = $registry->create('XML_Declaration_Parser', array(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8')));
  10012. if ($parser->parse())
  10013. {
  10014. $encoding[] = $parser->encoding;
  10015. }
  10016. }
  10017. $encoding[] = 'UTF-32BE';
  10018. }
  10019. // UTF-32 Little Endian Without BOM
  10020. 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")
  10021. {
  10022. if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
  10023. {
  10024. $parser = $registry->create('XML_Declaration_Parser', array(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8')));
  10025. if ($parser->parse())
  10026. {
  10027. $encoding[] = $parser->encoding;
  10028. }
  10029. }
  10030. $encoding[] = 'UTF-32LE';
  10031. }
  10032. // UTF-16 Big Endian Without BOM
  10033. elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
  10034. {
  10035. if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
  10036. {
  10037. $parser = $registry->create('XML_Declaration_Parser', array(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8')));
  10038. if ($parser->parse())
  10039. {
  10040. $encoding[] = $parser->encoding;
  10041. }
  10042. }
  10043. $encoding[] = 'UTF-16BE';
  10044. }
  10045. // UTF-16 Little Endian Without BOM
  10046. elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
  10047. {
  10048. if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
  10049. {
  10050. $parser = $registry->create('XML_Declaration_Parser', array(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8')));
  10051. if ($parser->parse())
  10052. {
  10053. $encoding[] = $parser->encoding;
  10054. }
  10055. }
  10056. $encoding[] = 'UTF-16LE';
  10057. }
  10058. // US-ASCII (or superset)
  10059. elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
  10060. {
  10061. if ($pos = strpos($data, "\x3F\x3E"))
  10062. {
  10063. $parser = $registry->create('XML_Declaration_Parser', array(substr($data, 5, $pos - 5)));
  10064. if ($parser->parse())
  10065. {
  10066. $encoding[] = $parser->encoding;
  10067. }
  10068. }
  10069. $encoding[] = 'UTF-8';
  10070. }
  10071. // Fallback to UTF-8
  10072. else
  10073. {
  10074. $encoding[] = 'UTF-8';
  10075. }
  10076. return $encoding;
  10077. }
  10078. public static function output_javascript()
  10079. {
  10080. if (function_exists('ob_gzhandler'))
  10081. {
  10082. ob_start('ob_gzhandler');
  10083. }
  10084. header('Content-type: text/javascript; charset: UTF-8');
  10085. header('Cache-Control: must-revalidate');
  10086. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  10087. ?>
  10088. function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
  10089. if (placeholder != '') {
  10090. 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>');
  10091. }
  10092. else {
  10093. 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>');
  10094. }
  10095. }
  10096. function embed_flash(bgcolor, width, height, link, loop, type) {
  10097. 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>');
  10098. }
  10099. function embed_flv(width, height, link, placeholder, loop, player) {
  10100. 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>');
  10101. }
  10102. function embed_wmedia(width, height, link) {
  10103. document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
  10104. }
  10105. <?php
  10106. }
  10107. public static function get_build()
  10108. {
  10109. $root = dirname(dirname(__FILE__));
  10110. if (file_exists($root . '/.git/index'))
  10111. {
  10112. return filemtime($root . '/.git/index');
  10113. }
  10114. elseif (file_exists($root . '/SimplePie'))
  10115. {
  10116. $time = 0;
  10117. foreach (glob($root . '/SimplePie/*.php') as $file)
  10118. {
  10119. if (($mtime = filemtime($file)) > $time)
  10120. {
  10121. $time = $mtime;
  10122. }
  10123. }
  10124. return $time;
  10125. }
  10126. elseif (file_exists(dirname(__FILE__) . '/Core.php'))
  10127. {
  10128. return filemtime(dirname(__FILE__) . '/Core.php');
  10129. }
  10130. else
  10131. {
  10132. return filemtime(__FILE__);
  10133. }
  10134. }
  10135. public static function debug(&$sp)
  10136. {
  10137. $info = 'SimplePie ' . SIMPLEPIE_VERSION . ' Build ' . SIMPLEPIE_BUILD . "\n";
  10138. $info .= 'PHP ' . PHP_VERSION . "\n";
  10139. if ($sp->error() !== null)
  10140. {
  10141. $info .= 'Error occurred: ' . $sp->error() . "\n";
  10142. }
  10143. else
  10144. {
  10145. $info .= "No error found.\n";
  10146. }
  10147. $info .= "Extensions:\n";
  10148. $extensions = array('pcre', 'curl', 'zlib', 'mbstring', 'iconv', 'xmlreader', 'xml');
  10149. foreach ($extensions as $ext)
  10150. {
  10151. if (extension_loaded($ext))
  10152. {
  10153. $info .= " $ext loaded\n";
  10154. switch ($ext)
  10155. {
  10156. case 'pcre':
  10157. $info .= ' Version ' . PCRE_VERSION . "\n";
  10158. break;
  10159. case 'curl':
  10160. $version = curl_version();
  10161. $info .= ' Version ' . $version['version'] . "\n";
  10162. break;
  10163. case 'mbstring':
  10164. $info .= ' Overloading: ' . mb_get_info('func_overload') . "\n";
  10165. break;
  10166. case 'iconv':
  10167. $info .= ' Version ' . ICONV_VERSION . "\n";
  10168. break;
  10169. case 'xml':
  10170. $info .= ' Version ' . LIBXML_DOTTED_VERSION . "\n";
  10171. break;
  10172. }
  10173. }
  10174. else
  10175. {
  10176. $info .= " $ext not loaded\n";
  10177. }
  10178. }
  10179. return $info;
  10180. }
  10181. public static function silence_errors($num, $str)
  10182. {
  10183. // No-op
  10184. }
  10185. }
  10186. class SimplePie_Net_IPv6
  10187. {
  10188. public static function uncompress($ip)
  10189. {
  10190. $c1 = -1;
  10191. $c2 = -1;
  10192. if (substr_count($ip, '::') === 1)
  10193. {
  10194. list($ip1, $ip2) = explode('::', $ip);
  10195. if ($ip1 === '')
  10196. {
  10197. $c1 = -1;
  10198. }
  10199. else
  10200. {
  10201. $c1 = substr_count($ip1, ':');
  10202. }
  10203. if ($ip2 === '')
  10204. {
  10205. $c2 = -1;
  10206. }
  10207. else
  10208. {
  10209. $c2 = substr_count($ip2, ':');
  10210. }
  10211. if (strpos($ip2, '.') !== false)
  10212. {
  10213. $c2++;
  10214. }
  10215. // ::
  10216. if ($c1 === -1 && $c2 === -1)
  10217. {
  10218. $ip = '0:0:0:0:0:0:0:0';
  10219. }
  10220. // ::xxx
  10221. else if ($c1 === -1)
  10222. {
  10223. $fill = str_repeat('0:', 7 - $c2);
  10224. $ip = str_replace('::', $fill, $ip);
  10225. }
  10226. // xxx::
  10227. else if ($c2 === -1)
  10228. {
  10229. $fill = str_repeat(':0', 7 - $c1);
  10230. $ip = str_replace('::', $fill, $ip);
  10231. }
  10232. // xxx::xxx
  10233. else
  10234. {
  10235. $fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
  10236. $ip = str_replace('::', $fill, $ip);
  10237. }
  10238. }
  10239. return $ip;
  10240. }
  10241. public static function compress($ip)
  10242. {
  10243. // Prepare the IP to be compressed
  10244. $ip = self::uncompress($ip);
  10245. $ip_parts = self::split_v6_v4($ip);
  10246. // Replace all leading zeros
  10247. $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
  10248. // Find bunches of zeros
  10249. if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE))
  10250. {
  10251. $max = 0;
  10252. $pos = null;
  10253. foreach ($matches[0] as $match)
  10254. {
  10255. if (strlen($match[0]) > $max)
  10256. {
  10257. $max = strlen($match[0]);
  10258. $pos = $match[1];
  10259. }
  10260. }
  10261. $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
  10262. }
  10263. if ($ip_parts[1] !== '')
  10264. {
  10265. return implode(':', $ip_parts);
  10266. }
  10267. else
  10268. {
  10269. return $ip_parts[0];
  10270. }
  10271. }
  10272. private static function split_v6_v4($ip)
  10273. {
  10274. if (strpos($ip, '.') !== false)
  10275. {
  10276. $pos = strrpos($ip, ':');
  10277. $ipv6_part = substr($ip, 0, $pos);
  10278. $ipv4_part = substr($ip, $pos + 1);
  10279. return array($ipv6_part, $ipv4_part);
  10280. }
  10281. else
  10282. {
  10283. return array($ip, '');
  10284. }
  10285. }
  10286. public static function check_ipv6($ip)
  10287. {
  10288. $ip = self::uncompress($ip);
  10289. list($ipv6, $ipv4) = self::split_v6_v4($ip);
  10290. $ipv6 = explode(':', $ipv6);
  10291. $ipv4 = explode('.', $ipv4);
  10292. if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4)
  10293. {
  10294. foreach ($ipv6 as $ipv6_part)
  10295. {
  10296. // The section can't be empty
  10297. if ($ipv6_part === '')
  10298. return false;
  10299. // Nor can it be over four characters
  10300. if (strlen($ipv6_part) > 4)
  10301. return false;
  10302. // Remove leading zeros (this is safe because of the above)
  10303. $ipv6_part = ltrim($ipv6_part, '0');
  10304. if ($ipv6_part === '')
  10305. $ipv6_part = '0';
  10306. // Check the value is valid
  10307. $value = hexdec($ipv6_part);
  10308. if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF)
  10309. return false;
  10310. }
  10311. if (count($ipv4) === 4)
  10312. {
  10313. foreach ($ipv4 as $ipv4_part)
  10314. {
  10315. $value = (int) $ipv4_part;
  10316. if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF)
  10317. return false;
  10318. }
  10319. }
  10320. return true;
  10321. }
  10322. else
  10323. {
  10324. return false;
  10325. }
  10326. }
  10327. public static function checkIPv6($ip)
  10328. {
  10329. return self::check_ipv6($ip);
  10330. }
  10331. }
  10332. class SimplePie_Parse_Date
  10333. {
  10334. var $date;
  10335. var $day = array(
  10336. // English
  10337. 'mon' => 1,
  10338. 'monday' => 1,
  10339. 'tue' => 2,
  10340. 'tuesday' => 2,
  10341. 'wed' => 3,
  10342. 'wednesday' => 3,
  10343. 'thu' => 4,
  10344. 'thursday' => 4,
  10345. 'fri' => 5,
  10346. 'friday' => 5,
  10347. 'sat' => 6,
  10348. 'saturday' => 6,
  10349. 'sun' => 7,
  10350. 'sunday' => 7,
  10351. // Dutch
  10352. 'maandag' => 1,
  10353. 'dinsdag' => 2,
  10354. 'woensdag' => 3,
  10355. 'donderdag' => 4,
  10356. 'vrijdag' => 5,
  10357. 'zaterdag' => 6,
  10358. 'zondag' => 7,
  10359. // French
  10360. 'lundi' => 1,
  10361. 'mardi' => 2,
  10362. 'mercredi' => 3,
  10363. 'jeudi' => 4,
  10364. 'vendredi' => 5,
  10365. 'samedi' => 6,
  10366. 'dimanche' => 7,
  10367. // German
  10368. 'montag' => 1,
  10369. 'dienstag' => 2,
  10370. 'mittwoch' => 3,
  10371. 'donnerstag' => 4,
  10372. 'freitag' => 5,
  10373. 'samstag' => 6,
  10374. 'sonnabend' => 6,
  10375. 'sonntag' => 7,
  10376. // Italian
  10377. 'lunedì' => 1,
  10378. 'martedì' => 2,
  10379. 'mercoledì' => 3,
  10380. 'giovedì' => 4,
  10381. 'venerdì' => 5,
  10382. 'sabato' => 6,
  10383. 'domenica' => 7,
  10384. // Spanish
  10385. 'lunes' => 1,
  10386. 'martes' => 2,
  10387. 'miércoles' => 3,
  10388. 'jueves' => 4,
  10389. 'viernes' => 5,
  10390. 'sábado' => 6,
  10391. 'domingo' => 7,
  10392. // Finnish
  10393. 'maanantai' => 1,
  10394. 'tiistai' => 2,
  10395. 'keskiviikko' => 3,
  10396. 'torstai' => 4,
  10397. 'perjantai' => 5,
  10398. 'lauantai' => 6,
  10399. 'sunnuntai' => 7,
  10400. // Hungarian
  10401. 'hétfő' => 1,
  10402. 'kedd' => 2,
  10403. 'szerda' => 3,
  10404. 'csütörtok' => 4,
  10405. 'péntek' => 5,
  10406. 'szombat' => 6,
  10407. 'vasárnap' => 7,
  10408. // Greek
  10409. 'Δευ' => 1,
  10410. 'Τρι' => 2,
  10411. 'Τετ' => 3,
  10412. 'Πεμ' => 4,
  10413. 'Παρ' => 5,
  10414. 'Σαβ' => 6,
  10415. 'Κυρ' => 7,
  10416. );
  10417. var $month = array(
  10418. // English
  10419. 'jan' => 1,
  10420. 'january' => 1,
  10421. 'feb' => 2,
  10422. 'february' => 2,
  10423. 'mar' => 3,
  10424. 'march' => 3,
  10425. 'apr' => 4,
  10426. 'april' => 4,
  10427. 'may' => 5,
  10428. // No long form of May
  10429. 'jun' => 6,
  10430. 'june' => 6,
  10431. 'jul' => 7,
  10432. 'july' => 7,
  10433. 'aug' => 8,
  10434. 'august' => 8,
  10435. 'sep' => 9,
  10436. 'september' => 8,
  10437. 'oct' => 10,
  10438. 'october' => 10,
  10439. 'nov' => 11,
  10440. 'november' => 11,
  10441. 'dec' => 12,
  10442. 'december' => 12,
  10443. // Dutch
  10444. 'januari' => 1,
  10445. 'februari' => 2,
  10446. 'maart' => 3,
  10447. 'april' => 4,
  10448. 'mei' => 5,
  10449. 'juni' => 6,
  10450. 'juli' => 7,
  10451. 'augustus' => 8,
  10452. 'september' => 9,
  10453. 'oktober' => 10,
  10454. 'november' => 11,
  10455. 'december' => 12,
  10456. // French
  10457. 'janvier' => 1,
  10458. 'février' => 2,
  10459. 'mars' => 3,
  10460. 'avril' => 4,
  10461. 'mai' => 5,
  10462. 'juin' => 6,
  10463. 'juillet' => 7,
  10464. 'août' => 8,
  10465. 'septembre' => 9,
  10466. 'octobre' => 10,
  10467. 'novembre' => 11,
  10468. 'décembre' => 12,
  10469. // German
  10470. 'januar' => 1,
  10471. 'februar' => 2,
  10472. 'märz' => 3,
  10473. 'april' => 4,
  10474. 'mai' => 5,
  10475. 'juni' => 6,
  10476. 'juli' => 7,
  10477. 'august' => 8,
  10478. 'september' => 9,
  10479. 'oktober' => 10,
  10480. 'november' => 11,
  10481. 'dezember' => 12,
  10482. // Italian
  10483. 'gennaio' => 1,
  10484. 'febbraio' => 2,
  10485. 'marzo' => 3,
  10486. 'aprile' => 4,
  10487. 'maggio' => 5,
  10488. 'giugno' => 6,
  10489. 'luglio' => 7,
  10490. 'agosto' => 8,
  10491. 'settembre' => 9,
  10492. 'ottobre' => 10,
  10493. 'novembre' => 11,
  10494. 'dicembre' => 12,
  10495. // Spanish
  10496. 'enero' => 1,
  10497. 'febrero' => 2,
  10498. 'marzo' => 3,
  10499. 'abril' => 4,
  10500. 'mayo' => 5,
  10501. 'junio' => 6,
  10502. 'julio' => 7,
  10503. 'agosto' => 8,
  10504. 'septiembre' => 9,
  10505. 'setiembre' => 9,
  10506. 'octubre' => 10,
  10507. 'noviembre' => 11,
  10508. 'diciembre' => 12,
  10509. // Finnish
  10510. 'tammikuu' => 1,
  10511. 'helmikuu' => 2,
  10512. 'maaliskuu' => 3,
  10513. 'huhtikuu' => 4,
  10514. 'toukokuu' => 5,
  10515. 'kesäkuu' => 6,
  10516. 'heinäkuu' => 7,
  10517. 'elokuu' => 8,
  10518. 'suuskuu' => 9,
  10519. 'lokakuu' => 10,
  10520. 'marras' => 11,
  10521. 'joulukuu' => 12,
  10522. // Hungarian
  10523. 'január' => 1,
  10524. 'február' => 2,
  10525. 'március' => 3,
  10526. 'április' => 4,
  10527. 'május' => 5,
  10528. 'június' => 6,
  10529. 'július' => 7,
  10530. 'augusztus' => 8,
  10531. 'szeptember' => 9,
  10532. 'október' => 10,
  10533. 'november' => 11,
  10534. 'december' => 12,
  10535. // Greek
  10536. 'Ιαν' => 1,
  10537. 'Φεβ' => 2,
  10538. 'Μάώ' => 3,
  10539. 'Μαώ' => 3,
  10540. 'Απρ' => 4,
  10541. 'Μάι' => 5,
  10542. 'Μαϊ' => 5,
  10543. 'Μαι' => 5,
  10544. 'Ιούν' => 6,
  10545. 'Ιον' => 6,
  10546. 'Ιούλ' => 7,
  10547. 'Ιολ' => 7,
  10548. 'Αύγ' => 8,
  10549. 'Αυγ' => 8,
  10550. 'Σεπ' => 9,
  10551. 'Οκτ' => 10,
  10552. 'Νοέ' => 11,
  10553. 'Δεκ' => 12,
  10554. );
  10555. var $timezone = array(
  10556. 'ACDT' => 37800,
  10557. 'ACIT' => 28800,
  10558. 'ACST' => 34200,
  10559. 'ACT' => -18000,
  10560. 'ACWDT' => 35100,
  10561. 'ACWST' => 31500,
  10562. 'AEDT' => 39600,
  10563. 'AEST' => 36000,
  10564. 'AFT' => 16200,
  10565. 'AKDT' => -28800,
  10566. 'AKST' => -32400,
  10567. 'AMDT' => 18000,
  10568. 'AMT' => -14400,
  10569. 'ANAST' => 46800,
  10570. 'ANAT' => 43200,
  10571. 'ART' => -10800,
  10572. 'AZOST' => -3600,
  10573. 'AZST' => 18000,
  10574. 'AZT' => 14400,
  10575. 'BIOT' => 21600,
  10576. 'BIT' => -43200,
  10577. 'BOT' => -14400,
  10578. 'BRST' => -7200,
  10579. 'BRT' => -10800,
  10580. 'BST' => 3600,
  10581. 'BTT' => 21600,
  10582. 'CAST' => 18000,
  10583. 'CAT' => 7200,
  10584. 'CCT' => 23400,
  10585. 'CDT' => -18000,
  10586. 'CEDT' => 7200,
  10587. 'CET' => 3600,
  10588. 'CGST' => -7200,
  10589. 'CGT' => -10800,
  10590. 'CHADT' => 49500,
  10591. 'CHAST' => 45900,
  10592. 'CIST' => -28800,
  10593. 'CKT' => -36000,
  10594. 'CLDT' => -10800,
  10595. 'CLST' => -14400,
  10596. 'COT' => -18000,
  10597. 'CST' => -21600,
  10598. 'CVT' => -3600,
  10599. 'CXT' => 25200,
  10600. 'DAVT' => 25200,
  10601. 'DTAT' => 36000,
  10602. 'EADT' => -18000,
  10603. 'EAST' => -21600,
  10604. 'EAT' => 10800,
  10605. 'ECT' => -18000,
  10606. 'EDT' => -14400,
  10607. 'EEST' => 10800,
  10608. 'EET' => 7200,
  10609. 'EGT' => -3600,
  10610. 'EKST' => 21600,
  10611. 'EST' => -18000,
  10612. 'FJT' => 43200,
  10613. 'FKDT' => -10800,
  10614. 'FKST' => -14400,
  10615. 'FNT' => -7200,
  10616. 'GALT' => -21600,
  10617. 'GEDT' => 14400,
  10618. 'GEST' => 10800,
  10619. 'GFT' => -10800,
  10620. 'GILT' => 43200,
  10621. 'GIT' => -32400,
  10622. 'GST' => 14400,
  10623. 'GST' => -7200,
  10624. 'GYT' => -14400,
  10625. 'HAA' => -10800,
  10626. 'HAC' => -18000,
  10627. 'HADT' => -32400,
  10628. 'HAE' => -14400,
  10629. 'HAP' => -25200,
  10630. 'HAR' => -21600,
  10631. 'HAST' => -36000,
  10632. 'HAT' => -9000,
  10633. 'HAY' => -28800,
  10634. 'HKST' => 28800,
  10635. 'HMT' => 18000,
  10636. 'HNA' => -14400,
  10637. 'HNC' => -21600,
  10638. 'HNE' => -18000,
  10639. 'HNP' => -28800,
  10640. 'HNR' => -25200,
  10641. 'HNT' => -12600,
  10642. 'HNY' => -32400,
  10643. 'IRDT' => 16200,
  10644. 'IRKST' => 32400,
  10645. 'IRKT' => 28800,
  10646. 'IRST' => 12600,
  10647. 'JFDT' => -10800,
  10648. 'JFST' => -14400,
  10649. 'JST' => 32400,
  10650. 'KGST' => 21600,
  10651. 'KGT' => 18000,
  10652. 'KOST' => 39600,
  10653. 'KOVST' => 28800,
  10654. 'KOVT' => 25200,
  10655. 'KRAST' => 28800,
  10656. 'KRAT' => 25200,
  10657. 'KST' => 32400,
  10658. 'LHDT' => 39600,
  10659. 'LHST' => 37800,
  10660. 'LINT' => 50400,
  10661. 'LKT' => 21600,
  10662. 'MAGST' => 43200,
  10663. 'MAGT' => 39600,
  10664. 'MAWT' => 21600,
  10665. 'MDT' => -21600,
  10666. 'MESZ' => 7200,
  10667. 'MEZ' => 3600,
  10668. 'MHT' => 43200,
  10669. 'MIT' => -34200,
  10670. 'MNST' => 32400,
  10671. 'MSDT' => 14400,
  10672. 'MSST' => 10800,
  10673. 'MST' => -25200,
  10674. 'MUT' => 14400,
  10675. 'MVT' => 18000,
  10676. 'MYT' => 28800,
  10677. 'NCT' => 39600,
  10678. 'NDT' => -9000,
  10679. 'NFT' => 41400,
  10680. 'NMIT' => 36000,
  10681. 'NOVST' => 25200,
  10682. 'NOVT' => 21600,
  10683. 'NPT' => 20700,
  10684. 'NRT' => 43200,
  10685. 'NST' => -12600,
  10686. 'NUT' => -39600,
  10687. 'NZDT' => 46800,
  10688. 'NZST' => 43200,
  10689. 'OMSST' => 25200,
  10690. 'OMST' => 21600,
  10691. 'PDT' => -25200,
  10692. 'PET' => -18000,
  10693. 'PETST' => 46800,
  10694. 'PETT' => 43200,
  10695. 'PGT' => 36000,
  10696. 'PHOT' => 46800,
  10697. 'PHT' => 28800,
  10698. 'PKT' => 18000,
  10699. 'PMDT' => -7200,
  10700. 'PMST' => -10800,
  10701. 'PONT' => 39600,
  10702. 'PST' => -28800,
  10703. 'PWT' => 32400,
  10704. 'PYST' => -10800,
  10705. 'PYT' => -14400,
  10706. 'RET' => 14400,
  10707. 'ROTT' => -10800,
  10708. 'SAMST' => 18000,
  10709. 'SAMT' => 14400,
  10710. 'SAST' => 7200,
  10711. 'SBT' => 39600,
  10712. 'SCDT' => 46800,
  10713. 'SCST' => 43200,
  10714. 'SCT' => 14400,
  10715. 'SEST' => 3600,
  10716. 'SGT' => 28800,
  10717. 'SIT' => 28800,
  10718. 'SRT' => -10800,
  10719. 'SST' => -39600,
  10720. 'SYST' => 10800,
  10721. 'SYT' => 7200,
  10722. 'TFT' => 18000,
  10723. 'THAT' => -36000,
  10724. 'TJT' => 18000,
  10725. 'TKT' => -36000,
  10726. 'TMT' => 18000,
  10727. 'TOT' => 46800,
  10728. 'TPT' => 32400,
  10729. 'TRUT' => 36000,
  10730. 'TVT' => 43200,
  10731. 'TWT' => 28800,
  10732. 'UYST' => -7200,
  10733. 'UYT' => -10800,
  10734. 'UZT' => 18000,
  10735. 'VET' => -14400,
  10736. 'VLAST' => 39600,
  10737. 'VLAT' => 36000,
  10738. 'VOST' => 21600,
  10739. 'VUT' => 39600,
  10740. 'WAST' => 7200,
  10741. 'WAT' => 3600,
  10742. 'WDT' => 32400,
  10743. 'WEST' => 3600,
  10744. 'WFT' => 43200,
  10745. 'WIB' => 25200,
  10746. 'WIT' => 32400,
  10747. 'WITA' => 28800,
  10748. 'WKST' => 18000,
  10749. 'WST' => 28800,
  10750. 'YAKST' => 36000,
  10751. 'YAKT' => 32400,
  10752. 'YAPT' => 36000,
  10753. 'YEKST' => 21600,
  10754. 'YEKT' => 18000,
  10755. );
  10756. var $day_pcre;
  10757. var $month_pcre;
  10758. var $built_in = array();
  10759. var $user = array();
  10760. public function __construct()
  10761. {
  10762. $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
  10763. $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
  10764. static $cache;
  10765. if (!isset($cache[get_class($this)]))
  10766. {
  10767. $all_methods = get_class_methods($this);
  10768. foreach ($all_methods as $method)
  10769. {
  10770. if (strtolower(substr($method, 0, 5)) === 'date_')
  10771. {
  10772. $cache[get_class($this)][] = $method;
  10773. }
  10774. }
  10775. }
  10776. foreach ($cache[get_class($this)] as $method)
  10777. {
  10778. $this->built_in[] = $method;
  10779. }
  10780. }
  10781. public static function get()
  10782. {
  10783. static $object;
  10784. if (!$object)
  10785. {
  10786. $object = new SimplePie_Parse_Date;
  10787. }
  10788. return $object;
  10789. }
  10790. public function parse($date)
  10791. {
  10792. foreach ($this->user as $method)
  10793. {
  10794. if (($returned = call_user_func($method, $date)) !== false)
  10795. {
  10796. return $returned;
  10797. }
  10798. }
  10799. foreach ($this->built_in as $method)
  10800. {
  10801. if (($returned = call_user_func(array($this, $method), $date)) !== false)
  10802. {
  10803. return $returned;
  10804. }
  10805. }
  10806. return false;
  10807. }
  10808. public function add_callback($callback)
  10809. {
  10810. if (is_callable($callback))
  10811. {
  10812. $this->user[] = $callback;
  10813. }
  10814. else
  10815. {
  10816. trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
  10817. }
  10818. }
  10819. public function date_w3cdtf($date)
  10820. {
  10821. static $pcre;
  10822. if (!$pcre)
  10823. {
  10824. $year = '([0-9]{4})';
  10825. $month = $day = $hour = $minute = $second = '([0-9]{2})';
  10826. $decimal = '([0-9]*)';
  10827. $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
  10828. $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
  10829. }
  10830. if (preg_match($pcre, $date, $match))
  10831. {
  10832. /*
  10833. Capturing subpatterns:
  10834. 1: Year
  10835. 2: Month
  10836. 3: Day
  10837. 4: Hour
  10838. 5: Minute
  10839. 6: Second
  10840. 7: Decimal fraction of a second
  10841. 8: Zulu
  10842. 9: Timezone ±
  10843. 10: Timezone hours
  10844. 11: Timezone minutes
  10845. */
  10846. // Fill in empty matches
  10847. for ($i = count($match); $i <= 3; $i++)
  10848. {
  10849. $match[$i] = '1';
  10850. }
  10851. for ($i = count($match); $i <= 7; $i++)
  10852. {
  10853. $match[$i] = '0';
  10854. }
  10855. // Numeric timezone
  10856. if (isset($match[9]) && $match[9] !== '')
  10857. {
  10858. $timezone = $match[10] * 3600;
  10859. $timezone += $match[11] * 60;
  10860. if ($match[9] === '-')
  10861. {
  10862. $timezone = 0 - $timezone;
  10863. }
  10864. }
  10865. else
  10866. {
  10867. $timezone = 0;
  10868. }
  10869. // Convert the number of seconds to an integer, taking decimals into account
  10870. $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
  10871. return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
  10872. }
  10873. else
  10874. {
  10875. return false;
  10876. }
  10877. }
  10878. public function remove_rfc2822_comments($string)
  10879. {
  10880. $string = (string) $string;
  10881. $position = 0;
  10882. $length = strlen($string);
  10883. $depth = 0;
  10884. $output = '';
  10885. while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
  10886. {
  10887. $output .= substr($string, $position, $pos - $position);
  10888. $position = $pos + 1;
  10889. if ($string[$pos - 1] !== '\\')
  10890. {
  10891. $depth++;
  10892. while ($depth && $position < $length)
  10893. {
  10894. $position += strcspn($string, '()', $position);
  10895. if ($string[$position - 1] === '\\')
  10896. {
  10897. $position++;
  10898. continue;
  10899. }
  10900. elseif (isset($string[$position]))
  10901. {
  10902. switch ($string[$position])
  10903. {
  10904. case '(':
  10905. $depth++;
  10906. break;
  10907. case ')':
  10908. $depth--;
  10909. break;
  10910. }
  10911. $position++;
  10912. }
  10913. else
  10914. {
  10915. break;
  10916. }
  10917. }
  10918. }
  10919. else
  10920. {
  10921. $output .= '(';
  10922. }
  10923. }
  10924. $output .= substr($string, $position);
  10925. return $output;
  10926. }
  10927. public function date_rfc2822($date)
  10928. {
  10929. static $pcre;
  10930. if (!$pcre)
  10931. {
  10932. $wsp = '[\x09\x20]';
  10933. $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
  10934. $optional_fws = $fws . '?';
  10935. $day_name = $this->day_pcre;
  10936. $month = $this->month_pcre;
  10937. $day = '([0-9]{1,2})';
  10938. $hour = $minute = $second = '([0-9]{2})';
  10939. $year = '([0-9]{2,4})';
  10940. $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
  10941. $character_zone = '([A-Z]{1,5})';
  10942. $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
  10943. $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
  10944. }
  10945. if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
  10946. {
  10947. /*
  10948. Capturing subpatterns:
  10949. 1: Day name
  10950. 2: Day
  10951. 3: Month
  10952. 4: Year
  10953. 5: Hour
  10954. 6: Minute
  10955. 7: Second
  10956. 8: Timezone ±
  10957. 9: Timezone hours
  10958. 10: Timezone minutes
  10959. 11: Alphabetic timezone
  10960. */
  10961. // Find the month number
  10962. $month = $this->month[strtolower($match[3])];
  10963. // Numeric timezone
  10964. if ($match[8] !== '')
  10965. {
  10966. $timezone = $match[9] * 3600;
  10967. $timezone += $match[10] * 60;
  10968. if ($match[8] === '-')
  10969. {
  10970. $timezone = 0 - $timezone;
  10971. }
  10972. }
  10973. // Character timezone
  10974. elseif (isset($this->timezone[strtoupper($match[11])]))
  10975. {
  10976. $timezone = $this->timezone[strtoupper($match[11])];
  10977. }
  10978. // Assume everything else to be -0000
  10979. else
  10980. {
  10981. $timezone = 0;
  10982. }
  10983. // Deal with 2/3 digit years
  10984. if ($match[4] < 50)
  10985. {
  10986. $match[4] += 2000;
  10987. }
  10988. elseif ($match[4] < 1000)
  10989. {
  10990. $match[4] += 1900;
  10991. }
  10992. // Second is optional, if it is empty set it to zero
  10993. if ($match[7] !== '')
  10994. {
  10995. $second = $match[7];
  10996. }
  10997. else
  10998. {
  10999. $second = 0;
  11000. }
  11001. return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
  11002. }
  11003. else
  11004. {
  11005. return false;
  11006. }
  11007. }
  11008. public function date_rfc850($date)
  11009. {
  11010. static $pcre;
  11011. if (!$pcre)
  11012. {
  11013. $space = '[\x09\x20]+';
  11014. $day_name = $this->day_pcre;
  11015. $month = $this->month_pcre;
  11016. $day = '([0-9]{1,2})';
  11017. $year = $hour = $minute = $second = '([0-9]{2})';
  11018. $zone = '([A-Z]{1,5})';
  11019. $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
  11020. }
  11021. if (preg_match($pcre, $date, $match))
  11022. {
  11023. /*
  11024. Capturing subpatterns:
  11025. 1: Day name
  11026. 2: Day
  11027. 3: Month
  11028. 4: Year
  11029. 5: Hour
  11030. 6: Minute
  11031. 7: Second
  11032. 8: Timezone
  11033. */
  11034. // Month
  11035. $month = $this->month[strtolower($match[3])];
  11036. // Character timezone
  11037. if (isset($this->timezone[strtoupper($match[8])]))
  11038. {
  11039. $timezone = $this->timezone[strtoupper($match[8])];
  11040. }
  11041. // Assume everything else to be -0000
  11042. else
  11043. {
  11044. $timezone = 0;
  11045. }
  11046. // Deal with 2 digit year
  11047. if ($match[4] < 50)
  11048. {
  11049. $match[4] += 2000;
  11050. }
  11051. else
  11052. {
  11053. $match[4] += 1900;
  11054. }
  11055. return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
  11056. }
  11057. else
  11058. {
  11059. return false;
  11060. }
  11061. }
  11062. public function date_asctime($date)
  11063. {
  11064. static $pcre;
  11065. if (!$pcre)
  11066. {
  11067. $space = '[\x09\x20]+';
  11068. $wday_name = $this->day_pcre;
  11069. $mon_name = $this->month_pcre;
  11070. $day = '([0-9]{1,2})';
  11071. $hour = $sec = $min = '([0-9]{2})';
  11072. $year = '([0-9]{4})';
  11073. $terminator = '\x0A?\x00?';
  11074. $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
  11075. }
  11076. if (preg_match($pcre, $date, $match))
  11077. {
  11078. /*
  11079. Capturing subpatterns:
  11080. 1: Day name
  11081. 2: Month
  11082. 3: Day
  11083. 4: Hour
  11084. 5: Minute
  11085. 6: Second
  11086. 7: Year
  11087. */
  11088. $month = $this->month[strtolower($match[2])];
  11089. return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
  11090. }
  11091. else
  11092. {
  11093. return false;
  11094. }
  11095. }
  11096. public function date_strtotime($date)
  11097. {
  11098. $strtotime = strtotime($date);
  11099. if ($strtotime === -1 || $strtotime === false)
  11100. {
  11101. return false;
  11102. }
  11103. else
  11104. {
  11105. return $strtotime;
  11106. }
  11107. }
  11108. }
  11109. class SimplePie_Parser
  11110. {
  11111. var $error_code;
  11112. var $error_string;
  11113. var $current_line;
  11114. var $current_column;
  11115. var $current_byte;
  11116. var $separator = ' ';
  11117. var $namespace = array('');
  11118. var $element = array('');
  11119. var $xml_base = array('');
  11120. var $xml_base_explicit = array(false);
  11121. var $xml_lang = array('');
  11122. var $data = array();
  11123. var $datas = array(array());
  11124. var $current_xhtml_construct = -1;
  11125. var $encoding;
  11126. protected $registry;
  11127. public function set_registry(SimplePie_Registry $registry)
  11128. {
  11129. $this->registry = $registry;
  11130. }
  11131. public function parse(&$data, $encoding)
  11132. {
  11133. // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
  11134. if (strtoupper($encoding) === 'US-ASCII')
  11135. {
  11136. $this->encoding = 'UTF-8';
  11137. }
  11138. else
  11139. {
  11140. $this->encoding = $encoding;
  11141. }
  11142. // Strip BOM:
  11143. // UTF-32 Big Endian BOM
  11144. if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
  11145. {
  11146. $data = substr($data, 4);
  11147. }
  11148. // UTF-32 Little Endian BOM
  11149. elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
  11150. {
  11151. $data = substr($data, 4);
  11152. }
  11153. // UTF-16 Big Endian BOM
  11154. elseif (substr($data, 0, 2) === "\xFE\xFF")
  11155. {
  11156. $data = substr($data, 2);
  11157. }
  11158. // UTF-16 Little Endian BOM
  11159. elseif (substr($data, 0, 2) === "\xFF\xFE")
  11160. {
  11161. $data = substr($data, 2);
  11162. }
  11163. // UTF-8 BOM
  11164. elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
  11165. {
  11166. $data = substr($data, 3);
  11167. }
  11168. if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
  11169. {
  11170. $declaration = $this->registry->create('XML_Declaration_Parser', array(substr($data, 5, $pos - 5)));
  11171. if ($declaration->parse())
  11172. {
  11173. $data = substr($data, $pos + 2);
  11174. $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
  11175. }
  11176. else
  11177. {
  11178. $this->error_string = 'SimplePie bug! Please report this!';
  11179. return false;
  11180. }
  11181. }
  11182. $return = true;
  11183. static $xml_is_sane = null;
  11184. if ($xml_is_sane === null)
  11185. {
  11186. $parser_check = xml_parser_create();
  11187. xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
  11188. xml_parser_free($parser_check);
  11189. $xml_is_sane = isset($values[0]['value']);
  11190. }
  11191. // Create the parser
  11192. if ($xml_is_sane)
  11193. {
  11194. $xml = xml_parser_create_ns($this->encoding, $this->separator);
  11195. xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
  11196. xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
  11197. xml_set_object($xml, $this);
  11198. xml_set_character_data_handler($xml, 'cdata');
  11199. xml_set_element_handler($xml, 'tag_open', 'tag_close');
  11200. // Parse!
  11201. if (!xml_parse($xml, $data, true))
  11202. {
  11203. $this->error_code = xml_get_error_code($xml);
  11204. $this->error_string = xml_error_string($this->error_code);
  11205. $return = false;
  11206. }
  11207. $this->current_line = xml_get_current_line_number($xml);
  11208. $this->current_column = xml_get_current_column_number($xml);
  11209. $this->current_byte = xml_get_current_byte_index($xml);
  11210. xml_parser_free($xml);
  11211. return $return;
  11212. }
  11213. else
  11214. {
  11215. libxml_clear_errors();
  11216. $xml = new XMLReader();
  11217. $xml->xml($data);
  11218. while (@$xml->read())
  11219. {
  11220. switch ($xml->nodeType)
  11221. {
  11222. case constant('XMLReader::END_ELEMENT'):
  11223. if ($xml->namespaceURI !== '')
  11224. {
  11225. $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
  11226. }
  11227. else
  11228. {
  11229. $tagName = $xml->localName;
  11230. }
  11231. $this->tag_close(null, $tagName);
  11232. break;
  11233. case constant('XMLReader::ELEMENT'):
  11234. $empty = $xml->isEmptyElement;
  11235. if ($xml->namespaceURI !== '')
  11236. {
  11237. $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
  11238. }
  11239. else
  11240. {
  11241. $tagName = $xml->localName;
  11242. }
  11243. $attributes = array();
  11244. while ($xml->moveToNextAttribute())
  11245. {
  11246. if ($xml->namespaceURI !== '')
  11247. {
  11248. $attrName = $xml->namespaceURI . $this->separator . $xml->localName;
  11249. }
  11250. else
  11251. {
  11252. $attrName = $xml->localName;
  11253. }
  11254. $attributes[$attrName] = $xml->value;
  11255. }
  11256. $this->tag_open(null, $tagName, $attributes);
  11257. if ($empty)
  11258. {
  11259. $this->tag_close(null, $tagName);
  11260. }
  11261. break;
  11262. case constant('XMLReader::TEXT'):
  11263. case constant('XMLReader::CDATA'):
  11264. $this->cdata(null, $xml->value);
  11265. break;
  11266. }
  11267. }
  11268. if ($error = libxml_get_last_error())
  11269. {
  11270. $this->error_code = $error->code;
  11271. $this->error_string = $error->message;
  11272. $this->current_line = $error->line;
  11273. $this->current_column = $error->column;
  11274. return false;
  11275. }
  11276. else
  11277. {
  11278. return true;
  11279. }
  11280. }
  11281. }
  11282. public function get_error_code()
  11283. {
  11284. return $this->error_code;
  11285. }
  11286. public function get_error_string()
  11287. {
  11288. return $this->error_string;
  11289. }
  11290. public function get_current_line()
  11291. {
  11292. return $this->current_line;
  11293. }
  11294. public function get_current_column()
  11295. {
  11296. return $this->current_column;
  11297. }
  11298. public function get_current_byte()
  11299. {
  11300. return $this->current_byte;
  11301. }
  11302. public function get_data()
  11303. {
  11304. return $this->data;
  11305. }
  11306. public function tag_open($parser, $tag, $attributes)
  11307. {
  11308. list($this->namespace[], $this->element[]) = $this->split_ns($tag);
  11309. $attribs = array();
  11310. foreach ($attributes as $name => $value)
  11311. {
  11312. list($attrib_namespace, $attribute) = $this->split_ns($name);
  11313. $attribs[$attrib_namespace][$attribute] = $value;
  11314. }
  11315. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
  11316. {
  11317. $this->xml_base[] = $this->registry->call('Misc', 'absolutize_url', array($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base)));
  11318. $this->xml_base_explicit[] = true;
  11319. }
  11320. else
  11321. {
  11322. $this->xml_base[] = end($this->xml_base);
  11323. $this->xml_base_explicit[] = end($this->xml_base_explicit);
  11324. }
  11325. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
  11326. {
  11327. $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
  11328. }
  11329. else
  11330. {
  11331. $this->xml_lang[] = end($this->xml_lang);
  11332. }
  11333. if ($this->current_xhtml_construct >= 0)
  11334. {
  11335. $this->current_xhtml_construct++;
  11336. if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
  11337. {
  11338. $this->data['data'] .= '<' . end($this->element);
  11339. if (isset($attribs['']))
  11340. {
  11341. foreach ($attribs[''] as $name => $value)
  11342. {
  11343. $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
  11344. }
  11345. }
  11346. $this->data['data'] .= '>';
  11347. }
  11348. }
  11349. else
  11350. {
  11351. $this->datas[] =& $this->data;
  11352. $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
  11353. $this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang));
  11354. if ((end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] === 'xml')
  11355. || (end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] === 'xhtml')
  11356. || (end($this->namespace) === SIMPLEPIE_NAMESPACE_RSS_20 && in_array(end($this->element), array('title')))
  11357. || (end($this->namespace) === SIMPLEPIE_NAMESPACE_RSS_090 && in_array(end($this->element), array('title')))
  11358. || (end($this->namespace) === SIMPLEPIE_NAMESPACE_RSS_10 && in_array(end($this->element), array('title'))))
  11359. {
  11360. $this->current_xhtml_construct = 0;
  11361. }
  11362. }
  11363. }
  11364. public function cdata($parser, $cdata)
  11365. {
  11366. if ($this->current_xhtml_construct >= 0)
  11367. {
  11368. $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
  11369. }
  11370. else
  11371. {
  11372. $this->data['data'] .= $cdata;
  11373. }
  11374. }
  11375. public function tag_close($parser, $tag)
  11376. {
  11377. if ($this->current_xhtml_construct >= 0)
  11378. {
  11379. $this->current_xhtml_construct--;
  11380. if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param')))
  11381. {
  11382. $this->data['data'] .= '</' . end($this->element) . '>';
  11383. }
  11384. }
  11385. if ($this->current_xhtml_construct === -1)
  11386. {
  11387. $this->data =& $this->datas[count($this->datas) - 1];
  11388. array_pop($this->datas);
  11389. }
  11390. array_pop($this->element);
  11391. array_pop($this->namespace);
  11392. array_pop($this->xml_base);
  11393. array_pop($this->xml_base_explicit);
  11394. array_pop($this->xml_lang);
  11395. }
  11396. public function split_ns($string)
  11397. {
  11398. static $cache = array();
  11399. if (!isset($cache[$string]))
  11400. {
  11401. if ($pos = strpos($string, $this->separator))
  11402. {
  11403. static $separator_length;
  11404. if (!$separator_length)
  11405. {
  11406. $separator_length = strlen($this->separator);
  11407. }
  11408. $namespace = substr($string, 0, $pos);
  11409. $local_name = substr($string, $pos + $separator_length);
  11410. if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
  11411. {
  11412. $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
  11413. }
  11414. // Normalize the Media RSS namespaces
  11415. if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG ||
  11416. $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2 ||
  11417. $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3 ||
  11418. $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4 ||
  11419. $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5 )
  11420. {
  11421. $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
  11422. }
  11423. $cache[$string] = array($namespace, $local_name);
  11424. }
  11425. else
  11426. {
  11427. $cache[$string] = array('', $string);
  11428. }
  11429. }
  11430. return $cache[$string];
  11431. }
  11432. }
  11433. class SimplePie_Rating
  11434. {
  11435. var $scheme;
  11436. var $value;
  11437. public function __construct($scheme = null, $value = null)
  11438. {
  11439. $this->scheme = $scheme;
  11440. $this->value = $value;
  11441. }
  11442. public function __toString()
  11443. {
  11444. // There is no $this->data here
  11445. return md5(serialize($this));
  11446. }
  11447. public function get_scheme()
  11448. {
  11449. if ($this->scheme !== null)
  11450. {
  11451. return $this->scheme;
  11452. }
  11453. else
  11454. {
  11455. return null;
  11456. }
  11457. }
  11458. public function get_value()
  11459. {
  11460. if ($this->value !== null)
  11461. {
  11462. return $this->value;
  11463. }
  11464. else
  11465. {
  11466. return null;
  11467. }
  11468. }
  11469. }
  11470. class SimplePie_Registry
  11471. {
  11472. protected $default = array(
  11473. 'Cache' => 'SimplePie_Cache',
  11474. 'Locator' => 'SimplePie_Locator',
  11475. 'Parser' => 'SimplePie_Parser',
  11476. 'File' => 'SimplePie_File',
  11477. 'Sanitize' => 'SimplePie_Sanitize',
  11478. 'Item' => 'SimplePie_Item',
  11479. 'Author' => 'SimplePie_Author',
  11480. 'Category' => 'SimplePie_Category',
  11481. 'Enclosure' => 'SimplePie_Enclosure',
  11482. 'Caption' => 'SimplePie_Caption',
  11483. 'Copyright' => 'SimplePie_Copyright',
  11484. 'Credit' => 'SimplePie_Credit',
  11485. 'Rating' => 'SimplePie_Rating',
  11486. 'Restriction' => 'SimplePie_Restriction',
  11487. 'Content_Type_Sniffer' => 'SimplePie_Content_Type_Sniffer',
  11488. 'Source' => 'SimplePie_Source',
  11489. 'Misc' => 'SimplePie_Misc',
  11490. 'XML_Declaration_Parser' => 'SimplePie_XML_Declaration_Parser',
  11491. 'Parse_Date' => 'SimplePie_Parse_Date',
  11492. );
  11493. protected $classes = array();
  11494. protected $legacy = array();
  11495. public function __construct() { }
  11496. public function register($type, $class, $legacy = false)
  11497. {
  11498. if (!is_subclass_of($class, $this->default[$type]))
  11499. {
  11500. return false;
  11501. }
  11502. $this->classes[$type] = $class;
  11503. if ($legacy)
  11504. {
  11505. $this->legacy[] = $class;
  11506. }
  11507. return true;
  11508. }
  11509. public function get_class($type)
  11510. {
  11511. if (!empty($this->classes[$type]))
  11512. {
  11513. return $this->classes[$type];
  11514. }
  11515. if (!empty($this->default[$type]))
  11516. {
  11517. return $this->default[$type];
  11518. }
  11519. return null;
  11520. }
  11521. public function &create($type, $parameters = array())
  11522. {
  11523. $class = $this->get_class($type);
  11524. if (in_array($class, $this->legacy))
  11525. {
  11526. switch ($type)
  11527. {
  11528. case 'locator':
  11529. // Legacy: file, timeout, useragent, file_class, max_checked_feeds, content_type_sniffer_class
  11530. // Specified: file, timeout, useragent, max_checked_feeds
  11531. $replacement = array($this->get_class('file'), $parameters[3], $this->get_class('content_type_sniffer'));
  11532. array_splice($parameters, 3, 1, $replacement);
  11533. break;
  11534. }
  11535. }
  11536. if (!method_exists($class, '__construct'))
  11537. {
  11538. $instance = new $class;
  11539. }
  11540. else
  11541. {
  11542. $reflector = new ReflectionClass($class);
  11543. $instance = $reflector->newInstanceArgs($parameters);
  11544. }
  11545. if (method_exists($instance, 'set_registry'))
  11546. {
  11547. $instance->set_registry($this);
  11548. }
  11549. return $instance;
  11550. }
  11551. public function &call($type, $method, $parameters = array())
  11552. {
  11553. $class = $this->get_class($type);
  11554. $result = call_user_func_array(array($class, $method), $parameters);
  11555. return $result;
  11556. }
  11557. }
  11558. class SimplePie_Restriction
  11559. {
  11560. var $relationship;
  11561. var $type;
  11562. var $value;
  11563. public function __construct($relationship = null, $type = null, $value = null)
  11564. {
  11565. $this->relationship = $relationship;
  11566. $this->type = $type;
  11567. $this->value = $value;
  11568. }
  11569. public function __toString()
  11570. {
  11571. // There is no $this->data here
  11572. return md5(serialize($this));
  11573. }
  11574. public function get_relationship()
  11575. {
  11576. if ($this->relationship !== null)
  11577. {
  11578. return $this->relationship;
  11579. }
  11580. else
  11581. {
  11582. return null;
  11583. }
  11584. }
  11585. public function get_type()
  11586. {
  11587. if ($this->type !== null)
  11588. {
  11589. return $this->type;
  11590. }
  11591. else
  11592. {
  11593. return null;
  11594. }
  11595. }
  11596. public function get_value()
  11597. {
  11598. if ($this->value !== null)
  11599. {
  11600. return $this->value;
  11601. }
  11602. else
  11603. {
  11604. return null;
  11605. }
  11606. }
  11607. }
  11608. class SimplePie_Sanitize
  11609. {
  11610. // Private vars
  11611. var $base;
  11612. // Options
  11613. var $remove_div = true;
  11614. var $image_handler = '';
  11615. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  11616. var $encode_instead_of_strip = false;
  11617. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  11618. var $strip_comments = false;
  11619. var $output_encoding = 'UTF-8';
  11620. var $enable_cache = true;
  11621. var $cache_location = './cache';
  11622. var $cache_name_function = 'md5';
  11623. var $timeout = 10;
  11624. var $useragent = '';
  11625. var $force_fsockopen = false;
  11626. var $replace_url_attributes = null;
  11627. public function __construct()
  11628. {
  11629. // Set defaults
  11630. $this->set_url_replacements(null);
  11631. }
  11632. public function remove_div($enable = true)
  11633. {
  11634. $this->remove_div = (bool) $enable;
  11635. }
  11636. public function set_image_handler($page = false)
  11637. {
  11638. if ($page)
  11639. {
  11640. $this->image_handler = (string) $page;
  11641. }
  11642. else
  11643. {
  11644. $this->image_handler = false;
  11645. }
  11646. }
  11647. public function set_registry(SimplePie_Registry $registry)
  11648. {
  11649. $this->registry = $registry;
  11650. }
  11651. public function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
  11652. {
  11653. if (isset($enable_cache))
  11654. {
  11655. $this->enable_cache = (bool) $enable_cache;
  11656. }
  11657. if ($cache_location)
  11658. {
  11659. $this->cache_location = (string) $cache_location;
  11660. }
  11661. if ($cache_name_function)
  11662. {
  11663. $this->cache_name_function = (string) $cache_name_function;
  11664. }
  11665. }
  11666. public function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
  11667. {
  11668. if ($timeout)
  11669. {
  11670. $this->timeout = (string) $timeout;
  11671. }
  11672. if ($useragent)
  11673. {
  11674. $this->useragent = (string) $useragent;
  11675. }
  11676. if ($force_fsockopen)
  11677. {
  11678. $this->force_fsockopen = (string) $force_fsockopen;
  11679. }
  11680. }
  11681. public function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
  11682. {
  11683. if ($tags)
  11684. {
  11685. if (is_array($tags))
  11686. {
  11687. $this->strip_htmltags = $tags;
  11688. }
  11689. else
  11690. {
  11691. $this->strip_htmltags = explode(',', $tags);
  11692. }
  11693. }
  11694. else
  11695. {
  11696. $this->strip_htmltags = false;
  11697. }
  11698. }
  11699. public function encode_instead_of_strip($encode = false)
  11700. {
  11701. $this->encode_instead_of_strip = (bool) $encode;
  11702. }
  11703. public function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
  11704. {
  11705. if ($attribs)
  11706. {
  11707. if (is_array($attribs))
  11708. {
  11709. $this->strip_attributes = $attribs;
  11710. }
  11711. else
  11712. {
  11713. $this->strip_attributes = explode(',', $attribs);
  11714. }
  11715. }
  11716. else
  11717. {
  11718. $this->strip_attributes = false;
  11719. }
  11720. }
  11721. public function strip_comments($strip = false)
  11722. {
  11723. $this->strip_comments = (bool) $strip;
  11724. }
  11725. public function set_output_encoding($encoding = 'UTF-8')
  11726. {
  11727. $this->output_encoding = (string) $encoding;
  11728. }
  11729. public function set_url_replacements($element_attribute = null)
  11730. {
  11731. if ($element_attribute === null)
  11732. {
  11733. $element_attribute = array(
  11734. 'a' => 'href',
  11735. 'area' => 'href',
  11736. 'blockquote' => 'cite',
  11737. 'del' => 'cite',
  11738. 'form' => 'action',
  11739. 'img' => array(
  11740. 'longdesc',
  11741. 'src'
  11742. ),
  11743. 'input' => 'src',
  11744. 'ins' => 'cite',
  11745. 'q' => 'cite'
  11746. );
  11747. }
  11748. $this->replace_url_attributes = (array) $element_attribute;
  11749. }
  11750. public function sanitize($data, $type, $base = '')
  11751. {
  11752. $data = trim($data);
  11753. if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
  11754. {
  11755. if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
  11756. {
  11757. if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
  11758. {
  11759. $type |= SIMPLEPIE_CONSTRUCT_HTML;
  11760. }
  11761. else
  11762. {
  11763. $type |= SIMPLEPIE_CONSTRUCT_TEXT;
  11764. }
  11765. }
  11766. if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
  11767. {
  11768. $data = base64_decode($data);
  11769. }
  11770. if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
  11771. {
  11772. $document = new DOMDocument();
  11773. $document->encoding = 'UTF-8';
  11774. $data = $this->preprocess($data, $type);
  11775. set_error_handler(array('SimplePie_Misc', 'silence_errors'));
  11776. $document->loadHTML($data);
  11777. restore_error_handler();
  11778. // Strip comments
  11779. if ($this->strip_comments)
  11780. {
  11781. $xpath = new DOMXPath($document);
  11782. $comments = $xpath->query('//comment()');
  11783. foreach ($comments as $comment)
  11784. {
  11785. $comment->parentNode->removeChild($comment);
  11786. }
  11787. }
  11788. // Strip out HTML tags and attributes that might cause various security problems.
  11789. // Based on recommendations by Mark Pilgrim at:
  11790. // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
  11791. if ($this->strip_htmltags)
  11792. {
  11793. foreach ($this->strip_htmltags as $tag)
  11794. {
  11795. $this->strip_tag($tag, $document, $type);
  11796. }
  11797. }
  11798. if ($this->strip_attributes)
  11799. {
  11800. foreach ($this->strip_attributes as $attrib)
  11801. {
  11802. $this->strip_attr($attrib, $document);
  11803. }
  11804. }
  11805. // Replace relative URLs
  11806. $this->base = $base;
  11807. foreach ($this->replace_url_attributes as $element => $attributes)
  11808. {
  11809. $this->replace_urls($document, $element, $attributes);
  11810. }
  11811. // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
  11812. if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
  11813. {
  11814. $images = $document->getElementsByTagName('img');
  11815. foreach ($images as $img)
  11816. {
  11817. if ($img->hasAttribute('src'))
  11818. {
  11819. $image_url = call_user_func($this->cache_name_function, $img->getAttribute('src'));
  11820. $cache = $this->registry->call('Cache', 'create', array($this->cache_location, $image_url, 'spi'));
  11821. if ($cache->load())
  11822. {
  11823. $img->setAttribute('src', $this->image_handler . $image_url);
  11824. }
  11825. else
  11826. {
  11827. $file = $this->registry->create('File', array($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen));
  11828. $headers = $file->headers;
  11829. if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
  11830. {
  11831. if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  11832. {
  11833. $img->setAttribute('src', $this->image_handler . $image_url);
  11834. }
  11835. else
  11836. {
  11837. trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
  11838. }
  11839. }
  11840. }
  11841. }
  11842. }
  11843. }
  11844. // Remove the DOCTYPE
  11845. // Seems to cause segfaulting if we don't do this
  11846. if ($document->firstChild instanceof DOMDocumentType)
  11847. {
  11848. $document->removeChild($document->firstChild);
  11849. }
  11850. // Move everything from the body to the root
  11851. $real_body = $document->getElementsByTagName('body')->item(0)->childNodes->item(0);
  11852. $document->replaceChild($real_body, $document->firstChild);
  11853. // Finally, convert to a HTML string
  11854. $data = trim($document->saveHTML());
  11855. if ($this->remove_div)
  11856. {
  11857. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
  11858. $data = preg_replace('/<\/div>$/', '', $data);
  11859. }
  11860. else
  11861. {
  11862. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
  11863. }
  11864. }
  11865. if ($type & SIMPLEPIE_CONSTRUCT_IRI)
  11866. {
  11867. $data = $this->registry->call('Misc', 'absolutize_url', array($data, $base));
  11868. }
  11869. if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
  11870. {
  11871. $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
  11872. }
  11873. if ($this->output_encoding !== 'UTF-8')
  11874. {
  11875. $data = $this->registry->call('Misc', 'change_encoding', array($data, 'UTF-8', $this->output_encoding));
  11876. }
  11877. }
  11878. return $data;
  11879. }
  11880. protected function preprocess($html, $type)
  11881. {
  11882. $ret = '';
  11883. if ($type & ~SIMPLEPIE_CONSTRUCT_XHTML)
  11884. {
  11885. // Atom XHTML constructs are wrapped with a div by default
  11886. // Note: No protection if $html contains a stray </div>!
  11887. $html = '<div>' . $html . '</div>';
  11888. $ret .= '<!DOCTYPE html>';
  11889. $content_type = 'text/html';
  11890. }
  11891. else
  11892. {
  11893. $ret .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
  11894. $content_type = 'application/xhtml+xml';
  11895. }
  11896. $ret .= '<html><head>';
  11897. $ret .= '<meta http-equiv="Content-Type" content="' . $content_type . '; charset=utf-8" />';
  11898. $ret .= '</head><body>' . $html . '</body></html>';
  11899. return $ret;
  11900. }
  11901. public function replace_urls($document, $tag, $attributes)
  11902. {
  11903. if (!is_array($attributes))
  11904. {
  11905. $attributes = array($attributes);
  11906. }
  11907. if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
  11908. {
  11909. $elements = $document->getElementsByTagName($tag);
  11910. foreach ($elements as $element)
  11911. {
  11912. foreach ($attributes as $attribute)
  11913. {
  11914. if ($element->hasAttribute($attribute))
  11915. {
  11916. $value = $this->registry->call('Misc', 'absolutize_url', array($element->getAttribute($attribute), $this->base));
  11917. $element->setAttribute($attribute, $value);
  11918. }
  11919. }
  11920. }
  11921. }
  11922. }
  11923. public function do_strip_htmltags($match)
  11924. {
  11925. if ($this->encode_instead_of_strip)
  11926. {
  11927. if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  11928. {
  11929. $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
  11930. $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
  11931. return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
  11932. }
  11933. else
  11934. {
  11935. return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
  11936. }
  11937. }
  11938. elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  11939. {
  11940. return $match[4];
  11941. }
  11942. else
  11943. {
  11944. return '';
  11945. }
  11946. }
  11947. protected function strip_tag($tag, $document, $type)
  11948. {
  11949. $xpath = new DOMXPath($document);
  11950. $elements = $xpath->query('body//' . $tag);
  11951. if ($this->encode_instead_of_strip)
  11952. {
  11953. foreach ($elements as $element)
  11954. {
  11955. $fragment = $document->createDocumentFragment();
  11956. // For elements which aren't script or style, include the tag itself
  11957. if (!in_array($tag, array('script', 'style')))
  11958. {
  11959. $text = '<' . $tag;
  11960. if ($element->hasAttributes())
  11961. {
  11962. $attrs = array();
  11963. foreach ($element->attributes as $name => $attr)
  11964. {
  11965. $value = $attr->value;
  11966. // In XHTML, empty values should never exist, so we repeat the value
  11967. if (empty($value) && ($type & SIMPLEPIE_CONSTRUCT_XHTML))
  11968. {
  11969. $value = $name;
  11970. }
  11971. // For HTML, empty is fine
  11972. elseif (empty($value) && ($type & SIMPLEPIE_CONSTRUCT_HTML))
  11973. {
  11974. $attrs[] = $name;
  11975. continue;
  11976. }
  11977. // Standard attribute text
  11978. $attrs[] = $name . '="' . $attr->value . '"';
  11979. }
  11980. $text .= ' ' . implode(' ', $attrs);
  11981. }
  11982. $text .= '>';
  11983. $fragment->appendChild(new DOMText($text));
  11984. }
  11985. $number = $element->childNodes->length;
  11986. for ($i = $number; $i > 0; $i--)
  11987. {
  11988. $child = $element->childNodes->item(0);
  11989. $fragment->appendChild($child);
  11990. }
  11991. if (!in_array($tag, array('script', 'style')))
  11992. {
  11993. $fragment->appendChild(new DOMText('</' . $tag . '>'));
  11994. }
  11995. $element->parentNode->replaceChild($fragment, $element);
  11996. }
  11997. return;
  11998. }
  11999. elseif (in_array($tag, array('script', 'style')))
  12000. {
  12001. foreach ($elements as $element)
  12002. {
  12003. $element->parentNode->removeChild($element);
  12004. }
  12005. return;
  12006. }
  12007. else
  12008. {
  12009. foreach ($elements as $element)
  12010. {
  12011. $fragment = $document->createDocumentFragment();
  12012. $number = $element->childNodes->length;
  12013. for ($i = $number; $i > 0; $i--)
  12014. {
  12015. $child = $element->childNodes->item(0);
  12016. $fragment->appendChild($child);
  12017. }
  12018. $element->parentNode->replaceChild($fragment, $element);
  12019. }
  12020. }
  12021. }
  12022. protected function strip_attr($attrib, $document)
  12023. {
  12024. $xpath = new DOMXPath($document);
  12025. $elements = $xpath->query('//*[@' . $attrib . ']');
  12026. foreach ($elements as $element)
  12027. {
  12028. $element->removeAttribute($attrib);
  12029. }
  12030. }
  12031. }
  12032. class SimplePie_Source
  12033. {
  12034. var $item;
  12035. var $data = array();
  12036. protected $registry;
  12037. public function __construct($item, $data)
  12038. {
  12039. $this->item = $item;
  12040. $this->data = $data;
  12041. }
  12042. public function set_registry(SimplePie_Registry $registry)
  12043. {
  12044. $this->registry = $registry;
  12045. }
  12046. public function __toString()
  12047. {
  12048. return md5(serialize($this->data));
  12049. }
  12050. public function get_source_tags($namespace, $tag)
  12051. {
  12052. if (isset($this->data['child'][$namespace][$tag]))
  12053. {
  12054. return $this->data['child'][$namespace][$tag];
  12055. }
  12056. else
  12057. {
  12058. return null;
  12059. }
  12060. }
  12061. public function get_base($element = array())
  12062. {
  12063. return $this->item->get_base($element);
  12064. }
  12065. public function sanitize($data, $type, $base = '')
  12066. {
  12067. return $this->item->sanitize($data, $type, $base);
  12068. }
  12069. public function get_item()
  12070. {
  12071. return $this->item;
  12072. }
  12073. public function get_title()
  12074. {
  12075. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  12076. {
  12077. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  12078. }
  12079. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  12080. {
  12081. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  12082. }
  12083. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  12084. {
  12085. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  12086. }
  12087. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  12088. {
  12089. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  12090. }
  12091. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  12092. {
  12093. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  12094. }
  12095. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  12096. {
  12097. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12098. }
  12099. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  12100. {
  12101. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12102. }
  12103. else
  12104. {
  12105. return null;
  12106. }
  12107. }
  12108. public function get_category($key = 0)
  12109. {
  12110. $categories = $this->get_categories();
  12111. if (isset($categories[$key]))
  12112. {
  12113. return $categories[$key];
  12114. }
  12115. else
  12116. {
  12117. return null;
  12118. }
  12119. }
  12120. public function get_categories()
  12121. {
  12122. $categories = array();
  12123. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  12124. {
  12125. $term = null;
  12126. $scheme = null;
  12127. $label = null;
  12128. if (isset($category['attribs']['']['term']))
  12129. {
  12130. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  12131. }
  12132. if (isset($category['attribs']['']['scheme']))
  12133. {
  12134. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  12135. }
  12136. if (isset($category['attribs']['']['label']))
  12137. {
  12138. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  12139. }
  12140. $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
  12141. }
  12142. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
  12143. {
  12144. // This is really the label, but keep this as the term also for BC.
  12145. // Label will also work on retrieving because that falls back to term.
  12146. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12147. if (isset($category['attribs']['']['domain']))
  12148. {
  12149. $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
  12150. }
  12151. else
  12152. {
  12153. $scheme = null;
  12154. }
  12155. $categories[] = $this->registry->create('Category', array($term, $scheme, null));
  12156. }
  12157. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  12158. {
  12159. $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  12160. }
  12161. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  12162. {
  12163. $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  12164. }
  12165. if (!empty($categories))
  12166. {
  12167. return array_unique($categories);
  12168. }
  12169. else
  12170. {
  12171. return null;
  12172. }
  12173. }
  12174. public function get_author($key = 0)
  12175. {
  12176. $authors = $this->get_authors();
  12177. if (isset($authors[$key]))
  12178. {
  12179. return $authors[$key];
  12180. }
  12181. else
  12182. {
  12183. return null;
  12184. }
  12185. }
  12186. public function get_authors()
  12187. {
  12188. $authors = array();
  12189. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  12190. {
  12191. $name = null;
  12192. $uri = null;
  12193. $email = null;
  12194. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  12195. {
  12196. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12197. }
  12198. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  12199. {
  12200. $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
  12201. }
  12202. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  12203. {
  12204. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12205. }
  12206. if ($name !== null || $email !== null || $uri !== null)
  12207. {
  12208. $authors[] = $this->registry->create('Author', array($name, $uri, $email));
  12209. }
  12210. }
  12211. if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  12212. {
  12213. $name = null;
  12214. $url = null;
  12215. $email = null;
  12216. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  12217. {
  12218. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12219. }
  12220. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  12221. {
  12222. $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
  12223. }
  12224. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  12225. {
  12226. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12227. }
  12228. if ($name !== null || $email !== null || $url !== null)
  12229. {
  12230. $authors[] = $this->registry->create('Author', array($name, $url, $email));
  12231. }
  12232. }
  12233. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  12234. {
  12235. $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  12236. }
  12237. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  12238. {
  12239. $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  12240. }
  12241. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  12242. {
  12243. $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
  12244. }
  12245. if (!empty($authors))
  12246. {
  12247. return array_unique($authors);
  12248. }
  12249. else
  12250. {
  12251. return null;
  12252. }
  12253. }
  12254. public function get_contributor($key = 0)
  12255. {
  12256. $contributors = $this->get_contributors();
  12257. if (isset($contributors[$key]))
  12258. {
  12259. return $contributors[$key];
  12260. }
  12261. else
  12262. {
  12263. return null;
  12264. }
  12265. }
  12266. public function get_contributors()
  12267. {
  12268. $contributors = array();
  12269. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  12270. {
  12271. $name = null;
  12272. $uri = null;
  12273. $email = null;
  12274. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  12275. {
  12276. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12277. }
  12278. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  12279. {
  12280. $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
  12281. }
  12282. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  12283. {
  12284. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12285. }
  12286. if ($name !== null || $email !== null || $uri !== null)
  12287. {
  12288. $contributors[] = $this->registry->create('Author', array($name, $uri, $email));
  12289. }
  12290. }
  12291. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  12292. {
  12293. $name = null;
  12294. $url = null;
  12295. $email = null;
  12296. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  12297. {
  12298. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12299. }
  12300. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  12301. {
  12302. $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
  12303. }
  12304. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  12305. {
  12306. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12307. }
  12308. if ($name !== null || $email !== null || $url !== null)
  12309. {
  12310. $contributors[] = $this->registry->create('Author', array($name, $url, $email));
  12311. }
  12312. }
  12313. if (!empty($contributors))
  12314. {
  12315. return array_unique($contributors);
  12316. }
  12317. else
  12318. {
  12319. return null;
  12320. }
  12321. }
  12322. public function get_link($key = 0, $rel = 'alternate')
  12323. {
  12324. $links = $this->get_links($rel);
  12325. if (isset($links[$key]))
  12326. {
  12327. return $links[$key];
  12328. }
  12329. else
  12330. {
  12331. return null;
  12332. }
  12333. }
  12334. public function get_permalink()
  12335. {
  12336. return $this->get_link(0);
  12337. }
  12338. public function get_links($rel = 'alternate')
  12339. {
  12340. if (!isset($this->data['links']))
  12341. {
  12342. $this->data['links'] = array();
  12343. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  12344. {
  12345. foreach ($links as $link)
  12346. {
  12347. if (isset($link['attribs']['']['href']))
  12348. {
  12349. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  12350. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  12351. }
  12352. }
  12353. }
  12354. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  12355. {
  12356. foreach ($links as $link)
  12357. {
  12358. if (isset($link['attribs']['']['href']))
  12359. {
  12360. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  12361. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  12362. }
  12363. }
  12364. }
  12365. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  12366. {
  12367. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  12368. }
  12369. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  12370. {
  12371. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  12372. }
  12373. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  12374. {
  12375. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  12376. }
  12377. $keys = array_keys($this->data['links']);
  12378. foreach ($keys as $key)
  12379. {
  12380. if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
  12381. {
  12382. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  12383. {
  12384. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  12385. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  12386. }
  12387. else
  12388. {
  12389. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  12390. }
  12391. }
  12392. elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  12393. {
  12394. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  12395. }
  12396. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  12397. }
  12398. }
  12399. if (isset($this->data['links'][$rel]))
  12400. {
  12401. return $this->data['links'][$rel];
  12402. }
  12403. else
  12404. {
  12405. return null;
  12406. }
  12407. }
  12408. public function get_description()
  12409. {
  12410. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  12411. {
  12412. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  12413. }
  12414. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  12415. {
  12416. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  12417. }
  12418. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  12419. {
  12420. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  12421. }
  12422. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  12423. {
  12424. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  12425. }
  12426. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
  12427. {
  12428. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  12429. }
  12430. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  12431. {
  12432. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12433. }
  12434. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  12435. {
  12436. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12437. }
  12438. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  12439. {
  12440. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  12441. }
  12442. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  12443. {
  12444. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  12445. }
  12446. else
  12447. {
  12448. return null;
  12449. }
  12450. }
  12451. public function get_copyright()
  12452. {
  12453. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  12454. {
  12455. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  12456. }
  12457. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
  12458. {
  12459. return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
  12460. }
  12461. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
  12462. {
  12463. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12464. }
  12465. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  12466. {
  12467. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12468. }
  12469. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  12470. {
  12471. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12472. }
  12473. else
  12474. {
  12475. return null;
  12476. }
  12477. }
  12478. public function get_language()
  12479. {
  12480. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
  12481. {
  12482. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12483. }
  12484. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  12485. {
  12486. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12487. }
  12488. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  12489. {
  12490. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  12491. }
  12492. elseif (isset($this->data['xml_lang']))
  12493. {
  12494. return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  12495. }
  12496. else
  12497. {
  12498. return null;
  12499. }
  12500. }
  12501. public function get_latitude()
  12502. {
  12503. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  12504. {
  12505. return (float) $return[0]['data'];
  12506. }
  12507. elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  12508. {
  12509. return (float) $match[1];
  12510. }
  12511. else
  12512. {
  12513. return null;
  12514. }
  12515. }
  12516. public function get_longitude()
  12517. {
  12518. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  12519. {
  12520. return (float) $return[0]['data'];
  12521. }
  12522. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  12523. {
  12524. return (float) $return[0]['data'];
  12525. }
  12526. elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  12527. {
  12528. return (float) $match[2];
  12529. }
  12530. else
  12531. {
  12532. return null;
  12533. }
  12534. }
  12535. public function get_image_url()
  12536. {
  12537. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  12538. {
  12539. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  12540. }
  12541. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  12542. {
  12543. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  12544. }
  12545. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  12546. {
  12547. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  12548. }
  12549. else
  12550. {
  12551. return null;
  12552. }
  12553. }
  12554. }
  12555. class SimplePie_XML_Declaration_Parser
  12556. {
  12557. var $version = '1.0';
  12558. var $encoding = 'UTF-8';
  12559. var $standalone = false;
  12560. var $state = 'before_version_name';
  12561. var $data = '';
  12562. var $data_length = 0;
  12563. var $position = 0;
  12564. public function __construct($data)
  12565. {
  12566. $this->data = $data;
  12567. $this->data_length = strlen($this->data);
  12568. }
  12569. public function parse()
  12570. {
  12571. while ($this->state && $this->state !== 'emit' && $this->has_data())
  12572. {
  12573. $state = $this->state;
  12574. $this->$state();
  12575. }
  12576. $this->data = '';
  12577. if ($this->state === 'emit')
  12578. {
  12579. return true;
  12580. }
  12581. else
  12582. {
  12583. $this->version = '';
  12584. $this->encoding = '';
  12585. $this->standalone = '';
  12586. return false;
  12587. }
  12588. }
  12589. public function has_data()
  12590. {
  12591. return (bool) ($this->position < $this->data_length);
  12592. }
  12593. public function skip_whitespace()
  12594. {
  12595. $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
  12596. $this->position += $whitespace;
  12597. return $whitespace;
  12598. }
  12599. public function get_value()
  12600. {
  12601. $quote = substr($this->data, $this->position, 1);
  12602. if ($quote === '"' || $quote === "'")
  12603. {
  12604. $this->position++;
  12605. $len = strcspn($this->data, $quote, $this->position);
  12606. if ($this->has_data())
  12607. {
  12608. $value = substr($this->data, $this->position, $len);
  12609. $this->position += $len + 1;
  12610. return $value;
  12611. }
  12612. }
  12613. return false;
  12614. }
  12615. public function before_version_name()
  12616. {
  12617. if ($this->skip_whitespace())
  12618. {
  12619. $this->state = 'version_name';
  12620. }
  12621. else
  12622. {
  12623. $this->state = false;
  12624. }
  12625. }
  12626. public function version_name()
  12627. {
  12628. if (substr($this->data, $this->position, 7) === 'version')
  12629. {
  12630. $this->position += 7;
  12631. $this->skip_whitespace();
  12632. $this->state = 'version_equals';
  12633. }
  12634. else
  12635. {
  12636. $this->state = false;
  12637. }
  12638. }
  12639. public function version_equals()
  12640. {
  12641. if (substr($this->data, $this->position, 1) === '=')
  12642. {
  12643. $this->position++;
  12644. $this->skip_whitespace();
  12645. $this->state = 'version_value';
  12646. }
  12647. else
  12648. {
  12649. $this->state = false;
  12650. }
  12651. }
  12652. public function version_value()
  12653. {
  12654. if ($this->version = $this->get_value())
  12655. {
  12656. $this->skip_whitespace();
  12657. if ($this->has_data())
  12658. {
  12659. $this->state = 'encoding_name';
  12660. }
  12661. else
  12662. {
  12663. $this->state = 'emit';
  12664. }
  12665. }
  12666. else
  12667. {
  12668. $this->state = false;
  12669. }
  12670. }
  12671. public function encoding_name()
  12672. {
  12673. if (substr($this->data, $this->position, 8) === 'encoding')
  12674. {
  12675. $this->position += 8;
  12676. $this->skip_whitespace();
  12677. $this->state = 'encoding_equals';
  12678. }
  12679. else
  12680. {
  12681. $this->state = 'standalone_name';
  12682. }
  12683. }
  12684. public function encoding_equals()
  12685. {
  12686. if (substr($this->data, $this->position, 1) === '=')
  12687. {
  12688. $this->position++;
  12689. $this->skip_whitespace();
  12690. $this->state = 'encoding_value';
  12691. }
  12692. else
  12693. {
  12694. $this->state = false;
  12695. }
  12696. }
  12697. public function encoding_value()
  12698. {
  12699. if ($this->encoding = $this->get_value())
  12700. {
  12701. $this->skip_whitespace();
  12702. if ($this->has_data())
  12703. {
  12704. $this->state = 'standalone_name';
  12705. }
  12706. else
  12707. {
  12708. $this->state = 'emit';
  12709. }
  12710. }
  12711. else
  12712. {
  12713. $this->state = false;
  12714. }
  12715. }
  12716. public function standalone_name()
  12717. {
  12718. if (substr($this->data, $this->position, 10) === 'standalone')
  12719. {
  12720. $this->position += 10;
  12721. $this->skip_whitespace();
  12722. $this->state = 'standalone_equals';
  12723. }
  12724. else
  12725. {
  12726. $this->state = false;
  12727. }
  12728. }
  12729. public function standalone_equals()
  12730. {
  12731. if (substr($this->data, $this->position, 1) === '=')
  12732. {
  12733. $this->position++;
  12734. $this->skip_whitespace();
  12735. $this->state = 'standalone_value';
  12736. }
  12737. else
  12738. {
  12739. $this->state = false;
  12740. }
  12741. }
  12742. public function standalone_value()
  12743. {
  12744. if ($standalone = $this->get_value())
  12745. {
  12746. switch ($standalone)
  12747. {
  12748. case 'yes':
  12749. $this->standalone = true;
  12750. break;
  12751. case 'no':
  12752. $this->standalone = false;
  12753. break;
  12754. default:
  12755. $this->state = false;
  12756. return;
  12757. }
  12758. $this->skip_whitespace();
  12759. if ($this->has_data())
  12760. {
  12761. $this->state = false;
  12762. }
  12763. else
  12764. {
  12765. $this->state = 'emit';
  12766. }
  12767. }
  12768. else
  12769. {
  12770. $this->state = false;
  12771. }
  12772. }
  12773. }