PageRenderTime 99ms CodeModel.GetById 48ms RepoModel.GetById 1ms 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

Large files files are truncated, but you can click here to view the full 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'];

Large files files are truncated, but you can click here to view the full file