PageRenderTime 343ms CodeModel.GetById 26ms RepoModel.GetById 38ms app.codeStats 4ms

/vtlib/thirdparty/parser/feed/simplepie.inc

https://bitbucket.org/jhunsinfotech/blue-blues
PHP | 13675 lines | 11719 code | 627 blank | 1329 comment | 918 complexity | 13c2cfe92db9b0170972ecf34c824c87 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, LGPL-3.0
  1. <?php
  2. /**
  3. * SimplePie
  4. *
  5. * A PHP-Based RSS and Atom Feed Framework.
  6. * Takes the hard work out of managing a complete RSS/Atom solution.
  7. *
  8. * Copyright (c) 2004-2008, Ryan Parman and Geoffrey Sneddon
  9. * All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without modification, are
  12. * permitted provided that the following conditions are met:
  13. *
  14. * * Redistributions of source code must retain the above copyright notice, this list of
  15. * conditions and the following disclaimer.
  16. *
  17. * * Redistributions in binary form must reproduce the above copyright notice, this list
  18. * of conditions and the following disclaimer in the documentation and/or other materials
  19. * provided with the distribution.
  20. *
  21. * * Neither the name of the SimplePie Team nor the names of its contributors may be used
  22. * to endorse or promote products derived from this software without specific prior
  23. * written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  26. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  27. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
  28. * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  30. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  32. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. *
  35. * @package SimplePie
  36. * @version 1.1.2
  37. * @copyright 2004-2008 Ryan Parman, Geoffrey Sneddon
  38. * @author Ryan Parman
  39. * @author Geoffrey Sneddon
  40. * @link http://simplepie.org/ SimplePie
  41. * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
  42. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  43. * @todo phpDoc comments
  44. */
  45. /**
  46. * SimplePie Name
  47. */
  48. define('SIMPLEPIE_NAME', 'SimplePie');
  49. /**
  50. * SimplePie Version
  51. */
  52. define('SIMPLEPIE_VERSION', '1.1.2');
  53. /**
  54. * SimplePie Build
  55. */
  56. define('SIMPLEPIE_BUILD', '20081109150825');
  57. /**
  58. * SimplePie Website URL
  59. */
  60. define('SIMPLEPIE_URL', 'http://simplepie.org');
  61. /**
  62. * SimplePie Useragent
  63. * @see SimplePie::set_useragent()
  64. */
  65. define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
  66. /**
  67. * SimplePie Linkback
  68. */
  69. define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
  70. /**
  71. * No Autodiscovery
  72. * @see SimplePie::set_autodiscovery_level()
  73. */
  74. define('SIMPLEPIE_LOCATOR_NONE', 0);
  75. /**
  76. * Feed Link Element Autodiscovery
  77. * @see SimplePie::set_autodiscovery_level()
  78. */
  79. define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
  80. /**
  81. * Local Feed Extension Autodiscovery
  82. * @see SimplePie::set_autodiscovery_level()
  83. */
  84. define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
  85. /**
  86. * Local Feed Body Autodiscovery
  87. * @see SimplePie::set_autodiscovery_level()
  88. */
  89. define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
  90. /**
  91. * Remote Feed Extension Autodiscovery
  92. * @see SimplePie::set_autodiscovery_level()
  93. */
  94. define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
  95. /**
  96. * Remote Feed Body Autodiscovery
  97. * @see SimplePie::set_autodiscovery_level()
  98. */
  99. define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
  100. /**
  101. * All Feed Autodiscovery
  102. * @see SimplePie::set_autodiscovery_level()
  103. */
  104. define('SIMPLEPIE_LOCATOR_ALL', 31);
  105. /**
  106. * No known feed type
  107. */
  108. define('SIMPLEPIE_TYPE_NONE', 0);
  109. /**
  110. * RSS 0.90
  111. */
  112. define('SIMPLEPIE_TYPE_RSS_090', 1);
  113. /**
  114. * RSS 0.91 (Netscape)
  115. */
  116. define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
  117. /**
  118. * RSS 0.91 (Userland)
  119. */
  120. define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
  121. /**
  122. * RSS 0.91 (both Netscape and Userland)
  123. */
  124. define('SIMPLEPIE_TYPE_RSS_091', 6);
  125. /**
  126. * RSS 0.92
  127. */
  128. define('SIMPLEPIE_TYPE_RSS_092', 8);
  129. /**
  130. * RSS 0.93
  131. */
  132. define('SIMPLEPIE_TYPE_RSS_093', 16);
  133. /**
  134. * RSS 0.94
  135. */
  136. define('SIMPLEPIE_TYPE_RSS_094', 32);
  137. /**
  138. * RSS 1.0
  139. */
  140. define('SIMPLEPIE_TYPE_RSS_10', 64);
  141. /**
  142. * RSS 2.0
  143. */
  144. define('SIMPLEPIE_TYPE_RSS_20', 128);
  145. /**
  146. * RDF-based RSS
  147. */
  148. define('SIMPLEPIE_TYPE_RSS_RDF', 65);
  149. /**
  150. * Non-RDF-based RSS (truly intended as syndication format)
  151. */
  152. define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
  153. /**
  154. * All RSS
  155. */
  156. define('SIMPLEPIE_TYPE_RSS_ALL', 255);
  157. /**
  158. * Atom 0.3
  159. */
  160. define('SIMPLEPIE_TYPE_ATOM_03', 256);
  161. /**
  162. * Atom 1.0
  163. */
  164. define('SIMPLEPIE_TYPE_ATOM_10', 512);
  165. /**
  166. * All Atom
  167. */
  168. define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
  169. /**
  170. * All feed types
  171. */
  172. define('SIMPLEPIE_TYPE_ALL', 1023);
  173. /**
  174. * No construct
  175. */
  176. define('SIMPLEPIE_CONSTRUCT_NONE', 0);
  177. /**
  178. * Text construct
  179. */
  180. define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
  181. /**
  182. * HTML construct
  183. */
  184. define('SIMPLEPIE_CONSTRUCT_HTML', 2);
  185. /**
  186. * XHTML construct
  187. */
  188. define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
  189. /**
  190. * base64-encoded construct
  191. */
  192. define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
  193. /**
  194. * IRI construct
  195. */
  196. define('SIMPLEPIE_CONSTRUCT_IRI', 16);
  197. /**
  198. * A construct that might be HTML
  199. */
  200. define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
  201. /**
  202. * All constructs
  203. */
  204. define('SIMPLEPIE_CONSTRUCT_ALL', 63);
  205. /**
  206. * PCRE for HTML attributes
  207. */
  208. 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]*');
  209. /**
  210. * PCRE for XML attributes
  211. */
  212. define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
  213. /**
  214. * XML Namespace
  215. */
  216. define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
  217. /**
  218. * Atom 1.0 Namespace
  219. */
  220. define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
  221. /**
  222. * Atom 0.3 Namespace
  223. */
  224. define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
  225. /**
  226. * RDF Namespace
  227. */
  228. define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
  229. /**
  230. * RSS 0.90 Namespace
  231. */
  232. define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
  233. /**
  234. * RSS 1.0 Namespace
  235. */
  236. define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
  237. /**
  238. * RSS 1.0 Content Module Namespace
  239. */
  240. define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
  241. /**
  242. * RSS 2.0 Namespace
  243. * (Stupid, I know, but I'm certain it will confuse people less with support.)
  244. */
  245. define('SIMPLEPIE_NAMESPACE_RSS_20', '');
  246. /**
  247. * DC 1.0 Namespace
  248. */
  249. define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
  250. /**
  251. * DC 1.1 Namespace
  252. */
  253. define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
  254. /**
  255. * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
  256. */
  257. define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
  258. /**
  259. * GeoRSS Namespace
  260. */
  261. define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
  262. /**
  263. * Media RSS Namespace
  264. */
  265. define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
  266. /**
  267. * Wrong Media RSS Namespace
  268. */
  269. define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
  270. /**
  271. * iTunes RSS Namespace
  272. */
  273. define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
  274. /**
  275. * XHTML Namespace
  276. */
  277. define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
  278. /**
  279. * IANA Link Relations Registry
  280. */
  281. define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
  282. /**
  283. * Whether we're running on PHP5
  284. */
  285. define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
  286. /**
  287. * No file source
  288. */
  289. define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
  290. /**
  291. * Remote file source
  292. */
  293. define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
  294. /**
  295. * Local file source
  296. */
  297. define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
  298. /**
  299. * fsockopen() file source
  300. */
  301. define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
  302. /**
  303. * cURL file source
  304. */
  305. define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
  306. /**
  307. * file_get_contents() file source
  308. */
  309. define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
  310. /**
  311. * SimplePie
  312. *
  313. * @package SimplePie
  314. * @version "Razzleberry"
  315. * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
  316. * @author Ryan Parman
  317. * @author Geoffrey Sneddon
  318. * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
  319. */
  320. class SimplePie
  321. {
  322. /**
  323. * @var array Raw data
  324. * @access private
  325. */
  326. var $data = array();
  327. /**
  328. * @var mixed Error string
  329. * @access private
  330. */
  331. var $error;
  332. /**
  333. * @var object Instance of SimplePie_Sanitize (or other class)
  334. * @see SimplePie::set_sanitize_class()
  335. * @access private
  336. */
  337. var $sanitize;
  338. /**
  339. * @var string SimplePie Useragent
  340. * @see SimplePie::set_useragent()
  341. * @access private
  342. */
  343. var $useragent = SIMPLEPIE_USERAGENT;
  344. /**
  345. * @var string Feed URL
  346. * @see SimplePie::set_feed_url()
  347. * @access private
  348. */
  349. var $feed_url;
  350. /**
  351. * @var object Instance of SimplePie_File to use as a feed
  352. * @see SimplePie::set_file()
  353. * @access private
  354. */
  355. var $file;
  356. /**
  357. * @var string Raw feed data
  358. * @see SimplePie::set_raw_data()
  359. * @access private
  360. */
  361. var $raw_data;
  362. /**
  363. * @var int Timeout for fetching remote files
  364. * @see SimplePie::set_timeout()
  365. * @access private
  366. */
  367. var $timeout = 10;
  368. /**
  369. * @var bool Forces fsockopen() to be used for remote files instead
  370. * of cURL, even if a new enough version is installed
  371. * @see SimplePie::force_fsockopen()
  372. * @access private
  373. */
  374. var $force_fsockopen = false;
  375. /**
  376. * @var bool Force the given data/URL to be treated as a feed no matter what
  377. * it appears like
  378. * @see SimplePie::force_feed()
  379. * @access private
  380. */
  381. var $force_feed = false;
  382. /**
  383. * @var bool Enable/Disable XML dump
  384. * @see SimplePie::enable_xml_dump()
  385. * @access private
  386. */
  387. var $xml_dump = false;
  388. /**
  389. * @var bool Enable/Disable Caching
  390. * @see SimplePie::enable_cache()
  391. * @access private
  392. */
  393. var $cache = true;
  394. /**
  395. * @var int Cache duration (in seconds)
  396. * @see SimplePie::set_cache_duration()
  397. * @access private
  398. */
  399. var $cache_duration = 3600;
  400. /**
  401. * @var int Auto-discovery cache duration (in seconds)
  402. * @see SimplePie::set_autodiscovery_cache_duration()
  403. * @access private
  404. */
  405. var $autodiscovery_cache_duration = 604800; // 7 Days.
  406. /**
  407. * @var string Cache location (relative to executing script)
  408. * @see SimplePie::set_cache_location()
  409. * @access private
  410. */
  411. var $cache_location = './cache';
  412. /**
  413. * @var string Function that creates the cache filename
  414. * @see SimplePie::set_cache_name_function()
  415. * @access private
  416. */
  417. var $cache_name_function = 'md5';
  418. /**
  419. * @var bool Reorder feed by date descending
  420. * @see SimplePie::enable_order_by_date()
  421. * @access private
  422. */
  423. var $order_by_date = true;
  424. /**
  425. * @var mixed Force input encoding to be set to the follow value
  426. * (false, or anything type-cast to false, disables this feature)
  427. * @see SimplePie::set_input_encoding()
  428. * @access private
  429. */
  430. var $input_encoding = false;
  431. /**
  432. * @var int Feed Autodiscovery Level
  433. * @see SimplePie::set_autodiscovery_level()
  434. * @access private
  435. */
  436. var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
  437. /**
  438. * @var string Class used for caching feeds
  439. * @see SimplePie::set_cache_class()
  440. * @access private
  441. */
  442. var $cache_class = 'SimplePie_Cache';
  443. /**
  444. * @var string Class used for locating feeds
  445. * @see SimplePie::set_locator_class()
  446. * @access private
  447. */
  448. var $locator_class = 'SimplePie_Locator';
  449. /**
  450. * @var string Class used for parsing feeds
  451. * @see SimplePie::set_parser_class()
  452. * @access private
  453. */
  454. var $parser_class = 'SimplePie_Parser';
  455. /**
  456. * @var string Class used for fetching feeds
  457. * @see SimplePie::set_file_class()
  458. * @access private
  459. */
  460. var $file_class = 'SimplePie_File';
  461. /**
  462. * @var string Class used for items
  463. * @see SimplePie::set_item_class()
  464. * @access private
  465. */
  466. var $item_class = 'SimplePie_Item';
  467. /**
  468. * @var string Class used for authors
  469. * @see SimplePie::set_author_class()
  470. * @access private
  471. */
  472. var $author_class = 'SimplePie_Author';
  473. /**
  474. * @var string Class used for categories
  475. * @see SimplePie::set_category_class()
  476. * @access private
  477. */
  478. var $category_class = 'SimplePie_Category';
  479. /**
  480. * @var string Class used for enclosures
  481. * @see SimplePie::set_enclosures_class()
  482. * @access private
  483. */
  484. var $enclosure_class = 'SimplePie_Enclosure';
  485. /**
  486. * @var string Class used for Media RSS <media:text> captions
  487. * @see SimplePie::set_caption_class()
  488. * @access private
  489. */
  490. var $caption_class = 'SimplePie_Caption';
  491. /**
  492. * @var string Class used for Media RSS <media:copyright>
  493. * @see SimplePie::set_copyright_class()
  494. * @access private
  495. */
  496. var $copyright_class = 'SimplePie_Copyright';
  497. /**
  498. * @var string Class used for Media RSS <media:credit>
  499. * @see SimplePie::set_credit_class()
  500. * @access private
  501. */
  502. var $credit_class = 'SimplePie_Credit';
  503. /**
  504. * @var string Class used for Media RSS <media:rating>
  505. * @see SimplePie::set_rating_class()
  506. * @access private
  507. */
  508. var $rating_class = 'SimplePie_Rating';
  509. /**
  510. * @var string Class used for Media RSS <media:restriction>
  511. * @see SimplePie::set_restriction_class()
  512. * @access private
  513. */
  514. var $restriction_class = 'SimplePie_Restriction';
  515. /**
  516. * @var string Class used for content-type sniffing
  517. * @see SimplePie::set_content_type_sniffer_class()
  518. * @access private
  519. */
  520. var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
  521. /**
  522. * @var string Class used for item sources.
  523. * @see SimplePie::set_source_class()
  524. * @access private
  525. */
  526. var $source_class = 'SimplePie_Source';
  527. /**
  528. * @var mixed Set javascript query string parameter (false, or
  529. * anything type-cast to false, disables this feature)
  530. * @see SimplePie::set_javascript()
  531. * @access private
  532. */
  533. var $javascript = 'js';
  534. /**
  535. * @var int Maximum number of feeds to check with autodiscovery
  536. * @see SimplePie::set_max_checked_feeds()
  537. * @access private
  538. */
  539. var $max_checked_feeds = 10;
  540. /**
  541. * @var string Web-accessible path to the handler_favicon.php file.
  542. * @see SimplePie::set_favicon_handler()
  543. * @access private
  544. */
  545. var $favicon_handler = '';
  546. /**
  547. * @var string Web-accessible path to the handler_image.php file.
  548. * @see SimplePie::set_image_handler()
  549. * @access private
  550. */
  551. var $image_handler = '';
  552. /**
  553. * @var array Stores the URLs when multiple feeds are being initialized.
  554. * @see SimplePie::set_feed_url()
  555. * @access private
  556. */
  557. var $multifeed_url = array();
  558. /**
  559. * @var array Stores SimplePie objects when multiple feeds initialized.
  560. * @access private
  561. */
  562. var $multifeed_objects = array();
  563. /**
  564. * @var array Stores the get_object_vars() array for use with multifeeds.
  565. * @see SimplePie::set_feed_url()
  566. * @access private
  567. */
  568. var $config_settings = null;
  569. /**
  570. * @var integer Stores the number of items to return per-feed with multifeeds.
  571. * @see SimplePie::set_item_limit()
  572. * @access private
  573. */
  574. var $item_limit = 0;
  575. /**
  576. * @var array Stores the default attributes to be stripped by strip_attributes().
  577. * @see SimplePie::strip_attributes()
  578. * @access private
  579. */
  580. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  581. /**
  582. * @var array Stores the default tags to be stripped by strip_htmltags().
  583. * @see SimplePie::strip_htmltags()
  584. * @access private
  585. */
  586. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  587. /**
  588. * The SimplePie class contains feed level data and options
  589. *
  590. * There are two ways that you can create a new SimplePie object. The first
  591. * is by passing a feed URL as a parameter to the SimplePie constructor
  592. * (as well as optionally setting the cache location and cache expiry). This
  593. * will initialise the whole feed with all of the default settings, and you
  594. * can begin accessing methods and properties immediately.
  595. *
  596. * The second way is to create the SimplePie object with no parameters
  597. * at all. This will enable you to set configuration options. After setting
  598. * them, you must initialise the feed using $feed->init(). At that point the
  599. * object's methods and properties will be available to you. This format is
  600. * what is used throughout this documentation.
  601. *
  602. * @access public
  603. * @since 1.0 Preview Release
  604. * @param string $feed_url This is the URL you want to parse.
  605. * @param string $cache_location This is where you want the cache to be stored.
  606. * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
  607. */
  608. function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
  609. {
  610. // Other objects, instances created here so we can set options on them
  611. $this->sanitize =& new SimplePie_Sanitize;
  612. // Set options if they're passed to the constructor
  613. if ($cache_location !== null)
  614. {
  615. $this->set_cache_location($cache_location);
  616. }
  617. if ($cache_duration !== null)
  618. {
  619. $this->set_cache_duration($cache_duration);
  620. }
  621. // Only init the script if we're passed a feed URL
  622. if ($feed_url !== null)
  623. {
  624. $this->set_feed_url($feed_url);
  625. $this->init();
  626. }
  627. }
  628. /**
  629. * Used for converting object to a string
  630. */
  631. function __toString()
  632. {
  633. return md5(serialize($this->data));
  634. }
  635. /**
  636. * Remove items that link back to this before destroying this object
  637. */
  638. function __destruct()
  639. {
  640. if (!empty($this->data['items']))
  641. {
  642. foreach ($this->data['items'] as $item)
  643. {
  644. $item->__destruct();
  645. }
  646. unset($this->data['items']);
  647. }
  648. if (!empty($this->data['ordered_items']))
  649. {
  650. foreach ($this->data['ordered_items'] as $item)
  651. {
  652. $item->__destruct();
  653. }
  654. unset($this->data['ordered_items']);
  655. }
  656. }
  657. /**
  658. * Force the given data/URL to be treated as a feed no matter what it
  659. * appears like
  660. *
  661. * @access public
  662. * @since 1.1
  663. * @param bool $enable Force the given data/URL to be treated as a feed
  664. */
  665. function force_feed($enable = false)
  666. {
  667. $this->force_feed = (bool) $enable;
  668. }
  669. /**
  670. * This is the URL of the feed you want to parse.
  671. *
  672. * This allows you to enter the URL of the feed you want to parse, or the
  673. * website you want to try to use auto-discovery on. This takes priority
  674. * over any set raw data.
  675. *
  676. * You can set multiple feeds to mash together by passing an array instead
  677. * of a string for the $url. Remember that with each additional feed comes
  678. * additional processing and resources.
  679. *
  680. * @access public
  681. * @since 1.0 Preview Release
  682. * @param mixed $url This is the URL (or array of URLs) that you want to parse.
  683. * @see SimplePie::set_raw_data()
  684. */
  685. function set_feed_url($url)
  686. {
  687. if (is_array($url))
  688. {
  689. $this->multifeed_url = array();
  690. foreach ($url as $value)
  691. {
  692. $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
  693. }
  694. }
  695. else
  696. {
  697. $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
  698. }
  699. }
  700. /**
  701. * Provides an instance of SimplePie_File to use as a feed
  702. *
  703. * @access public
  704. * @param object &$file Instance of SimplePie_File (or subclass)
  705. * @return bool True on success, false on failure
  706. */
  707. function set_file(&$file)
  708. {
  709. if (is_a($file, 'SimplePie_File'))
  710. {
  711. $this->feed_url = $file->url;
  712. $this->file =& $file;
  713. return true;
  714. }
  715. return false;
  716. }
  717. /**
  718. * Allows you to use a string of RSS/Atom data instead of a remote feed.
  719. *
  720. * If you have a feed available as a string in PHP, you can tell SimplePie
  721. * to parse that data string instead of a remote feed. Any set feed URL
  722. * takes precedence.
  723. *
  724. * @access public
  725. * @since 1.0 Beta 3
  726. * @param string $data RSS or Atom data as a string.
  727. * @see SimplePie::set_feed_url()
  728. */
  729. function set_raw_data($data)
  730. {
  731. $this->raw_data = $data;
  732. }
  733. /**
  734. * Allows you to override the default timeout for fetching remote feeds.
  735. *
  736. * This allows you to change the maximum time the feed's server to respond
  737. * and send the feed back.
  738. *
  739. * @access public
  740. * @since 1.0 Beta 3
  741. * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
  742. */
  743. function set_timeout($timeout = 10)
  744. {
  745. $this->timeout = (int) $timeout;
  746. }
  747. /**
  748. * Forces SimplePie to use fsockopen() instead of the preferred cURL
  749. * functions.
  750. *
  751. * @access public
  752. * @since 1.0 Beta 3
  753. * @param bool $enable Force fsockopen() to be used
  754. */
  755. function force_fsockopen($enable = false)
  756. {
  757. $this->force_fsockopen = (bool) $enable;
  758. }
  759. /**
  760. * Outputs the raw XML content of the feed, after it has gone through
  761. * SimplePie's filters.
  762. *
  763. * Used only for debugging, this function will output the XML content as
  764. * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
  765. * before trying to parse it. Many parts of the feed are re-written in
  766. * memory, and in the end, you have a parsable feed. XML dump shows you the
  767. * actual XML that SimplePie tries to parse, which may or may not be very
  768. * different from the original feed.
  769. *
  770. * @access public
  771. * @since 1.0 Preview Release
  772. * @param bool $enable Enable XML dump
  773. */
  774. function enable_xml_dump($enable = false)
  775. {
  776. $this->xml_dump = (bool) $enable;
  777. }
  778. /**
  779. * Enables/disables caching in SimplePie.
  780. *
  781. * This option allows you to disable caching all-together in SimplePie.
  782. * However, disabling the cache can lead to longer load times.
  783. *
  784. * @access public
  785. * @since 1.0 Preview Release
  786. * @param bool $enable Enable caching
  787. */
  788. function enable_cache($enable = true)
  789. {
  790. $this->cache = (bool) $enable;
  791. }
  792. /**
  793. * Set the length of time (in seconds) that the contents of a feed
  794. * will be cached.
  795. *
  796. * @access public
  797. * @param int $seconds The feed content cache duration.
  798. */
  799. function set_cache_duration($seconds = 3600)
  800. {
  801. $this->cache_duration = (int) $seconds;
  802. }
  803. /**
  804. * Set the length of time (in seconds) that the autodiscovered feed
  805. * URL will be cached.
  806. *
  807. * @access public
  808. * @param int $seconds The autodiscovered feed URL cache duration.
  809. */
  810. function set_autodiscovery_cache_duration($seconds = 604800)
  811. {
  812. $this->autodiscovery_cache_duration = (int) $seconds;
  813. }
  814. /**
  815. * Set the file system location where the cached files should be stored.
  816. *
  817. * @access public
  818. * @param string $location The file system location.
  819. */
  820. function set_cache_location($location = './cache')
  821. {
  822. $this->cache_location = (string) $location;
  823. }
  824. /**
  825. * Determines whether feed items should be sorted into reverse chronological order.
  826. *
  827. * @access public
  828. * @param bool $enable Sort as reverse chronological order.
  829. */
  830. function enable_order_by_date($enable = true)
  831. {
  832. $this->order_by_date = (bool) $enable;
  833. }
  834. /**
  835. * Allows you to override the character encoding reported by the feed.
  836. *
  837. * @access public
  838. * @param string $encoding Character encoding.
  839. */
  840. function set_input_encoding($encoding = false)
  841. {
  842. if ($encoding)
  843. {
  844. $this->input_encoding = (string) $encoding;
  845. }
  846. else
  847. {
  848. $this->input_encoding = false;
  849. }
  850. }
  851. /**
  852. * Set how much feed autodiscovery to do
  853. *
  854. * @access public
  855. * @see SIMPLEPIE_LOCATOR_NONE
  856. * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
  857. * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
  858. * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
  859. * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
  860. * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
  861. * @see SIMPLEPIE_LOCATOR_ALL
  862. * @param int $level Feed Autodiscovery Level (level can be a
  863. * combination of the above constants, see bitwise OR operator)
  864. */
  865. function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
  866. {
  867. $this->autodiscovery = (int) $level;
  868. }
  869. /**
  870. * Allows you to change which class SimplePie uses for caching.
  871. * Useful when you are overloading or extending SimplePie's default classes.
  872. *
  873. * @access public
  874. * @param string $class Name of custom class.
  875. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  876. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  877. */
  878. function set_cache_class($class = 'SimplePie_Cache')
  879. {
  880. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
  881. {
  882. $this->cache_class = $class;
  883. return true;
  884. }
  885. return false;
  886. }
  887. /**
  888. * Allows you to change which class SimplePie uses for auto-discovery.
  889. * Useful when you are overloading or extending SimplePie's default classes.
  890. *
  891. * @access public
  892. * @param string $class Name of custom class.
  893. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  894. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  895. */
  896. function set_locator_class($class = 'SimplePie_Locator')
  897. {
  898. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
  899. {
  900. $this->locator_class = $class;
  901. return true;
  902. }
  903. return false;
  904. }
  905. /**
  906. * Allows you to change which class SimplePie uses for XML parsing.
  907. * Useful when you are overloading or extending SimplePie's default classes.
  908. *
  909. * @access public
  910. * @param string $class Name of custom class.
  911. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  912. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  913. */
  914. function set_parser_class($class = 'SimplePie_Parser')
  915. {
  916. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
  917. {
  918. $this->parser_class = $class;
  919. return true;
  920. }
  921. return false;
  922. }
  923. /**
  924. * Allows you to change which class SimplePie uses for remote file fetching.
  925. * Useful when you are overloading or extending SimplePie's default classes.
  926. *
  927. * @access public
  928. * @param string $class Name of custom class.
  929. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  930. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  931. */
  932. function set_file_class($class = 'SimplePie_File')
  933. {
  934. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
  935. {
  936. $this->file_class = $class;
  937. return true;
  938. }
  939. return false;
  940. }
  941. /**
  942. * Allows you to change which class SimplePie uses for data sanitization.
  943. * Useful when you are overloading or extending SimplePie's default classes.
  944. *
  945. * @access public
  946. * @param string $class Name of custom class.
  947. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  948. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  949. */
  950. function set_sanitize_class($class = 'SimplePie_Sanitize')
  951. {
  952. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
  953. {
  954. $this->sanitize =& new $class;
  955. return true;
  956. }
  957. return false;
  958. }
  959. /**
  960. * Allows you to change which class SimplePie uses for handling feed items.
  961. * Useful when you are overloading or extending SimplePie's default classes.
  962. *
  963. * @access public
  964. * @param string $class Name of custom class.
  965. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  966. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  967. */
  968. function set_item_class($class = 'SimplePie_Item')
  969. {
  970. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
  971. {
  972. $this->item_class = $class;
  973. return true;
  974. }
  975. return false;
  976. }
  977. /**
  978. * Allows you to change which class SimplePie uses for handling author data.
  979. * Useful when you are overloading or extending SimplePie's default classes.
  980. *
  981. * @access public
  982. * @param string $class Name of custom class.
  983. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  984. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  985. */
  986. function set_author_class($class = 'SimplePie_Author')
  987. {
  988. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
  989. {
  990. $this->author_class = $class;
  991. return true;
  992. }
  993. return false;
  994. }
  995. /**
  996. * Allows you to change which class SimplePie uses for handling category data.
  997. * Useful when you are overloading or extending SimplePie's default classes.
  998. *
  999. * @access public
  1000. * @param string $class Name of custom class.
  1001. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1002. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1003. */
  1004. function set_category_class($class = 'SimplePie_Category')
  1005. {
  1006. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
  1007. {
  1008. $this->category_class = $class;
  1009. return true;
  1010. }
  1011. return false;
  1012. }
  1013. /**
  1014. * Allows you to change which class SimplePie uses for feed enclosures.
  1015. * Useful when you are overloading or extending SimplePie's default classes.
  1016. *
  1017. * @access public
  1018. * @param string $class Name of custom class.
  1019. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1020. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1021. */
  1022. function set_enclosure_class($class = 'SimplePie_Enclosure')
  1023. {
  1024. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
  1025. {
  1026. $this->enclosure_class = $class;
  1027. return true;
  1028. }
  1029. return false;
  1030. }
  1031. /**
  1032. * Allows you to change which class SimplePie uses for <media:text> captions
  1033. * Useful when you are overloading or extending SimplePie's default classes.
  1034. *
  1035. * @access public
  1036. * @param string $class Name of custom class.
  1037. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1038. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1039. */
  1040. function set_caption_class($class = 'SimplePie_Caption')
  1041. {
  1042. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
  1043. {
  1044. $this->caption_class = $class;
  1045. return true;
  1046. }
  1047. return false;
  1048. }
  1049. /**
  1050. * Allows you to change which class SimplePie uses for <media:copyright>
  1051. * Useful when you are overloading or extending SimplePie's default classes.
  1052. *
  1053. * @access public
  1054. * @param string $class Name of custom class.
  1055. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1056. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1057. */
  1058. function set_copyright_class($class = 'SimplePie_Copyright')
  1059. {
  1060. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
  1061. {
  1062. $this->copyright_class = $class;
  1063. return true;
  1064. }
  1065. return false;
  1066. }
  1067. /**
  1068. * Allows you to change which class SimplePie uses for <media:credit>
  1069. * Useful when you are overloading or extending SimplePie's default classes.
  1070. *
  1071. * @access public
  1072. * @param string $class Name of custom class.
  1073. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1074. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1075. */
  1076. function set_credit_class($class = 'SimplePie_Credit')
  1077. {
  1078. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
  1079. {
  1080. $this->credit_class = $class;
  1081. return true;
  1082. }
  1083. return false;
  1084. }
  1085. /**
  1086. * Allows you to change which class SimplePie uses for <media:rating>
  1087. * Useful when you are overloading or extending SimplePie's default classes.
  1088. *
  1089. * @access public
  1090. * @param string $class Name of custom class.
  1091. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1092. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1093. */
  1094. function set_rating_class($class = 'SimplePie_Rating')
  1095. {
  1096. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
  1097. {
  1098. $this->rating_class = $class;
  1099. return true;
  1100. }
  1101. return false;
  1102. }
  1103. /**
  1104. * Allows you to change which class SimplePie uses for <media:restriction>
  1105. * Useful when you are overloading or extending SimplePie's default classes.
  1106. *
  1107. * @access public
  1108. * @param string $class Name of custom class.
  1109. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1110. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1111. */
  1112. function set_restriction_class($class = 'SimplePie_Restriction')
  1113. {
  1114. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
  1115. {
  1116. $this->restriction_class = $class;
  1117. return true;
  1118. }
  1119. return false;
  1120. }
  1121. /**
  1122. * Allows you to change which class SimplePie uses for content-type sniffing.
  1123. * Useful when you are overloading or extending SimplePie's default classes.
  1124. *
  1125. * @access public
  1126. * @param string $class Name of custom class.
  1127. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1128. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1129. */
  1130. function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
  1131. {
  1132. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
  1133. {
  1134. $this->content_type_sniffer_class = $class;
  1135. return true;
  1136. }
  1137. return false;
  1138. }
  1139. /**
  1140. * Allows you to change which class SimplePie uses item sources.
  1141. * Useful when you are overloading or extending SimplePie's default classes.
  1142. *
  1143. * @access public
  1144. * @param string $class Name of custom class.
  1145. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1146. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1147. */
  1148. function set_source_class($class = 'SimplePie_Source')
  1149. {
  1150. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
  1151. {
  1152. $this->source_class = $class;
  1153. return true;
  1154. }
  1155. return false;
  1156. }
  1157. /**
  1158. * Allows you to override the default user agent string.
  1159. *
  1160. * @access public
  1161. * @param string $ua New user agent string.
  1162. */
  1163. function set_useragent($ua = SIMPLEPIE_USERAGENT)
  1164. {
  1165. $this->useragent = (string) $ua;
  1166. }
  1167. /**
  1168. * Set callback function to create cache filename with
  1169. *
  1170. * @access public
  1171. * @param mixed $function Callback function
  1172. */
  1173. function set_cache_name_function($function = 'md5')
  1174. {
  1175. if (is_callable($function))
  1176. {
  1177. $this->cache_name_function = $function;
  1178. }
  1179. }
  1180. /**
  1181. * Set javascript query string parameter
  1182. *
  1183. * @access public
  1184. * @param mixed $get Javascript query string parameter
  1185. */
  1186. function set_javascript($get = 'js')
  1187. {
  1188. if ($get)
  1189. {
  1190. $this->javascript = (string) $get;
  1191. }
  1192. else
  1193. {
  1194. $this->javascript = false;
  1195. }
  1196. }
  1197. /**
  1198. * Set options to make SP as fast as possible. Forgoes a
  1199. * substantial amount of data sanitization in favor of speed.
  1200. *
  1201. * @access public
  1202. * @param bool $set Whether to set them or not
  1203. */
  1204. function set_stupidly_fast($set = false)
  1205. {
  1206. if ($set)
  1207. {
  1208. $this->enable_order_by_date(false);
  1209. $this->remove_div(false);
  1210. $this->strip_comments(false);
  1211. $this->strip_htmltags(false);
  1212. $this->strip_attributes(false);
  1213. $this->set_image_handler(false);
  1214. }
  1215. }
  1216. /**
  1217. * Set maximum number of feeds to check with autodiscovery
  1218. *
  1219. * @access public
  1220. * @param int $max Maximum number of feeds to check
  1221. */
  1222. function set_max_checked_feeds($max = 10)
  1223. {
  1224. $this->max_checked_feeds = (int) $max;
  1225. }
  1226. function remove_div($enable = true)
  1227. {
  1228. $this->sanitize->remove_div($enable);
  1229. }
  1230. function strip_htmltags($tags = '', $encode = null)
  1231. {
  1232. if ($tags === '')
  1233. {
  1234. $tags = $this->strip_htmltags;
  1235. }
  1236. $this->sanitize->strip_htmltags($tags);
  1237. if ($encode !== null)
  1238. {
  1239. $this->sanitize->encode_instead_of_strip($tags);
  1240. }
  1241. }
  1242. function encode_instead_of_strip($enable = true)
  1243. {
  1244. $this->sanitize->encode_instead_of_strip($enable);
  1245. }
  1246. function strip_attributes($attribs = '')
  1247. {
  1248. if ($attribs === '')
  1249. {
  1250. $attribs = $this->strip_attributes;
  1251. }
  1252. $this->sanitize->strip_attributes($attribs);
  1253. }
  1254. function set_output_encoding($encoding = 'UTF-8')
  1255. {
  1256. $this->sanitize->set_output_encoding($encoding);
  1257. }
  1258. function strip_comments($strip = false)
  1259. {
  1260. $this->sanitize->strip_comments($strip);
  1261. }
  1262. /**
  1263. * Set element/attribute key/value pairs of HTML attributes
  1264. * containing URLs that need to be resolved relative to the feed
  1265. *
  1266. * @access public
  1267. * @since 1.0
  1268. * @param array $element_attribute Element/attribute key/value pairs
  1269. */
  1270. function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
  1271. {
  1272. $this->sanitize->set_url_replacements($element_attribute);
  1273. }
  1274. /**
  1275. * Set the handler to enable the display of cached favicons.
  1276. *
  1277. * @access public
  1278. * @param str $page Web-accessible path to the handler_favicon.php file.
  1279. * @param str $qs The query string that the value should be passed to.
  1280. */
  1281. function set_favicon_handler($page = false, $qs = 'i')
  1282. {
  1283. if ($page != false)
  1284. {
  1285. $this->favicon_handler = $page . '?' . $qs . '=';
  1286. }
  1287. else
  1288. {
  1289. $this->favicon_handler = '';
  1290. }
  1291. }
  1292. /**
  1293. * Set the handler to enable the display of cached images.
  1294. *
  1295. * @access public
  1296. * @param str $page Web-accessible path to the handler_image.php file.
  1297. * @param str $qs The query string that the value should be passed to.
  1298. */
  1299. function set_image_handler($page = false, $qs = 'i')
  1300. {
  1301. if ($page != false)
  1302. {
  1303. $this->sanitize->set_image_handler($page . '?' . $qs . '=');
  1304. }
  1305. else
  1306. {
  1307. $this->image_handler = '';
  1308. }
  1309. }
  1310. /**
  1311. * Set the limit for items returned per-feed with multifeeds.
  1312. *
  1313. * @access public
  1314. * @param integer $limit The maximum number of items to return.
  1315. */
  1316. function set_item_limit($limit = 0)
  1317. {
  1318. $this->item_limit = (int) $limit;
  1319. }
  1320. function init()
  1321. {
  1322. if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
  1323. {
  1324. return false;
  1325. }
  1326. if (isset($_GET[$this->javascript]))
  1327. {
  1328. if (function_exists('ob_gzhandler'))
  1329. {
  1330. ob_start('ob_gzhandler');
  1331. }
  1332. header('Content-type: text/javascript; charset: UTF-8');
  1333. header('Cache-Control: must-revalidate');
  1334. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  1335. ?>
  1336. function embed_odeo(link) {
  1337. document.writeln('<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url='+link+'"></embed>');
  1338. }
  1339. function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
  1340. if (placeholder != '') {
  1341. 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>');
  1342. }
  1343. else {
  1344. 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>');
  1345. }
  1346. }
  1347. function embed_flash(bgcolor, width, height, link, loop, type) {
  1348. 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>');
  1349. }
  1350. function embed_flv(width, height, link, placeholder, loop, player) {
  1351. 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>');
  1352. }
  1353. function embed_wmedia(width, height, link) {
  1354. document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
  1355. }
  1356. <?php
  1357. exit;
  1358. }
  1359. // Pass whatever was set with config options over to the sanitizer.
  1360. $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
  1361. $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
  1362. if ($this->feed_url !== null || $this->raw_data !== null)
  1363. {
  1364. $this->data = array();
  1365. $this->multifeed_objects = array();
  1366. $cache = false;
  1367. if ($this->feed_url !== null)
  1368. {
  1369. $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
  1370. // Decide whether to enable caching
  1371. if ($this->cache && $parsed_feed_url['scheme'] !== '')
  1372. {
  1373. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
  1374. }
  1375. // If it's enabled and we don't want an XML dump, use the cache
  1376. if ($cache && !$this->xml_dump)
  1377. {
  1378. // Load the Cache
  1379. $this->data = $cache->load();
  1380. if (!empty($this->data))
  1381. {
  1382. // If the cache is for an outdated build of SimplePie
  1383. if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
  1384. {
  1385. $cache->unlink();
  1386. $this->data = array();
  1387. }
  1388. // If we've hit a collision just rerun it with caching disabled
  1389. elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
  1390. {
  1391. $cache = false;
  1392. $this->data = array();
  1393. }
  1394. // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
  1395. elseif (isset($this->data['feed_url']))
  1396. {
  1397. // If the autodiscovery cache is still valid use it.
  1398. if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
  1399. {
  1400. // Do not need to do feed autodiscovery yet.
  1401. if ($this->data['feed_url'] == $this->data['url'])
  1402. {
  1403. $cache->unlink();
  1404. $this->data = array();
  1405. }
  1406. else
  1407. {
  1408. $this->set_feed_url($this->data['feed_url']);
  1409. return $this->init();
  1410. }
  1411. }
  1412. }
  1413. // Check if the cache has been updated
  1414. elseif ($cache->mtime() + $this->cache_duration < time())
  1415. {
  1416. // If we have last-modified and/or etag set
  1417. if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
  1418. {
  1419. $headers = array();
  1420. if (isset($this->data['headers']['last-modified']))
  1421. {
  1422. $headers['if-modified-since'] = $this->data['headers']['last-modified'];
  1423. }
  1424. if (isset($this->data['headers']['etag']))
  1425. {
  1426. $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
  1427. }
  1428. $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
  1429. if ($file->success)
  1430. {
  1431. if ($file->status_code == 304)
  1432. {
  1433. $cache->touch();
  1434. return true;
  1435. }
  1436. else
  1437. {
  1438. $headers = $file->headers;
  1439. }
  1440. }
  1441. else
  1442. {
  1443. unset($file);
  1444. }
  1445. }
  1446. }
  1447. // If the cache is still valid, just return true
  1448. else
  1449. {
  1450. return true;
  1451. }
  1452. }
  1453. // If the cache is empty, delete it
  1454. else
  1455. {
  1456. $cache->unlink();
  1457. $this->data = array();
  1458. }
  1459. }
  1460. // 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.
  1461. if (!isset($file))
  1462. {
  1463. if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
  1464. {
  1465. $file =& $this->file;
  1466. }
  1467. else
  1468. {
  1469. $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
  1470. }
  1471. }
  1472. // If the file connection has an error, set SimplePie::error to that and quit
  1473. if (!$file->success)
  1474. {
  1475. $this->error = $file->error;
  1476. if (!empty($this->data))
  1477. {
  1478. return true;
  1479. }
  1480. else
  1481. {
  1482. return false;
  1483. }
  1484. }
  1485. if (!$this->force_feed)
  1486. {
  1487. // Check if the supplied URL is a feed, if it isn't, look for it.
  1488. $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
  1489. if (!$locate->is_feed($file))
  1490. {
  1491. // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
  1492. unset($file);
  1493. if ($file = $locate->find($this->autodiscovery))
  1494. {
  1495. if ($cache)
  1496. {
  1497. $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
  1498. if (!$cache->save($this))
  1499. {
  1500. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1501. }
  1502. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
  1503. }
  1504. $this->feed_url = $file->url;
  1505. }
  1506. else
  1507. {
  1508. $this->error = "A feed could not be found at $this->feed_url";
  1509. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1510. return false;
  1511. }
  1512. }
  1513. $locate = null;
  1514. }
  1515. $headers = $file->headers;
  1516. $data = $file->body;
  1517. $sniffer = new $this->content_type_sniffer_class($file);
  1518. $sniffed = $sniffer->get_type();
  1519. }
  1520. else
  1521. {
  1522. $data = $this->raw_data;
  1523. }
  1524. // Set up array of possible encodings
  1525. $encodings = array();
  1526. // First check to see if input has been overridden.
  1527. if ($this->input_encoding !== false)
  1528. {
  1529. $encodings[] = $this->input_encoding;
  1530. }
  1531. $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
  1532. $text_types = array('text/xml', 'text/xml-external-parsed-entity');
  1533. // RFC 3023 (only applies to sniffed content)
  1534. if (isset($sniffed))
  1535. {
  1536. if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
  1537. {
  1538. if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  1539. {
  1540. $encodings[] = strtoupper($charset[1]);
  1541. }
  1542. $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
  1543. $encodings[] = 'UTF-8';
  1544. }
  1545. elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
  1546. {
  1547. if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  1548. {
  1549. $encodings[] = $charset[1];
  1550. }
  1551. $encodings[] = 'US-ASCII';
  1552. }
  1553. // Text MIME-type default
  1554. elseif (substr($sniffed, 0, 5) === 'text/')
  1555. {
  1556. $encodings[] = 'US-ASCII';
  1557. }
  1558. }
  1559. // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
  1560. $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
  1561. $encodings[] = 'UTF-8';
  1562. $encodings[] = 'ISO-8859-1';
  1563. // There's no point in trying an encoding twice
  1564. $encodings = array_unique($encodings);
  1565. // If we want the XML, just output that with the most likely encoding and quit
  1566. if ($this->xml_dump)
  1567. {
  1568. header('Content-type: text/xml; charset=' . $encodings[0]);
  1569. echo $data;
  1570. exit;
  1571. }
  1572. // Loop through each possible encoding, till we return something, or run out of possibilities
  1573. foreach ($encodings as $encoding)
  1574. {
  1575. // Change the encoding to UTF-8 (as we always use UTF-8 internally)
  1576. if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
  1577. {
  1578. // Create new parser
  1579. $parser =& new $this->parser_class();
  1580. // If it's parsed fine
  1581. if ($parser->parse($utf8_data, 'UTF-8'))
  1582. {
  1583. $this->data = $parser->get_data();
  1584. if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
  1585. {
  1586. if (isset($headers))
  1587. {
  1588. $this->data['headers'] = $headers;
  1589. }
  1590. $this->data['build'] = SIMPLEPIE_BUILD;
  1591. // Cache the file if caching is enabled
  1592. if ($cache && !$cache->save($this))
  1593. {
  1594. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1595. }
  1596. return true;
  1597. }
  1598. else
  1599. {
  1600. $this->error = "A feed could not be found at $this->feed_url";
  1601. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1602. return false;
  1603. }
  1604. }
  1605. }
  1606. }
  1607. // We have an error, just set SimplePie::error to it and quit
  1608. $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
  1609. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1610. return false;
  1611. }
  1612. elseif (!empty($this->multifeed_url))
  1613. {
  1614. $i = 0;
  1615. $success = 0;
  1616. $this->multifeed_objects = array();
  1617. foreach ($this->multifeed_url as $url)
  1618. {
  1619. if (SIMPLEPIE_PHP5)
  1620. {
  1621. // This keyword needs to defy coding standards for PHP4 compatibility
  1622. $this->multifeed_objects[$i] = clone($this);
  1623. }
  1624. else
  1625. {
  1626. $this->multifeed_objects[$i] = $this;
  1627. }
  1628. $this->multifeed_objects[$i]->set_feed_url($url);
  1629. $success |= $this->multifeed_objects[$i]->init();
  1630. $i++;
  1631. }
  1632. return (bool) $success;
  1633. }
  1634. else
  1635. {
  1636. return false;
  1637. }
  1638. }
  1639. /**
  1640. * Return the error message for the occured error
  1641. *
  1642. * @access public
  1643. * @return string Error message
  1644. */
  1645. function error()
  1646. {
  1647. return $this->error;
  1648. }
  1649. function get_encoding()
  1650. {
  1651. return $this->sanitize->output_encoding;
  1652. }
  1653. function handle_content_type($mime = 'text/html')
  1654. {
  1655. if (!headers_sent())
  1656. {
  1657. $header = "Content-type: $mime;";
  1658. if ($this->get_encoding())
  1659. {
  1660. $header .= ' charset=' . $this->get_encoding();
  1661. }
  1662. else
  1663. {
  1664. $header .= ' charset=UTF-8';
  1665. }
  1666. header($header);
  1667. }
  1668. }
  1669. function get_type()
  1670. {
  1671. if (!isset($this->data['type']))
  1672. {
  1673. $this->data['type'] = SIMPLEPIE_TYPE_ALL;
  1674. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
  1675. {
  1676. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
  1677. }
  1678. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
  1679. {
  1680. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
  1681. }
  1682. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
  1683. {
  1684. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
  1685. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
  1686. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
  1687. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
  1688. {
  1689. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
  1690. }
  1691. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
  1692. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
  1693. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
  1694. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
  1695. {
  1696. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
  1697. }
  1698. }
  1699. elseif (isset($this->data['child']['']['rss']))
  1700. {
  1701. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
  1702. if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
  1703. {
  1704. switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
  1705. {
  1706. case '0.91':
  1707. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
  1708. if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
  1709. {
  1710. switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
  1711. {
  1712. case '0':
  1713. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
  1714. break;
  1715. case '24':
  1716. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
  1717. break;
  1718. }
  1719. }
  1720. break;
  1721. case '0.92':
  1722. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
  1723. break;
  1724. case '0.93':
  1725. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
  1726. break;
  1727. case '0.94':
  1728. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
  1729. break;
  1730. case '2.0':
  1731. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
  1732. break;
  1733. }
  1734. }
  1735. }
  1736. else
  1737. {
  1738. $this->data['type'] = SIMPLEPIE_TYPE_NONE;
  1739. }
  1740. }
  1741. return $this->data['type'];
  1742. }
  1743. /**
  1744. * Returns the URL for the favicon of the feed's website.
  1745. *
  1746. * @todo Cache atom:icon
  1747. * @access public
  1748. * @since 1.0
  1749. */
  1750. function get_favicon()
  1751. {
  1752. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  1753. {
  1754. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1755. }
  1756. elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
  1757. {
  1758. $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
  1759. if ($this->cache && $this->favicon_handler)
  1760. {
  1761. $favicon_filename = call_user_func($this->cache_name_function, $favicon);
  1762. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
  1763. if ($cache->load())
  1764. {
  1765. return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
  1766. }
  1767. else
  1768. {
  1769. $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
  1770. if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
  1771. {
  1772. $sniffer = new $this->content_type_sniffer_class($file);
  1773. if (substr($sniffer->get_type(), 0, 6) === 'image/')
  1774. {
  1775. if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  1776. {
  1777. return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
  1778. }
  1779. else
  1780. {
  1781. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1782. return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
  1783. }
  1784. }
  1785. }
  1786. }
  1787. }
  1788. else
  1789. {
  1790. return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
  1791. }
  1792. }
  1793. return false;
  1794. }
  1795. /**
  1796. * @todo If we have a perm redirect we should return the new URL
  1797. * @todo When we make the above change, let's support <itunes:new-feed-url> as well
  1798. * @todo Also, |atom:link|@rel=self
  1799. */
  1800. function subscribe_url()
  1801. {
  1802. if ($this->feed_url !== null)
  1803. {
  1804. return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
  1805. }
  1806. else
  1807. {
  1808. return null;
  1809. }
  1810. }
  1811. function subscribe_feed()
  1812. {
  1813. if ($this->feed_url !== null)
  1814. {
  1815. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
  1816. }
  1817. else
  1818. {
  1819. return null;
  1820. }
  1821. }
  1822. function subscribe_outlook()
  1823. {
  1824. if ($this->feed_url !== null)
  1825. {
  1826. return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
  1827. }
  1828. else
  1829. {
  1830. return null;
  1831. }
  1832. }
  1833. function subscribe_podcast()
  1834. {
  1835. if ($this->feed_url !== null)
  1836. {
  1837. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
  1838. }
  1839. else
  1840. {
  1841. return null;
  1842. }
  1843. }
  1844. function subscribe_itunes()
  1845. {
  1846. if ($this->feed_url !== null)
  1847. {
  1848. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
  1849. }
  1850. else
  1851. {
  1852. return null;
  1853. }
  1854. }
  1855. /**
  1856. * Creates the subscribe_* methods' return data
  1857. *
  1858. * @access private
  1859. * @param string $feed_url String to prefix to the feed URL
  1860. * @param string $site_url String to prefix to the site URL (and
  1861. * suffix to the feed URL)
  1862. * @return mixed URL if feed exists, false otherwise
  1863. */
  1864. function subscribe_service($feed_url, $site_url = null)
  1865. {
  1866. if ($this->subscribe_url())
  1867. {
  1868. $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
  1869. if ($site_url !== null && $this->get_link() !== null)
  1870. {
  1871. $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
  1872. }
  1873. return $return;
  1874. }
  1875. else
  1876. {
  1877. return null;
  1878. }
  1879. }
  1880. function subscribe_aol()
  1881. {
  1882. return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
  1883. }
  1884. function subscribe_bloglines()
  1885. {
  1886. return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
  1887. }
  1888. function subscribe_eskobo()
  1889. {
  1890. return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
  1891. }
  1892. function subscribe_feedfeeds()
  1893. {
  1894. return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
  1895. }
  1896. function subscribe_feedster()
  1897. {
  1898. return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
  1899. }
  1900. function subscribe_google()
  1901. {
  1902. return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
  1903. }
  1904. function subscribe_gritwire()
  1905. {
  1906. return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
  1907. }
  1908. function subscribe_msn()
  1909. {
  1910. return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
  1911. }
  1912. function subscribe_netvibes()
  1913. {
  1914. return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
  1915. }
  1916. function subscribe_newsburst()
  1917. {
  1918. return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
  1919. }
  1920. function subscribe_newsgator()
  1921. {
  1922. return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
  1923. }
  1924. function subscribe_odeo()
  1925. {
  1926. return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
  1927. }
  1928. function subscribe_podnova()
  1929. {
  1930. return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
  1931. }
  1932. function subscribe_rojo()
  1933. {
  1934. return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
  1935. }
  1936. function subscribe_yahoo()
  1937. {
  1938. return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
  1939. }
  1940. function get_feed_tags($namespace, $tag)
  1941. {
  1942. $type = $this->get_type();
  1943. if ($type & SIMPLEPIE_TYPE_ATOM_10)
  1944. {
  1945. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
  1946. {
  1947. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
  1948. }
  1949. }
  1950. if ($type & SIMPLEPIE_TYPE_ATOM_03)
  1951. {
  1952. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
  1953. {
  1954. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
  1955. }
  1956. }
  1957. if ($type & SIMPLEPIE_TYPE_RSS_RDF)
  1958. {
  1959. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
  1960. {
  1961. return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
  1962. }
  1963. }
  1964. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  1965. {
  1966. if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
  1967. {
  1968. return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
  1969. }
  1970. }
  1971. return null;
  1972. }
  1973. function get_channel_tags($namespace, $tag)
  1974. {
  1975. $type = $this->get_type();
  1976. if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
  1977. {
  1978. if ($return = $this->get_feed_tags($namespace, $tag))
  1979. {
  1980. return $return;
  1981. }
  1982. }
  1983. if ($type & SIMPLEPIE_TYPE_RSS_10)
  1984. {
  1985. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
  1986. {
  1987. if (isset($channel[0]['child'][$namespace][$tag]))
  1988. {
  1989. return $channel[0]['child'][$namespace][$tag];
  1990. }
  1991. }
  1992. }
  1993. if ($type & SIMPLEPIE_TYPE_RSS_090)
  1994. {
  1995. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
  1996. {
  1997. if (isset($channel[0]['child'][$namespace][$tag]))
  1998. {
  1999. return $channel[0]['child'][$namespace][$tag];
  2000. }
  2001. }
  2002. }
  2003. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  2004. {
  2005. if ($channel = $this->get_feed_tags('', 'channel'))
  2006. {
  2007. if (isset($channel[0]['child'][$namespace][$tag]))
  2008. {
  2009. return $channel[0]['child'][$namespace][$tag];
  2010. }
  2011. }
  2012. }
  2013. return null;
  2014. }
  2015. function get_image_tags($namespace, $tag)
  2016. {
  2017. $type = $this->get_type();
  2018. if ($type & SIMPLEPIE_TYPE_RSS_10)
  2019. {
  2020. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
  2021. {
  2022. if (isset($image[0]['child'][$namespace][$tag]))
  2023. {
  2024. return $image[0]['child'][$namespace][$tag];
  2025. }
  2026. }
  2027. }
  2028. if ($type & SIMPLEPIE_TYPE_RSS_090)
  2029. {
  2030. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
  2031. {
  2032. if (isset($image[0]['child'][$namespace][$tag]))
  2033. {
  2034. return $image[0]['child'][$namespace][$tag];
  2035. }
  2036. }
  2037. }
  2038. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  2039. {
  2040. if ($image = $this->get_channel_tags('', 'image'))
  2041. {
  2042. if (isset($image[0]['child'][$namespace][$tag]))
  2043. {
  2044. return $image[0]['child'][$namespace][$tag];
  2045. }
  2046. }
  2047. }
  2048. return null;
  2049. }
  2050. function get_base($element = array())
  2051. {
  2052. if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
  2053. {
  2054. return $element['xml_base'];
  2055. }
  2056. elseif ($this->get_link() !== null)
  2057. {
  2058. return $this->get_link();
  2059. }
  2060. else
  2061. {
  2062. return $this->subscribe_url();
  2063. }
  2064. }
  2065. function sanitize($data, $type, $base = '')
  2066. {
  2067. return $this->sanitize->sanitize($data, $type, $base);
  2068. }
  2069. function get_title()
  2070. {
  2071. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  2072. {
  2073. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2074. }
  2075. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  2076. {
  2077. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2078. }
  2079. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2080. {
  2081. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2082. }
  2083. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2084. {
  2085. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2086. }
  2087. elseif ($return = $this->get_channel_tags('', 'title'))
  2088. {
  2089. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2090. }
  2091. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2092. {
  2093. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2094. }
  2095. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2096. {
  2097. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2098. }
  2099. else
  2100. {
  2101. return null;
  2102. }
  2103. }
  2104. function get_category($key = 0)
  2105. {
  2106. $categories = $this->get_categories();
  2107. if (isset($categories[$key]))
  2108. {
  2109. return $categories[$key];
  2110. }
  2111. else
  2112. {
  2113. return null;
  2114. }
  2115. }
  2116. function get_categories()
  2117. {
  2118. $categories = array();
  2119. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  2120. {
  2121. $term = null;
  2122. $scheme = null;
  2123. $label = null;
  2124. if (isset($category['attribs']['']['term']))
  2125. {
  2126. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  2127. }
  2128. if (isset($category['attribs']['']['scheme']))
  2129. {
  2130. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  2131. }
  2132. if (isset($category['attribs']['']['label']))
  2133. {
  2134. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  2135. }
  2136. $categories[] =& new $this->category_class($term, $scheme, $label);
  2137. }
  2138. foreach ((array) $this->get_channel_tags('', 'category') as $category)
  2139. {
  2140. $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2141. }
  2142. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  2143. {
  2144. $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2145. }
  2146. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  2147. {
  2148. $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2149. }
  2150. if (!empty($categories))
  2151. {
  2152. return SimplePie_Misc::array_unique($categories);
  2153. }
  2154. else
  2155. {
  2156. return null;
  2157. }
  2158. }
  2159. function get_author($key = 0)
  2160. {
  2161. $authors = $this->get_authors();
  2162. if (isset($authors[$key]))
  2163. {
  2164. return $authors[$key];
  2165. }
  2166. else
  2167. {
  2168. return null;
  2169. }
  2170. }
  2171. function get_authors()
  2172. {
  2173. $authors = array();
  2174. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  2175. {
  2176. $name = null;
  2177. $uri = null;
  2178. $email = null;
  2179. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  2180. {
  2181. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2182. }
  2183. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  2184. {
  2185. $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]));
  2186. }
  2187. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  2188. {
  2189. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2190. }
  2191. if ($name !== null || $email !== null || $uri !== null)
  2192. {
  2193. $authors[] =& new $this->author_class($name, $uri, $email);
  2194. }
  2195. }
  2196. if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  2197. {
  2198. $name = null;
  2199. $url = null;
  2200. $email = null;
  2201. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  2202. {
  2203. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2204. }
  2205. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  2206. {
  2207. $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]));
  2208. }
  2209. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  2210. {
  2211. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2212. }
  2213. if ($name !== null || $email !== null || $url !== null)
  2214. {
  2215. $authors[] =& new $this->author_class($name, $url, $email);
  2216. }
  2217. }
  2218. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  2219. {
  2220. $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2221. }
  2222. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  2223. {
  2224. $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2225. }
  2226. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  2227. {
  2228. $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2229. }
  2230. if (!empty($authors))
  2231. {
  2232. return SimplePie_Misc::array_unique($authors);
  2233. }
  2234. else
  2235. {
  2236. return null;
  2237. }
  2238. }
  2239. function get_contributor($key = 0)
  2240. {
  2241. $contributors = $this->get_contributors();
  2242. if (isset($contributors[$key]))
  2243. {
  2244. return $contributors[$key];
  2245. }
  2246. else
  2247. {
  2248. return null;
  2249. }
  2250. }
  2251. function get_contributors()
  2252. {
  2253. $contributors = array();
  2254. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  2255. {
  2256. $name = null;
  2257. $uri = null;
  2258. $email = null;
  2259. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  2260. {
  2261. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2262. }
  2263. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  2264. {
  2265. $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]));
  2266. }
  2267. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  2268. {
  2269. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2270. }
  2271. if ($name !== null || $email !== null || $uri !== null)
  2272. {
  2273. $contributors[] =& new $this->author_class($name, $uri, $email);
  2274. }
  2275. }
  2276. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  2277. {
  2278. $name = null;
  2279. $url = null;
  2280. $email = null;
  2281. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  2282. {
  2283. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2284. }
  2285. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  2286. {
  2287. $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]));
  2288. }
  2289. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  2290. {
  2291. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2292. }
  2293. if ($name !== null || $email !== null || $url !== null)
  2294. {
  2295. $contributors[] =& new $this->author_class($name, $url, $email);
  2296. }
  2297. }
  2298. if (!empty($contributors))
  2299. {
  2300. return SimplePie_Misc::array_unique($contributors);
  2301. }
  2302. else
  2303. {
  2304. return null;
  2305. }
  2306. }
  2307. function get_link($key = 0, $rel = 'alternate')
  2308. {
  2309. $links = $this->get_links($rel);
  2310. if (isset($links[$key]))
  2311. {
  2312. return $links[$key];
  2313. }
  2314. else
  2315. {
  2316. return null;
  2317. }
  2318. }
  2319. /**
  2320. * Added for parity between the parent-level and the item/entry-level.
  2321. */
  2322. function get_permalink()
  2323. {
  2324. return $this->get_link(0);
  2325. }
  2326. function get_links($rel = 'alternate')
  2327. {
  2328. if (!isset($this->data['links']))
  2329. {
  2330. $this->data['links'] = array();
  2331. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  2332. {
  2333. foreach ($links as $link)
  2334. {
  2335. if (isset($link['attribs']['']['href']))
  2336. {
  2337. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2338. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2339. }
  2340. }
  2341. }
  2342. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  2343. {
  2344. foreach ($links as $link)
  2345. {
  2346. if (isset($link['attribs']['']['href']))
  2347. {
  2348. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2349. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2350. }
  2351. }
  2352. }
  2353. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2354. {
  2355. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2356. }
  2357. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2358. {
  2359. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2360. }
  2361. if ($links = $this->get_channel_tags('', 'link'))
  2362. {
  2363. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2364. }
  2365. $keys = array_keys($this->data['links']);
  2366. foreach ($keys as $key)
  2367. {
  2368. if (SimplePie_Misc::is_isegment_nz_nc($key))
  2369. {
  2370. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  2371. {
  2372. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  2373. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  2374. }
  2375. else
  2376. {
  2377. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  2378. }
  2379. }
  2380. elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  2381. {
  2382. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  2383. }
  2384. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  2385. }
  2386. }
  2387. if (isset($this->data['links'][$rel]))
  2388. {
  2389. return $this->data['links'][$rel];
  2390. }
  2391. else
  2392. {
  2393. return null;
  2394. }
  2395. }
  2396. function get_description()
  2397. {
  2398. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  2399. {
  2400. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2401. }
  2402. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  2403. {
  2404. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2405. }
  2406. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  2407. {
  2408. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2409. }
  2410. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  2411. {
  2412. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2413. }
  2414. elseif ($return = $this->get_channel_tags('', 'description'))
  2415. {
  2416. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2417. }
  2418. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  2419. {
  2420. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2421. }
  2422. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  2423. {
  2424. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2425. }
  2426. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  2427. {
  2428. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2429. }
  2430. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  2431. {
  2432. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2433. }
  2434. else
  2435. {
  2436. return null;
  2437. }
  2438. }
  2439. function get_copyright()
  2440. {
  2441. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  2442. {
  2443. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2444. }
  2445. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
  2446. {
  2447. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2448. }
  2449. elseif ($return = $this->get_channel_tags('', 'copyright'))
  2450. {
  2451. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2452. }
  2453. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  2454. {
  2455. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2456. }
  2457. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  2458. {
  2459. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2460. }
  2461. else
  2462. {
  2463. return null;
  2464. }
  2465. }
  2466. function get_language()
  2467. {
  2468. if ($return = $this->get_channel_tags('', 'language'))
  2469. {
  2470. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2471. }
  2472. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  2473. {
  2474. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2475. }
  2476. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  2477. {
  2478. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2479. }
  2480. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
  2481. {
  2482. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2483. }
  2484. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
  2485. {
  2486. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2487. }
  2488. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
  2489. {
  2490. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2491. }
  2492. elseif (isset($this->data['headers']['content-language']))
  2493. {
  2494. return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
  2495. }
  2496. else
  2497. {
  2498. return null;
  2499. }
  2500. }
  2501. function get_latitude()
  2502. {
  2503. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  2504. {
  2505. return (float) $return[0]['data'];
  2506. }
  2507. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  2508. {
  2509. return (float) $match[1];
  2510. }
  2511. else
  2512. {
  2513. return null;
  2514. }
  2515. }
  2516. function get_longitude()
  2517. {
  2518. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  2519. {
  2520. return (float) $return[0]['data'];
  2521. }
  2522. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  2523. {
  2524. return (float) $return[0]['data'];
  2525. }
  2526. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  2527. {
  2528. return (float) $match[2];
  2529. }
  2530. else
  2531. {
  2532. return null;
  2533. }
  2534. }
  2535. function get_image_title()
  2536. {
  2537. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2538. {
  2539. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2540. }
  2541. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2542. {
  2543. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2544. }
  2545. elseif ($return = $this->get_image_tags('', 'title'))
  2546. {
  2547. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2548. }
  2549. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2550. {
  2551. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2552. }
  2553. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2554. {
  2555. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2556. }
  2557. else
  2558. {
  2559. return null;
  2560. }
  2561. }
  2562. function get_image_url()
  2563. {
  2564. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  2565. {
  2566. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  2567. }
  2568. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  2569. {
  2570. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2571. }
  2572. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  2573. {
  2574. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2575. }
  2576. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
  2577. {
  2578. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2579. }
  2580. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
  2581. {
  2582. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2583. }
  2584. elseif ($return = $this->get_image_tags('', 'url'))
  2585. {
  2586. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2587. }
  2588. else
  2589. {
  2590. return null;
  2591. }
  2592. }
  2593. function get_image_link()
  2594. {
  2595. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2596. {
  2597. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2598. }
  2599. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2600. {
  2601. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2602. }
  2603. elseif ($return = $this->get_image_tags('', 'link'))
  2604. {
  2605. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2606. }
  2607. else
  2608. {
  2609. return null;
  2610. }
  2611. }
  2612. function get_image_width()
  2613. {
  2614. if ($return = $this->get_image_tags('', 'width'))
  2615. {
  2616. return round($return[0]['data']);
  2617. }
  2618. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
  2619. {
  2620. return 88.0;
  2621. }
  2622. else
  2623. {
  2624. return null;
  2625. }
  2626. }
  2627. function get_image_height()
  2628. {
  2629. if ($return = $this->get_image_tags('', 'height'))
  2630. {
  2631. return round($return[0]['data']);
  2632. }
  2633. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
  2634. {
  2635. return 31.0;
  2636. }
  2637. else
  2638. {
  2639. return null;
  2640. }
  2641. }
  2642. function get_item_quantity($max = 0)
  2643. {
  2644. $qty = count($this->get_items());
  2645. if ($max == 0)
  2646. {
  2647. return $qty;
  2648. }
  2649. else
  2650. {
  2651. return ($qty > $max) ? $max : $qty;
  2652. }
  2653. }
  2654. function get_item($key = 0)
  2655. {
  2656. $items = $this->get_items();
  2657. if (isset($items[$key]))
  2658. {
  2659. return $items[$key];
  2660. }
  2661. else
  2662. {
  2663. return null;
  2664. }
  2665. }
  2666. function get_items($start = 0, $end = 0)
  2667. {
  2668. if (!empty($this->multifeed_objects))
  2669. {
  2670. return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
  2671. }
  2672. elseif (!isset($this->data['items']))
  2673. {
  2674. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
  2675. {
  2676. $keys = array_keys($items);
  2677. foreach ($keys as $key)
  2678. {
  2679. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2680. }
  2681. }
  2682. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
  2683. {
  2684. $keys = array_keys($items);
  2685. foreach ($keys as $key)
  2686. {
  2687. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2688. }
  2689. }
  2690. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
  2691. {
  2692. $keys = array_keys($items);
  2693. foreach ($keys as $key)
  2694. {
  2695. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2696. }
  2697. }
  2698. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
  2699. {
  2700. $keys = array_keys($items);
  2701. foreach ($keys as $key)
  2702. {
  2703. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2704. }
  2705. }
  2706. if ($items = $this->get_channel_tags('', 'item'))
  2707. {
  2708. $keys = array_keys($items);
  2709. foreach ($keys as $key)
  2710. {
  2711. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2712. }
  2713. }
  2714. }
  2715. if (!empty($this->data['items']))
  2716. {
  2717. // If we want to order it by date, check if all items have a date, and then sort it
  2718. if ($this->order_by_date)
  2719. {
  2720. if (!isset($this->data['ordered_items']))
  2721. {
  2722. $do_sort = true;
  2723. foreach ($this->data['items'] as $item)
  2724. {
  2725. if (!$item->get_date('U'))
  2726. {
  2727. $do_sort = false;
  2728. break;
  2729. }
  2730. }
  2731. $item = null;
  2732. $this->data['ordered_items'] = $this->data['items'];
  2733. if ($do_sort)
  2734. {
  2735. usort($this->data['ordered_items'], array(&$this, 'sort_items'));
  2736. }
  2737. }
  2738. $items = $this->data['ordered_items'];
  2739. }
  2740. else
  2741. {
  2742. $items = $this->data['items'];
  2743. }
  2744. // Slice the data as desired
  2745. if ($end == 0)
  2746. {
  2747. return array_slice($items, $start);
  2748. }
  2749. else
  2750. {
  2751. return array_slice($items, $start, $end);
  2752. }
  2753. }
  2754. else
  2755. {
  2756. return array();
  2757. }
  2758. }
  2759. function sort_items($a, $b)
  2760. {
  2761. return $a->get_date('U') <= $b->get_date('U');
  2762. }
  2763. function merge_items($urls, $start = 0, $end = 0, $limit = 0)
  2764. {
  2765. if (is_array($urls) && sizeof($urls) > 0)
  2766. {
  2767. $items = array();
  2768. foreach ($urls as $arg)
  2769. {
  2770. if (is_a($arg, 'SimplePie'))
  2771. {
  2772. $items = array_merge($items, $arg->get_items(0, $limit));
  2773. }
  2774. else
  2775. {
  2776. trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
  2777. }
  2778. }
  2779. $do_sort = true;
  2780. foreach ($items as $item)
  2781. {
  2782. if (!$item->get_date('U'))
  2783. {
  2784. $do_sort = false;
  2785. break;
  2786. }
  2787. }
  2788. $item = null;
  2789. if ($do_sort)
  2790. {
  2791. usort($items, array('SimplePie', 'sort_items'));
  2792. }
  2793. if ($end == 0)
  2794. {
  2795. return array_slice($items, $start);
  2796. }
  2797. else
  2798. {
  2799. return array_slice($items, $start, $end);
  2800. }
  2801. }
  2802. else
  2803. {
  2804. trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
  2805. return array();
  2806. }
  2807. }
  2808. }
  2809. class SimplePie_Item
  2810. {
  2811. var $feed;
  2812. var $data = array();
  2813. function SimplePie_Item($feed, $data)
  2814. {
  2815. $this->feed = $feed;
  2816. $this->data = $data;
  2817. }
  2818. function __toString()
  2819. {
  2820. return md5(serialize($this->data));
  2821. }
  2822. /**
  2823. * Remove items that link back to this before destroying this object
  2824. */
  2825. function __destruct()
  2826. {
  2827. unset($this->feed);
  2828. }
  2829. function get_item_tags($namespace, $tag)
  2830. {
  2831. if (isset($this->data['child'][$namespace][$tag]))
  2832. {
  2833. return $this->data['child'][$namespace][$tag];
  2834. }
  2835. else
  2836. {
  2837. return null;
  2838. }
  2839. }
  2840. function get_base($element = array())
  2841. {
  2842. return $this->feed->get_base($element);
  2843. }
  2844. function sanitize($data, $type, $base = '')
  2845. {
  2846. return $this->feed->sanitize($data, $type, $base);
  2847. }
  2848. function get_feed()
  2849. {
  2850. return $this->feed;
  2851. }
  2852. function get_id($hash = false)
  2853. {
  2854. if (!$hash)
  2855. {
  2856. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
  2857. {
  2858. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2859. }
  2860. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
  2861. {
  2862. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2863. }
  2864. elseif ($return = $this->get_item_tags('', 'guid'))
  2865. {
  2866. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2867. }
  2868. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
  2869. {
  2870. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2871. }
  2872. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
  2873. {
  2874. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2875. }
  2876. elseif (($return = $this->get_permalink()) !== null)
  2877. {
  2878. return $return;
  2879. }
  2880. elseif (($return = $this->get_title()) !== null)
  2881. {
  2882. return $return;
  2883. }
  2884. }
  2885. if ($this->get_permalink() !== null || $this->get_title() !== null)
  2886. {
  2887. return md5($this->get_permalink() . $this->get_title());
  2888. }
  2889. else
  2890. {
  2891. return md5(serialize($this->data));
  2892. }
  2893. }
  2894. function get_title()
  2895. {
  2896. if (!isset($this->data['title']))
  2897. {
  2898. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  2899. {
  2900. $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2901. }
  2902. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  2903. {
  2904. $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2905. }
  2906. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2907. {
  2908. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2909. }
  2910. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2911. {
  2912. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2913. }
  2914. elseif ($return = $this->get_item_tags('', 'title'))
  2915. {
  2916. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2917. }
  2918. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2919. {
  2920. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2921. }
  2922. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2923. {
  2924. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2925. }
  2926. else
  2927. {
  2928. $this->data['title'] = null;
  2929. }
  2930. }
  2931. return $this->data['title'];
  2932. }
  2933. function get_description($description_only = false)
  2934. {
  2935. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
  2936. {
  2937. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2938. }
  2939. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
  2940. {
  2941. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2942. }
  2943. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  2944. {
  2945. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2946. }
  2947. elseif ($return = $this->get_item_tags('', 'description'))
  2948. {
  2949. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2950. }
  2951. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  2952. {
  2953. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2954. }
  2955. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  2956. {
  2957. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2958. }
  2959. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  2960. {
  2961. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2962. }
  2963. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  2964. {
  2965. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2966. }
  2967. elseif (!$description_only)
  2968. {
  2969. return $this->get_content(true);
  2970. }
  2971. else
  2972. {
  2973. return null;
  2974. }
  2975. }
  2976. function get_content($content_only = false)
  2977. {
  2978. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
  2979. {
  2980. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2981. }
  2982. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
  2983. {
  2984. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2985. }
  2986. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
  2987. {
  2988. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2989. }
  2990. elseif (!$content_only)
  2991. {
  2992. return $this->get_description(true);
  2993. }
  2994. else
  2995. {
  2996. return null;
  2997. }
  2998. }
  2999. function get_category($key = 0)
  3000. {
  3001. $categories = $this->get_categories();
  3002. if (isset($categories[$key]))
  3003. {
  3004. return $categories[$key];
  3005. }
  3006. else
  3007. {
  3008. return null;
  3009. }
  3010. }
  3011. function get_categories()
  3012. {
  3013. $categories = array();
  3014. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  3015. {
  3016. $term = null;
  3017. $scheme = null;
  3018. $label = null;
  3019. if (isset($category['attribs']['']['term']))
  3020. {
  3021. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  3022. }
  3023. if (isset($category['attribs']['']['scheme']))
  3024. {
  3025. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3026. }
  3027. if (isset($category['attribs']['']['label']))
  3028. {
  3029. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3030. }
  3031. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  3032. }
  3033. foreach ((array) $this->get_item_tags('', 'category') as $category)
  3034. {
  3035. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3036. }
  3037. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  3038. {
  3039. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3040. }
  3041. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  3042. {
  3043. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3044. }
  3045. if (!empty($categories))
  3046. {
  3047. return SimplePie_Misc::array_unique($categories);
  3048. }
  3049. else
  3050. {
  3051. return null;
  3052. }
  3053. }
  3054. function get_author($key = 0)
  3055. {
  3056. $authors = $this->get_authors();
  3057. if (isset($authors[$key]))
  3058. {
  3059. return $authors[$key];
  3060. }
  3061. else
  3062. {
  3063. return null;
  3064. }
  3065. }
  3066. function get_contributor($key = 0)
  3067. {
  3068. $contributors = $this->get_contributors();
  3069. if (isset($contributors[$key]))
  3070. {
  3071. return $contributors[$key];
  3072. }
  3073. else
  3074. {
  3075. return null;
  3076. }
  3077. }
  3078. function get_contributors()
  3079. {
  3080. $contributors = array();
  3081. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  3082. {
  3083. $name = null;
  3084. $uri = null;
  3085. $email = null;
  3086. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  3087. {
  3088. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3089. }
  3090. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  3091. {
  3092. $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]));
  3093. }
  3094. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  3095. {
  3096. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3097. }
  3098. if ($name !== null || $email !== null || $uri !== null)
  3099. {
  3100. $contributors[] =& new $this->feed->author_class($name, $uri, $email);
  3101. }
  3102. }
  3103. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  3104. {
  3105. $name = null;
  3106. $url = null;
  3107. $email = null;
  3108. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  3109. {
  3110. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3111. }
  3112. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  3113. {
  3114. $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]));
  3115. }
  3116. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  3117. {
  3118. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3119. }
  3120. if ($name !== null || $email !== null || $url !== null)
  3121. {
  3122. $contributors[] =& new $this->feed->author_class($name, $url, $email);
  3123. }
  3124. }
  3125. if (!empty($contributors))
  3126. {
  3127. return SimplePie_Misc::array_unique($contributors);
  3128. }
  3129. else
  3130. {
  3131. return null;
  3132. }
  3133. }
  3134. /**
  3135. * @todo Atom inheritance (item author, source author, feed author)
  3136. */
  3137. function get_authors()
  3138. {
  3139. $authors = array();
  3140. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  3141. {
  3142. $name = null;
  3143. $uri = null;
  3144. $email = null;
  3145. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  3146. {
  3147. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3148. }
  3149. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  3150. {
  3151. $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]));
  3152. }
  3153. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  3154. {
  3155. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3156. }
  3157. if ($name !== null || $email !== null || $uri !== null)
  3158. {
  3159. $authors[] =& new $this->feed->author_class($name, $uri, $email);
  3160. }
  3161. }
  3162. if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  3163. {
  3164. $name = null;
  3165. $url = null;
  3166. $email = null;
  3167. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  3168. {
  3169. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3170. }
  3171. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  3172. {
  3173. $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]));
  3174. }
  3175. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  3176. {
  3177. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3178. }
  3179. if ($name !== null || $email !== null || $url !== null)
  3180. {
  3181. $authors[] =& new $this->feed->author_class($name, $url, $email);
  3182. }
  3183. }
  3184. if ($author = $this->get_item_tags('', 'author'))
  3185. {
  3186. $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3187. }
  3188. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  3189. {
  3190. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3191. }
  3192. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  3193. {
  3194. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3195. }
  3196. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  3197. {
  3198. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3199. }
  3200. if (!empty($authors))
  3201. {
  3202. return SimplePie_Misc::array_unique($authors);
  3203. }
  3204. elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
  3205. {
  3206. return $authors;
  3207. }
  3208. elseif ($authors = $this->feed->get_authors())
  3209. {
  3210. return $authors;
  3211. }
  3212. else
  3213. {
  3214. return null;
  3215. }
  3216. }
  3217. function get_copyright()
  3218. {
  3219. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  3220. {
  3221. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  3222. }
  3223. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  3224. {
  3225. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3226. }
  3227. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  3228. {
  3229. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3230. }
  3231. else
  3232. {
  3233. return null;
  3234. }
  3235. }
  3236. function get_date($date_format = 'j F Y, g:i a')
  3237. {
  3238. if (!isset($this->data['date']))
  3239. {
  3240. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
  3241. {
  3242. $this->data['date']['raw'] = $return[0]['data'];
  3243. }
  3244. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
  3245. {
  3246. $this->data['date']['raw'] = $return[0]['data'];
  3247. }
  3248. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
  3249. {
  3250. $this->data['date']['raw'] = $return[0]['data'];
  3251. }
  3252. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
  3253. {
  3254. $this->data['date']['raw'] = $return[0]['data'];
  3255. }
  3256. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
  3257. {
  3258. $this->data['date']['raw'] = $return[0]['data'];
  3259. }
  3260. elseif ($return = $this->get_item_tags('', 'pubDate'))
  3261. {
  3262. $this->data['date']['raw'] = $return[0]['data'];
  3263. }
  3264. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
  3265. {
  3266. $this->data['date']['raw'] = $return[0]['data'];
  3267. }
  3268. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
  3269. {
  3270. $this->data['date']['raw'] = $return[0]['data'];
  3271. }
  3272. if (!empty($this->data['date']['raw']))
  3273. {
  3274. $parser = SimplePie_Parse_Date::get();
  3275. $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
  3276. }
  3277. else
  3278. {
  3279. $this->data['date'] = null;
  3280. }
  3281. }
  3282. if ($this->data['date'])
  3283. {
  3284. $date_format = (string) $date_format;
  3285. switch ($date_format)
  3286. {
  3287. case '':
  3288. return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
  3289. case 'U':
  3290. return $this->data['date']['parsed'];
  3291. default:
  3292. return date($date_format, $this->data['date']['parsed']);
  3293. }
  3294. }
  3295. else
  3296. {
  3297. return null;
  3298. }
  3299. }
  3300. function get_local_date($date_format = '%c')
  3301. {
  3302. if (!$date_format)
  3303. {
  3304. return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
  3305. }
  3306. elseif (($date = $this->get_date('U')) !== null)
  3307. {
  3308. return strftime($date_format, $date);
  3309. }
  3310. else
  3311. {
  3312. return null;
  3313. }
  3314. }
  3315. function get_permalink()
  3316. {
  3317. $link = $this->get_link();
  3318. $enclosure = $this->get_enclosure(0);
  3319. if ($link !== null)
  3320. {
  3321. return $link;
  3322. }
  3323. elseif ($enclosure !== null)
  3324. {
  3325. return $enclosure->get_link();
  3326. }
  3327. else
  3328. {
  3329. return null;
  3330. }
  3331. }
  3332. function get_link($key = 0, $rel = 'alternate')
  3333. {
  3334. $links = $this->get_links($rel);
  3335. if ($links[$key] !== null)
  3336. {
  3337. return $links[$key];
  3338. }
  3339. else
  3340. {
  3341. return null;
  3342. }
  3343. }
  3344. function get_links($rel = 'alternate')
  3345. {
  3346. if (!isset($this->data['links']))
  3347. {
  3348. $this->data['links'] = array();
  3349. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  3350. {
  3351. if (isset($link['attribs']['']['href']))
  3352. {
  3353. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  3354. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  3355. }
  3356. }
  3357. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  3358. {
  3359. if (isset($link['attribs']['']['href']))
  3360. {
  3361. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  3362. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  3363. }
  3364. }
  3365. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  3366. {
  3367. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3368. }
  3369. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  3370. {
  3371. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3372. }
  3373. if ($links = $this->get_item_tags('', 'link'))
  3374. {
  3375. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3376. }
  3377. if ($links = $this->get_item_tags('', 'guid'))
  3378. {
  3379. if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
  3380. {
  3381. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3382. }
  3383. }
  3384. $keys = array_keys($this->data['links']);
  3385. foreach ($keys as $key)
  3386. {
  3387. if (SimplePie_Misc::is_isegment_nz_nc($key))
  3388. {
  3389. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  3390. {
  3391. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  3392. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  3393. }
  3394. else
  3395. {
  3396. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  3397. }
  3398. }
  3399. elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  3400. {
  3401. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  3402. }
  3403. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  3404. }
  3405. }
  3406. if (isset($this->data['links'][$rel]))
  3407. {
  3408. return $this->data['links'][$rel];
  3409. }
  3410. else
  3411. {
  3412. return null;
  3413. }
  3414. }
  3415. /**
  3416. * @todo Add ability to prefer one type of content over another (in a media group).
  3417. */
  3418. function get_enclosure($key = 0, $prefer = null)
  3419. {
  3420. $enclosures = $this->get_enclosures();
  3421. if (isset($enclosures[$key]))
  3422. {
  3423. return $enclosures[$key];
  3424. }
  3425. else
  3426. {
  3427. return null;
  3428. }
  3429. }
  3430. /**
  3431. * Grabs all available enclosures (podcasts, etc.)
  3432. *
  3433. * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
  3434. *
  3435. * At this point, we're pretty much assuming that all enclosures for an item are the same content. Anything else is too complicated to properly support.
  3436. *
  3437. * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
  3438. * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists).
  3439. */
  3440. function get_enclosures()
  3441. {
  3442. if (!isset($this->data['enclosures']))
  3443. {
  3444. $this->data['enclosures'] = array();
  3445. // Elements
  3446. $captions_parent = null;
  3447. $categories_parent = null;
  3448. $copyrights_parent = null;
  3449. $credits_parent = null;
  3450. $description_parent = null;
  3451. $duration_parent = null;
  3452. $hashes_parent = null;
  3453. $keywords_parent = null;
  3454. $player_parent = null;
  3455. $ratings_parent = null;
  3456. $restrictions_parent = null;
  3457. $thumbnails_parent = null;
  3458. $title_parent = null;
  3459. // Let's do the channel and item-level ones first, and just re-use them if we need to.
  3460. $parent = $this->get_feed();
  3461. // CAPTIONS
  3462. if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  3463. {
  3464. foreach ($captions as $caption)
  3465. {
  3466. $caption_type = null;
  3467. $caption_lang = null;
  3468. $caption_startTime = null;
  3469. $caption_endTime = null;
  3470. $caption_text = null;
  3471. if (isset($caption['attribs']['']['type']))
  3472. {
  3473. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3474. }
  3475. if (isset($caption['attribs']['']['lang']))
  3476. {
  3477. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3478. }
  3479. if (isset($caption['attribs']['']['start']))
  3480. {
  3481. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3482. }
  3483. if (isset($caption['attribs']['']['end']))
  3484. {
  3485. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3486. }
  3487. if (isset($caption['data']))
  3488. {
  3489. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3490. }
  3491. $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3492. }
  3493. }
  3494. elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  3495. {
  3496. foreach ($captions as $caption)
  3497. {
  3498. $caption_type = null;
  3499. $caption_lang = null;
  3500. $caption_startTime = null;
  3501. $caption_endTime = null;
  3502. $caption_text = null;
  3503. if (isset($caption['attribs']['']['type']))
  3504. {
  3505. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3506. }
  3507. if (isset($caption['attribs']['']['lang']))
  3508. {
  3509. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3510. }
  3511. if (isset($caption['attribs']['']['start']))
  3512. {
  3513. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3514. }
  3515. if (isset($caption['attribs']['']['end']))
  3516. {
  3517. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3518. }
  3519. if (isset($caption['data']))
  3520. {
  3521. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3522. }
  3523. $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3524. }
  3525. }
  3526. if (is_array($captions_parent))
  3527. {
  3528. $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
  3529. }
  3530. // CATEGORIES
  3531. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  3532. {
  3533. $term = null;
  3534. $scheme = null;
  3535. $label = null;
  3536. if (isset($category['data']))
  3537. {
  3538. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3539. }
  3540. if (isset($category['attribs']['']['scheme']))
  3541. {
  3542. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3543. }
  3544. else
  3545. {
  3546. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3547. }
  3548. if (isset($category['attribs']['']['label']))
  3549. {
  3550. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3551. }
  3552. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3553. }
  3554. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  3555. {
  3556. $term = null;
  3557. $scheme = null;
  3558. $label = null;
  3559. if (isset($category['data']))
  3560. {
  3561. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3562. }
  3563. if (isset($category['attribs']['']['scheme']))
  3564. {
  3565. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3566. }
  3567. else
  3568. {
  3569. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3570. }
  3571. if (isset($category['attribs']['']['label']))
  3572. {
  3573. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3574. }
  3575. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3576. }
  3577. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
  3578. {
  3579. $term = null;
  3580. $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
  3581. $label = null;
  3582. if (isset($category['attribs']['']['text']))
  3583. {
  3584. $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  3585. }
  3586. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3587. if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
  3588. {
  3589. foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
  3590. {
  3591. if (isset($subcategory['attribs']['']['text']))
  3592. {
  3593. $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  3594. }
  3595. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3596. }
  3597. }
  3598. }
  3599. if (is_array($categories_parent))
  3600. {
  3601. $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
  3602. }
  3603. // COPYRIGHT
  3604. if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  3605. {
  3606. $copyright_url = null;
  3607. $copyright_label = null;
  3608. if (isset($copyright[0]['attribs']['']['url']))
  3609. {
  3610. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3611. }
  3612. if (isset($copyright[0]['data']))
  3613. {
  3614. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3615. }
  3616. $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  3617. }
  3618. elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  3619. {
  3620. $copyright_url = null;
  3621. $copyright_label = null;
  3622. if (isset($copyright[0]['attribs']['']['url']))
  3623. {
  3624. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3625. }
  3626. if (isset($copyright[0]['data']))
  3627. {
  3628. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3629. }
  3630. $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  3631. }
  3632. // CREDITS
  3633. if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  3634. {
  3635. foreach ($credits as $credit)
  3636. {
  3637. $credit_role = null;
  3638. $credit_scheme = null;
  3639. $credit_name = null;
  3640. if (isset($credit['attribs']['']['role']))
  3641. {
  3642. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3643. }
  3644. if (isset($credit['attribs']['']['scheme']))
  3645. {
  3646. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3647. }
  3648. else
  3649. {
  3650. $credit_scheme = 'urn:ebu';
  3651. }
  3652. if (isset($credit['data']))
  3653. {
  3654. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3655. }
  3656. $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3657. }
  3658. }
  3659. elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  3660. {
  3661. foreach ($credits as $credit)
  3662. {
  3663. $credit_role = null;
  3664. $credit_scheme = null;
  3665. $credit_name = null;
  3666. if (isset($credit['attribs']['']['role']))
  3667. {
  3668. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3669. }
  3670. if (isset($credit['attribs']['']['scheme']))
  3671. {
  3672. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3673. }
  3674. else
  3675. {
  3676. $credit_scheme = 'urn:ebu';
  3677. }
  3678. if (isset($credit['data']))
  3679. {
  3680. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3681. }
  3682. $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3683. }
  3684. }
  3685. if (is_array($credits_parent))
  3686. {
  3687. $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
  3688. }
  3689. // DESCRIPTION
  3690. if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  3691. {
  3692. if (isset($description_parent[0]['data']))
  3693. {
  3694. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3695. }
  3696. }
  3697. elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  3698. {
  3699. if (isset($description_parent[0]['data']))
  3700. {
  3701. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3702. }
  3703. }
  3704. // DURATION
  3705. if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
  3706. {
  3707. $seconds = null;
  3708. $minutes = null;
  3709. $hours = null;
  3710. if (isset($duration_parent[0]['data']))
  3711. {
  3712. $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3713. if (sizeof($temp) > 0)
  3714. {
  3715. (int) $seconds = array_pop($temp);
  3716. }
  3717. if (sizeof($temp) > 0)
  3718. {
  3719. (int) $minutes = array_pop($temp);
  3720. $seconds += $minutes * 60;
  3721. }
  3722. if (sizeof($temp) > 0)
  3723. {
  3724. (int) $hours = array_pop($temp);
  3725. $seconds += $hours * 3600;
  3726. }
  3727. unset($temp);
  3728. $duration_parent = $seconds;
  3729. }
  3730. }
  3731. // HASHES
  3732. if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  3733. {
  3734. foreach ($hashes_iterator as $hash)
  3735. {
  3736. $value = null;
  3737. $algo = null;
  3738. if (isset($hash['data']))
  3739. {
  3740. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3741. }
  3742. if (isset($hash['attribs']['']['algo']))
  3743. {
  3744. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3745. }
  3746. else
  3747. {
  3748. $algo = 'md5';
  3749. }
  3750. $hashes_parent[] = $algo.':'.$value;
  3751. }
  3752. }
  3753. elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  3754. {
  3755. foreach ($hashes_iterator as $hash)
  3756. {
  3757. $value = null;
  3758. $algo = null;
  3759. if (isset($hash['data']))
  3760. {
  3761. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3762. }
  3763. if (isset($hash['attribs']['']['algo']))
  3764. {
  3765. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3766. }
  3767. else
  3768. {
  3769. $algo = 'md5';
  3770. }
  3771. $hashes_parent[] = $algo.':'.$value;
  3772. }
  3773. }
  3774. if (is_array($hashes_parent))
  3775. {
  3776. $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
  3777. }
  3778. // KEYWORDS
  3779. if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  3780. {
  3781. if (isset($keywords[0]['data']))
  3782. {
  3783. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3784. foreach ($temp as $word)
  3785. {
  3786. $keywords_parent[] = trim($word);
  3787. }
  3788. }
  3789. unset($temp);
  3790. }
  3791. elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  3792. {
  3793. if (isset($keywords[0]['data']))
  3794. {
  3795. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3796. foreach ($temp as $word)
  3797. {
  3798. $keywords_parent[] = trim($word);
  3799. }
  3800. }
  3801. unset($temp);
  3802. }
  3803. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  3804. {
  3805. if (isset($keywords[0]['data']))
  3806. {
  3807. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3808. foreach ($temp as $word)
  3809. {
  3810. $keywords_parent[] = trim($word);
  3811. }
  3812. }
  3813. unset($temp);
  3814. }
  3815. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  3816. {
  3817. if (isset($keywords[0]['data']))
  3818. {
  3819. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3820. foreach ($temp as $word)
  3821. {
  3822. $keywords_parent[] = trim($word);
  3823. }
  3824. }
  3825. unset($temp);
  3826. }
  3827. if (is_array($keywords_parent))
  3828. {
  3829. $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
  3830. }
  3831. // PLAYER
  3832. if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  3833. {
  3834. if (isset($player_parent[0]['attribs']['']['url']))
  3835. {
  3836. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3837. }
  3838. }
  3839. elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  3840. {
  3841. if (isset($player_parent[0]['attribs']['']['url']))
  3842. {
  3843. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3844. }
  3845. }
  3846. // RATINGS
  3847. if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  3848. {
  3849. foreach ($ratings as $rating)
  3850. {
  3851. $rating_scheme = null;
  3852. $rating_value = null;
  3853. if (isset($rating['attribs']['']['scheme']))
  3854. {
  3855. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3856. }
  3857. else
  3858. {
  3859. $rating_scheme = 'urn:simple';
  3860. }
  3861. if (isset($rating['data']))
  3862. {
  3863. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3864. }
  3865. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3866. }
  3867. }
  3868. elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  3869. {
  3870. foreach ($ratings as $rating)
  3871. {
  3872. $rating_scheme = 'urn:itunes';
  3873. $rating_value = null;
  3874. if (isset($rating['data']))
  3875. {
  3876. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3877. }
  3878. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3879. }
  3880. }
  3881. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  3882. {
  3883. foreach ($ratings as $rating)
  3884. {
  3885. $rating_scheme = null;
  3886. $rating_value = null;
  3887. if (isset($rating['attribs']['']['scheme']))
  3888. {
  3889. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3890. }
  3891. else
  3892. {
  3893. $rating_scheme = 'urn:simple';
  3894. }
  3895. if (isset($rating['data']))
  3896. {
  3897. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3898. }
  3899. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3900. }
  3901. }
  3902. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  3903. {
  3904. foreach ($ratings as $rating)
  3905. {
  3906. $rating_scheme = 'urn:itunes';
  3907. $rating_value = null;
  3908. if (isset($rating['data']))
  3909. {
  3910. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3911. }
  3912. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3913. }
  3914. }
  3915. if (is_array($ratings_parent))
  3916. {
  3917. $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
  3918. }
  3919. // RESTRICTIONS
  3920. if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  3921. {
  3922. foreach ($restrictions as $restriction)
  3923. {
  3924. $restriction_relationship = null;
  3925. $restriction_type = null;
  3926. $restriction_value = null;
  3927. if (isset($restriction['attribs']['']['relationship']))
  3928. {
  3929. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  3930. }
  3931. if (isset($restriction['attribs']['']['type']))
  3932. {
  3933. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3934. }
  3935. if (isset($restriction['data']))
  3936. {
  3937. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3938. }
  3939. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3940. }
  3941. }
  3942. elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  3943. {
  3944. foreach ($restrictions as $restriction)
  3945. {
  3946. $restriction_relationship = 'allow';
  3947. $restriction_type = null;
  3948. $restriction_value = 'itunes';
  3949. if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
  3950. {
  3951. $restriction_relationship = 'deny';
  3952. }
  3953. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3954. }
  3955. }
  3956. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  3957. {
  3958. foreach ($restrictions as $restriction)
  3959. {
  3960. $restriction_relationship = null;
  3961. $restriction_type = null;
  3962. $restriction_value = null;
  3963. if (isset($restriction['attribs']['']['relationship']))
  3964. {
  3965. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  3966. }
  3967. if (isset($restriction['attribs']['']['type']))
  3968. {
  3969. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3970. }
  3971. if (isset($restriction['data']))
  3972. {
  3973. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3974. }
  3975. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3976. }
  3977. }
  3978. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  3979. {
  3980. foreach ($restrictions as $restriction)
  3981. {
  3982. $restriction_relationship = 'allow';
  3983. $restriction_type = null;
  3984. $restriction_value = 'itunes';
  3985. if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
  3986. {
  3987. $restriction_relationship = 'deny';
  3988. }
  3989. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3990. }
  3991. }
  3992. if (is_array($restrictions_parent))
  3993. {
  3994. $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
  3995. }
  3996. // THUMBNAILS
  3997. if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  3998. {
  3999. foreach ($thumbnails as $thumbnail)
  4000. {
  4001. if (isset($thumbnail['attribs']['']['url']))
  4002. {
  4003. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4004. }
  4005. }
  4006. }
  4007. elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  4008. {
  4009. foreach ($thumbnails as $thumbnail)
  4010. {
  4011. if (isset($thumbnail['attribs']['']['url']))
  4012. {
  4013. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4014. }
  4015. }
  4016. }
  4017. // TITLES
  4018. if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  4019. {
  4020. if (isset($title_parent[0]['data']))
  4021. {
  4022. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4023. }
  4024. }
  4025. elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  4026. {
  4027. if (isset($title_parent[0]['data']))
  4028. {
  4029. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4030. }
  4031. }
  4032. // Clear the memory
  4033. unset($parent);
  4034. // Attributes
  4035. $bitrate = null;
  4036. $channels = null;
  4037. $duration = null;
  4038. $expression = null;
  4039. $framerate = null;
  4040. $height = null;
  4041. $javascript = null;
  4042. $lang = null;
  4043. $length = null;
  4044. $medium = null;
  4045. $samplingrate = null;
  4046. $type = null;
  4047. $url = null;
  4048. $width = null;
  4049. // Elements
  4050. $captions = null;
  4051. $categories = null;
  4052. $copyrights = null;
  4053. $credits = null;
  4054. $description = null;
  4055. $hashes = null;
  4056. $keywords = null;
  4057. $player = null;
  4058. $ratings = null;
  4059. $restrictions = null;
  4060. $thumbnails = null;
  4061. $title = null;
  4062. // If we have media:group tags, loop through them.
  4063. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
  4064. {
  4065. // If we have media:content tags, loop through them.
  4066. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  4067. {
  4068. if (isset($content['attribs']['']['url']))
  4069. {
  4070. // Attributes
  4071. $bitrate = null;
  4072. $channels = null;
  4073. $duration = null;
  4074. $expression = null;
  4075. $framerate = null;
  4076. $height = null;
  4077. $javascript = null;
  4078. $lang = null;
  4079. $length = null;
  4080. $medium = null;
  4081. $samplingrate = null;
  4082. $type = null;
  4083. $url = null;
  4084. $width = null;
  4085. // Elements
  4086. $captions = null;
  4087. $categories = null;
  4088. $copyrights = null;
  4089. $credits = null;
  4090. $description = null;
  4091. $hashes = null;
  4092. $keywords = null;
  4093. $player = null;
  4094. $ratings = null;
  4095. $restrictions = null;
  4096. $thumbnails = null;
  4097. $title = null;
  4098. // Start checking the attributes of media:content
  4099. if (isset($content['attribs']['']['bitrate']))
  4100. {
  4101. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4102. }
  4103. if (isset($content['attribs']['']['channels']))
  4104. {
  4105. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  4106. }
  4107. if (isset($content['attribs']['']['duration']))
  4108. {
  4109. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  4110. }
  4111. else
  4112. {
  4113. $duration = $duration_parent;
  4114. }
  4115. if (isset($content['attribs']['']['expression']))
  4116. {
  4117. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  4118. }
  4119. if (isset($content['attribs']['']['framerate']))
  4120. {
  4121. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4122. }
  4123. if (isset($content['attribs']['']['height']))
  4124. {
  4125. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  4126. }
  4127. if (isset($content['attribs']['']['lang']))
  4128. {
  4129. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4130. }
  4131. if (isset($content['attribs']['']['fileSize']))
  4132. {
  4133. $length = ceil($content['attribs']['']['fileSize']);
  4134. }
  4135. if (isset($content['attribs']['']['medium']))
  4136. {
  4137. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  4138. }
  4139. if (isset($content['attribs']['']['samplingrate']))
  4140. {
  4141. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4142. }
  4143. if (isset($content['attribs']['']['type']))
  4144. {
  4145. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4146. }
  4147. if (isset($content['attribs']['']['width']))
  4148. {
  4149. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  4150. }
  4151. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4152. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  4153. // CAPTIONS
  4154. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4155. {
  4156. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4157. {
  4158. $caption_type = null;
  4159. $caption_lang = null;
  4160. $caption_startTime = null;
  4161. $caption_endTime = null;
  4162. $caption_text = null;
  4163. if (isset($caption['attribs']['']['type']))
  4164. {
  4165. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4166. }
  4167. if (isset($caption['attribs']['']['lang']))
  4168. {
  4169. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4170. }
  4171. if (isset($caption['attribs']['']['start']))
  4172. {
  4173. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4174. }
  4175. if (isset($caption['attribs']['']['end']))
  4176. {
  4177. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4178. }
  4179. if (isset($caption['data']))
  4180. {
  4181. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4182. }
  4183. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4184. }
  4185. if (is_array($captions))
  4186. {
  4187. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4188. }
  4189. }
  4190. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4191. {
  4192. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4193. {
  4194. $caption_type = null;
  4195. $caption_lang = null;
  4196. $caption_startTime = null;
  4197. $caption_endTime = null;
  4198. $caption_text = null;
  4199. if (isset($caption['attribs']['']['type']))
  4200. {
  4201. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4202. }
  4203. if (isset($caption['attribs']['']['lang']))
  4204. {
  4205. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4206. }
  4207. if (isset($caption['attribs']['']['start']))
  4208. {
  4209. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4210. }
  4211. if (isset($caption['attribs']['']['end']))
  4212. {
  4213. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4214. }
  4215. if (isset($caption['data']))
  4216. {
  4217. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4218. }
  4219. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4220. }
  4221. if (is_array($captions))
  4222. {
  4223. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4224. }
  4225. }
  4226. else
  4227. {
  4228. $captions = $captions_parent;
  4229. }
  4230. // CATEGORIES
  4231. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4232. {
  4233. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4234. {
  4235. $term = null;
  4236. $scheme = null;
  4237. $label = null;
  4238. if (isset($category['data']))
  4239. {
  4240. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4241. }
  4242. if (isset($category['attribs']['']['scheme']))
  4243. {
  4244. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4245. }
  4246. else
  4247. {
  4248. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4249. }
  4250. if (isset($category['attribs']['']['label']))
  4251. {
  4252. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4253. }
  4254. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4255. }
  4256. }
  4257. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4258. {
  4259. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4260. {
  4261. $term = null;
  4262. $scheme = null;
  4263. $label = null;
  4264. if (isset($category['data']))
  4265. {
  4266. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4267. }
  4268. if (isset($category['attribs']['']['scheme']))
  4269. {
  4270. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4271. }
  4272. else
  4273. {
  4274. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4275. }
  4276. if (isset($category['attribs']['']['label']))
  4277. {
  4278. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4279. }
  4280. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4281. }
  4282. }
  4283. if (is_array($categories) && is_array($categories_parent))
  4284. {
  4285. $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
  4286. }
  4287. elseif (is_array($categories))
  4288. {
  4289. $categories = array_values(SimplePie_Misc::array_unique($categories));
  4290. }
  4291. elseif (is_array($categories_parent))
  4292. {
  4293. $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
  4294. }
  4295. // COPYRIGHTS
  4296. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4297. {
  4298. $copyright_url = null;
  4299. $copyright_label = null;
  4300. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4301. {
  4302. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4303. }
  4304. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4305. {
  4306. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4307. }
  4308. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4309. }
  4310. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4311. {
  4312. $copyright_url = null;
  4313. $copyright_label = null;
  4314. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4315. {
  4316. $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4317. }
  4318. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4319. {
  4320. $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4321. }
  4322. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4323. }
  4324. else
  4325. {
  4326. $copyrights = $copyrights_parent;
  4327. }
  4328. // CREDITS
  4329. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4330. {
  4331. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4332. {
  4333. $credit_role = null;
  4334. $credit_scheme = null;
  4335. $credit_name = null;
  4336. if (isset($credit['attribs']['']['role']))
  4337. {
  4338. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4339. }
  4340. if (isset($credit['attribs']['']['scheme']))
  4341. {
  4342. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4343. }
  4344. else
  4345. {
  4346. $credit_scheme = 'urn:ebu';
  4347. }
  4348. if (isset($credit['data']))
  4349. {
  4350. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4351. }
  4352. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4353. }
  4354. if (is_array($credits))
  4355. {
  4356. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4357. }
  4358. }
  4359. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4360. {
  4361. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4362. {
  4363. $credit_role = null;
  4364. $credit_scheme = null;
  4365. $credit_name = null;
  4366. if (isset($credit['attribs']['']['role']))
  4367. {
  4368. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4369. }
  4370. if (isset($credit['attribs']['']['scheme']))
  4371. {
  4372. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4373. }
  4374. else
  4375. {
  4376. $credit_scheme = 'urn:ebu';
  4377. }
  4378. if (isset($credit['data']))
  4379. {
  4380. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4381. }
  4382. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4383. }
  4384. if (is_array($credits))
  4385. {
  4386. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4387. }
  4388. }
  4389. else
  4390. {
  4391. $credits = $credits_parent;
  4392. }
  4393. // DESCRIPTION
  4394. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4395. {
  4396. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4397. }
  4398. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4399. {
  4400. $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4401. }
  4402. else
  4403. {
  4404. $description = $description_parent;
  4405. }
  4406. // HASHES
  4407. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4408. {
  4409. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4410. {
  4411. $value = null;
  4412. $algo = null;
  4413. if (isset($hash['data']))
  4414. {
  4415. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4416. }
  4417. if (isset($hash['attribs']['']['algo']))
  4418. {
  4419. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4420. }
  4421. else
  4422. {
  4423. $algo = 'md5';
  4424. }
  4425. $hashes[] = $algo.':'.$value;
  4426. }
  4427. if (is_array($hashes))
  4428. {
  4429. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4430. }
  4431. }
  4432. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4433. {
  4434. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4435. {
  4436. $value = null;
  4437. $algo = null;
  4438. if (isset($hash['data']))
  4439. {
  4440. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4441. }
  4442. if (isset($hash['attribs']['']['algo']))
  4443. {
  4444. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4445. }
  4446. else
  4447. {
  4448. $algo = 'md5';
  4449. }
  4450. $hashes[] = $algo.':'.$value;
  4451. }
  4452. if (is_array($hashes))
  4453. {
  4454. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4455. }
  4456. }
  4457. else
  4458. {
  4459. $hashes = $hashes_parent;
  4460. }
  4461. // KEYWORDS
  4462. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4463. {
  4464. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4465. {
  4466. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4467. foreach ($temp as $word)
  4468. {
  4469. $keywords[] = trim($word);
  4470. }
  4471. unset($temp);
  4472. }
  4473. if (is_array($keywords))
  4474. {
  4475. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4476. }
  4477. }
  4478. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4479. {
  4480. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4481. {
  4482. $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4483. foreach ($temp as $word)
  4484. {
  4485. $keywords[] = trim($word);
  4486. }
  4487. unset($temp);
  4488. }
  4489. if (is_array($keywords))
  4490. {
  4491. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4492. }
  4493. }
  4494. else
  4495. {
  4496. $keywords = $keywords_parent;
  4497. }
  4498. // PLAYER
  4499. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4500. {
  4501. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4502. }
  4503. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4504. {
  4505. $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4506. }
  4507. else
  4508. {
  4509. $player = $player_parent;
  4510. }
  4511. // RATINGS
  4512. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4513. {
  4514. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4515. {
  4516. $rating_scheme = null;
  4517. $rating_value = null;
  4518. if (isset($rating['attribs']['']['scheme']))
  4519. {
  4520. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4521. }
  4522. else
  4523. {
  4524. $rating_scheme = 'urn:simple';
  4525. }
  4526. if (isset($rating['data']))
  4527. {
  4528. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4529. }
  4530. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4531. }
  4532. if (is_array($ratings))
  4533. {
  4534. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4535. }
  4536. }
  4537. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4538. {
  4539. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4540. {
  4541. $rating_scheme = null;
  4542. $rating_value = null;
  4543. if (isset($rating['attribs']['']['scheme']))
  4544. {
  4545. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4546. }
  4547. else
  4548. {
  4549. $rating_scheme = 'urn:simple';
  4550. }
  4551. if (isset($rating['data']))
  4552. {
  4553. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4554. }
  4555. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4556. }
  4557. if (is_array($ratings))
  4558. {
  4559. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4560. }
  4561. }
  4562. else
  4563. {
  4564. $ratings = $ratings_parent;
  4565. }
  4566. // RESTRICTIONS
  4567. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4568. {
  4569. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4570. {
  4571. $restriction_relationship = null;
  4572. $restriction_type = null;
  4573. $restriction_value = null;
  4574. if (isset($restriction['attribs']['']['relationship']))
  4575. {
  4576. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4577. }
  4578. if (isset($restriction['attribs']['']['type']))
  4579. {
  4580. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4581. }
  4582. if (isset($restriction['data']))
  4583. {
  4584. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4585. }
  4586. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4587. }
  4588. if (is_array($restrictions))
  4589. {
  4590. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4591. }
  4592. }
  4593. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4594. {
  4595. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4596. {
  4597. $restriction_relationship = null;
  4598. $restriction_type = null;
  4599. $restriction_value = null;
  4600. if (isset($restriction['attribs']['']['relationship']))
  4601. {
  4602. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4603. }
  4604. if (isset($restriction['attribs']['']['type']))
  4605. {
  4606. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4607. }
  4608. if (isset($restriction['data']))
  4609. {
  4610. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4611. }
  4612. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4613. }
  4614. if (is_array($restrictions))
  4615. {
  4616. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4617. }
  4618. }
  4619. else
  4620. {
  4621. $restrictions = $restrictions_parent;
  4622. }
  4623. // THUMBNAILS
  4624. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4625. {
  4626. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4627. {
  4628. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4629. }
  4630. if (is_array($thumbnails))
  4631. {
  4632. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4633. }
  4634. }
  4635. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4636. {
  4637. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4638. {
  4639. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4640. }
  4641. if (is_array($thumbnails))
  4642. {
  4643. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4644. }
  4645. }
  4646. else
  4647. {
  4648. $thumbnails = $thumbnails_parent;
  4649. }
  4650. // TITLES
  4651. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4652. {
  4653. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4654. }
  4655. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4656. {
  4657. $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4658. }
  4659. else
  4660. {
  4661. $title = $title_parent;
  4662. }
  4663. $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
  4664. }
  4665. }
  4666. }
  4667. // If we have standalone media:content tags, loop through them.
  4668. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
  4669. {
  4670. foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  4671. {
  4672. if (isset($content['attribs']['']['url']))
  4673. {
  4674. // Attributes
  4675. $bitrate = null;
  4676. $channels = null;
  4677. $duration = null;
  4678. $expression = null;
  4679. $framerate = null;
  4680. $height = null;
  4681. $javascript = null;
  4682. $lang = null;
  4683. $length = null;
  4684. $medium = null;
  4685. $samplingrate = null;
  4686. $type = null;
  4687. $url = null;
  4688. $width = null;
  4689. // Elements
  4690. $captions = null;
  4691. $categories = null;
  4692. $copyrights = null;
  4693. $credits = null;
  4694. $description = null;
  4695. $hashes = null;
  4696. $keywords = null;
  4697. $player = null;
  4698. $ratings = null;
  4699. $restrictions = null;
  4700. $thumbnails = null;
  4701. $title = null;
  4702. // Start checking the attributes of media:content
  4703. if (isset($content['attribs']['']['bitrate']))
  4704. {
  4705. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4706. }
  4707. if (isset($content['attribs']['']['channels']))
  4708. {
  4709. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  4710. }
  4711. if (isset($content['attribs']['']['duration']))
  4712. {
  4713. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  4714. }
  4715. else
  4716. {
  4717. $duration = $duration_parent;
  4718. }
  4719. if (isset($content['attribs']['']['expression']))
  4720. {
  4721. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  4722. }
  4723. if (isset($content['attribs']['']['framerate']))
  4724. {
  4725. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4726. }
  4727. if (isset($content['attribs']['']['height']))
  4728. {
  4729. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  4730. }
  4731. if (isset($content['attribs']['']['lang']))
  4732. {
  4733. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4734. }
  4735. if (isset($content['attribs']['']['fileSize']))
  4736. {
  4737. $length = ceil($content['attribs']['']['fileSize']);
  4738. }
  4739. if (isset($content['attribs']['']['medium']))
  4740. {
  4741. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  4742. }
  4743. if (isset($content['attribs']['']['samplingrate']))
  4744. {
  4745. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4746. }
  4747. if (isset($content['attribs']['']['type']))
  4748. {
  4749. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4750. }
  4751. if (isset($content['attribs']['']['width']))
  4752. {
  4753. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  4754. }
  4755. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4756. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  4757. // CAPTIONS
  4758. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4759. {
  4760. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4761. {
  4762. $caption_type = null;
  4763. $caption_lang = null;
  4764. $caption_startTime = null;
  4765. $caption_endTime = null;
  4766. $caption_text = null;
  4767. if (isset($caption['attribs']['']['type']))
  4768. {
  4769. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4770. }
  4771. if (isset($caption['attribs']['']['lang']))
  4772. {
  4773. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4774. }
  4775. if (isset($caption['attribs']['']['start']))
  4776. {
  4777. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4778. }
  4779. if (isset($caption['attribs']['']['end']))
  4780. {
  4781. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4782. }
  4783. if (isset($caption['data']))
  4784. {
  4785. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4786. }
  4787. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4788. }
  4789. if (is_array($captions))
  4790. {
  4791. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4792. }
  4793. }
  4794. else
  4795. {
  4796. $captions = $captions_parent;
  4797. }
  4798. // CATEGORIES
  4799. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4800. {
  4801. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4802. {
  4803. $term = null;
  4804. $scheme = null;
  4805. $label = null;
  4806. if (isset($category['data']))
  4807. {
  4808. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4809. }
  4810. if (isset($category['attribs']['']['scheme']))
  4811. {
  4812. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4813. }
  4814. else
  4815. {
  4816. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4817. }
  4818. if (isset($category['attribs']['']['label']))
  4819. {
  4820. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4821. }
  4822. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4823. }
  4824. }
  4825. if (is_array($categories) && is_array($categories_parent))
  4826. {
  4827. $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
  4828. }
  4829. elseif (is_array($categories))
  4830. {
  4831. $categories = array_values(SimplePie_Misc::array_unique($categories));
  4832. }
  4833. elseif (is_array($categories_parent))
  4834. {
  4835. $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
  4836. }
  4837. else
  4838. {
  4839. $categories = null;
  4840. }
  4841. // COPYRIGHTS
  4842. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4843. {
  4844. $copyright_url = null;
  4845. $copyright_label = null;
  4846. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4847. {
  4848. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4849. }
  4850. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4851. {
  4852. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4853. }
  4854. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4855. }
  4856. else
  4857. {
  4858. $copyrights = $copyrights_parent;
  4859. }
  4860. // CREDITS
  4861. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4862. {
  4863. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4864. {
  4865. $credit_role = null;
  4866. $credit_scheme = null;
  4867. $credit_name = null;
  4868. if (isset($credit['attribs']['']['role']))
  4869. {
  4870. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4871. }
  4872. if (isset($credit['attribs']['']['scheme']))
  4873. {
  4874. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4875. }
  4876. else
  4877. {
  4878. $credit_scheme = 'urn:ebu';
  4879. }
  4880. if (isset($credit['data']))
  4881. {
  4882. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4883. }
  4884. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4885. }
  4886. if (is_array($credits))
  4887. {
  4888. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4889. }
  4890. }
  4891. else
  4892. {
  4893. $credits = $credits_parent;
  4894. }
  4895. // DESCRIPTION
  4896. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4897. {
  4898. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4899. }
  4900. else
  4901. {
  4902. $description = $description_parent;
  4903. }
  4904. // HASHES
  4905. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4906. {
  4907. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4908. {
  4909. $value = null;
  4910. $algo = null;
  4911. if (isset($hash['data']))
  4912. {
  4913. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4914. }
  4915. if (isset($hash['attribs']['']['algo']))
  4916. {
  4917. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4918. }
  4919. else
  4920. {
  4921. $algo = 'md5';
  4922. }
  4923. $hashes[] = $algo.':'.$value;
  4924. }
  4925. if (is_array($hashes))
  4926. {
  4927. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4928. }
  4929. }
  4930. else
  4931. {
  4932. $hashes = $hashes_parent;
  4933. }
  4934. // KEYWORDS
  4935. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4936. {
  4937. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4938. {
  4939. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4940. foreach ($temp as $word)
  4941. {
  4942. $keywords[] = trim($word);
  4943. }
  4944. unset($temp);
  4945. }
  4946. if (is_array($keywords))
  4947. {
  4948. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4949. }
  4950. }
  4951. else
  4952. {
  4953. $keywords = $keywords_parent;
  4954. }
  4955. // PLAYER
  4956. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4957. {
  4958. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4959. }
  4960. else
  4961. {
  4962. $player = $player_parent;
  4963. }
  4964. // RATINGS
  4965. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4966. {
  4967. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4968. {
  4969. $rating_scheme = null;
  4970. $rating_value = null;
  4971. if (isset($rating['attribs']['']['scheme']))
  4972. {
  4973. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4974. }
  4975. else
  4976. {
  4977. $rating_scheme = 'urn:simple';
  4978. }
  4979. if (isset($rating['data']))
  4980. {
  4981. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4982. }
  4983. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4984. }
  4985. if (is_array($ratings))
  4986. {
  4987. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4988. }
  4989. }
  4990. else
  4991. {
  4992. $ratings = $ratings_parent;
  4993. }
  4994. // RESTRICTIONS
  4995. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4996. {
  4997. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4998. {
  4999. $restriction_relationship = null;
  5000. $restriction_type = null;
  5001. $restriction_value = null;
  5002. if (isset($restriction['attribs']['']['relationship']))
  5003. {
  5004. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  5005. }
  5006. if (isset($restriction['attribs']['']['type']))
  5007. {
  5008. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5009. }
  5010. if (isset($restriction['data']))
  5011. {
  5012. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5013. }
  5014. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  5015. }
  5016. if (is_array($restrictions))
  5017. {
  5018. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  5019. }
  5020. }
  5021. else
  5022. {
  5023. $restrictions = $restrictions_parent;
  5024. }
  5025. // THUMBNAILS
  5026. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  5027. {
  5028. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  5029. {
  5030. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  5031. }
  5032. if (is_array($thumbnails))
  5033. {
  5034. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  5035. }
  5036. }
  5037. else
  5038. {
  5039. $thumbnails = $thumbnails_parent;
  5040. }
  5041. // TITLES
  5042. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  5043. {
  5044. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5045. }
  5046. else
  5047. {
  5048. $title = $title_parent;
  5049. }
  5050. $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
  5051. }
  5052. }
  5053. }
  5054. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  5055. {
  5056. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
  5057. {
  5058. // Attributes
  5059. $bitrate = null;
  5060. $channels = null;
  5061. $duration = null;
  5062. $expression = null;
  5063. $framerate = null;
  5064. $height = null;
  5065. $javascript = null;
  5066. $lang = null;
  5067. $length = null;
  5068. $medium = null;
  5069. $samplingrate = null;
  5070. $type = null;
  5071. $url = null;
  5072. $width = null;
  5073. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5074. if (isset($link['attribs']['']['type']))
  5075. {
  5076. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5077. }
  5078. if (isset($link['attribs']['']['length']))
  5079. {
  5080. $length = ceil($link['attribs']['']['length']);
  5081. }
  5082. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5083. $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
  5084. }
  5085. }
  5086. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  5087. {
  5088. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
  5089. {
  5090. // Attributes
  5091. $bitrate = null;
  5092. $channels = null;
  5093. $duration = null;
  5094. $expression = null;
  5095. $framerate = null;
  5096. $height = null;
  5097. $javascript = null;
  5098. $lang = null;
  5099. $length = null;
  5100. $medium = null;
  5101. $samplingrate = null;
  5102. $type = null;
  5103. $url = null;
  5104. $width = null;
  5105. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5106. if (isset($link['attribs']['']['type']))
  5107. {
  5108. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5109. }
  5110. if (isset($link['attribs']['']['length']))
  5111. {
  5112. $length = ceil($link['attribs']['']['length']);
  5113. }
  5114. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5115. $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
  5116. }
  5117. }
  5118. if ($enclosure = $this->get_item_tags('', 'enclosure'))
  5119. {
  5120. if (isset($enclosure[0]['attribs']['']['url']))
  5121. {
  5122. // Attributes
  5123. $bitrate = null;
  5124. $channels = null;
  5125. $duration = null;
  5126. $expression = null;
  5127. $framerate = null;
  5128. $height = null;
  5129. $javascript = null;
  5130. $lang = null;
  5131. $length = null;
  5132. $medium = null;
  5133. $samplingrate = null;
  5134. $type = null;
  5135. $url = null;
  5136. $width = null;
  5137. $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
  5138. if (isset($enclosure[0]['attribs']['']['type']))
  5139. {
  5140. $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5141. }
  5142. if (isset($enclosure[0]['attribs']['']['length']))
  5143. {
  5144. $length = ceil($enclosure[0]['attribs']['']['length']);
  5145. }
  5146. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5147. $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
  5148. }
  5149. }
  5150. 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))
  5151. {
  5152. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5153. $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
  5154. }
  5155. $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
  5156. }
  5157. if (!empty($this->data['enclosures']))
  5158. {
  5159. return $this->data['enclosures'];
  5160. }
  5161. else
  5162. {
  5163. return null;
  5164. }
  5165. }
  5166. function get_latitude()
  5167. {
  5168. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  5169. {
  5170. return (float) $return[0]['data'];
  5171. }
  5172. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5173. {
  5174. return (float) $match[1];
  5175. }
  5176. else
  5177. {
  5178. return null;
  5179. }
  5180. }
  5181. function get_longitude()
  5182. {
  5183. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  5184. {
  5185. return (float) $return[0]['data'];
  5186. }
  5187. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  5188. {
  5189. return (float) $return[0]['data'];
  5190. }
  5191. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5192. {
  5193. return (float) $match[2];
  5194. }
  5195. else
  5196. {
  5197. return null;
  5198. }
  5199. }
  5200. function get_source()
  5201. {
  5202. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
  5203. {
  5204. return new $this->feed->source_class($this, $return[0]);
  5205. }
  5206. else
  5207. {
  5208. return null;
  5209. }
  5210. }
  5211. /**
  5212. * Creates the add_to_* methods' return data
  5213. *
  5214. * @access private
  5215. * @param string $item_url String to prefix to the item permalink
  5216. * @param string $title_url String to prefix to the item title
  5217. * (and suffix to the item permalink)
  5218. * @return mixed URL if feed exists, false otherwise
  5219. */
  5220. function add_to_service($item_url, $title_url = null, $summary_url = null)
  5221. {
  5222. if ($this->get_permalink() !== null)
  5223. {
  5224. $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
  5225. if ($title_url !== null && $this->get_title() !== null)
  5226. {
  5227. $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
  5228. }
  5229. if ($summary_url !== null && $this->get_description() !== null)
  5230. {
  5231. $return .= $this->sanitize($summary_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_description());
  5232. }
  5233. return $return;
  5234. }
  5235. else
  5236. {
  5237. return null;
  5238. }
  5239. }
  5240. function add_to_blinklist()
  5241. {
  5242. return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
  5243. }
  5244. function add_to_blogmarks()
  5245. {
  5246. return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
  5247. }
  5248. function add_to_delicious()
  5249. {
  5250. return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
  5251. }
  5252. function add_to_digg()
  5253. {
  5254. return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
  5255. }
  5256. function add_to_furl()
  5257. {
  5258. return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
  5259. }
  5260. function add_to_magnolia()
  5261. {
  5262. return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
  5263. }
  5264. function add_to_myweb20()
  5265. {
  5266. return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
  5267. }
  5268. function add_to_newsvine()
  5269. {
  5270. return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
  5271. }
  5272. function add_to_reddit()
  5273. {
  5274. return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
  5275. }
  5276. function add_to_segnalo()
  5277. {
  5278. return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
  5279. }
  5280. function add_to_simpy()
  5281. {
  5282. return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
  5283. }
  5284. function add_to_spurl()
  5285. {
  5286. return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
  5287. }
  5288. function add_to_wists()
  5289. {
  5290. return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
  5291. }
  5292. function search_technorati()
  5293. {
  5294. return $this->add_to_service('http://www.technorati.com/search/');
  5295. }
  5296. }
  5297. class SimplePie_Source
  5298. {
  5299. var $item;
  5300. var $data = array();
  5301. function SimplePie_Source($item, $data)
  5302. {
  5303. $this->item = $item;
  5304. $this->data = $data;
  5305. }
  5306. function __toString()
  5307. {
  5308. return md5(serialize($this->data));
  5309. }
  5310. /**
  5311. * Remove items that link back to this before destroying this object
  5312. */
  5313. function __destruct()
  5314. {
  5315. unset($this->item);
  5316. }
  5317. function get_source_tags($namespace, $tag)
  5318. {
  5319. if (isset($this->data['child'][$namespace][$tag]))
  5320. {
  5321. return $this->data['child'][$namespace][$tag];
  5322. }
  5323. else
  5324. {
  5325. return null;
  5326. }
  5327. }
  5328. function get_base($element = array())
  5329. {
  5330. return $this->item->get_base($element);
  5331. }
  5332. function sanitize($data, $type, $base = '')
  5333. {
  5334. return $this->item->sanitize($data, $type, $base);
  5335. }
  5336. function get_item()
  5337. {
  5338. return $this->item;
  5339. }
  5340. function get_title()
  5341. {
  5342. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  5343. {
  5344. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5345. }
  5346. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  5347. {
  5348. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5349. }
  5350. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  5351. {
  5352. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5353. }
  5354. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  5355. {
  5356. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5357. }
  5358. elseif ($return = $this->get_source_tags('', 'title'))
  5359. {
  5360. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5361. }
  5362. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  5363. {
  5364. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5365. }
  5366. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  5367. {
  5368. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5369. }
  5370. else
  5371. {
  5372. return null;
  5373. }
  5374. }
  5375. function get_category($key = 0)
  5376. {
  5377. $categories = $this->get_categories();
  5378. if (isset($categories[$key]))
  5379. {
  5380. return $categories[$key];
  5381. }
  5382. else
  5383. {
  5384. return null;
  5385. }
  5386. }
  5387. function get_categories()
  5388. {
  5389. $categories = array();
  5390. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  5391. {
  5392. $term = null;
  5393. $scheme = null;
  5394. $label = null;
  5395. if (isset($category['attribs']['']['term']))
  5396. {
  5397. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  5398. }
  5399. if (isset($category['attribs']['']['scheme']))
  5400. {
  5401. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  5402. }
  5403. if (isset($category['attribs']['']['label']))
  5404. {
  5405. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  5406. }
  5407. $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
  5408. }
  5409. foreach ((array) $this->get_source_tags('', 'category') as $category)
  5410. {
  5411. $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5412. }
  5413. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  5414. {
  5415. $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5416. }
  5417. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  5418. {
  5419. $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5420. }
  5421. if (!empty($categories))
  5422. {
  5423. return SimplePie_Misc::array_unique($categories);
  5424. }
  5425. else
  5426. {
  5427. return null;
  5428. }
  5429. }
  5430. function get_author($key = 0)
  5431. {
  5432. $authors = $this->get_authors();
  5433. if (isset($authors[$key]))
  5434. {
  5435. return $authors[$key];
  5436. }
  5437. else
  5438. {
  5439. return null;
  5440. }
  5441. }
  5442. function get_authors()
  5443. {
  5444. $authors = array();
  5445. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  5446. {
  5447. $name = null;
  5448. $uri = null;
  5449. $email = null;
  5450. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  5451. {
  5452. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5453. }
  5454. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  5455. {
  5456. $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]));
  5457. }
  5458. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  5459. {
  5460. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5461. }
  5462. if ($name !== null || $email !== null || $uri !== null)
  5463. {
  5464. $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
  5465. }
  5466. }
  5467. if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  5468. {
  5469. $name = null;
  5470. $url = null;
  5471. $email = null;
  5472. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  5473. {
  5474. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5475. }
  5476. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  5477. {
  5478. $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]));
  5479. }
  5480. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  5481. {
  5482. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5483. }
  5484. if ($name !== null || $email !== null || $url !== null)
  5485. {
  5486. $authors[] =& new $this->item->feed->author_class($name, $url, $email);
  5487. }
  5488. }
  5489. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  5490. {
  5491. $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5492. }
  5493. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  5494. {
  5495. $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5496. }
  5497. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  5498. {
  5499. $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5500. }
  5501. if (!empty($authors))
  5502. {
  5503. return SimplePie_Misc::array_unique($authors);
  5504. }
  5505. else
  5506. {
  5507. return null;
  5508. }
  5509. }
  5510. function get_contributor($key = 0)
  5511. {
  5512. $contributors = $this->get_contributors();
  5513. if (isset($contributors[$key]))
  5514. {
  5515. return $contributors[$key];
  5516. }
  5517. else
  5518. {
  5519. return null;
  5520. }
  5521. }
  5522. function get_contributors()
  5523. {
  5524. $contributors = array();
  5525. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  5526. {
  5527. $name = null;
  5528. $uri = null;
  5529. $email = null;
  5530. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  5531. {
  5532. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5533. }
  5534. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  5535. {
  5536. $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]));
  5537. }
  5538. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  5539. {
  5540. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5541. }
  5542. if ($name !== null || $email !== null || $uri !== null)
  5543. {
  5544. $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
  5545. }
  5546. }
  5547. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  5548. {
  5549. $name = null;
  5550. $url = null;
  5551. $email = null;
  5552. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  5553. {
  5554. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5555. }
  5556. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  5557. {
  5558. $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]));
  5559. }
  5560. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  5561. {
  5562. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5563. }
  5564. if ($name !== null || $email !== null || $url !== null)
  5565. {
  5566. $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
  5567. }
  5568. }
  5569. if (!empty($contributors))
  5570. {
  5571. return SimplePie_Misc::array_unique($contributors);
  5572. }
  5573. else
  5574. {
  5575. return null;
  5576. }
  5577. }
  5578. function get_link($key = 0, $rel = 'alternate')
  5579. {
  5580. $links = $this->get_links($rel);
  5581. if (isset($links[$key]))
  5582. {
  5583. return $links[$key];
  5584. }
  5585. else
  5586. {
  5587. return null;
  5588. }
  5589. }
  5590. /**
  5591. * Added for parity between the parent-level and the item/entry-level.
  5592. */
  5593. function get_permalink()
  5594. {
  5595. return $this->get_link(0);
  5596. }
  5597. function get_links($rel = 'alternate')
  5598. {
  5599. if (!isset($this->data['links']))
  5600. {
  5601. $this->data['links'] = array();
  5602. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  5603. {
  5604. foreach ($links as $link)
  5605. {
  5606. if (isset($link['attribs']['']['href']))
  5607. {
  5608. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  5609. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5610. }
  5611. }
  5612. }
  5613. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  5614. {
  5615. foreach ($links as $link)
  5616. {
  5617. if (isset($link['attribs']['']['href']))
  5618. {
  5619. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  5620. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5621. }
  5622. }
  5623. }
  5624. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  5625. {
  5626. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5627. }
  5628. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  5629. {
  5630. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5631. }
  5632. if ($links = $this->get_source_tags('', 'link'))
  5633. {
  5634. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5635. }
  5636. $keys = array_keys($this->data['links']);
  5637. foreach ($keys as $key)
  5638. {
  5639. if (SimplePie_Misc::is_isegment_nz_nc($key))
  5640. {
  5641. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  5642. {
  5643. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  5644. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  5645. }
  5646. else
  5647. {
  5648. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  5649. }
  5650. }
  5651. elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  5652. {
  5653. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  5654. }
  5655. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  5656. }
  5657. }
  5658. if (isset($this->data['links'][$rel]))
  5659. {
  5660. return $this->data['links'][$rel];
  5661. }
  5662. else
  5663. {
  5664. return null;
  5665. }
  5666. }
  5667. function get_description()
  5668. {
  5669. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  5670. {
  5671. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5672. }
  5673. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  5674. {
  5675. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5676. }
  5677. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  5678. {
  5679. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5680. }
  5681. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  5682. {
  5683. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5684. }
  5685. elseif ($return = $this->get_source_tags('', 'description'))
  5686. {
  5687. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5688. }
  5689. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  5690. {
  5691. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5692. }
  5693. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  5694. {
  5695. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5696. }
  5697. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  5698. {
  5699. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5700. }
  5701. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  5702. {
  5703. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5704. }
  5705. else
  5706. {
  5707. return null;
  5708. }
  5709. }
  5710. function get_copyright()
  5711. {
  5712. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  5713. {
  5714. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5715. }
  5716. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
  5717. {
  5718. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5719. }
  5720. elseif ($return = $this->get_source_tags('', 'copyright'))
  5721. {
  5722. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5723. }
  5724. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  5725. {
  5726. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5727. }
  5728. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  5729. {
  5730. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5731. }
  5732. else
  5733. {
  5734. return null;
  5735. }
  5736. }
  5737. function get_language()
  5738. {
  5739. if ($return = $this->get_source_tags('', 'language'))
  5740. {
  5741. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5742. }
  5743. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  5744. {
  5745. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5746. }
  5747. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  5748. {
  5749. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5750. }
  5751. elseif (isset($this->data['xml_lang']))
  5752. {
  5753. return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  5754. }
  5755. else
  5756. {
  5757. return null;
  5758. }
  5759. }
  5760. function get_latitude()
  5761. {
  5762. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  5763. {
  5764. return (float) $return[0]['data'];
  5765. }
  5766. elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5767. {
  5768. return (float) $match[1];
  5769. }
  5770. else
  5771. {
  5772. return null;
  5773. }
  5774. }
  5775. function get_longitude()
  5776. {
  5777. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  5778. {
  5779. return (float) $return[0]['data'];
  5780. }
  5781. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  5782. {
  5783. return (float) $return[0]['data'];
  5784. }
  5785. elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5786. {
  5787. return (float) $match[2];
  5788. }
  5789. else
  5790. {
  5791. return null;
  5792. }
  5793. }
  5794. function get_image_url()
  5795. {
  5796. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  5797. {
  5798. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  5799. }
  5800. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  5801. {
  5802. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  5803. }
  5804. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  5805. {
  5806. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  5807. }
  5808. else
  5809. {
  5810. return null;
  5811. }
  5812. }
  5813. }
  5814. class SimplePie_Author
  5815. {
  5816. var $name;
  5817. var $link;
  5818. var $email;
  5819. // Constructor, used to input the data
  5820. function SimplePie_Author($name = null, $link = null, $email = null)
  5821. {
  5822. $this->name = $name;
  5823. $this->link = $link;
  5824. $this->email = $email;
  5825. }
  5826. function __toString()
  5827. {
  5828. // There is no $this->data here
  5829. return md5(serialize($this));
  5830. }
  5831. function get_name()
  5832. {
  5833. if ($this->name !== null)
  5834. {
  5835. return $this->name;
  5836. }
  5837. else
  5838. {
  5839. return null;
  5840. }
  5841. }
  5842. function get_link()
  5843. {
  5844. if ($this->link !== null)
  5845. {
  5846. return $this->link;
  5847. }
  5848. else
  5849. {
  5850. return null;
  5851. }
  5852. }
  5853. function get_email()
  5854. {
  5855. if ($this->email !== null)
  5856. {
  5857. return $this->email;
  5858. }
  5859. else
  5860. {
  5861. return null;
  5862. }
  5863. }
  5864. }
  5865. class SimplePie_Category
  5866. {
  5867. var $term;
  5868. var $scheme;
  5869. var $label;
  5870. // Constructor, used to input the data
  5871. function SimplePie_Category($term = null, $scheme = null, $label = null)
  5872. {
  5873. $this->term = $term;
  5874. $this->scheme = $scheme;
  5875. $this->label = $label;
  5876. }
  5877. function __toString()
  5878. {
  5879. // There is no $this->data here
  5880. return md5(serialize($this));
  5881. }
  5882. function get_term()
  5883. {
  5884. if ($this->term !== null)
  5885. {
  5886. return $this->term;
  5887. }
  5888. else
  5889. {
  5890. return null;
  5891. }
  5892. }
  5893. function get_scheme()
  5894. {
  5895. if ($this->scheme !== null)
  5896. {
  5897. return $this->scheme;
  5898. }
  5899. else
  5900. {
  5901. return null;
  5902. }
  5903. }
  5904. function get_label()
  5905. {
  5906. if ($this->label !== null)
  5907. {
  5908. return $this->label;
  5909. }
  5910. else
  5911. {
  5912. return $this->get_term();
  5913. }
  5914. }
  5915. }
  5916. class SimplePie_Enclosure
  5917. {
  5918. var $bitrate;
  5919. var $captions;
  5920. var $categories;
  5921. var $channels;
  5922. var $copyright;
  5923. var $credits;
  5924. var $description;
  5925. var $duration;
  5926. var $expression;
  5927. var $framerate;
  5928. var $handler;
  5929. var $hashes;
  5930. var $height;
  5931. var $javascript;
  5932. var $keywords;
  5933. var $lang;
  5934. var $length;
  5935. var $link;
  5936. var $medium;
  5937. var $player;
  5938. var $ratings;
  5939. var $restrictions;
  5940. var $samplingrate;
  5941. var $thumbnails;
  5942. var $title;
  5943. var $type;
  5944. var $width;
  5945. // Constructor, used to input the data
  5946. function SimplePie_Enclosure($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)
  5947. {
  5948. $this->bitrate = $bitrate;
  5949. $this->captions = $captions;
  5950. $this->categories = $categories;
  5951. $this->channels = $channels;
  5952. $this->copyright = $copyright;
  5953. $this->credits = $credits;
  5954. $this->description = $description;
  5955. $this->duration = $duration;
  5956. $this->expression = $expression;
  5957. $this->framerate = $framerate;
  5958. $this->hashes = $hashes;
  5959. $this->height = $height;
  5960. $this->javascript = $javascript;
  5961. $this->keywords = $keywords;
  5962. $this->lang = $lang;
  5963. $this->length = $length;
  5964. $this->link = $link;
  5965. $this->medium = $medium;
  5966. $this->player = $player;
  5967. $this->ratings = $ratings;
  5968. $this->restrictions = $restrictions;
  5969. $this->samplingrate = $samplingrate;
  5970. $this->thumbnails = $thumbnails;
  5971. $this->title = $title;
  5972. $this->type = $type;
  5973. $this->width = $width;
  5974. if (class_exists('idna_convert'))
  5975. {
  5976. $idn =& new idna_convert;
  5977. $parsed = SimplePie_Misc::parse_url($link);
  5978. $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  5979. }
  5980. $this->handler = $this->get_handler(); // Needs to load last
  5981. }
  5982. function __toString()
  5983. {
  5984. // There is no $this->data here
  5985. return md5(serialize($this));
  5986. }
  5987. function get_bitrate()
  5988. {
  5989. if ($this->bitrate !== null)
  5990. {
  5991. return $this->bitrate;
  5992. }
  5993. else
  5994. {
  5995. return null;
  5996. }
  5997. }
  5998. function get_caption($key = 0)
  5999. {
  6000. $captions = $this->get_captions();
  6001. if (isset($captions[$key]))
  6002. {
  6003. return $captions[$key];
  6004. }
  6005. else
  6006. {
  6007. return null;
  6008. }
  6009. }
  6010. function get_captions()
  6011. {
  6012. if ($this->captions !== null)
  6013. {
  6014. return $this->captions;
  6015. }
  6016. else
  6017. {
  6018. return null;
  6019. }
  6020. }
  6021. function get_category($key = 0)
  6022. {
  6023. $categories = $this->get_categories();
  6024. if (isset($categories[$key]))
  6025. {
  6026. return $categories[$key];
  6027. }
  6028. else
  6029. {
  6030. return null;
  6031. }
  6032. }
  6033. function get_categories()
  6034. {
  6035. if ($this->categories !== null)
  6036. {
  6037. return $this->categories;
  6038. }
  6039. else
  6040. {
  6041. return null;
  6042. }
  6043. }
  6044. function get_channels()
  6045. {
  6046. if ($this->channels !== null)
  6047. {
  6048. return $this->channels;
  6049. }
  6050. else
  6051. {
  6052. return null;
  6053. }
  6054. }
  6055. function get_copyright()
  6056. {
  6057. if ($this->copyright !== null)
  6058. {
  6059. return $this->copyright;
  6060. }
  6061. else
  6062. {
  6063. return null;
  6064. }
  6065. }
  6066. function get_credit($key = 0)
  6067. {
  6068. $credits = $this->get_credits();
  6069. if (isset($credits[$key]))
  6070. {
  6071. return $credits[$key];
  6072. }
  6073. else
  6074. {
  6075. return null;
  6076. }
  6077. }
  6078. function get_credits()
  6079. {
  6080. if ($this->credits !== null)
  6081. {
  6082. return $this->credits;
  6083. }
  6084. else
  6085. {
  6086. return null;
  6087. }
  6088. }
  6089. function get_description()
  6090. {
  6091. if ($this->description !== null)
  6092. {
  6093. return $this->description;
  6094. }
  6095. else
  6096. {
  6097. return null;
  6098. }
  6099. }
  6100. function get_duration($convert = false)
  6101. {
  6102. if ($this->duration !== null)
  6103. {
  6104. if ($convert)
  6105. {
  6106. $time = SimplePie_Misc::time_hms($this->duration);
  6107. return $time;
  6108. }
  6109. else
  6110. {
  6111. return $this->duration;
  6112. }
  6113. }
  6114. else
  6115. {
  6116. return null;
  6117. }
  6118. }
  6119. function get_expression()
  6120. {
  6121. if ($this->expression !== null)
  6122. {
  6123. return $this->expression;
  6124. }
  6125. else
  6126. {
  6127. return 'full';
  6128. }
  6129. }
  6130. function get_extension()
  6131. {
  6132. if ($this->link !== null)
  6133. {
  6134. $url = SimplePie_Misc::parse_url($this->link);
  6135. if ($url['path'] !== '')
  6136. {
  6137. return pathinfo($url['path'], PATHINFO_EXTENSION);
  6138. }
  6139. }
  6140. return null;
  6141. }
  6142. function get_framerate()
  6143. {
  6144. if ($this->framerate !== null)
  6145. {
  6146. return $this->framerate;
  6147. }
  6148. else
  6149. {
  6150. return null;
  6151. }
  6152. }
  6153. function get_handler()
  6154. {
  6155. return $this->get_real_type(true);
  6156. }
  6157. function get_hash($key = 0)
  6158. {
  6159. $hashes = $this->get_hashes();
  6160. if (isset($hashes[$key]))
  6161. {
  6162. return $hashes[$key];
  6163. }
  6164. else
  6165. {
  6166. return null;
  6167. }
  6168. }
  6169. function get_hashes()
  6170. {
  6171. if ($this->hashes !== null)
  6172. {
  6173. return $this->hashes;
  6174. }
  6175. else
  6176. {
  6177. return null;
  6178. }
  6179. }
  6180. function get_height()
  6181. {
  6182. if ($this->height !== null)
  6183. {
  6184. return $this->height;
  6185. }
  6186. else
  6187. {
  6188. return null;
  6189. }
  6190. }
  6191. function get_language()
  6192. {
  6193. if ($this->lang !== null)
  6194. {
  6195. return $this->lang;
  6196. }
  6197. else
  6198. {
  6199. return null;
  6200. }
  6201. }
  6202. function get_keyword($key = 0)
  6203. {
  6204. $keywords = $this->get_keywords();
  6205. if (isset($keywords[$key]))
  6206. {
  6207. return $keywords[$key];
  6208. }
  6209. else
  6210. {
  6211. return null;
  6212. }
  6213. }
  6214. function get_keywords()
  6215. {
  6216. if ($this->keywords !== null)
  6217. {
  6218. return $this->keywords;
  6219. }
  6220. else
  6221. {
  6222. return null;
  6223. }
  6224. }
  6225. function get_length()
  6226. {
  6227. if ($this->length !== null)
  6228. {
  6229. return $this->length;
  6230. }
  6231. else
  6232. {
  6233. return null;
  6234. }
  6235. }
  6236. function get_link()
  6237. {
  6238. if ($this->link !== null)
  6239. {
  6240. return urldecode($this->link);
  6241. }
  6242. else
  6243. {
  6244. return null;
  6245. }
  6246. }
  6247. function get_medium()
  6248. {
  6249. if ($this->medium !== null)
  6250. {
  6251. return $this->medium;
  6252. }
  6253. else
  6254. {
  6255. return null;
  6256. }
  6257. }
  6258. function get_player()
  6259. {
  6260. if ($this->player !== null)
  6261. {
  6262. return $this->player;
  6263. }
  6264. else
  6265. {
  6266. return null;
  6267. }
  6268. }
  6269. function get_rating($key = 0)
  6270. {
  6271. $ratings = $this->get_ratings();
  6272. if (isset($ratings[$key]))
  6273. {
  6274. return $ratings[$key];
  6275. }
  6276. else
  6277. {
  6278. return null;
  6279. }
  6280. }
  6281. function get_ratings()
  6282. {
  6283. if ($this->ratings !== null)
  6284. {
  6285. return $this->ratings;
  6286. }
  6287. else
  6288. {
  6289. return null;
  6290. }
  6291. }
  6292. function get_restriction($key = 0)
  6293. {
  6294. $restrictions = $this->get_restrictions();
  6295. if (isset($restrictions[$key]))
  6296. {
  6297. return $restrictions[$key];
  6298. }
  6299. else
  6300. {
  6301. return null;
  6302. }
  6303. }
  6304. function get_restrictions()
  6305. {
  6306. if ($this->restrictions !== null)
  6307. {
  6308. return $this->restrictions;
  6309. }
  6310. else
  6311. {
  6312. return null;
  6313. }
  6314. }
  6315. function get_sampling_rate()
  6316. {
  6317. if ($this->samplingrate !== null)
  6318. {
  6319. return $this->samplingrate;
  6320. }
  6321. else
  6322. {
  6323. return null;
  6324. }
  6325. }
  6326. function get_size()
  6327. {
  6328. $length = $this->get_length();
  6329. if ($length !== null)
  6330. {
  6331. return round($length/1048576, 2);
  6332. }
  6333. else
  6334. {
  6335. return null;
  6336. }
  6337. }
  6338. function get_thumbnail($key = 0)
  6339. {
  6340. $thumbnails = $this->get_thumbnails();
  6341. if (isset($thumbnails[$key]))
  6342. {
  6343. return $thumbnails[$key];
  6344. }
  6345. else
  6346. {
  6347. return null;
  6348. }
  6349. }
  6350. function get_thumbnails()
  6351. {
  6352. if ($this->thumbnails !== null)
  6353. {
  6354. return $this->thumbnails;
  6355. }
  6356. else
  6357. {
  6358. return null;
  6359. }
  6360. }
  6361. function get_title()
  6362. {
  6363. if ($this->title !== null)
  6364. {
  6365. return $this->title;
  6366. }
  6367. else
  6368. {
  6369. return null;
  6370. }
  6371. }
  6372. function get_type()
  6373. {
  6374. if ($this->type !== null)
  6375. {
  6376. return $this->type;
  6377. }
  6378. else
  6379. {
  6380. return null;
  6381. }
  6382. }
  6383. function get_width()
  6384. {
  6385. if ($this->width !== null)
  6386. {
  6387. return $this->width;
  6388. }
  6389. else
  6390. {
  6391. return null;
  6392. }
  6393. }
  6394. function native_embed($options='')
  6395. {
  6396. return $this->embed($options, true);
  6397. }
  6398. /**
  6399. * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
  6400. */
  6401. function embed($options = '', $native = false)
  6402. {
  6403. // Set up defaults
  6404. $audio = '';
  6405. $video = '';
  6406. $alt = '';
  6407. $altclass = '';
  6408. $loop = 'false';
  6409. $width = 'auto';
  6410. $height = 'auto';
  6411. $bgcolor = '#ffffff';
  6412. $mediaplayer = '';
  6413. $widescreen = false;
  6414. $handler = $this->get_handler();
  6415. $type = $this->get_real_type();
  6416. // Process options and reassign values as necessary
  6417. if (is_array($options))
  6418. {
  6419. extract($options);
  6420. }
  6421. else
  6422. {
  6423. $options = explode(',', $options);
  6424. foreach($options as $option)
  6425. {
  6426. $opt = explode(':', $option, 2);
  6427. if (isset($opt[0], $opt[1]))
  6428. {
  6429. $opt[0] = trim($opt[0]);
  6430. $opt[1] = trim($opt[1]);
  6431. switch ($opt[0])
  6432. {
  6433. case 'audio':
  6434. $audio = $opt[1];
  6435. break;
  6436. case 'video':
  6437. $video = $opt[1];
  6438. break;
  6439. case 'alt':
  6440. $alt = $opt[1];
  6441. break;
  6442. case 'altclass':
  6443. $altclass = $opt[1];
  6444. break;
  6445. case 'loop':
  6446. $loop = $opt[1];
  6447. break;
  6448. case 'width':
  6449. $width = $opt[1];
  6450. break;
  6451. case 'height':
  6452. $height = $opt[1];
  6453. break;
  6454. case 'bgcolor':
  6455. $bgcolor = $opt[1];
  6456. break;
  6457. case 'mediaplayer':
  6458. $mediaplayer = $opt[1];
  6459. break;
  6460. case 'widescreen':
  6461. $widescreen = $opt[1];
  6462. break;
  6463. }
  6464. }
  6465. }
  6466. }
  6467. $mime = explode('/', $type, 2);
  6468. $mime = $mime[0];
  6469. // Process values for 'auto'
  6470. if ($width == 'auto')
  6471. {
  6472. if ($mime == 'video')
  6473. {
  6474. if ($height == 'auto')
  6475. {
  6476. $width = 480;
  6477. }
  6478. elseif ($widescreen)
  6479. {
  6480. $width = round((intval($height)/9)*16);
  6481. }
  6482. else
  6483. {
  6484. $width = round((intval($height)/3)*4);
  6485. }
  6486. }
  6487. else
  6488. {
  6489. $width = '100%';
  6490. }
  6491. }
  6492. if ($height == 'auto')
  6493. {
  6494. if ($mime == 'audio')
  6495. {
  6496. $height = 0;
  6497. }
  6498. elseif ($mime == 'video')
  6499. {
  6500. if ($width == 'auto')
  6501. {
  6502. if ($widescreen)
  6503. {
  6504. $height = 270;
  6505. }
  6506. else
  6507. {
  6508. $height = 360;
  6509. }
  6510. }
  6511. elseif ($widescreen)
  6512. {
  6513. $height = round((intval($width)/16)*9);
  6514. }
  6515. else
  6516. {
  6517. $height = round((intval($width)/4)*3);
  6518. }
  6519. }
  6520. else
  6521. {
  6522. $height = 376;
  6523. }
  6524. }
  6525. elseif ($mime == 'audio')
  6526. {
  6527. $height = 0;
  6528. }
  6529. // Set proper placeholder value
  6530. if ($mime == 'audio')
  6531. {
  6532. $placeholder = $audio;
  6533. }
  6534. elseif ($mime == 'video')
  6535. {
  6536. $placeholder = $video;
  6537. }
  6538. $embed = '';
  6539. // Make sure the JS library is included
  6540. if (!$native)
  6541. {
  6542. static $javascript_outputted = null;
  6543. if (!$javascript_outputted && $this->javascript)
  6544. {
  6545. $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
  6546. $javascript_outputted = true;
  6547. }
  6548. }
  6549. // Odeo Feed MP3's
  6550. if ($handler == 'odeo')
  6551. {
  6552. if ($native)
  6553. {
  6554. $embed .= '<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://adobe.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url=' . $this->get_link() . '"></embed>';
  6555. }
  6556. else
  6557. {
  6558. $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
  6559. }
  6560. }
  6561. // Flash
  6562. elseif ($handler == 'flash')
  6563. {
  6564. if ($native)
  6565. {
  6566. $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>";
  6567. }
  6568. else
  6569. {
  6570. $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
  6571. }
  6572. }
  6573. // Flash Media Player file types.
  6574. // Preferred handler for MP3 file types.
  6575. elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
  6576. {
  6577. $height += 20;
  6578. if ($native)
  6579. {
  6580. $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>";
  6581. }
  6582. else
  6583. {
  6584. $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
  6585. }
  6586. }
  6587. // QuickTime 7 file types. Need to test with QuickTime 6.
  6588. // Only handle MP3's if the Flash Media Player is not present.
  6589. elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
  6590. {
  6591. $height += 16;
  6592. if ($native)
  6593. {
  6594. if ($placeholder != ""){
  6595. $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>";
  6596. }
  6597. else {
  6598. $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>";
  6599. }
  6600. }
  6601. else
  6602. {
  6603. $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
  6604. }
  6605. }
  6606. // Windows Media
  6607. elseif ($handler == 'wmedia')
  6608. {
  6609. $height += 45;
  6610. if ($native)
  6611. {
  6612. $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>";
  6613. }
  6614. else
  6615. {
  6616. $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
  6617. }
  6618. }
  6619. // Everything else
  6620. else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
  6621. return $embed;
  6622. }
  6623. function get_real_type($find_handler = false)
  6624. {
  6625. // If it's Odeo, let's get it out of the way.
  6626. if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
  6627. {
  6628. return 'odeo';
  6629. }
  6630. // Mime-types by handler.
  6631. $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
  6632. $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
  6633. $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
  6634. $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
  6635. $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
  6636. if ($this->get_type() !== null)
  6637. {
  6638. $type = strtolower($this->type);
  6639. }
  6640. else
  6641. {
  6642. $type = null;
  6643. }
  6644. // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
  6645. if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
  6646. {
  6647. switch (strtolower($this->get_extension()))
  6648. {
  6649. // Audio mime-types
  6650. case 'aac':
  6651. case 'adts':
  6652. $type = 'audio/acc';
  6653. break;
  6654. case 'aif':
  6655. case 'aifc':
  6656. case 'aiff':
  6657. case 'cdda':
  6658. $type = 'audio/aiff';
  6659. break;
  6660. case 'bwf':
  6661. $type = 'audio/wav';
  6662. break;
  6663. case 'kar':
  6664. case 'mid':
  6665. case 'midi':
  6666. case 'smf':
  6667. $type = 'audio/midi';
  6668. break;
  6669. case 'm4a':
  6670. $type = 'audio/x-m4a';
  6671. break;
  6672. case 'mp3':
  6673. case 'swa':
  6674. $type = 'audio/mp3';
  6675. break;
  6676. case 'wav':
  6677. $type = 'audio/wav';
  6678. break;
  6679. case 'wax':
  6680. $type = 'audio/x-ms-wax';
  6681. break;
  6682. case 'wma':
  6683. $type = 'audio/x-ms-wma';
  6684. break;
  6685. // Video mime-types
  6686. case '3gp':
  6687. case '3gpp':
  6688. $type = 'video/3gpp';
  6689. break;
  6690. case '3g2':
  6691. case '3gp2':
  6692. $type = 'video/3gpp2';
  6693. break;
  6694. case 'asf':
  6695. $type = 'video/x-ms-asf';
  6696. break;
  6697. case 'flv':
  6698. $type = 'video/x-flv';
  6699. break;
  6700. case 'm1a':
  6701. case 'm1s':
  6702. case 'm1v':
  6703. case 'm15':
  6704. case 'm75':
  6705. case 'mp2':
  6706. case 'mpa':
  6707. case 'mpeg':
  6708. case 'mpg':
  6709. case 'mpm':
  6710. case 'mpv':
  6711. $type = 'video/mpeg';
  6712. break;
  6713. case 'm4v':
  6714. $type = 'video/x-m4v';
  6715. break;
  6716. case 'mov':
  6717. case 'qt':
  6718. $type = 'video/quicktime';
  6719. break;
  6720. case 'mp4':
  6721. case 'mpg4':
  6722. $type = 'video/mp4';
  6723. break;
  6724. case 'sdv':
  6725. $type = 'video/sd-video';
  6726. break;
  6727. case 'wm':
  6728. $type = 'video/x-ms-wm';
  6729. break;
  6730. case 'wmv':
  6731. $type = 'video/x-ms-wmv';
  6732. break;
  6733. case 'wvx':
  6734. $type = 'video/x-ms-wvx';
  6735. break;
  6736. // Flash mime-types
  6737. case 'spl':
  6738. $type = 'application/futuresplash';
  6739. break;
  6740. case 'swf':
  6741. $type = 'application/x-shockwave-flash';
  6742. break;
  6743. }
  6744. }
  6745. if ($find_handler)
  6746. {
  6747. if (in_array($type, $types_flash))
  6748. {
  6749. return 'flash';
  6750. }
  6751. elseif (in_array($type, $types_fmedia))
  6752. {
  6753. return 'fmedia';
  6754. }
  6755. elseif (in_array($type, $types_quicktime))
  6756. {
  6757. return 'quicktime';
  6758. }
  6759. elseif (in_array($type, $types_wmedia))
  6760. {
  6761. return 'wmedia';
  6762. }
  6763. elseif (in_array($type, $types_mp3))
  6764. {
  6765. return 'mp3';
  6766. }
  6767. else
  6768. {
  6769. return null;
  6770. }
  6771. }
  6772. else
  6773. {
  6774. return $type;
  6775. }
  6776. }
  6777. }
  6778. class SimplePie_Caption
  6779. {
  6780. var $type;
  6781. var $lang;
  6782. var $startTime;
  6783. var $endTime;
  6784. var $text;
  6785. // Constructor, used to input the data
  6786. function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
  6787. {
  6788. $this->type = $type;
  6789. $this->lang = $lang;
  6790. $this->startTime = $startTime;
  6791. $this->endTime = $endTime;
  6792. $this->text = $text;
  6793. }
  6794. function __toString()
  6795. {
  6796. // There is no $this->data here
  6797. return md5(serialize($this));
  6798. }
  6799. function get_endtime()
  6800. {
  6801. if ($this->endTime !== null)
  6802. {
  6803. return $this->endTime;
  6804. }
  6805. else
  6806. {
  6807. return null;
  6808. }
  6809. }
  6810. function get_language()
  6811. {
  6812. if ($this->lang !== null)
  6813. {
  6814. return $this->lang;
  6815. }
  6816. else
  6817. {
  6818. return null;
  6819. }
  6820. }
  6821. function get_starttime()
  6822. {
  6823. if ($this->startTime !== null)
  6824. {
  6825. return $this->startTime;
  6826. }
  6827. else
  6828. {
  6829. return null;
  6830. }
  6831. }
  6832. function get_text()
  6833. {
  6834. if ($this->text !== null)
  6835. {
  6836. return $this->text;
  6837. }
  6838. else
  6839. {
  6840. return null;
  6841. }
  6842. }
  6843. function get_type()
  6844. {
  6845. if ($this->type !== null)
  6846. {
  6847. return $this->type;
  6848. }
  6849. else
  6850. {
  6851. return null;
  6852. }
  6853. }
  6854. }
  6855. class SimplePie_Credit
  6856. {
  6857. var $role;
  6858. var $scheme;
  6859. var $name;
  6860. // Constructor, used to input the data
  6861. function SimplePie_Credit($role = null, $scheme = null, $name = null)
  6862. {
  6863. $this->role = $role;
  6864. $this->scheme = $scheme;
  6865. $this->name = $name;
  6866. }
  6867. function __toString()
  6868. {
  6869. // There is no $this->data here
  6870. return md5(serialize($this));
  6871. }
  6872. function get_role()
  6873. {
  6874. if ($this->role !== null)
  6875. {
  6876. return $this->role;
  6877. }
  6878. else
  6879. {
  6880. return null;
  6881. }
  6882. }
  6883. function get_scheme()
  6884. {
  6885. if ($this->scheme !== null)
  6886. {
  6887. return $this->scheme;
  6888. }
  6889. else
  6890. {
  6891. return null;
  6892. }
  6893. }
  6894. function get_name()
  6895. {
  6896. if ($this->name !== null)
  6897. {
  6898. return $this->name;
  6899. }
  6900. else
  6901. {
  6902. return null;
  6903. }
  6904. }
  6905. }
  6906. class SimplePie_Copyright
  6907. {
  6908. var $url;
  6909. var $label;
  6910. // Constructor, used to input the data
  6911. function SimplePie_Copyright($url = null, $label = null)
  6912. {
  6913. $this->url = $url;
  6914. $this->label = $label;
  6915. }
  6916. function __toString()
  6917. {
  6918. // There is no $this->data here
  6919. return md5(serialize($this));
  6920. }
  6921. function get_url()
  6922. {
  6923. if ($this->url !== null)
  6924. {
  6925. return $this->url;
  6926. }
  6927. else
  6928. {
  6929. return null;
  6930. }
  6931. }
  6932. function get_attribution()
  6933. {
  6934. if ($this->label !== null)
  6935. {
  6936. return $this->label;
  6937. }
  6938. else
  6939. {
  6940. return null;
  6941. }
  6942. }
  6943. }
  6944. class SimplePie_Rating
  6945. {
  6946. var $scheme;
  6947. var $value;
  6948. // Constructor, used to input the data
  6949. function SimplePie_Rating($scheme = null, $value = null)
  6950. {
  6951. $this->scheme = $scheme;
  6952. $this->value = $value;
  6953. }
  6954. function __toString()
  6955. {
  6956. // There is no $this->data here
  6957. return md5(serialize($this));
  6958. }
  6959. function get_scheme()
  6960. {
  6961. if ($this->scheme !== null)
  6962. {
  6963. return $this->scheme;
  6964. }
  6965. else
  6966. {
  6967. return null;
  6968. }
  6969. }
  6970. function get_value()
  6971. {
  6972. if ($this->value !== null)
  6973. {
  6974. return $this->value;
  6975. }
  6976. else
  6977. {
  6978. return null;
  6979. }
  6980. }
  6981. }
  6982. class SimplePie_Restriction
  6983. {
  6984. var $relationship;
  6985. var $type;
  6986. var $value;
  6987. // Constructor, used to input the data
  6988. function SimplePie_Restriction($relationship = null, $type = null, $value = null)
  6989. {
  6990. $this->relationship = $relationship;
  6991. $this->type = $type;
  6992. $this->value = $value;
  6993. }
  6994. function __toString()
  6995. {
  6996. // There is no $this->data here
  6997. return md5(serialize($this));
  6998. }
  6999. function get_relationship()
  7000. {
  7001. if ($this->relationship !== null)
  7002. {
  7003. return $this->relationship;
  7004. }
  7005. else
  7006. {
  7007. return null;
  7008. }
  7009. }
  7010. function get_type()
  7011. {
  7012. if ($this->type !== null)
  7013. {
  7014. return $this->type;
  7015. }
  7016. else
  7017. {
  7018. return null;
  7019. }
  7020. }
  7021. function get_value()
  7022. {
  7023. if ($this->value !== null)
  7024. {
  7025. return $this->value;
  7026. }
  7027. else
  7028. {
  7029. return null;
  7030. }
  7031. }
  7032. }
  7033. /**
  7034. * @todo Move to properly supporting RFC2616 (HTTP/1.1)
  7035. */
  7036. class SimplePie_File
  7037. {
  7038. var $url;
  7039. var $useragent;
  7040. var $success = true;
  7041. var $headers = array();
  7042. var $body;
  7043. var $status_code;
  7044. var $redirects = 0;
  7045. var $error;
  7046. var $method = SIMPLEPIE_FILE_SOURCE_NONE;
  7047. function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
  7048. {
  7049. if (class_exists('idna_convert'))
  7050. {
  7051. $idn =& new idna_convert;
  7052. $parsed = SimplePie_Misc::parse_url($url);
  7053. $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  7054. }
  7055. $this->url = $url;
  7056. $this->useragent = $useragent;
  7057. if (preg_match('/^http(s)?:\/\//i', $url))
  7058. {
  7059. if ($useragent === null)
  7060. {
  7061. $useragent = ini_get('user_agent');
  7062. $this->useragent = $useragent;
  7063. }
  7064. if (!is_array($headers))
  7065. {
  7066. $headers = array();
  7067. }
  7068. if (!$force_fsockopen && function_exists('curl_exec'))
  7069. {
  7070. $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
  7071. $fp = curl_init();
  7072. $headers2 = array();
  7073. foreach ($headers as $key => $value)
  7074. {
  7075. $headers2[] = "$key: $value";
  7076. }
  7077. if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
  7078. {
  7079. curl_setopt($fp, CURLOPT_ENCODING, '');
  7080. }
  7081. curl_setopt($fp, CURLOPT_URL, $url);
  7082. curl_setopt($fp, CURLOPT_HEADER, 1);
  7083. curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
  7084. curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
  7085. curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
  7086. curl_setopt($fp, CURLOPT_REFERER, $url);
  7087. curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
  7088. curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
  7089. if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
  7090. {
  7091. curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
  7092. curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
  7093. }
  7094. $this->headers = curl_exec($fp);
  7095. if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
  7096. {
  7097. curl_setopt($fp, CURLOPT_ENCODING, 'none');
  7098. $this->headers = curl_exec($fp);
  7099. }
  7100. if (curl_errno($fp))
  7101. {
  7102. $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
  7103. $this->success = false;
  7104. }
  7105. else
  7106. {
  7107. $info = curl_getinfo($fp);
  7108. curl_close($fp);
  7109. $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
  7110. $this->headers = array_pop($this->headers);
  7111. $parser =& new SimplePie_HTTP_Parser($this->headers);
  7112. if ($parser->parse())
  7113. {
  7114. $this->headers = $parser->headers;
  7115. $this->body = $parser->body;
  7116. $this->status_code = $parser->status_code;
  7117. if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  7118. {
  7119. $this->redirects++;
  7120. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  7121. return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  7122. }
  7123. }
  7124. }
  7125. }
  7126. else
  7127. {
  7128. $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
  7129. $url_parts = parse_url($url);
  7130. if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
  7131. {
  7132. $url_parts['host'] = "ssl://$url_parts[host]";
  7133. $url_parts['port'] = 443;
  7134. }
  7135. if (!isset($url_parts['port']))
  7136. {
  7137. $url_parts['port'] = 80;
  7138. }
  7139. $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
  7140. if (!$fp)
  7141. {
  7142. $this->error = 'fsockopen error: ' . $errstr;
  7143. $this->success = false;
  7144. }
  7145. else
  7146. {
  7147. stream_set_timeout($fp, $timeout);
  7148. if (isset($url_parts['path']))
  7149. {
  7150. if (isset($url_parts['query']))
  7151. {
  7152. $get = "$url_parts[path]?$url_parts[query]";
  7153. }
  7154. else
  7155. {
  7156. $get = $url_parts['path'];
  7157. }
  7158. }
  7159. else
  7160. {
  7161. $get = '/';
  7162. }
  7163. $out = "GET $get HTTP/1.0\r\n";
  7164. $out .= "Host: $url_parts[host]\r\n";
  7165. $out .= "User-Agent: $useragent\r\n";
  7166. if (extension_loaded('zlib'))
  7167. {
  7168. $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
  7169. }
  7170. if (isset($url_parts['user']) && isset($url_parts['pass']))
  7171. {
  7172. $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
  7173. }
  7174. foreach ($headers as $key => $value)
  7175. {
  7176. $out .= "$key: $value\r\n";
  7177. }
  7178. $out .= "Connection: Close\r\n\r\n";
  7179. fwrite($fp, $out);
  7180. $info = stream_get_meta_data($fp);
  7181. $this->headers = '';
  7182. while (!$info['eof'] && !$info['timed_out'])
  7183. {
  7184. $this->headers .= fread($fp, 1160);
  7185. $info = stream_get_meta_data($fp);
  7186. }
  7187. if (!$info['timed_out'])
  7188. {
  7189. $parser =& new SimplePie_HTTP_Parser($this->headers);
  7190. if ($parser->parse())
  7191. {
  7192. $this->headers = $parser->headers;
  7193. $this->body = $parser->body;
  7194. $this->status_code = $parser->status_code;
  7195. if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  7196. {
  7197. $this->redirects++;
  7198. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  7199. return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  7200. }
  7201. if (isset($this->headers['content-encoding']))
  7202. {
  7203. // Hey, we act dumb elsewhere, so let's do that here too
  7204. switch(strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
  7205. {
  7206. case 'gzip':
  7207. case 'x-gzip':
  7208. $decoder = new SimplePie_gzdecode($this->body);
  7209. if (!$decoder->parse())
  7210. {
  7211. $this->error = 'Unable to decode HTTP "gzip" stream';
  7212. $this->success = false;
  7213. }
  7214. else
  7215. {
  7216. $this->body = $decoder->data;
  7217. }
  7218. break;
  7219. case 'deflate':
  7220. if (($body = gzuncompress($this->body)) === false)
  7221. {
  7222. if (($body = gzinflate($this->body)) === false)
  7223. {
  7224. $this->error = 'Unable to decode HTTP "deflate" stream';
  7225. $this->success = false;
  7226. }
  7227. }
  7228. $this->body = $body;
  7229. break;
  7230. default:
  7231. $this->error = 'Unknown content coding';
  7232. $this->success = false;
  7233. }
  7234. }
  7235. }
  7236. }
  7237. else
  7238. {
  7239. $this->error = 'fsocket timed out';
  7240. $this->success = false;
  7241. }
  7242. fclose($fp);
  7243. }
  7244. }
  7245. }
  7246. else
  7247. {
  7248. $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
  7249. if (!$this->body = file_get_contents($url))
  7250. {
  7251. $this->error = 'file_get_contents could not read the file';
  7252. $this->success = false;
  7253. }
  7254. }
  7255. }
  7256. }
  7257. /**
  7258. * HTTP Response Parser
  7259. *
  7260. * @package SimplePie
  7261. */
  7262. class SimplePie_HTTP_Parser
  7263. {
  7264. /**
  7265. * HTTP Version
  7266. *
  7267. * @access public
  7268. * @var float
  7269. */
  7270. var $http_version = 0.0;
  7271. /**
  7272. * Status code
  7273. *
  7274. * @access public
  7275. * @var int
  7276. */
  7277. var $status_code = 0;
  7278. /**
  7279. * Reason phrase
  7280. *
  7281. * @access public
  7282. * @var string
  7283. */
  7284. var $reason = '';
  7285. /**
  7286. * Key/value pairs of the headers
  7287. *
  7288. * @access public
  7289. * @var array
  7290. */
  7291. var $headers = array();
  7292. /**
  7293. * Body of the response
  7294. *
  7295. * @access public
  7296. * @var string
  7297. */
  7298. var $body = '';
  7299. /**
  7300. * Current state of the state machine
  7301. *
  7302. * @access private
  7303. * @var string
  7304. */
  7305. var $state = 'http_version';
  7306. /**
  7307. * Input data
  7308. *
  7309. * @access private
  7310. * @var string
  7311. */
  7312. var $data = '';
  7313. /**
  7314. * Input data length (to avoid calling strlen() everytime this is needed)
  7315. *
  7316. * @access private
  7317. * @var int
  7318. */
  7319. var $data_length = 0;
  7320. /**
  7321. * Current position of the pointer
  7322. *
  7323. * @var int
  7324. * @access private
  7325. */
  7326. var $position = 0;
  7327. /**
  7328. * Name of the hedaer currently being parsed
  7329. *
  7330. * @access private
  7331. * @var string
  7332. */
  7333. var $name = '';
  7334. /**
  7335. * Value of the hedaer currently being parsed
  7336. *
  7337. * @access private
  7338. * @var string
  7339. */
  7340. var $value = '';
  7341. /**
  7342. * Create an instance of the class with the input data
  7343. *
  7344. * @access public
  7345. * @param string $data Input data
  7346. */
  7347. function SimplePie_HTTP_Parser($data)
  7348. {
  7349. $this->data = $data;
  7350. $this->data_length = strlen($this->data);
  7351. }
  7352. /**
  7353. * Parse the input data
  7354. *
  7355. * @access public
  7356. * @return bool true on success, false on failure
  7357. */
  7358. function parse()
  7359. {
  7360. while ($this->state && $this->state !== 'emit' && $this->has_data())
  7361. {
  7362. $state = $this->state;
  7363. $this->$state();
  7364. }
  7365. $this->data = '';
  7366. if ($this->state === 'emit' || $this->state === 'body')
  7367. {
  7368. return true;
  7369. }
  7370. else
  7371. {
  7372. $this->http_version = '';
  7373. $this->status_code = '';
  7374. $this->reason = '';
  7375. $this->headers = array();
  7376. $this->body = '';
  7377. return false;
  7378. }
  7379. }
  7380. /**
  7381. * Check whether there is data beyond the pointer
  7382. *
  7383. * @access private
  7384. * @return bool true if there is further data, false if not
  7385. */
  7386. function has_data()
  7387. {
  7388. return (bool) ($this->position < $this->data_length);
  7389. }
  7390. /**
  7391. * See if the next character is LWS
  7392. *
  7393. * @access private
  7394. * @return bool true if the next character is LWS, false if not
  7395. */
  7396. function is_linear_whitespace()
  7397. {
  7398. return (bool) ($this->data[$this->position] === "\x09"
  7399. || $this->data[$this->position] === "\x20"
  7400. || ($this->data[$this->position] === "\x0A"
  7401. && isset($this->data[$this->position + 1])
  7402. && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
  7403. }
  7404. /**
  7405. * Parse the HTTP version
  7406. *
  7407. * @access private
  7408. */
  7409. function http_version()
  7410. {
  7411. if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
  7412. {
  7413. $len = strspn($this->data, '0123456789.', 5);
  7414. $this->http_version = substr($this->data, 5, $len);
  7415. $this->position += 5 + $len;
  7416. if (substr_count($this->http_version, '.') <= 1)
  7417. {
  7418. $this->http_version = (float) $this->http_version;
  7419. $this->position += strspn($this->data, "\x09\x20", $this->position);
  7420. $this->state = 'status';
  7421. }
  7422. else
  7423. {
  7424. $this->state = false;
  7425. }
  7426. }
  7427. else
  7428. {
  7429. $this->state = false;
  7430. }
  7431. }
  7432. /**
  7433. * Parse the status code
  7434. *
  7435. * @access private
  7436. */
  7437. function status()
  7438. {
  7439. if ($len = strspn($this->data, '0123456789', $this->position))
  7440. {
  7441. $this->status_code = (int) substr($this->data, $this->position, $len);
  7442. $this->position += $len;
  7443. $this->state = 'reason';
  7444. }
  7445. else
  7446. {
  7447. $this->state = false;
  7448. }
  7449. }
  7450. /**
  7451. * Parse the reason phrase
  7452. *
  7453. * @access private
  7454. */
  7455. function reason()
  7456. {
  7457. $len = strcspn($this->data, "\x0A", $this->position);
  7458. $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
  7459. $this->position += $len + 1;
  7460. $this->state = 'new_line';
  7461. }
  7462. /**
  7463. * Deal with a new line, shifting data around as needed
  7464. *
  7465. * @access private
  7466. */
  7467. function new_line()
  7468. {
  7469. $this->value = trim($this->value, "\x0D\x20");
  7470. if ($this->name !== '' && $this->value !== '')
  7471. {
  7472. $this->name = strtolower($this->name);
  7473. if (isset($this->headers[$this->name]))
  7474. {
  7475. $this->headers[$this->name] .= ', ' . $this->value;
  7476. }
  7477. else
  7478. {
  7479. $this->headers[$this->name] = $this->value;
  7480. }
  7481. }
  7482. $this->name = '';
  7483. $this->value = '';
  7484. if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
  7485. {
  7486. $this->position += 2;
  7487. $this->state = 'body';
  7488. }
  7489. elseif ($this->data[$this->position] === "\x0A")
  7490. {
  7491. $this->position++;
  7492. $this->state = 'body';
  7493. }
  7494. else
  7495. {
  7496. $this->state = 'name';
  7497. }
  7498. }
  7499. /**
  7500. * Parse a header name
  7501. *
  7502. * @access private
  7503. */
  7504. function name()
  7505. {
  7506. $len = strcspn($this->data, "\x0A:", $this->position);
  7507. if (isset($this->data[$this->position + $len]))
  7508. {
  7509. if ($this->data[$this->position + $len] === "\x0A")
  7510. {
  7511. $this->position += $len;
  7512. $this->state = 'new_line';
  7513. }
  7514. else
  7515. {
  7516. $this->name = substr($this->data, $this->position, $len);
  7517. $this->position += $len + 1;
  7518. $this->state = 'value';
  7519. }
  7520. }
  7521. else
  7522. {
  7523. $this->state = false;
  7524. }
  7525. }
  7526. /**
  7527. * Parse LWS, replacing consecutive LWS characters with a single space
  7528. *
  7529. * @access private
  7530. */
  7531. function linear_whitespace()
  7532. {
  7533. do
  7534. {
  7535. if (substr($this->data, $this->position, 2) === "\x0D\x0A")
  7536. {
  7537. $this->position += 2;
  7538. }
  7539. elseif ($this->data[$this->position] === "\x0A")
  7540. {
  7541. $this->position++;
  7542. }
  7543. $this->position += strspn($this->data, "\x09\x20", $this->position);
  7544. } while ($this->has_data() && $this->is_linear_whitespace());
  7545. $this->value .= "\x20";
  7546. }
  7547. /**
  7548. * See what state to move to while within non-quoted header values
  7549. *
  7550. * @access private
  7551. */
  7552. function value()
  7553. {
  7554. if ($this->is_linear_whitespace())
  7555. {
  7556. $this->linear_whitespace();
  7557. }
  7558. else
  7559. {
  7560. switch ($this->data[$this->position])
  7561. {
  7562. case '"':
  7563. $this->position++;
  7564. $this->state = 'quote';
  7565. break;
  7566. case "\x0A":
  7567. $this->position++;
  7568. $this->state = 'new_line';
  7569. break;
  7570. default:
  7571. $this->state = 'value_char';
  7572. break;
  7573. }
  7574. }
  7575. }
  7576. /**
  7577. * Parse a header value while outside quotes
  7578. *
  7579. * @access private
  7580. */
  7581. function value_char()
  7582. {
  7583. $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
  7584. $this->value .= substr($this->data, $this->position, $len);
  7585. $this->position += $len;
  7586. $this->state = 'value';
  7587. }
  7588. /**
  7589. * See what state to move to while within quoted header values
  7590. *
  7591. * @access private
  7592. */
  7593. function quote()
  7594. {
  7595. if ($this->is_linear_whitespace())
  7596. {
  7597. $this->linear_whitespace();
  7598. }
  7599. else
  7600. {
  7601. switch ($this->data[$this->position])
  7602. {
  7603. case '"':
  7604. $this->position++;
  7605. $this->state = 'value';
  7606. break;
  7607. case "\x0A":
  7608. $this->position++;
  7609. $this->state = 'new_line';
  7610. break;
  7611. case '\\':
  7612. $this->position++;
  7613. $this->state = 'quote_escaped';
  7614. break;
  7615. default:
  7616. $this->state = 'quote_char';
  7617. break;
  7618. }
  7619. }
  7620. }
  7621. /**
  7622. * Parse a header value while within quotes
  7623. *
  7624. * @access private
  7625. */
  7626. function quote_char()
  7627. {
  7628. $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
  7629. $this->value .= substr($this->data, $this->position, $len);
  7630. $this->position += $len;
  7631. $this->state = 'value';
  7632. }
  7633. /**
  7634. * Parse an escaped character within quotes
  7635. *
  7636. * @access private
  7637. */
  7638. function quote_escaped()
  7639. {
  7640. $this->value .= $this->data[$this->position];
  7641. $this->position++;
  7642. $this->state = 'quote';
  7643. }
  7644. /**
  7645. * Parse the body
  7646. *
  7647. * @access private
  7648. */
  7649. function body()
  7650. {
  7651. $this->body = substr($this->data, $this->position);
  7652. $this->state = 'emit';
  7653. }
  7654. }
  7655. /**
  7656. * gzdecode
  7657. *
  7658. * @package SimplePie
  7659. */
  7660. class SimplePie_gzdecode
  7661. {
  7662. /**
  7663. * Compressed data
  7664. *
  7665. * @access private
  7666. * @see gzdecode::$data
  7667. */
  7668. var $compressed_data;
  7669. /**
  7670. * Size of compressed data
  7671. *
  7672. * @access private
  7673. */
  7674. var $compressed_size;
  7675. /**
  7676. * Minimum size of a valid gzip string
  7677. *
  7678. * @access private
  7679. */
  7680. var $min_compressed_size = 18;
  7681. /**
  7682. * Current position of pointer
  7683. *
  7684. * @access private
  7685. */
  7686. var $position = 0;
  7687. /**
  7688. * Flags (FLG)
  7689. *
  7690. * @access private
  7691. */
  7692. var $flags;
  7693. /**
  7694. * Uncompressed data
  7695. *
  7696. * @access public
  7697. * @see gzdecode::$compressed_data
  7698. */
  7699. var $data;
  7700. /**
  7701. * Modified time
  7702. *
  7703. * @access public
  7704. */
  7705. var $MTIME;
  7706. /**
  7707. * Extra Flags
  7708. *
  7709. * @access public
  7710. */
  7711. var $XFL;
  7712. /**
  7713. * Operating System
  7714. *
  7715. * @access public
  7716. */
  7717. var $OS;
  7718. /**
  7719. * Subfield ID 1
  7720. *
  7721. * @access public
  7722. * @see gzdecode::$extra_field
  7723. * @see gzdecode::$SI2
  7724. */
  7725. var $SI1;
  7726. /**
  7727. * Subfield ID 2
  7728. *
  7729. * @access public
  7730. * @see gzdecode::$extra_field
  7731. * @see gzdecode::$SI1
  7732. */
  7733. var $SI2;
  7734. /**
  7735. * Extra field content
  7736. *
  7737. * @access public
  7738. * @see gzdecode::$SI1
  7739. * @see gzdecode::$SI2
  7740. */
  7741. var $extra_field;
  7742. /**
  7743. * Original filename
  7744. *
  7745. * @access public
  7746. */
  7747. var $filename;
  7748. /**
  7749. * Human readable comment
  7750. *
  7751. * @access public
  7752. */
  7753. var $comment;
  7754. /**
  7755. * Don't allow anything to be set
  7756. *
  7757. * @access public
  7758. */
  7759. function __set($name, $value)
  7760. {
  7761. trigger_error("Cannot write property $name", E_USER_ERROR);
  7762. }
  7763. /**
  7764. * Set the compressed string and related properties
  7765. *
  7766. * @access public
  7767. */
  7768. function SimplePie_gzdecode($data)
  7769. {
  7770. $this->compressed_data = $data;
  7771. $this->compressed_size = strlen($data);
  7772. }
  7773. /**
  7774. * Decode the GZIP stream
  7775. *
  7776. * @access public
  7777. */
  7778. function parse()
  7779. {
  7780. if ($this->compressed_size >= $this->min_compressed_size)
  7781. {
  7782. // Check ID1, ID2, and CM
  7783. if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
  7784. {
  7785. return false;
  7786. }
  7787. // Get the FLG (FLaGs)
  7788. $this->flags = ord($this->compressed_data[3]);
  7789. // FLG bits above (1 << 4) are reserved
  7790. if ($flg > 0x1F)
  7791. {
  7792. return false;
  7793. }
  7794. // Advance the pointer after the above
  7795. $this->position += 4;
  7796. // MTIME
  7797. $mtime = substr($this->compressed_data, $this->position, 4);
  7798. // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
  7799. if (current(unpack('S', "\x00\x01")) === 1)
  7800. {
  7801. $mtime = strrev($mtime);
  7802. }
  7803. $this->MTIME = current(unpack('l', $mtime));
  7804. $this->position += 4;
  7805. // Get the XFL (eXtra FLags)
  7806. $this->XFL = ord($this->compressed_data[$this->position++]);
  7807. // Get the OS (Operating System)
  7808. $this->OS = ord($this->compressed_data[$this->position++]);
  7809. // Parse the FEXTRA
  7810. if ($this->flags & 4)
  7811. {
  7812. // Read subfield IDs
  7813. $this->SI1 = $this->compressed_data[$this->position++];
  7814. $this->SI2 = $this->compressed_data[$this->position++];
  7815. // SI2 set to zero is reserved for future use
  7816. if ($this->SI2 === "\x00")
  7817. {
  7818. return false;
  7819. }
  7820. // Get the length of the extra field
  7821. $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
  7822. $position += 2;
  7823. // Check the length of the string is still valid
  7824. $this->min_compressed_size += $len + 4;
  7825. if ($this->compressed_size >= $this->min_compressed_size)
  7826. {
  7827. // Set the extra field to the given data
  7828. $this->extra_field = substr($this->compressed_data, $this->position, $len);
  7829. $this->position += $len;
  7830. }
  7831. else
  7832. {
  7833. return false;
  7834. }
  7835. }
  7836. // Parse the FNAME
  7837. if ($this->flags & 8)
  7838. {
  7839. // Get the length of the filename
  7840. $len = strspn($this->compressed_data, "\x00", $this->position);
  7841. // Check the length of the string is still valid
  7842. $this->min_compressed_size += $len + 1;
  7843. if ($this->compressed_size >= $this->min_compressed_size)
  7844. {
  7845. // Set the original filename to the given string
  7846. $this->filename = substr($this->compressed_data, $this->position, $len);
  7847. $this->position += $len + 1;
  7848. }
  7849. else
  7850. {
  7851. return false;
  7852. }
  7853. }
  7854. // Parse the FCOMMENT
  7855. if ($this->flags & 16)
  7856. {
  7857. // Get the length of the comment
  7858. $len = strspn($this->compressed_data, "\x00", $this->position);
  7859. // Check the length of the string is still valid
  7860. $this->min_compressed_size += $len + 1;
  7861. if ($this->compressed_size >= $this->min_compressed_size)
  7862. {
  7863. // Set the original comment to the given string
  7864. $this->comment = substr($this->compressed_data, $this->position, $len);
  7865. $this->position += $len + 1;
  7866. }
  7867. else
  7868. {
  7869. return false;
  7870. }
  7871. }
  7872. // Parse the FHCRC
  7873. if ($this->flags & 2)
  7874. {
  7875. // Check the length of the string is still valid
  7876. $this->min_compressed_size += $len + 2;
  7877. if ($this->compressed_size >= $this->min_compressed_size)
  7878. {
  7879. // Read the CRC
  7880. $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
  7881. // Check the CRC matches
  7882. if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
  7883. {
  7884. $this->position += 2;
  7885. }
  7886. else
  7887. {
  7888. return false;
  7889. }
  7890. }
  7891. else
  7892. {
  7893. return false;
  7894. }
  7895. }
  7896. // Decompress the actual data
  7897. if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
  7898. {
  7899. return false;
  7900. }
  7901. else
  7902. {
  7903. $this->position = $this->compressed_size - 8;
  7904. }
  7905. // Check CRC of data
  7906. $crc = current(unpack('N', substr($this->compressed_data, $this->position, 4)));
  7907. $this->position += 4;
  7908. if (extension_loaded('hash') && hexdec(hash('crc32b', $this->data)) !== $crc)
  7909. {
  7910. return false;
  7911. }
  7912. // Check ISIZE of data
  7913. $isize = current(unpack('N', substr($this->compressed_data, $this->position, 4)));
  7914. $this->position += 4;
  7915. if (strlen($this->data) & 0xFFFFFFFF !== $isize)
  7916. {
  7917. return false;
  7918. }
  7919. // Wow, against all odds, we've actually got a valid gzip string
  7920. return true;
  7921. }
  7922. else
  7923. {
  7924. return false;
  7925. }
  7926. }
  7927. }
  7928. class SimplePie_Cache
  7929. {
  7930. /**
  7931. * Don't call the constructor. Please.
  7932. *
  7933. * @access private
  7934. */
  7935. function SimplePie_Cache()
  7936. {
  7937. trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
  7938. }
  7939. /**
  7940. * Create a new SimplePie_Cache object
  7941. *
  7942. * @static
  7943. * @access public
  7944. */
  7945. function create($location, $filename, $extension)
  7946. {
  7947. return new SimplePie_Cache_File($location, $filename, $extension);
  7948. }
  7949. }
  7950. class SimplePie_Cache_File
  7951. {
  7952. var $location;
  7953. var $filename;
  7954. var $extension;
  7955. var $name;
  7956. function SimplePie_Cache_File($location, $filename, $extension)
  7957. {
  7958. $this->location = $location;
  7959. $this->filename = rawurlencode($filename);
  7960. $this->extension = rawurlencode($extension);
  7961. $this->name = "$location/$this->filename.$this->extension";
  7962. }
  7963. function save($data)
  7964. {
  7965. if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
  7966. {
  7967. if (is_a($data, 'SimplePie'))
  7968. {
  7969. $data = $data->data;
  7970. }
  7971. $data = serialize($data);
  7972. if (function_exists('file_put_contents'))
  7973. {
  7974. return (bool) file_put_contents($this->name, $data);
  7975. }
  7976. else
  7977. {
  7978. $fp = fopen($this->name, 'wb');
  7979. if ($fp)
  7980. {
  7981. fwrite($fp, $data);
  7982. fclose($fp);
  7983. return true;
  7984. }
  7985. }
  7986. }
  7987. return false;
  7988. }
  7989. function load()
  7990. {
  7991. if (file_exists($this->name) && is_readable($this->name))
  7992. {
  7993. return unserialize(file_get_contents($this->name));
  7994. }
  7995. return false;
  7996. }
  7997. function mtime()
  7998. {
  7999. if (file_exists($this->name))
  8000. {
  8001. return filemtime($this->name);
  8002. }
  8003. return false;
  8004. }
  8005. function touch()
  8006. {
  8007. if (file_exists($this->name))
  8008. {
  8009. return touch($this->name);
  8010. }
  8011. return false;
  8012. }
  8013. function unlink()
  8014. {
  8015. if (file_exists($this->name))
  8016. {
  8017. return unlink($this->name);
  8018. }
  8019. return false;
  8020. }
  8021. }
  8022. class SimplePie_Misc
  8023. {
  8024. function time_hms($seconds)
  8025. {
  8026. $time = '';
  8027. $hours = floor($seconds / 3600);
  8028. $remainder = $seconds % 3600;
  8029. if ($hours > 0)
  8030. {
  8031. $time .= $hours.':';
  8032. }
  8033. $minutes = floor($remainder / 60);
  8034. $seconds = $remainder % 60;
  8035. if ($minutes < 10 && $hours > 0)
  8036. {
  8037. $minutes = '0' . $minutes;
  8038. }
  8039. if ($seconds < 10)
  8040. {
  8041. $seconds = '0' . $seconds;
  8042. }
  8043. $time .= $minutes.':';
  8044. $time .= $seconds;
  8045. return $time;
  8046. }
  8047. function absolutize_url($relative, $base)
  8048. {
  8049. if ($relative !== '')
  8050. {
  8051. $relative = SimplePie_Misc::parse_url($relative);
  8052. if ($relative['scheme'] !== '')
  8053. {
  8054. $target = $relative;
  8055. }
  8056. elseif ($base !== '')
  8057. {
  8058. $base = SimplePie_Misc::parse_url($base);
  8059. $target = SimplePie_Misc::parse_url('');
  8060. if ($relative['authority'] !== '')
  8061. {
  8062. $target = $relative;
  8063. $target['scheme'] = $base['scheme'];
  8064. }
  8065. else
  8066. {
  8067. $target['scheme'] = $base['scheme'];
  8068. $target['authority'] = $base['authority'];
  8069. if ($relative['path'] !== '')
  8070. {
  8071. if (strpos($relative['path'], '/') === 0)
  8072. {
  8073. $target['path'] = $relative['path'];
  8074. }
  8075. elseif ($base['authority'] !== '' && $base['path'] === '')
  8076. {
  8077. $target['path'] = '/' . $relative['path'];
  8078. }
  8079. elseif (($last_segment = strrpos($base['path'], '/')) !== false)
  8080. {
  8081. $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
  8082. }
  8083. else
  8084. {
  8085. $target['path'] = $relative['path'];
  8086. }
  8087. $target['query'] = $relative['query'];
  8088. }
  8089. else
  8090. {
  8091. $target['path'] = $base['path'];
  8092. if ($relative['query'] !== '')
  8093. {
  8094. $target['query'] = $relative['query'];
  8095. }
  8096. elseif ($base['query'] !== '')
  8097. {
  8098. $target['query'] = $base['query'];
  8099. }
  8100. }
  8101. }
  8102. $target['fragment'] = $relative['fragment'];
  8103. }
  8104. else
  8105. {
  8106. // No base URL, just return the relative URL
  8107. $target = $relative;
  8108. }
  8109. $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
  8110. }
  8111. else
  8112. {
  8113. $return = $base;
  8114. }
  8115. $return = SimplePie_Misc::normalize_url($return);
  8116. return $return;
  8117. }
  8118. function remove_dot_segments($input)
  8119. {
  8120. $output = '';
  8121. while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
  8122. {
  8123. // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
  8124. if (strpos($input, '../') === 0)
  8125. {
  8126. $input = substr($input, 3);
  8127. }
  8128. elseif (strpos($input, './') === 0)
  8129. {
  8130. $input = substr($input, 2);
  8131. }
  8132. // 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,
  8133. elseif (strpos($input, '/./') === 0)
  8134. {
  8135. $input = substr_replace($input, '/', 0, 3);
  8136. }
  8137. elseif ($input == '/.')
  8138. {
  8139. $input = '/';
  8140. }
  8141. // 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,
  8142. elseif (strpos($input, '/../') === 0)
  8143. {
  8144. $input = substr_replace($input, '/', 0, 4);
  8145. $output = substr_replace($output, '', strrpos($output, '/'));
  8146. }
  8147. elseif ($input == '/..')
  8148. {
  8149. $input = '/';
  8150. $output = substr_replace($output, '', strrpos($output, '/'));
  8151. }
  8152. // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
  8153. elseif ($input == '.' || $input == '..')
  8154. {
  8155. $input = '';
  8156. }
  8157. // 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
  8158. elseif (($pos = strpos($input, '/', 1)) !== false)
  8159. {
  8160. $output .= substr($input, 0, $pos);
  8161. $input = substr_replace($input, '', 0, $pos);
  8162. }
  8163. else
  8164. {
  8165. $output .= $input;
  8166. $input = '';
  8167. }
  8168. }
  8169. return $output . $input;
  8170. }
  8171. function get_element($realname, $string)
  8172. {
  8173. $return = array();
  8174. $name = preg_quote($realname, '/');
  8175. if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
  8176. {
  8177. for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
  8178. {
  8179. $return[$i]['tag'] = $realname;
  8180. $return[$i]['full'] = $matches[$i][0][0];
  8181. $return[$i]['offset'] = $matches[$i][0][1];
  8182. if (strlen($matches[$i][3][0]) <= 2)
  8183. {
  8184. $return[$i]['self_closing'] = true;
  8185. }
  8186. else
  8187. {
  8188. $return[$i]['self_closing'] = false;
  8189. $return[$i]['content'] = $matches[$i][4][0];
  8190. }
  8191. $return[$i]['attribs'] = array();
  8192. 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))
  8193. {
  8194. for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
  8195. {
  8196. if (count($attribs[$j]) == 2)
  8197. {
  8198. $attribs[$j][2] = $attribs[$j][1];
  8199. }
  8200. $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
  8201. }
  8202. }
  8203. }
  8204. }
  8205. return $return;
  8206. }
  8207. function element_implode($element)
  8208. {
  8209. $full = "<$element[tag]";
  8210. foreach ($element['attribs'] as $key => $value)
  8211. {
  8212. $key = strtolower($key);
  8213. $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
  8214. }
  8215. if ($element['self_closing'])
  8216. {
  8217. $full .= ' />';
  8218. }
  8219. else
  8220. {
  8221. $full .= ">$element[content]</$element[tag]>";
  8222. }
  8223. return $full;
  8224. }
  8225. function error($message, $level, $file, $line)
  8226. {
  8227. switch ($level)
  8228. {
  8229. case E_USER_ERROR:
  8230. $note = 'PHP Error';
  8231. break;
  8232. case E_USER_WARNING:
  8233. $note = 'PHP Warning';
  8234. break;
  8235. case E_USER_NOTICE:
  8236. $note = 'PHP Notice';
  8237. break;
  8238. default:
  8239. $note = 'Unknown Error';
  8240. break;
  8241. }
  8242. error_log("$note: $message in $file on line $line", 0);
  8243. return $message;
  8244. }
  8245. /**
  8246. * If a file has been cached, retrieve and display it.
  8247. *
  8248. * This is most useful for caching images (get_favicon(), etc.),
  8249. * however it works for all cached files. This WILL NOT display ANY
  8250. * file/image/page/whatever, but rather only display what has already
  8251. * been cached by SimplePie.
  8252. *
  8253. * @access public
  8254. * @see SimplePie::get_favicon()
  8255. * @param str $identifier_url URL that is used to identify the content.
  8256. * This may or may not be the actual URL of the live content.
  8257. * @param str $cache_location Location of SimplePie's cache. Defaults
  8258. * to './cache'.
  8259. * @param str $cache_extension The file extension that the file was
  8260. * cached with. Defaults to 'spc'.
  8261. * @param str $cache_class Name of the cache-handling class being used
  8262. * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
  8263. * as-is unless you've overloaded the class.
  8264. * @param str $cache_name_function Obsolete. Exists for backwards
  8265. * compatibility reasons only.
  8266. */
  8267. function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
  8268. {
  8269. $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
  8270. if ($file = $cache->load())
  8271. {
  8272. if (isset($file['headers']['content-type']))
  8273. {
  8274. header('Content-type:' . $file['headers']['content-type']);
  8275. }
  8276. else
  8277. {
  8278. header('Content-type: application/octet-stream');
  8279. }
  8280. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  8281. echo $file['body'];
  8282. exit;
  8283. }
  8284. die('Cached file for ' . $identifier_url . ' cannot be found.');
  8285. }
  8286. function fix_protocol($url, $http = 1)
  8287. {
  8288. $url = SimplePie_Misc::normalize_url($url);
  8289. $parsed = SimplePie_Misc::parse_url($url);
  8290. if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
  8291. {
  8292. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
  8293. }
  8294. if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
  8295. {
  8296. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
  8297. }
  8298. if ($http == 2 && $parsed['scheme'] !== '')
  8299. {
  8300. return "feed:$url";
  8301. }
  8302. elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
  8303. {
  8304. return substr_replace($url, 'podcast', 0, 4);
  8305. }
  8306. elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
  8307. {
  8308. return substr_replace($url, 'itpc', 0, 4);
  8309. }
  8310. else
  8311. {
  8312. return $url;
  8313. }
  8314. }
  8315. function parse_url($url)
  8316. {
  8317. static $cache = array();
  8318. if (isset($cache[$url]))
  8319. {
  8320. return $cache[$url];
  8321. }
  8322. elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
  8323. {
  8324. for ($i = count($match); $i <= 9; $i++)
  8325. {
  8326. $match[$i] = '';
  8327. }
  8328. return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
  8329. }
  8330. else
  8331. {
  8332. return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
  8333. }
  8334. }
  8335. function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
  8336. {
  8337. $return = '';
  8338. if ($scheme !== '')
  8339. {
  8340. $return .= "$scheme:";
  8341. }
  8342. if ($authority !== '')
  8343. {
  8344. $return .= "//$authority";
  8345. }
  8346. if ($path !== '')
  8347. {
  8348. $return .= $path;
  8349. }
  8350. if ($query !== '')
  8351. {
  8352. $return .= "?$query";
  8353. }
  8354. if ($fragment !== '')
  8355. {
  8356. $return .= "#$fragment";
  8357. }
  8358. return $return;
  8359. }
  8360. function normalize_url($url)
  8361. {
  8362. $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
  8363. $url = SimplePie_Misc::parse_url($url);
  8364. $url['scheme'] = strtolower($url['scheme']);
  8365. if ($url['authority'] !== '')
  8366. {
  8367. $url['authority'] = strtolower($url['authority']);
  8368. $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
  8369. }
  8370. return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
  8371. }
  8372. function percent_encoding_normalization($match)
  8373. {
  8374. $integer = hexdec($match[1]);
  8375. if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
  8376. {
  8377. return chr($integer);
  8378. }
  8379. else
  8380. {
  8381. return strtoupper($match[0]);
  8382. }
  8383. }
  8384. /**
  8385. * Remove bad UTF-8 bytes
  8386. *
  8387. * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
  8388. * FAQ: Multilingual Forms (modified to include full ASCII range)
  8389. *
  8390. * @author Geoffrey Sneddon
  8391. * @see http://www.w3.org/International/questions/qa-forms-utf-8
  8392. * @param string $str String to remove bad UTF-8 bytes from
  8393. * @return string UTF-8 string
  8394. */
  8395. function utf8_bad_replace($str)
  8396. {
  8397. if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
  8398. {
  8399. return $return;
  8400. }
  8401. elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
  8402. {
  8403. return $return;
  8404. }
  8405. elseif (preg_match_all('/(?:[\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})+/', $str, $matches))
  8406. {
  8407. return implode("\xEF\xBF\xBD", $matches[0]);
  8408. }
  8409. elseif ($str !== '')
  8410. {
  8411. return "\xEF\xBF\xBD";
  8412. }
  8413. else
  8414. {
  8415. return '';
  8416. }
  8417. }
  8418. /**
  8419. * Converts a Windows-1252 encoded string to a UTF-8 encoded string
  8420. *
  8421. * @static
  8422. * @access public
  8423. * @param string $string Windows-1252 encoded string
  8424. * @return string UTF-8 encoded string
  8425. */
  8426. function windows_1252_to_utf8($string)
  8427. {
  8428. 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");
  8429. return strtr($string, $convert_table);
  8430. }
  8431. function change_encoding($data, $input, $output)
  8432. {
  8433. $input = SimplePie_Misc::encoding($input);
  8434. $output = SimplePie_Misc::encoding($output);
  8435. // We fail to fail on non US-ASCII bytes
  8436. if ($input === 'US-ASCII')
  8437. {
  8438. static $non_ascii_octects = '';
  8439. if (!$non_ascii_octects)
  8440. {
  8441. for ($i = 0x80; $i <= 0xFF; $i++)
  8442. {
  8443. $non_ascii_octects .= chr($i);
  8444. }
  8445. }
  8446. $data = substr($data, 0, strcspn($data, $non_ascii_octects));
  8447. }
  8448. // This is first, as behaviour of this is completely predictable
  8449. if ($input === 'Windows-1252' && $output === 'UTF-8')
  8450. {
  8451. return SimplePie_Misc::windows_1252_to_utf8($data);
  8452. }
  8453. // This is second, as behaviour of this varies only with PHP version
  8454. elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
  8455. {
  8456. return $return;
  8457. }
  8458. // This is last, as behaviour of this varies with OS userland and PHP version
  8459. elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
  8460. {
  8461. return $return;
  8462. }
  8463. // If we can't do anything, just fail
  8464. else
  8465. {
  8466. return false;
  8467. }
  8468. }
  8469. function encoding($charset)
  8470. {
  8471. /* Character sets are case-insensitive, and also need some further
  8472. normalization in the real world (though we'll return them in the form given
  8473. in their registration). */
  8474. switch (strtolower(preg_replace('/[\x09-\x0D\x20-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]/', '', $charset)))
  8475. {
  8476. case 'adobestandardencoding':
  8477. case 'csadobestandardencoding':
  8478. return 'Adobe-Standard-Encoding';
  8479. case 'adobesymbolencoding':
  8480. case 'cshppsmath':
  8481. return 'Adobe-Symbol-Encoding';
  8482. case 'ami1251':
  8483. case 'ami1251':
  8484. case 'amiga1251':
  8485. case 'amiga1251':
  8486. return 'Amiga-1251';
  8487. case 'ansix31101983':
  8488. case 'csat5001983':
  8489. case 'csiso99naplps':
  8490. case 'isoir99':
  8491. case 'naplps':
  8492. return 'ANSI_X3.110-1983';
  8493. case 'arabic7':
  8494. case 'asmo449':
  8495. case 'csiso89asmo449':
  8496. case 'isoir89':
  8497. case 'iso9036':
  8498. return 'ASMO_449';
  8499. case 'big5':
  8500. case 'csbig5':
  8501. case 'xxbig5':
  8502. return 'Big5';
  8503. case 'big5hkscs':
  8504. return 'Big5-HKSCS';
  8505. case 'bocu1':
  8506. case 'csbocu1':
  8507. return 'BOCU-1';
  8508. case 'brf':
  8509. case 'csbrf':
  8510. return 'BRF';
  8511. case 'bs4730':
  8512. case 'csiso4unitedkingdom':
  8513. case 'gb':
  8514. case 'isoir4':
  8515. case 'iso646gb':
  8516. case 'uk':
  8517. return 'BS_4730';
  8518. case 'bsviewdata':
  8519. case 'csiso47bsviewdata':
  8520. case 'isoir47':
  8521. return 'BS_viewdata';
  8522. case 'cesu8':
  8523. case 'cscesu8':
  8524. return 'CESU-8';
  8525. case 'ca':
  8526. case 'csa71':
  8527. case 'csaz243419851':
  8528. case 'csiso121canadian1':
  8529. case 'isoir121':
  8530. case 'iso646ca':
  8531. return 'CSA_Z243.4-1985-1';
  8532. case 'csa72':
  8533. case 'csaz243419852':
  8534. case 'csiso122canadian2':
  8535. case 'isoir122':
  8536. case 'iso646ca2':
  8537. return 'CSA_Z243.4-1985-2';
  8538. case 'csaz24341985gr':
  8539. case 'csiso123csaz24341985gr':
  8540. case 'isoir123':
  8541. return 'CSA_Z243.4-1985-gr';
  8542. case 'csiso139csn369103':
  8543. case 'csn369103':
  8544. case 'isoir139':
  8545. return 'CSN_369103';
  8546. case 'csdecmcs':
  8547. case 'dec':
  8548. case 'decmcs':
  8549. return 'DEC-MCS';
  8550. case 'csiso21german':
  8551. case 'de':
  8552. case 'din66003':
  8553. case 'isoir21':
  8554. case 'iso646de':
  8555. return 'DIN_66003';
  8556. case 'csdkus':
  8557. case 'dkus':
  8558. return 'dk-us';
  8559. case 'csiso646danish':
  8560. case 'dk':
  8561. case 'ds2089':
  8562. case 'ds2089':
  8563. case 'iso646dk':
  8564. return 'DS_2089';
  8565. case 'csibmebcdicatde':
  8566. case 'ebcdicatde':
  8567. return 'EBCDIC-AT-DE';
  8568. case 'csebcdicatdea':
  8569. case 'ebcdicatdea':
  8570. return 'EBCDIC-AT-DE-A';
  8571. case 'csebcdiccafr':
  8572. case 'ebcdiccafr':
  8573. return 'EBCDIC-CA-FR';
  8574. case 'csebcdicdkno':
  8575. case 'ebcdicdkno':
  8576. return 'EBCDIC-DK-NO';
  8577. case 'csebcdicdknoa':
  8578. case 'ebcdicdknoa':
  8579. return 'EBCDIC-DK-NO-A';
  8580. case 'csebcdices':
  8581. case 'ebcdices':
  8582. return 'EBCDIC-ES';
  8583. case 'csebcdicesa':
  8584. case 'ebcdicesa':
  8585. return 'EBCDIC-ES-A';
  8586. case 'csebcdicess':
  8587. case 'ebcdicess':
  8588. return 'EBCDIC-ES-S';
  8589. case 'csebcdicfise':
  8590. case 'ebcdicfise':
  8591. return 'EBCDIC-FI-SE';
  8592. case 'csebcdicfisea':
  8593. case 'ebcdicfisea':
  8594. return 'EBCDIC-FI-SE-A';
  8595. case 'csebcdicfr':
  8596. case 'ebcdicfr':
  8597. return 'EBCDIC-FR';
  8598. case 'csebcdicit':
  8599. case 'ebcdicit':
  8600. return 'EBCDIC-IT';
  8601. case 'csebcdicpt':
  8602. case 'ebcdicpt':
  8603. return 'EBCDIC-PT';
  8604. case 'csebcdicuk':
  8605. case 'ebcdicuk':
  8606. return 'EBCDIC-UK';
  8607. case 'csebcdicus':
  8608. case 'ebcdicus':
  8609. return 'EBCDIC-US';
  8610. case 'csiso111ecmacyrillic':
  8611. case 'ecmacyrillic':
  8612. case 'isoir111':
  8613. case 'koi8e':
  8614. return 'ECMA-cyrillic';
  8615. case 'csiso17spanish':
  8616. case 'es':
  8617. case 'isoir17':
  8618. case 'iso646es':
  8619. return 'ES';
  8620. case 'csiso85spanish2':
  8621. case 'es2':
  8622. case 'isoir85':
  8623. case 'iso646es2':
  8624. return 'ES2';
  8625. case 'cseucfixwidjapanese':
  8626. case 'extendedunixcodefixedwidthforjapanese':
  8627. return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
  8628. case 'cseucpkdfmtjapanese':
  8629. case 'eucjp':
  8630. case 'extendedunixcodepackedformatforjapanese':
  8631. return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
  8632. case 'gb18030':
  8633. return 'GB18030';
  8634. case 'cp936':
  8635. case 'gbk':
  8636. case 'ms936':
  8637. case 'windows936':
  8638. case 'csgb2312':
  8639. case 'gb2312':
  8640. case 'chinese':
  8641. case 'csiso58gb231280':
  8642. case 'gb231280':
  8643. case 'isoir58':
  8644. return 'GBK';
  8645. case 'cn':
  8646. case 'csiso57gb1988':
  8647. case 'gb198880':
  8648. case 'isoir57':
  8649. case 'iso646cn':
  8650. return 'GB_1988-80';
  8651. case 'csiso153gost1976874':
  8652. case 'gost1976874':
  8653. case 'isoir153':
  8654. case 'stsev35888':
  8655. return 'GOST_19768-74';
  8656. case 'csiso150':
  8657. case 'csiso150greekccitt':
  8658. case 'greekccitt':
  8659. case 'isoir150':
  8660. return 'greek-ccitt';
  8661. case 'csiso88greek7':
  8662. case 'greek7':
  8663. case 'isoir88':
  8664. return 'greek7';
  8665. case 'csiso18greek7old':
  8666. case 'greek7old':
  8667. case 'isoir18':
  8668. return 'greek7-old';
  8669. case 'cshpdesktop':
  8670. case 'hpdesktop':
  8671. return 'HP-DeskTop';
  8672. case 'cshplegal':
  8673. case 'hplegal':
  8674. return 'HP-Legal';
  8675. case 'cshpmath8':
  8676. case 'hpmath8':
  8677. return 'HP-Math8';
  8678. case 'cshppifont':
  8679. case 'hppifont':
  8680. return 'HP-Pi-font';
  8681. case 'cshproman8':
  8682. case 'hproman8':
  8683. case 'r8':
  8684. case 'roman8':
  8685. return 'hp-roman8';
  8686. case 'hzgb2312':
  8687. return 'HZ-GB-2312';
  8688. case 'csibmsymbols':
  8689. case 'ibmsymbols':
  8690. return 'IBM-Symbols';
  8691. case 'csibmthai':
  8692. case 'ibmthai':
  8693. return 'IBM-Thai';
  8694. case 'ccsid00858':
  8695. case 'cp00858':
  8696. case 'ibm00858':
  8697. case 'pcmultilingual850euro':
  8698. return 'IBM00858';
  8699. case 'ccsid00924':
  8700. case 'cp00924':
  8701. case 'ebcdiclatin9euro':
  8702. case 'ibm00924':
  8703. return 'IBM00924';
  8704. case 'ccsid01140':
  8705. case 'cp01140':
  8706. case 'ebcdicus37euro':
  8707. case 'ibm01140':
  8708. return 'IBM01140';
  8709. case 'ccsid01141':
  8710. case 'cp01141':
  8711. case 'ebcdicde273euro':
  8712. case 'ibm01141':
  8713. return 'IBM01141';
  8714. case 'ccsid01142':
  8715. case 'cp01142':
  8716. case 'ebcdicdk277euro':
  8717. case 'ebcdicno277euro':
  8718. case 'ibm01142':
  8719. return 'IBM01142';
  8720. case 'ccsid01143':
  8721. case 'cp01143':
  8722. case 'ebcdicfi278euro':
  8723. case 'ebcdicse278euro':
  8724. case 'ibm01143':
  8725. return 'IBM01143';
  8726. case 'ccsid01144':
  8727. case 'cp01144':
  8728. case 'ebcdicit280euro':
  8729. case 'ibm01144':
  8730. return 'IBM01144';
  8731. case 'ccsid01145':
  8732. case 'cp01145':
  8733. case 'ebcdices284euro':
  8734. case 'ibm01145':
  8735. return 'IBM01145';
  8736. case 'ccsid01146':
  8737. case 'cp01146':
  8738. case 'ebcdicgb285euro':
  8739. case 'ibm01146':
  8740. return 'IBM01146';
  8741. case 'ccsid01147':
  8742. case 'cp01147':
  8743. case 'ebcdicfr297euro':
  8744. case 'ibm01147':
  8745. return 'IBM01147';
  8746. case 'ccsid01148':
  8747. case 'cp01148':
  8748. case 'ebcdicinternational500euro':
  8749. case 'ibm01148':
  8750. return 'IBM01148';
  8751. case 'ccsid01149':
  8752. case 'cp01149':
  8753. case 'ebcdicis871euro':
  8754. case 'ibm01149':
  8755. return 'IBM01149';
  8756. case 'cp037':
  8757. case 'csibm037':
  8758. case 'ebcdiccpca':
  8759. case 'ebcdiccpnl':
  8760. case 'ebcdiccpus':
  8761. case 'ebcdiccpwt':
  8762. case 'ibm037':
  8763. return 'IBM037';
  8764. case 'cp038':
  8765. case 'csibm038':
  8766. case 'ebcdicint':
  8767. case 'ibm038':
  8768. return 'IBM038';
  8769. case 'cp273':
  8770. case 'csibm273':
  8771. case 'ibm273':
  8772. return 'IBM273';
  8773. case 'cp274':
  8774. case 'csibm274':
  8775. case 'ebcdicbe':
  8776. case 'ibm274':
  8777. return 'IBM274';
  8778. case 'cp275':
  8779. case 'csibm275':
  8780. case 'ebcdicbr':
  8781. case 'ibm275':
  8782. return 'IBM275';
  8783. case 'csibm277':
  8784. case 'ebcdiccpdk':
  8785. case 'ebcdiccpno':
  8786. case 'ibm277':
  8787. return 'IBM277';
  8788. case 'cp278':
  8789. case 'csibm278':
  8790. case 'ebcdiccpfi':
  8791. case 'ebcdiccpse':
  8792. case 'ibm278':
  8793. return 'IBM278';
  8794. case 'cp280':
  8795. case 'csibm280':
  8796. case 'ebcdiccpit':
  8797. case 'ibm280':
  8798. return 'IBM280';
  8799. case 'cp281':
  8800. case 'csibm281':
  8801. case 'ebcdicjpe':
  8802. case 'ibm281':
  8803. return 'IBM281';
  8804. case 'cp284':
  8805. case 'csibm284':
  8806. case 'ebcdiccpes':
  8807. case 'ibm284':
  8808. return 'IBM284';
  8809. case 'cp285':
  8810. case 'csibm285':
  8811. case 'ebcdiccpgb':
  8812. case 'ibm285':
  8813. return 'IBM285';
  8814. case 'cp290':
  8815. case 'csibm290':
  8816. case 'ebcdicjpkana':
  8817. case 'ibm290':
  8818. return 'IBM290';
  8819. case 'cp297':
  8820. case 'csibm297':
  8821. case 'ebcdiccpfr':
  8822. case 'ibm297':
  8823. return 'IBM297';
  8824. case 'cp420':
  8825. case 'csibm420':
  8826. case 'ebcdiccpar1':
  8827. case 'ibm420':
  8828. return 'IBM420';
  8829. case 'cp423':
  8830. case 'csibm423':
  8831. case 'ebcdiccpgr':
  8832. case 'ibm423':
  8833. return 'IBM423';
  8834. case 'cp424':
  8835. case 'csibm424':
  8836. case 'ebcdiccphe':
  8837. case 'ibm424':
  8838. return 'IBM424';
  8839. case '437':
  8840. case 'cp437':
  8841. case 'cspc8codepage437':
  8842. case 'ibm437':
  8843. return 'IBM437';
  8844. case 'cp500':
  8845. case 'csibm500':
  8846. case 'ebcdiccpbe':
  8847. case 'ebcdiccpch':
  8848. case 'ibm500':
  8849. return 'IBM500';
  8850. case 'cp775':
  8851. case 'cspc775baltic':
  8852. case 'ibm775':
  8853. return 'IBM775';
  8854. case '850':
  8855. case 'cp850':
  8856. case 'cspc850multilingual':
  8857. case 'ibm850':
  8858. return 'IBM850';
  8859. case '851':
  8860. case 'cp851':
  8861. case 'csibm851':
  8862. case 'ibm851':
  8863. return 'IBM851';
  8864. case '852':
  8865. case 'cp852':
  8866. case 'cspcp852':
  8867. case 'ibm852':
  8868. return 'IBM852';
  8869. case '855':
  8870. case 'cp855':
  8871. case 'csibm855':
  8872. case 'ibm855':
  8873. return 'IBM855';
  8874. case '857':
  8875. case 'cp857':
  8876. case 'csibm857':
  8877. case 'ibm857':
  8878. return 'IBM857';
  8879. case '860':
  8880. case 'cp860':
  8881. case 'csibm860':
  8882. case 'ibm860':
  8883. return 'IBM860';
  8884. case '861':
  8885. case 'cpis':
  8886. case 'cp861':
  8887. case 'csibm861':
  8888. case 'ibm861':
  8889. return 'IBM861';
  8890. case '862':
  8891. case 'cp862':
  8892. case 'cspc862latinhebrew':
  8893. case 'ibm862':
  8894. return 'IBM862';
  8895. case '863':
  8896. case 'cp863':
  8897. case 'csibm863':
  8898. case 'ibm863':
  8899. return 'IBM863';
  8900. case 'cp864':
  8901. case 'csibm864':
  8902. case 'ibm864':
  8903. return 'IBM864';
  8904. case '865':
  8905. case 'cp865':
  8906. case 'csibm865':
  8907. case 'ibm865':
  8908. return 'IBM865';
  8909. case '866':
  8910. case 'cp866':
  8911. case 'csibm866':
  8912. case 'ibm866':
  8913. return 'IBM866';
  8914. case 'cpar':
  8915. case 'cp868':
  8916. case 'csibm868':
  8917. case 'ibm868':
  8918. return 'IBM868';
  8919. case '869':
  8920. case 'cpgr':
  8921. case 'cp869':
  8922. case 'csibm869':
  8923. case 'ibm869':
  8924. return 'IBM869';
  8925. case 'cp870':
  8926. case 'csibm870':
  8927. case 'ebcdiccproece':
  8928. case 'ebcdiccpyu':
  8929. case 'ibm870':
  8930. return 'IBM870';
  8931. case 'cp871':
  8932. case 'csibm871':
  8933. case 'ebcdiccpis':
  8934. case 'ibm871':
  8935. return 'IBM871';
  8936. case 'cp880':
  8937. case 'csibm880':
  8938. case 'ebcdiccyrillic':
  8939. case 'ibm880':
  8940. return 'IBM880';
  8941. case 'cp891':
  8942. case 'csibm891':
  8943. case 'ibm891':
  8944. return 'IBM891';
  8945. case 'cp903':
  8946. case 'csibm903':
  8947. case 'ibm903':
  8948. return 'IBM903';
  8949. case '904':
  8950. case 'cp904':
  8951. case 'csibbm904':
  8952. case 'ibm904':
  8953. return 'IBM904';
  8954. case 'cp905':
  8955. case 'csibm905':
  8956. case 'ebcdiccptr':
  8957. case 'ibm905':
  8958. return 'IBM905';
  8959. case 'cp918':
  8960. case 'csibm918':
  8961. case 'ebcdiccpar2':
  8962. case 'ibm918':
  8963. return 'IBM918';
  8964. case 'cp1026':
  8965. case 'csibm1026':
  8966. case 'ibm1026':
  8967. return 'IBM1026';
  8968. case 'ibm1047':
  8969. case 'ibm1047':
  8970. return 'IBM1047';
  8971. case 'csiso143iecp271':
  8972. case 'iecp271':
  8973. case 'isoir143':
  8974. return 'IEC_P27-1';
  8975. case 'csiso49inis':
  8976. case 'inis':
  8977. case 'isoir49':
  8978. return 'INIS';
  8979. case 'csiso50inis8':
  8980. case 'inis8':
  8981. case 'isoir50':
  8982. return 'INIS-8';
  8983. case 'csiso51iniscyrillic':
  8984. case 'iniscyrillic':
  8985. case 'isoir51':
  8986. return 'INIS-cyrillic';
  8987. case 'csinvariant':
  8988. case 'invariant':
  8989. return 'INVARIANT';
  8990. case 'iso2022cn':
  8991. return 'ISO-2022-CN';
  8992. case 'iso2022cnext':
  8993. return 'ISO-2022-CN-EXT';
  8994. case 'csiso2022jp':
  8995. case 'iso2022jp':
  8996. return 'ISO-2022-JP';
  8997. case 'csiso2022jp2':
  8998. case 'iso2022jp2':
  8999. return 'ISO-2022-JP-2';
  9000. case 'csiso2022kr':
  9001. case 'iso2022kr':
  9002. return 'ISO-2022-KR';
  9003. case 'cswindows30latin1':
  9004. case 'iso88591windows30latin1':
  9005. return 'ISO-8859-1-Windows-3.0-Latin-1';
  9006. case 'cswindows31latin1':
  9007. case 'iso88591windows31latin1':
  9008. return 'ISO-8859-1-Windows-3.1-Latin-1';
  9009. case 'csisolatin2':
  9010. case 'iso88592':
  9011. case 'isoir101':
  9012. case 'iso88592':
  9013. case 'iso885921987':
  9014. case 'l2':
  9015. case 'latin2':
  9016. return 'ISO-8859-2';
  9017. case 'cswindows31latin2':
  9018. case 'iso88592windowslatin2':
  9019. return 'ISO-8859-2-Windows-Latin-2';
  9020. case 'csisolatin3':
  9021. case 'iso88593':
  9022. case 'isoir109':
  9023. case 'iso88593':
  9024. case 'iso885931988':
  9025. case 'l3':
  9026. case 'latin3':
  9027. return 'ISO-8859-3';
  9028. case 'csisolatin4':
  9029. case 'iso88594':
  9030. case 'isoir110':
  9031. case 'iso88594':
  9032. case 'iso885941988':
  9033. case 'l4':
  9034. case 'latin4':
  9035. return 'ISO-8859-4';
  9036. case 'csisolatincyrillic':
  9037. case 'cyrillic':
  9038. case 'iso88595':
  9039. case 'isoir144':
  9040. case 'iso88595':
  9041. case 'iso885951988':
  9042. return 'ISO-8859-5';
  9043. case 'arabic':
  9044. case 'asmo708':
  9045. case 'csisolatinarabic':
  9046. case 'ecma114':
  9047. case 'iso88596':
  9048. case 'isoir127':
  9049. case 'iso88596':
  9050. case 'iso885961987':
  9051. return 'ISO-8859-6';
  9052. case 'csiso88596e':
  9053. case 'iso88596e':
  9054. case 'iso88596e':
  9055. return 'ISO-8859-6-E';
  9056. case 'csiso88596i':
  9057. case 'iso88596i':
  9058. case 'iso88596i':
  9059. return 'ISO-8859-6-I';
  9060. case 'csisolatingreek':
  9061. case 'ecma118':
  9062. case 'elot928':
  9063. case 'greek':
  9064. case 'greek8':
  9065. case 'iso88597':
  9066. case 'isoir126':
  9067. case 'iso88597':
  9068. case 'iso885971987':
  9069. return 'ISO-8859-7';
  9070. case 'csisolatinhebrew':
  9071. case 'hebrew':
  9072. case 'iso88598':
  9073. case 'isoir138':
  9074. case 'iso88598':
  9075. case 'iso885981988':
  9076. return 'ISO-8859-8';
  9077. case 'csiso88598e':
  9078. case 'iso88598e':
  9079. case 'iso88598e':
  9080. return 'ISO-8859-8-E';
  9081. case 'csiso88598i':
  9082. case 'iso88598i':
  9083. case 'iso88598i':
  9084. return 'ISO-8859-8-I';
  9085. case 'cswindows31latin5':
  9086. case 'iso88599windowslatin5':
  9087. return 'ISO-8859-9-Windows-Latin-5';
  9088. case 'csisolatin6':
  9089. case 'iso885910':
  9090. case 'isoir157':
  9091. case 'iso8859101992':
  9092. case 'l6':
  9093. case 'latin6':
  9094. return 'ISO-8859-10';
  9095. case 'iso885913':
  9096. return 'ISO-8859-13';
  9097. case 'iso885914':
  9098. case 'isoceltic':
  9099. case 'isoir199':
  9100. case 'iso885914':
  9101. case 'iso8859141998':
  9102. case 'l8':
  9103. case 'latin8':
  9104. return 'ISO-8859-14';
  9105. case 'iso885915':
  9106. case 'iso885915':
  9107. case 'latin9':
  9108. return 'ISO-8859-15';
  9109. case 'iso885916':
  9110. case 'isoir226':
  9111. case 'iso885916':
  9112. case 'iso8859162001':
  9113. case 'l10':
  9114. case 'latin10':
  9115. return 'ISO-8859-16';
  9116. case 'iso10646j1':
  9117. return 'ISO-10646-J-1';
  9118. case 'csunicode':
  9119. case 'iso10646ucs2':
  9120. return 'ISO-10646-UCS-2';
  9121. case 'csucs4':
  9122. case 'iso10646ucs4':
  9123. return 'ISO-10646-UCS-4';
  9124. case 'csunicodeascii':
  9125. case 'iso10646ucsbasic':
  9126. return 'ISO-10646-UCS-Basic';
  9127. case 'csunicodelatin1':
  9128. case 'iso10646':
  9129. case 'iso10646unicodelatin1':
  9130. return 'ISO-10646-Unicode-Latin1';
  9131. case 'csiso10646utf1':
  9132. case 'iso10646utf1':
  9133. return 'ISO-10646-UTF-1';
  9134. case 'csiso115481':
  9135. case 'iso115481':
  9136. case 'iso115481':
  9137. case 'isotr115481':
  9138. return 'ISO-11548-1';
  9139. case 'csiso90':
  9140. case 'isoir90':
  9141. return 'iso-ir-90';
  9142. case 'csunicodeibm1261':
  9143. case 'isounicodeibm1261':
  9144. return 'ISO-Unicode-IBM-1261';
  9145. case 'csunicodeibm1264':
  9146. case 'isounicodeibm1264':
  9147. return 'ISO-Unicode-IBM-1264';
  9148. case 'csunicodeibm1265':
  9149. case 'isounicodeibm1265':
  9150. return 'ISO-Unicode-IBM-1265';
  9151. case 'csunicodeibm1268':
  9152. case 'isounicodeibm1268':
  9153. return 'ISO-Unicode-IBM-1268';
  9154. case 'csunicodeibm1276':
  9155. case 'isounicodeibm1276':
  9156. return 'ISO-Unicode-IBM-1276';
  9157. case 'csiso646basic1983':
  9158. case 'iso646basic1983':
  9159. case 'ref':
  9160. return 'ISO_646.basic:1983';
  9161. case 'csiso2intlrefversion':
  9162. case 'irv':
  9163. case 'isoir2':
  9164. case 'iso646irv1983':
  9165. return 'ISO_646.irv:1983';
  9166. case 'csiso2033':
  9167. case 'e13b':
  9168. case 'isoir98':
  9169. case 'iso20331983':
  9170. return 'ISO_2033-1983';
  9171. case 'csiso5427cyrillic':
  9172. case 'isoir37':
  9173. case 'iso5427':
  9174. return 'ISO_5427';
  9175. case 'isoir54':
  9176. case 'iso5427cyrillic1981':
  9177. case 'iso54271981':
  9178. return 'ISO_5427:1981';
  9179. case 'csiso5428greek':
  9180. case 'isoir55':
  9181. case 'iso54281980':
  9182. return 'ISO_5428:1980';
  9183. case 'csiso6937add':
  9184. case 'isoir152':
  9185. case 'iso6937225':
  9186. return 'ISO_6937-2-25';
  9187. case 'csisotextcomm':
  9188. case 'isoir142':
  9189. case 'iso69372add':
  9190. return 'ISO_6937-2-add';
  9191. case 'csiso8859supp':
  9192. case 'isoir154':
  9193. case 'iso8859supp':
  9194. case 'latin125':
  9195. return 'ISO_8859-supp';
  9196. case 'csiso10367box':
  9197. case 'isoir155':
  9198. case 'iso10367box':
  9199. return 'ISO_10367-box';
  9200. case 'csiso15italian':
  9201. case 'isoir15':
  9202. case 'iso646it':
  9203. case 'it':
  9204. return 'IT';
  9205. case 'csiso13jisc6220jp':
  9206. case 'isoir13':
  9207. case 'jisc62201969':
  9208. case 'jisc62201969jp':
  9209. case 'katakana':
  9210. case 'x02017':
  9211. return 'JIS_C6220-1969-jp';
  9212. case 'csiso14jisc6220ro':
  9213. case 'isoir14':
  9214. case 'iso646jp':
  9215. case 'jisc62201969ro':
  9216. case 'jp':
  9217. return 'JIS_C6220-1969-ro';
  9218. case 'csiso42jisc62261978':
  9219. case 'isoir42':
  9220. case 'jisc62261978':
  9221. return 'JIS_C6226-1978';
  9222. case 'csiso87jisx0208':
  9223. case 'isoir87':
  9224. case 'jisc62261983':
  9225. case 'jisx02081983':
  9226. case 'x0208':
  9227. return 'JIS_C6226-1983';
  9228. case 'csiso91jisc62291984a':
  9229. case 'isoir91':
  9230. case 'jisc62291984a':
  9231. case 'jpocra':
  9232. return 'JIS_C6229-1984-a';
  9233. case 'csiso92jisc62991984b':
  9234. case 'isoir92':
  9235. case 'iso646jpocrb':
  9236. case 'jisc62291984b':
  9237. case 'jpocrb':
  9238. return 'JIS_C6229-1984-b';
  9239. case 'csiso93jis62291984badd':
  9240. case 'isoir93':
  9241. case 'jisc62291984badd':
  9242. case 'jpocrbadd':
  9243. return 'JIS_C6229-1984-b-add';
  9244. case 'csiso94jis62291984hand':
  9245. case 'isoir94':
  9246. case 'jisc62291984hand':
  9247. case 'jpocrhand':
  9248. return 'JIS_C6229-1984-hand';
  9249. case 'csiso95jis62291984handadd':
  9250. case 'isoir95':
  9251. case 'jisc62291984handadd':
  9252. case 'jpocrhandadd':
  9253. return 'JIS_C6229-1984-hand-add';
  9254. case 'csiso96jisc62291984kana':
  9255. case 'isoir96':
  9256. case 'jisc62291984kana':
  9257. return 'JIS_C6229-1984-kana';
  9258. case 'csjisencoding':
  9259. case 'jisencoding':
  9260. return 'JIS_Encoding';
  9261. case 'cshalfwidthkatakana':
  9262. case 'jisx0201':
  9263. case 'x0201':
  9264. return 'JIS_X0201';
  9265. case 'csiso159jisx02121990':
  9266. case 'isoir159':
  9267. case 'jisx02121990':
  9268. case 'x0212':
  9269. return 'JIS_X0212-1990';
  9270. case 'csiso141jusib1002':
  9271. case 'isoir141':
  9272. case 'iso646yu':
  9273. case 'js':
  9274. case 'jusib1002':
  9275. case 'yu':
  9276. return 'JUS_I.B1.002';
  9277. case 'csiso147macedonian':
  9278. case 'isoir147':
  9279. case 'jusib1003mac':
  9280. case 'macedonian':
  9281. return 'JUS_I.B1.003-mac';
  9282. case 'csiso146serbian':
  9283. case 'isoir146':
  9284. case 'jusib1003serb':
  9285. case 'serbian':
  9286. return 'JUS_I.B1.003-serb';
  9287. case 'koi7switched':
  9288. return 'KOI7-switched';
  9289. case 'cskoi8r':
  9290. case 'koi8r':
  9291. return 'KOI8-R';
  9292. case 'koi8u':
  9293. return 'KOI8-U';
  9294. case 'csksc5636':
  9295. case 'iso646kr':
  9296. case 'ksc5636':
  9297. return 'KSC5636';
  9298. case 'cskz1048':
  9299. case 'kz1048':
  9300. case 'rk1048':
  9301. case 'strk10482002':
  9302. return 'KZ-1048';
  9303. case 'csiso19latingreek':
  9304. case 'isoir19':
  9305. case 'latingreek':
  9306. return 'latin-greek';
  9307. case 'csiso27latingreek1':
  9308. case 'isoir27':
  9309. case 'latingreek1':
  9310. return 'Latin-greek-1';
  9311. case 'csiso158lap':
  9312. case 'isoir158':
  9313. case 'lap':
  9314. case 'latinlap':
  9315. return 'latin-lap';
  9316. case 'csmacintosh':
  9317. case 'mac':
  9318. case 'macintosh':
  9319. return 'macintosh';
  9320. case 'csmicrosoftpublishing':
  9321. case 'microsoftpublishing':
  9322. return 'Microsoft-Publishing';
  9323. case 'csmnem':
  9324. case 'mnem':
  9325. return 'MNEM';
  9326. case 'csmnemonic':
  9327. case 'mnemonic':
  9328. return 'MNEMONIC';
  9329. case 'csiso86hungarian':
  9330. case 'hu':
  9331. case 'isoir86':
  9332. case 'iso646hu':
  9333. case 'msz77953':
  9334. return 'MSZ_7795.3';
  9335. case 'csnatsdano':
  9336. case 'isoir91':
  9337. case 'natsdano':
  9338. return 'NATS-DANO';
  9339. case 'csnatsdanoadd':
  9340. case 'isoir92':
  9341. case 'natsdanoadd':
  9342. return 'NATS-DANO-ADD';
  9343. case 'csnatssefi':
  9344. case 'isoir81':
  9345. case 'natssefi':
  9346. return 'NATS-SEFI';
  9347. case 'csnatssefiadd':
  9348. case 'isoir82':
  9349. case 'natssefiadd':
  9350. return 'NATS-SEFI-ADD';
  9351. case 'csiso151cuba':
  9352. case 'cuba':
  9353. case 'isoir151':
  9354. case 'iso646cu':
  9355. case 'ncnc001081':
  9356. return 'NC_NC00-10:81';
  9357. case 'csiso69french':
  9358. case 'fr':
  9359. case 'isoir69':
  9360. case 'iso646fr':
  9361. case 'nfz62010':
  9362. return 'NF_Z_62-010';
  9363. case 'csiso25french':
  9364. case 'isoir25':
  9365. case 'iso646fr1':
  9366. case 'nfz620101973':
  9367. return 'NF_Z_62-010_(1973)';
  9368. case 'csiso60danishnorwegian':
  9369. case 'csiso60norwegian1':
  9370. case 'isoir60':
  9371. case 'iso646no':
  9372. case 'no':
  9373. case 'ns45511':
  9374. return 'NS_4551-1';
  9375. case 'csiso61norwegian2':
  9376. case 'isoir61':
  9377. case 'iso646no2':
  9378. case 'no2':
  9379. case 'ns45512':
  9380. return 'NS_4551-2';
  9381. case 'osdebcdicdf03irv':
  9382. return 'OSD_EBCDIC_DF03_IRV';
  9383. case 'osdebcdicdf041':
  9384. return 'OSD_EBCDIC_DF04_1';
  9385. case 'osdebcdicdf0415':
  9386. return 'OSD_EBCDIC_DF04_15';
  9387. case 'cspc8danishnorwegian':
  9388. case 'pc8danishnorwegian':
  9389. return 'PC8-Danish-Norwegian';
  9390. case 'cspc8turkish':
  9391. case 'pc8turkish':
  9392. return 'PC8-Turkish';
  9393. case 'csiso16portuguese':
  9394. case 'isoir16':
  9395. case 'iso646pt':
  9396. case 'pt':
  9397. return 'PT';
  9398. case 'csiso84portuguese2':
  9399. case 'isoir84':
  9400. case 'iso646pt2':
  9401. case 'pt2':
  9402. return 'PT2';
  9403. case 'cp154':
  9404. case 'csptcp154':
  9405. case 'cyrillicasian':
  9406. case 'pt154':
  9407. case 'ptcp154':
  9408. return 'PTCP154';
  9409. case 'scsu':
  9410. return 'SCSU';
  9411. case 'csiso10swedish':
  9412. case 'fi':
  9413. case 'isoir10':
  9414. case 'iso646fi':
  9415. case 'iso646se':
  9416. case 'se':
  9417. case 'sen850200b':
  9418. return 'SEN_850200_B';
  9419. case 'csiso11swedishfornames':
  9420. case 'isoir11':
  9421. case 'iso646se2':
  9422. case 'se2':
  9423. case 'sen850200c':
  9424. return 'SEN_850200_C';
  9425. case 'csshiftjis':
  9426. case 'mskanji':
  9427. case 'shiftjis':
  9428. return 'Shift_JIS';
  9429. case 'csiso102t617bit':
  9430. case 'isoir102':
  9431. case 't617bit':
  9432. return 'T.61-7bit';
  9433. case 'csiso103t618bit':
  9434. case 'isoir103':
  9435. case 't61':
  9436. case 't618bit':
  9437. return 'T.61-8bit';
  9438. case 'csiso128t101g2':
  9439. case 'isoir128':
  9440. case 't101g2':
  9441. return 'T.101-G2';
  9442. case 'cstscii':
  9443. case 'tscii':
  9444. return 'TSCII';
  9445. case 'csunicode11':
  9446. case 'unicode11':
  9447. return 'UNICODE-1-1';
  9448. case 'csunicode11utf7':
  9449. case 'unicode11utf7':
  9450. return 'UNICODE-1-1-UTF-7';
  9451. case 'csunknown8bit':
  9452. case 'unknown8bit':
  9453. return 'UNKNOWN-8BIT';
  9454. case 'ansix341968':
  9455. case 'ansix341986':
  9456. case 'ascii':
  9457. case 'cp367':
  9458. case 'csascii':
  9459. case 'ibm367':
  9460. case 'isoir6':
  9461. case 'iso646us':
  9462. case 'iso646irv1991':
  9463. case 'us':
  9464. case 'usascii':
  9465. return 'US-ASCII';
  9466. case 'csusdk':
  9467. case 'usdk':
  9468. return 'us-dk';
  9469. case 'utf7':
  9470. return 'UTF-7';
  9471. case 'utf8':
  9472. return 'UTF-8';
  9473. case 'utf16':
  9474. return 'UTF-16';
  9475. case 'utf16be':
  9476. return 'UTF-16BE';
  9477. case 'utf16le':
  9478. return 'UTF-16LE';
  9479. case 'utf32':
  9480. return 'UTF-32';
  9481. case 'utf32be':
  9482. return 'UTF-32BE';
  9483. case 'utf32le':
  9484. return 'UTF-32LE';
  9485. case 'csventurainternational':
  9486. case 'venturainternational':
  9487. return 'Ventura-International';
  9488. case 'csventuramath':
  9489. case 'venturamath':
  9490. return 'Ventura-Math';
  9491. case 'csventuraus':
  9492. case 'venturaus':
  9493. return 'Ventura-US';
  9494. case 'csiso70videotexsupp1':
  9495. case 'isoir70':
  9496. case 'videotexsuppl':
  9497. return 'videotex-suppl';
  9498. case 'csviqr':
  9499. case 'viqr':
  9500. return 'VIQR';
  9501. case 'csviscii':
  9502. case 'viscii':
  9503. return 'VISCII';
  9504. case 'cswindows31j':
  9505. case 'windows31j':
  9506. return 'Windows-31J';
  9507. case 'iso885911':
  9508. case 'tis620':
  9509. return 'Windows-874';
  9510. case 'cseuckr':
  9511. case 'euckr':
  9512. case 'windows949':
  9513. case 'csksc56011987':
  9514. case 'isoir149':
  9515. case 'korean':
  9516. case 'ksc5601':
  9517. case 'ksc56011987':
  9518. case 'ksc56011989':
  9519. return 'Windows-949';
  9520. case 'windows1250':
  9521. return 'windows-1250';
  9522. case 'windows1251':
  9523. return 'windows-1251';
  9524. case 'cp819':
  9525. case 'csisolatin1':
  9526. case 'ibm819':
  9527. case 'iso88591':
  9528. case 'isoir100':
  9529. case 'iso885911987':
  9530. case 'l1':
  9531. case 'latin1':
  9532. case 'windows1252':
  9533. return 'Windows-1252';
  9534. case 'windows1252':
  9535. return 'windows-1252';
  9536. case 'windows1253':
  9537. return 'windows-1253';
  9538. case 'csisolatin5':
  9539. case 'iso88599':
  9540. case 'isoir148':
  9541. case 'iso885991989':
  9542. case 'l5':
  9543. case 'latin5':
  9544. case 'windows1254':
  9545. return 'Windows-1254';
  9546. case 'windows1254':
  9547. return 'windows-1254';
  9548. case 'windows1255':
  9549. return 'windows-1255';
  9550. case 'windows1256':
  9551. return 'windows-1256';
  9552. case 'windows1257':
  9553. return 'windows-1257';
  9554. case 'windows1258':
  9555. return 'windows-1258';
  9556. default:
  9557. return $charset;
  9558. }
  9559. }
  9560. function get_curl_version()
  9561. {
  9562. if (is_array($curl = curl_version()))
  9563. {
  9564. $curl = $curl['version'];
  9565. }
  9566. elseif (substr($curl, 0, 5) == 'curl/')
  9567. {
  9568. $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
  9569. }
  9570. elseif (substr($curl, 0, 8) == 'libcurl/')
  9571. {
  9572. $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
  9573. }
  9574. else
  9575. {
  9576. $curl = 0;
  9577. }
  9578. return $curl;
  9579. }
  9580. function is_subclass_of($class1, $class2)
  9581. {
  9582. if (func_num_args() != 2)
  9583. {
  9584. trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
  9585. }
  9586. elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
  9587. {
  9588. return is_subclass_of($class1, $class2);
  9589. }
  9590. elseif (is_string($class1) && is_string($class2))
  9591. {
  9592. if (class_exists($class1))
  9593. {
  9594. if (class_exists($class2))
  9595. {
  9596. $class2 = strtolower($class2);
  9597. while ($class1 = strtolower(get_parent_class($class1)))
  9598. {
  9599. if ($class1 == $class2)
  9600. {
  9601. return true;
  9602. }
  9603. }
  9604. }
  9605. }
  9606. else
  9607. {
  9608. trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
  9609. }
  9610. }
  9611. return false;
  9612. }
  9613. /**
  9614. * Strip HTML comments
  9615. *
  9616. * @access public
  9617. * @param string $data Data to strip comments from
  9618. * @return string Comment stripped string
  9619. */
  9620. function strip_comments($data)
  9621. {
  9622. $output = '';
  9623. while (($start = strpos($data, '<!--')) !== false)
  9624. {
  9625. $output .= substr($data, 0, $start);
  9626. if (($end = strpos($data, '-->', $start)) !== false)
  9627. {
  9628. $data = substr_replace($data, '', 0, $end + 3);
  9629. }
  9630. else
  9631. {
  9632. $data = '';
  9633. }
  9634. }
  9635. return $output . $data;
  9636. }
  9637. function parse_date($dt)
  9638. {
  9639. $parser = SimplePie_Parse_Date::get();
  9640. return $parser->parse($dt);
  9641. }
  9642. /**
  9643. * Decode HTML entities
  9644. *
  9645. * @static
  9646. * @access public
  9647. * @param string $data Input data
  9648. * @return string Output data
  9649. */
  9650. function entities_decode($data)
  9651. {
  9652. $decoder = new SimplePie_Decode_HTML_Entities($data);
  9653. return $decoder->parse();
  9654. }
  9655. /**
  9656. * Remove RFC822 comments
  9657. *
  9658. * @access public
  9659. * @param string $data Data to strip comments from
  9660. * @return string Comment stripped string
  9661. */
  9662. function uncomment_rfc822($string)
  9663. {
  9664. $string = (string) $string;
  9665. $position = 0;
  9666. $length = strlen($string);
  9667. $depth = 0;
  9668. $output = '';
  9669. while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
  9670. {
  9671. $output .= substr($string, $position, $pos - $position);
  9672. $position = $pos + 1;
  9673. if ($string[$pos - 1] !== '\\')
  9674. {
  9675. $depth++;
  9676. while ($depth && $position < $length)
  9677. {
  9678. $position += strcspn($string, '()', $position);
  9679. if ($string[$position - 1] === '\\')
  9680. {
  9681. $position++;
  9682. continue;
  9683. }
  9684. elseif (isset($string[$position]))
  9685. {
  9686. switch ($string[$position])
  9687. {
  9688. case '(':
  9689. $depth++;
  9690. break;
  9691. case ')':
  9692. $depth--;
  9693. break;
  9694. }
  9695. $position++;
  9696. }
  9697. else
  9698. {
  9699. break;
  9700. }
  9701. }
  9702. }
  9703. else
  9704. {
  9705. $output .= '(';
  9706. }
  9707. }
  9708. $output .= substr($string, $position);
  9709. return $output;
  9710. }
  9711. function parse_mime($mime)
  9712. {
  9713. if (($pos = strpos($mime, ';')) === false)
  9714. {
  9715. return trim($mime);
  9716. }
  9717. else
  9718. {
  9719. return trim(substr($mime, 0, $pos));
  9720. }
  9721. }
  9722. function htmlspecialchars_decode($string, $quote_style)
  9723. {
  9724. if (function_exists('htmlspecialchars_decode'))
  9725. {
  9726. return htmlspecialchars_decode($string, $quote_style);
  9727. }
  9728. else
  9729. {
  9730. return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
  9731. }
  9732. }
  9733. function atom_03_construct_type($attribs)
  9734. {
  9735. if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
  9736. {
  9737. $mode = SIMPLEPIE_CONSTRUCT_BASE64;
  9738. }
  9739. else
  9740. {
  9741. $mode = SIMPLEPIE_CONSTRUCT_NONE;
  9742. }
  9743. if (isset($attribs['']['type']))
  9744. {
  9745. switch (strtolower(trim($attribs['']['type'])))
  9746. {
  9747. case 'text':
  9748. case 'text/plain':
  9749. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  9750. case 'html':
  9751. case 'text/html':
  9752. return SIMPLEPIE_CONSTRUCT_HTML | $mode;
  9753. case 'xhtml':
  9754. case 'application/xhtml+xml':
  9755. return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
  9756. default:
  9757. return SIMPLEPIE_CONSTRUCT_NONE | $mode;
  9758. }
  9759. }
  9760. else
  9761. {
  9762. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  9763. }
  9764. }
  9765. function atom_10_construct_type($attribs)
  9766. {
  9767. if (isset($attribs['']['type']))
  9768. {
  9769. switch (strtolower(trim($attribs['']['type'])))
  9770. {
  9771. case 'text':
  9772. return SIMPLEPIE_CONSTRUCT_TEXT;
  9773. case 'html':
  9774. return SIMPLEPIE_CONSTRUCT_HTML;
  9775. case 'xhtml':
  9776. return SIMPLEPIE_CONSTRUCT_XHTML;
  9777. default:
  9778. return SIMPLEPIE_CONSTRUCT_NONE;
  9779. }
  9780. }
  9781. return SIMPLEPIE_CONSTRUCT_TEXT;
  9782. }
  9783. function atom_10_content_construct_type($attribs)
  9784. {
  9785. if (isset($attribs['']['type']))
  9786. {
  9787. $type = strtolower(trim($attribs['']['type']));
  9788. switch ($type)
  9789. {
  9790. case 'text':
  9791. return SIMPLEPIE_CONSTRUCT_TEXT;
  9792. case 'html':
  9793. return SIMPLEPIE_CONSTRUCT_HTML;
  9794. case 'xhtml':
  9795. return SIMPLEPIE_CONSTRUCT_XHTML;
  9796. }
  9797. if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
  9798. {
  9799. return SIMPLEPIE_CONSTRUCT_NONE;
  9800. }
  9801. else
  9802. {
  9803. return SIMPLEPIE_CONSTRUCT_BASE64;
  9804. }
  9805. }
  9806. else
  9807. {
  9808. return SIMPLEPIE_CONSTRUCT_TEXT;
  9809. }
  9810. }
  9811. function is_isegment_nz_nc($string)
  9812. {
  9813. 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);
  9814. }
  9815. function space_seperated_tokens($string)
  9816. {
  9817. $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
  9818. $string_length = strlen($string);
  9819. $position = strspn($string, $space_characters);
  9820. $tokens = array();
  9821. while ($position < $string_length)
  9822. {
  9823. $len = strcspn($string, $space_characters, $position);
  9824. $tokens[] = substr($string, $position, $len);
  9825. $position += $len;
  9826. $position += strspn($string, $space_characters, $position);
  9827. }
  9828. return $tokens;
  9829. }
  9830. function array_unique($array)
  9831. {
  9832. if (version_compare(PHP_VERSION, '5.2', '>='))
  9833. {
  9834. return array_unique($array);
  9835. }
  9836. else
  9837. {
  9838. $array = (array) $array;
  9839. $new_array = array();
  9840. $new_array_strings = array();
  9841. foreach ($array as $key => $value)
  9842. {
  9843. if (is_object($value))
  9844. {
  9845. if (method_exists($value, '__toString'))
  9846. {
  9847. $cmp = $value->__toString();
  9848. }
  9849. else
  9850. {
  9851. trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
  9852. }
  9853. }
  9854. elseif (is_array($value))
  9855. {
  9856. $cmp = (string) reset($value);
  9857. }
  9858. else
  9859. {
  9860. $cmp = (string) $value;
  9861. }
  9862. if (!in_array($cmp, $new_array_strings))
  9863. {
  9864. $new_array[$key] = $value;
  9865. $new_array_strings[] = $cmp;
  9866. }
  9867. }
  9868. return $new_array;
  9869. }
  9870. }
  9871. /**
  9872. * Converts a unicode codepoint to a UTF-8 character
  9873. *
  9874. * @static
  9875. * @access public
  9876. * @param int $codepoint Unicode codepoint
  9877. * @return string UTF-8 character
  9878. */
  9879. function codepoint_to_utf8($codepoint)
  9880. {
  9881. static $cache = array();
  9882. $codepoint = (int) $codepoint;
  9883. if (isset($cache[$codepoint]))
  9884. {
  9885. return $cache[$codepoint];
  9886. }
  9887. elseif ($codepoint < 0)
  9888. {
  9889. return $cache[$codepoint] = false;
  9890. }
  9891. else if ($codepoint <= 0x7f)
  9892. {
  9893. return $cache[$codepoint] = chr($codepoint);
  9894. }
  9895. else if ($codepoint <= 0x7ff)
  9896. {
  9897. return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
  9898. }
  9899. else if ($codepoint <= 0xffff)
  9900. {
  9901. return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  9902. }
  9903. else if ($codepoint <= 0x10ffff)
  9904. {
  9905. return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  9906. }
  9907. else
  9908. {
  9909. // U+FFFD REPLACEMENT CHARACTER
  9910. return $cache[$codepoint] = "\xEF\xBF\xBD";
  9911. }
  9912. }
  9913. /**
  9914. * Re-implementation of PHP 5's stripos()
  9915. *
  9916. * Returns the numeric position of the first occurrence of needle in the
  9917. * haystack string.
  9918. *
  9919. * @static
  9920. * @access string
  9921. * @param object $haystack
  9922. * @param string $needle Note that the needle may be a string of one or more
  9923. * characters. If needle is not a string, it is converted to an integer
  9924. * and applied as the ordinal value of a character.
  9925. * @param int $offset The optional offset parameter allows you to specify which
  9926. * character in haystack to start searching. The position returned is still
  9927. * relative to the beginning of haystack.
  9928. * @return bool If needle is not found, stripos() will return boolean false.
  9929. */
  9930. function stripos($haystack, $needle, $offset = 0)
  9931. {
  9932. if (function_exists('stripos'))
  9933. {
  9934. return stripos($haystack, $needle, $offset);
  9935. }
  9936. else
  9937. {
  9938. if (is_string($needle))
  9939. {
  9940. $needle = strtolower($needle);
  9941. }
  9942. elseif (is_int($needle) || is_bool($needle) || is_double($needle))
  9943. {
  9944. $needle = strtolower(chr($needle));
  9945. }
  9946. else
  9947. {
  9948. trigger_error('needle is not a string or an integer', E_USER_WARNING);
  9949. return false;
  9950. }
  9951. return strpos(strtolower($haystack), $needle, $offset);
  9952. }
  9953. }
  9954. /**
  9955. * Similar to parse_str()
  9956. *
  9957. * Returns an associative array of name/value pairs, where the value is an
  9958. * array of values that have used the same name
  9959. *
  9960. * @static
  9961. * @access string
  9962. * @param string $str The input string.
  9963. * @return array
  9964. */
  9965. function parse_str($str)
  9966. {
  9967. $return = array();
  9968. $str = explode('&', $str);
  9969. foreach ($str as $section)
  9970. {
  9971. if (strpos($section, '=') !== false)
  9972. {
  9973. list($name, $value) = explode('=', $section, 2);
  9974. $return[urldecode($name)][] = urldecode($value);
  9975. }
  9976. else
  9977. {
  9978. $return[urldecode($section)][] = null;
  9979. }
  9980. }
  9981. return $return;
  9982. }
  9983. /**
  9984. * Detect XML encoding, as per XML 1.0 Appendix F.1
  9985. *
  9986. * @todo Add support for EBCDIC
  9987. * @param string $data XML data
  9988. * @return array Possible encodings
  9989. */
  9990. function xml_encoding($data)
  9991. {
  9992. // UTF-32 Big Endian BOM
  9993. if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
  9994. {
  9995. $encoding[] = 'UTF-32BE';
  9996. }
  9997. // UTF-32 Little Endian BOM
  9998. elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
  9999. {
  10000. $encoding[] = 'UTF-32LE';
  10001. }
  10002. // UTF-16 Big Endian BOM
  10003. elseif (substr($data, 0, 2) === "\xFE\xFF")
  10004. {
  10005. $encoding[] = 'UTF-16BE';
  10006. }
  10007. // UTF-16 Little Endian BOM
  10008. elseif (substr($data, 0, 2) === "\xFF\xFE")
  10009. {
  10010. $encoding[] = 'UTF-16LE';
  10011. }
  10012. // UTF-8 BOM
  10013. elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
  10014. {
  10015. $encoding[] = 'UTF-8';
  10016. }
  10017. // UTF-32 Big Endian Without BOM
  10018. 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")
  10019. {
  10020. if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
  10021. {
  10022. $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
  10023. if ($parser->parse())
  10024. {
  10025. $encoding[] = $parser->encoding;
  10026. }
  10027. }
  10028. $encoding[] = 'UTF-32BE';
  10029. }
  10030. // UTF-32 Little Endian Without BOM
  10031. 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")
  10032. {
  10033. if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
  10034. {
  10035. $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
  10036. if ($parser->parse())
  10037. {
  10038. $encoding[] = $parser->encoding;
  10039. }
  10040. }
  10041. $encoding[] = 'UTF-32LE';
  10042. }
  10043. // UTF-16 Big Endian Without BOM
  10044. elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
  10045. {
  10046. if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
  10047. {
  10048. $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
  10049. if ($parser->parse())
  10050. {
  10051. $encoding[] = $parser->encoding;
  10052. }
  10053. }
  10054. $encoding[] = 'UTF-16BE';
  10055. }
  10056. // UTF-16 Little Endian Without BOM
  10057. elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
  10058. {
  10059. if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
  10060. {
  10061. $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
  10062. if ($parser->parse())
  10063. {
  10064. $encoding[] = $parser->encoding;
  10065. }
  10066. }
  10067. $encoding[] = 'UTF-16LE';
  10068. }
  10069. // US-ASCII (or superset)
  10070. elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
  10071. {
  10072. if ($pos = strpos($data, "\x3F\x3E"))
  10073. {
  10074. $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
  10075. if ($parser->parse())
  10076. {
  10077. $encoding[] = $parser->encoding;
  10078. }
  10079. }
  10080. $encoding[] = 'UTF-8';
  10081. }
  10082. // Fallback to UTF-8
  10083. else
  10084. {
  10085. $encoding[] = 'UTF-8';
  10086. }
  10087. return $encoding;
  10088. }
  10089. }
  10090. /**
  10091. * Decode HTML Entities
  10092. *
  10093. * This implements HTML5 as of revision 967 (2007-06-28)
  10094. *
  10095. * @package SimplePie
  10096. */
  10097. class SimplePie_Decode_HTML_Entities
  10098. {
  10099. /**
  10100. * Data to be parsed
  10101. *
  10102. * @access private
  10103. * @var string
  10104. */
  10105. var $data = '';
  10106. /**
  10107. * Currently consumed bytes
  10108. *
  10109. * @access private
  10110. * @var string
  10111. */
  10112. var $consumed = '';
  10113. /**
  10114. * Position of the current byte being parsed
  10115. *
  10116. * @access private
  10117. * @var int
  10118. */
  10119. var $position = 0;
  10120. /**
  10121. * Create an instance of the class with the input data
  10122. *
  10123. * @access public
  10124. * @param string $data Input data
  10125. */
  10126. function SimplePie_Decode_HTML_Entities($data)
  10127. {
  10128. $this->data = $data;
  10129. }
  10130. /**
  10131. * Parse the input data
  10132. *
  10133. * @access public
  10134. * @return string Output data
  10135. */
  10136. function parse()
  10137. {
  10138. while (($this->position = strpos($this->data, '&', $this->position)) !== false)
  10139. {
  10140. $this->consume();
  10141. $this->entity();
  10142. $this->consumed = '';
  10143. }
  10144. return $this->data;
  10145. }
  10146. /**
  10147. * Consume the next byte
  10148. *
  10149. * @access private
  10150. * @return mixed The next byte, or false, if there is no more data
  10151. */
  10152. function consume()
  10153. {
  10154. if (isset($this->data[$this->position]))
  10155. {
  10156. $this->consumed .= $this->data[$this->position];
  10157. return $this->data[$this->position++];
  10158. }
  10159. else
  10160. {
  10161. $this->consumed = false;
  10162. return false;
  10163. }
  10164. }
  10165. /**
  10166. * Consume a range of characters
  10167. *
  10168. * @access private
  10169. * @param string $chars Characters to consume
  10170. * @return mixed A series of characters that match the range, or false
  10171. */
  10172. function consume_range($chars)
  10173. {
  10174. if ($len = strspn($this->data, $chars, $this->position))
  10175. {
  10176. $data = substr($this->data, $this->position, $len);
  10177. $this->consumed .= $data;
  10178. $this->position += $len;
  10179. return $data;
  10180. }
  10181. else
  10182. {
  10183. $this->consumed = false;
  10184. return false;
  10185. }
  10186. }
  10187. /**
  10188. * Unconsume one byte
  10189. *
  10190. * @access private
  10191. */
  10192. function unconsume()
  10193. {
  10194. $this->consumed = substr($this->consumed, 0, -1);
  10195. $this->position--;
  10196. }
  10197. /**
  10198. * Decode an entity
  10199. *
  10200. * @access private
  10201. */
  10202. function entity()
  10203. {
  10204. switch ($this->consume())
  10205. {
  10206. case "\x09":
  10207. case "\x0A":
  10208. case "\x0B":
  10209. case "\x0B":
  10210. case "\x0C":
  10211. case "\x20":
  10212. case "\x3C":
  10213. case "\x26":
  10214. case false:
  10215. break;
  10216. case "\x23":
  10217. switch ($this->consume())
  10218. {
  10219. case "\x78":
  10220. case "\x58":
  10221. $range = '0123456789ABCDEFabcdef';
  10222. $hex = true;
  10223. break;
  10224. default:
  10225. $range = '0123456789';
  10226. $hex = false;
  10227. $this->unconsume();
  10228. break;
  10229. }
  10230. if ($codepoint = $this->consume_range($range))
  10231. {
  10232. 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");
  10233. if ($hex)
  10234. {
  10235. $codepoint = hexdec($codepoint);
  10236. }
  10237. else
  10238. {
  10239. $codepoint = intval($codepoint);
  10240. }
  10241. if (isset($windows_1252_specials[$codepoint]))
  10242. {
  10243. $replacement = $windows_1252_specials[$codepoint];
  10244. }
  10245. else
  10246. {
  10247. $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
  10248. }
  10249. if ($this->consume() != ';')
  10250. {
  10251. $this->unconsume();
  10252. }
  10253. $consumed_length = strlen($this->consumed);
  10254. $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
  10255. $this->position += strlen($replacement) - $consumed_length;
  10256. }
  10257. break;
  10258. default:
  10259. static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C");
  10260. for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
  10261. {
  10262. $consumed = substr($this->consumed, 1);
  10263. if (isset($entities[$consumed]))
  10264. {
  10265. $match = $consumed;
  10266. }
  10267. }
  10268. if ($match !== null)
  10269. {
  10270. $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
  10271. $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
  10272. }
  10273. break;
  10274. }
  10275. }
  10276. }
  10277. /**
  10278. * Date Parser
  10279. *
  10280. * @package SimplePie
  10281. */
  10282. class SimplePie_Parse_Date
  10283. {
  10284. /**
  10285. * Input data
  10286. *
  10287. * @access protected
  10288. * @var string
  10289. */
  10290. var $date;
  10291. /**
  10292. * List of days, calendar day name => ordinal day number in the week
  10293. *
  10294. * @access protected
  10295. * @var array
  10296. */
  10297. var $day = array(
  10298. // English
  10299. 'mon' => 1,
  10300. 'monday' => 1,
  10301. 'tue' => 2,
  10302. 'tuesday' => 2,
  10303. 'wed' => 3,
  10304. 'wednesday' => 3,
  10305. 'thu' => 4,
  10306. 'thursday' => 4,
  10307. 'fri' => 5,
  10308. 'friday' => 5,
  10309. 'sat' => 6,
  10310. 'saturday' => 6,
  10311. 'sun' => 7,
  10312. 'sunday' => 7,
  10313. // Dutch
  10314. 'maandag' => 1,
  10315. 'dinsdag' => 2,
  10316. 'woensdag' => 3,
  10317. 'donderdag' => 4,
  10318. 'vrijdag' => 5,
  10319. 'zaterdag' => 6,
  10320. 'zondag' => 7,
  10321. // French
  10322. 'lundi' => 1,
  10323. 'mardi' => 2,
  10324. 'mercredi' => 3,
  10325. 'jeudi' => 4,
  10326. 'vendredi' => 5,
  10327. 'samedi' => 6,
  10328. 'dimanche' => 7,
  10329. // German
  10330. 'montag' => 1,
  10331. 'dienstag' => 2,
  10332. 'mittwoch' => 3,
  10333. 'donnerstag' => 4,
  10334. 'freitag' => 5,
  10335. 'samstag' => 6,
  10336. 'sonnabend' => 6,
  10337. 'sonntag' => 7,
  10338. // Italian
  10339. 'lunedì' => 1,
  10340. 'martedì' => 2,
  10341. 'mercoledì' => 3,
  10342. 'giovedì' => 4,
  10343. 'venerdì' => 5,
  10344. 'sabato' => 6,
  10345. 'domenica' => 7,
  10346. // Spanish
  10347. 'lunes' => 1,
  10348. 'martes' => 2,
  10349. 'miércoles' => 3,
  10350. 'jueves' => 4,
  10351. 'viernes' => 5,
  10352. 'sábado' => 6,
  10353. 'domingo' => 7,
  10354. // Finnish
  10355. 'maanantai' => 1,
  10356. 'tiistai' => 2,
  10357. 'keskiviikko' => 3,
  10358. 'torstai' => 4,
  10359. 'perjantai' => 5,
  10360. 'lauantai' => 6,
  10361. 'sunnuntai' => 7,
  10362. // Hungarian
  10363. 'hétfő' => 1,
  10364. 'kedd' => 2,
  10365. 'szerda' => 3,
  10366. 'csütörtok' => 4,
  10367. 'péntek' => 5,
  10368. 'szombat' => 6,
  10369. 'vasárnap' => 7,
  10370. // Greek
  10371. 'Δευ' => 1,
  10372. 'Τρι' => 2,
  10373. 'Τετ' => 3,
  10374. 'Πεμ' => 4,
  10375. 'Παρ' => 5,
  10376. 'Σαβ' => 6,
  10377. 'Κυρ' => 7,
  10378. );
  10379. /**
  10380. * List of months, calendar month name => calendar month number
  10381. *
  10382. * @access protected
  10383. * @var array
  10384. */
  10385. var $month = array(
  10386. // English
  10387. 'jan' => 1,
  10388. 'january' => 1,
  10389. 'feb' => 2,
  10390. 'february' => 2,
  10391. 'mar' => 3,
  10392. 'march' => 3,
  10393. 'apr' => 4,
  10394. 'april' => 4,
  10395. 'may' => 5,
  10396. // No long form of May
  10397. 'jun' => 6,
  10398. 'june' => 6,
  10399. 'jul' => 7,
  10400. 'july' => 7,
  10401. 'aug' => 8,
  10402. 'august' => 8,
  10403. 'sep' => 9,
  10404. 'september' => 8,
  10405. 'oct' => 10,
  10406. 'october' => 10,
  10407. 'nov' => 11,
  10408. 'november' => 11,
  10409. 'dec' => 12,
  10410. 'december' => 12,
  10411. // Dutch
  10412. 'januari' => 1,
  10413. 'februari' => 2,
  10414. 'maart' => 3,
  10415. 'april' => 4,
  10416. 'mei' => 5,
  10417. 'juni' => 6,
  10418. 'juli' => 7,
  10419. 'augustus' => 8,
  10420. 'september' => 9,
  10421. 'oktober' => 10,
  10422. 'november' => 11,
  10423. 'december' => 12,
  10424. // French
  10425. 'janvier' => 1,
  10426. 'février' => 2,
  10427. 'mars' => 3,
  10428. 'avril' => 4,
  10429. 'mai' => 5,
  10430. 'juin' => 6,
  10431. 'juillet' => 7,
  10432. 'août' => 8,
  10433. 'septembre' => 9,
  10434. 'octobre' => 10,
  10435. 'novembre' => 11,
  10436. 'décembre' => 12,
  10437. // German
  10438. 'januar' => 1,
  10439. 'februar' => 2,
  10440. 'märz' => 3,
  10441. 'april' => 4,
  10442. 'mai' => 5,
  10443. 'juni' => 6,
  10444. 'juli' => 7,
  10445. 'august' => 8,
  10446. 'september' => 9,
  10447. 'oktober' => 10,
  10448. 'november' => 11,
  10449. 'dezember' => 12,
  10450. // Italian
  10451. 'gennaio' => 1,
  10452. 'febbraio' => 2,
  10453. 'marzo' => 3,
  10454. 'aprile' => 4,
  10455. 'maggio' => 5,
  10456. 'giugno' => 6,
  10457. 'luglio' => 7,
  10458. 'agosto' => 8,
  10459. 'settembre' => 9,
  10460. 'ottobre' => 10,
  10461. 'novembre' => 11,
  10462. 'dicembre' => 12,
  10463. // Spanish
  10464. 'enero' => 1,
  10465. 'febrero' => 2,
  10466. 'marzo' => 3,
  10467. 'abril' => 4,
  10468. 'mayo' => 5,
  10469. 'junio' => 6,
  10470. 'julio' => 7,
  10471. 'agosto' => 8,
  10472. 'septiembre' => 9,
  10473. 'setiembre' => 9,
  10474. 'octubre' => 10,
  10475. 'noviembre' => 11,
  10476. 'diciembre' => 12,
  10477. // Finnish
  10478. 'tammikuu' => 1,
  10479. 'helmikuu' => 2,
  10480. 'maaliskuu' => 3,
  10481. 'huhtikuu' => 4,
  10482. 'toukokuu' => 5,
  10483. 'kesäkuu' => 6,
  10484. 'heinäkuu' => 7,
  10485. 'elokuu' => 8,
  10486. 'suuskuu' => 9,
  10487. 'lokakuu' => 10,
  10488. 'marras' => 11,
  10489. 'joulukuu' => 12,
  10490. // Hungarian
  10491. 'január' => 1,
  10492. 'február' => 2,
  10493. 'március' => 3,
  10494. 'április' => 4,
  10495. 'május' => 5,
  10496. 'június' => 6,
  10497. 'július' => 7,
  10498. 'augusztus' => 8,
  10499. 'szeptember' => 9,
  10500. 'október' => 10,
  10501. 'november' => 11,
  10502. 'december' => 12,
  10503. // Greek
  10504. 'Ιαν' => 1,
  10505. 'Φεβ' => 2,
  10506. 'Μάώ' => 3,
  10507. 'Μαώ' => 3,
  10508. 'Απρ' => 4,
  10509. 'Μάι' => 5,
  10510. 'Μαϊ' => 5,
  10511. 'Μαι' => 5,
  10512. 'Ιούν' => 6,
  10513. 'Ιον' => 6,
  10514. 'Ιούλ' => 7,
  10515. 'Ιολ' => 7,
  10516. 'Αύγ' => 8,
  10517. 'Αυγ' => 8,
  10518. 'Σεπ' => 9,
  10519. 'Οκτ' => 10,
  10520. 'Νοέ' => 11,
  10521. 'Δεκ' => 12,
  10522. );
  10523. /**
  10524. * List of timezones, abbreviation => offset from UTC
  10525. *
  10526. * @access protected
  10527. * @var array
  10528. */
  10529. var $timezone = array(
  10530. 'ACDT' => 37800,
  10531. 'ACIT' => 28800,
  10532. 'ACST' => 34200,
  10533. 'ACT' => -18000,
  10534. 'ACWDT' => 35100,
  10535. 'ACWST' => 31500,
  10536. 'AEDT' => 39600,
  10537. 'AEST' => 36000,
  10538. 'AFT' => 16200,
  10539. 'AKDT' => -28800,
  10540. 'AKST' => -32400,
  10541. 'AMDT' => 18000,
  10542. 'AMT' => -14400,
  10543. 'ANAST' => 46800,
  10544. 'ANAT' => 43200,
  10545. 'ART' => -10800,
  10546. 'AZOST' => -3600,
  10547. 'AZST' => 18000,
  10548. 'AZT' => 14400,
  10549. 'BIOT' => 21600,
  10550. 'BIT' => -43200,
  10551. 'BOT' => -14400,
  10552. 'BRST' => -7200,
  10553. 'BRT' => -10800,
  10554. 'BST' => 3600,
  10555. 'BTT' => 21600,
  10556. 'CAST' => 18000,
  10557. 'CAT' => 7200,
  10558. 'CCT' => 23400,
  10559. 'CDT' => -18000,
  10560. 'CEDT' => 7200,
  10561. 'CET' => 3600,
  10562. 'CGST' => -7200,
  10563. 'CGT' => -10800,
  10564. 'CHADT' => 49500,
  10565. 'CHAST' => 45900,
  10566. 'CIST' => -28800,
  10567. 'CKT' => -36000,
  10568. 'CLDT' => -10800,
  10569. 'CLST' => -14400,
  10570. 'COT' => -18000,
  10571. 'CST' => -21600,
  10572. 'CVT' => -3600,
  10573. 'CXT' => 25200,
  10574. 'DAVT' => 25200,
  10575. 'DTAT' => 36000,
  10576. 'EADT' => -18000,
  10577. 'EAST' => -21600,
  10578. 'EAT' => 10800,
  10579. 'ECT' => -18000,
  10580. 'EDT' => -14400,
  10581. 'EEST' => 10800,
  10582. 'EET' => 7200,
  10583. 'EGT' => -3600,
  10584. 'EKST' => 21600,
  10585. 'EST' => -18000,
  10586. 'FJT' => 43200,
  10587. 'FKDT' => -10800,
  10588. 'FKST' => -14400,
  10589. 'FNT' => -7200,
  10590. 'GALT' => -21600,
  10591. 'GEDT' => 14400,
  10592. 'GEST' => 10800,
  10593. 'GFT' => -10800,
  10594. 'GILT' => 43200,
  10595. 'GIT' => -32400,
  10596. 'GST' => 14400,
  10597. 'GST' => -7200,
  10598. 'GYT' => -14400,
  10599. 'HAA' => -10800,
  10600. 'HAC' => -18000,
  10601. 'HADT' => -32400,
  10602. 'HAE' => -14400,
  10603. 'HAP' => -25200,
  10604. 'HAR' => -21600,
  10605. 'HAST' => -36000,
  10606. 'HAT' => -9000,
  10607. 'HAY' => -28800,
  10608. 'HKST' => 28800,
  10609. 'HMT' => 18000,
  10610. 'HNA' => -14400,
  10611. 'HNC' => -21600,
  10612. 'HNE' => -18000,
  10613. 'HNP' => -28800,
  10614. 'HNR' => -25200,
  10615. 'HNT' => -12600,
  10616. 'HNY' => -32400,
  10617. 'IRDT' => 16200,
  10618. 'IRKST' => 32400,
  10619. 'IRKT' => 28800,
  10620. 'IRST' => 12600,
  10621. 'JFDT' => -10800,
  10622. 'JFST' => -14400,
  10623. 'JST' => 32400,
  10624. 'KGST' => 21600,
  10625. 'KGT' => 18000,
  10626. 'KOST' => 39600,
  10627. 'KOVST' => 28800,
  10628. 'KOVT' => 25200,
  10629. 'KRAST' => 28800,
  10630. 'KRAT' => 25200,
  10631. 'KST' => 32400,
  10632. 'LHDT' => 39600,
  10633. 'LHST' => 37800,
  10634. 'LINT' => 50400,
  10635. 'LKT' => 21600,
  10636. 'MAGST' => 43200,
  10637. 'MAGT' => 39600,
  10638. 'MAWT' => 21600,
  10639. 'MDT' => -21600,
  10640. 'MESZ' => 7200,
  10641. 'MEZ' => 3600,
  10642. 'MHT' => 43200,
  10643. 'MIT' => -34200,
  10644. 'MNST' => 32400,
  10645. 'MSDT' => 14400,
  10646. 'MSST' => 10800,
  10647. 'MST' => -25200,
  10648. 'MUT' => 14400,
  10649. 'MVT' => 18000,
  10650. 'MYT' => 28800,
  10651. 'NCT' => 39600,
  10652. 'NDT' => -9000,
  10653. 'NFT' => 41400,
  10654. 'NMIT' => 36000,
  10655. 'NOVST' => 25200,
  10656. 'NOVT' => 21600,
  10657. 'NPT' => 20700,
  10658. 'NRT' => 43200,
  10659. 'NST' => -12600,
  10660. 'NUT' => -39600,
  10661. 'NZDT' => 46800,
  10662. 'NZST' => 43200,
  10663. 'OMSST' => 25200,
  10664. 'OMST' => 21600,
  10665. 'PDT' => -25200,
  10666. 'PET' => -18000,
  10667. 'PETST' => 46800,
  10668. 'PETT' => 43200,
  10669. 'PGT' => 36000,
  10670. 'PHOT' => 46800,
  10671. 'PHT' => 28800,
  10672. 'PKT' => 18000,
  10673. 'PMDT' => -7200,
  10674. 'PMST' => -10800,
  10675. 'PONT' => 39600,
  10676. 'PST' => -28800,
  10677. 'PWT' => 32400,
  10678. 'PYST' => -10800,
  10679. 'PYT' => -14400,
  10680. 'RET' => 14400,
  10681. 'ROTT' => -10800,
  10682. 'SAMST' => 18000,
  10683. 'SAMT' => 14400,
  10684. 'SAST' => 7200,
  10685. 'SBT' => 39600,
  10686. 'SCDT' => 46800,
  10687. 'SCST' => 43200,
  10688. 'SCT' => 14400,
  10689. 'SEST' => 3600,
  10690. 'SGT' => 28800,
  10691. 'SIT' => 28800,
  10692. 'SRT' => -10800,
  10693. 'SST' => -39600,
  10694. 'SYST' => 10800,
  10695. 'SYT' => 7200,
  10696. 'TFT' => 18000,
  10697. 'THAT' => -36000,
  10698. 'TJT' => 18000,
  10699. 'TKT' => -36000,
  10700. 'TMT' => 18000,
  10701. 'TOT' => 46800,
  10702. 'TPT' => 32400,
  10703. 'TRUT' => 36000,
  10704. 'TVT' => 43200,
  10705. 'TWT' => 28800,
  10706. 'UYST' => -7200,
  10707. 'UYT' => -10800,
  10708. 'UZT' => 18000,
  10709. 'VET' => -14400,
  10710. 'VLAST' => 39600,
  10711. 'VLAT' => 36000,
  10712. 'VOST' => 21600,
  10713. 'VUT' => 39600,
  10714. 'WAST' => 7200,
  10715. 'WAT' => 3600,
  10716. 'WDT' => 32400,
  10717. 'WEST' => 3600,
  10718. 'WFT' => 43200,
  10719. 'WIB' => 25200,
  10720. 'WIT' => 32400,
  10721. 'WITA' => 28800,
  10722. 'WKST' => 18000,
  10723. 'WST' => 28800,
  10724. 'YAKST' => 36000,
  10725. 'YAKT' => 32400,
  10726. 'YAPT' => 36000,
  10727. 'YEKST' => 21600,
  10728. 'YEKT' => 18000,
  10729. );
  10730. /**
  10731. * Cached PCRE for SimplePie_Parse_Date::$day
  10732. *
  10733. * @access protected
  10734. * @var string
  10735. */
  10736. var $day_pcre;
  10737. /**
  10738. * Cached PCRE for SimplePie_Parse_Date::$month
  10739. *
  10740. * @access protected
  10741. * @var string
  10742. */
  10743. var $month_pcre;
  10744. /**
  10745. * Array of user-added callback methods
  10746. *
  10747. * @access private
  10748. * @var array
  10749. */
  10750. var $built_in = array();
  10751. /**
  10752. * Array of user-added callback methods
  10753. *
  10754. * @access private
  10755. * @var array
  10756. */
  10757. var $user = array();
  10758. /**
  10759. * Create new SimplePie_Parse_Date object, and set self::day_pcre,
  10760. * self::month_pcre, and self::built_in
  10761. *
  10762. * @access private
  10763. */
  10764. function SimplePie_Parse_Date()
  10765. {
  10766. $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
  10767. $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
  10768. static $cache;
  10769. if (!isset($cache[get_class($this)]))
  10770. {
  10771. if (extension_loaded('Reflection'))
  10772. {
  10773. $class = new ReflectionClass(get_class($this));
  10774. $methods = $class->getMethods();
  10775. $all_methods = array();
  10776. foreach ($methods as $method)
  10777. {
  10778. $all_methods[] = $method->getName();
  10779. }
  10780. }
  10781. else
  10782. {
  10783. $all_methods = get_class_methods($this);
  10784. }
  10785. foreach ($all_methods as $method)
  10786. {
  10787. if (strtolower(substr($method, 0, 5)) === 'date_')
  10788. {
  10789. $cache[get_class($this)][] = $method;
  10790. }
  10791. }
  10792. }
  10793. foreach ($cache[get_class($this)] as $method)
  10794. {
  10795. $this->built_in[] = $method;
  10796. }
  10797. }
  10798. /**
  10799. * Get the object
  10800. *
  10801. * @access public
  10802. */
  10803. function get()
  10804. {
  10805. static $object;
  10806. if (!$object)
  10807. {
  10808. $object = new SimplePie_Parse_Date;
  10809. }
  10810. return $object;
  10811. }
  10812. /**
  10813. * Parse a date
  10814. *
  10815. * @final
  10816. * @access public
  10817. * @param string $date Date to parse
  10818. * @return int Timestamp corresponding to date string, or false on failure
  10819. */
  10820. function parse($date)
  10821. {
  10822. foreach ($this->user as $method)
  10823. {
  10824. if (($returned = call_user_func($method, $date)) !== false)
  10825. {
  10826. return $returned;
  10827. }
  10828. }
  10829. foreach ($this->built_in as $method)
  10830. {
  10831. if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
  10832. {
  10833. return $returned;
  10834. }
  10835. }
  10836. return false;
  10837. }
  10838. /**
  10839. * Add a callback method to parse a date
  10840. *
  10841. * @final
  10842. * @access public
  10843. * @param callback $callback
  10844. */
  10845. function add_callback($callback)
  10846. {
  10847. if (is_callable($callback))
  10848. {
  10849. $this->user[] = $callback;
  10850. }
  10851. else
  10852. {
  10853. trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
  10854. }
  10855. }
  10856. /**
  10857. * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
  10858. * well as allowing any of upper or lower case "T", horizontal tabs, or
  10859. * spaces to be used as the time seperator (including more than one))
  10860. *
  10861. * @access protected
  10862. * @return int Timestamp
  10863. */
  10864. function date_w3cdtf($date)
  10865. {
  10866. static $pcre;
  10867. if (!$pcre)
  10868. {
  10869. $year = '([0-9]{4})';
  10870. $month = $day = $hour = $minute = $second = '([0-9]{2})';
  10871. $decimal = '([0-9]*)';
  10872. $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
  10873. $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
  10874. }
  10875. if (preg_match($pcre, $date, $match))
  10876. {
  10877. /*
  10878. Capturing subpatterns:
  10879. 1: Year
  10880. 2: Month
  10881. 3: Day
  10882. 4: Hour
  10883. 5: Minute
  10884. 6: Second
  10885. 7: Decimal fraction of a second
  10886. 8: Zulu
  10887. 9: Timezone ±
  10888. 10: Timezone hours
  10889. 11: Timezone minutes
  10890. */
  10891. // Fill in empty matches
  10892. for ($i = count($match); $i <= 3; $i++)
  10893. {
  10894. $match[$i] = '1';
  10895. }
  10896. for ($i = count($match); $i <= 7; $i++)
  10897. {
  10898. $match[$i] = '0';
  10899. }
  10900. // Numeric timezone
  10901. if (isset($match[9]) && $match[9] !== '')
  10902. {
  10903. $timezone = $match[10] * 3600;
  10904. $timezone += $match[11] * 60;
  10905. if ($match[9] === '-')
  10906. {
  10907. $timezone = 0 - $timezone;
  10908. }
  10909. }
  10910. else
  10911. {
  10912. $timezone = 0;
  10913. }
  10914. // Convert the number of seconds to an integer, taking decimals into account
  10915. $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
  10916. return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
  10917. }
  10918. else
  10919. {
  10920. return false;
  10921. }
  10922. }
  10923. /**
  10924. * Remove RFC822 comments
  10925. *
  10926. * @access protected
  10927. * @param string $data Data to strip comments from
  10928. * @return string Comment stripped string
  10929. */
  10930. function remove_rfc2822_comments($string)
  10931. {
  10932. $string = (string) $string;
  10933. $position = 0;
  10934. $length = strlen($string);
  10935. $depth = 0;
  10936. $output = '';
  10937. while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
  10938. {
  10939. $output .= substr($string, $position, $pos - $position);
  10940. $position = $pos + 1;
  10941. if ($string[$pos - 1] !== '\\')
  10942. {
  10943. $depth++;
  10944. while ($depth && $position < $length)
  10945. {
  10946. $position += strcspn($string, '()', $position);
  10947. if ($string[$position - 1] === '\\')
  10948. {
  10949. $position++;
  10950. continue;
  10951. }
  10952. elseif (isset($string[$position]))
  10953. {
  10954. switch ($string[$position])
  10955. {
  10956. case '(':
  10957. $depth++;
  10958. break;
  10959. case ')':
  10960. $depth--;
  10961. break;
  10962. }
  10963. $position++;
  10964. }
  10965. else
  10966. {
  10967. break;
  10968. }
  10969. }
  10970. }
  10971. else
  10972. {
  10973. $output .= '(';
  10974. }
  10975. }
  10976. $output .= substr($string, $position);
  10977. return $output;
  10978. }
  10979. /**
  10980. * Parse RFC2822's date format
  10981. *
  10982. * @access protected
  10983. * @return int Timestamp
  10984. */
  10985. function date_rfc2822($date)
  10986. {
  10987. static $pcre;
  10988. if (!$pcre)
  10989. {
  10990. $wsp = '[\x09\x20]';
  10991. $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
  10992. $optional_fws = $fws . '?';
  10993. $day_name = $this->day_pcre;
  10994. $month = $this->month_pcre;
  10995. $day = '([0-9]{1,2})';
  10996. $hour = $minute = $second = '([0-9]{2})';
  10997. $year = '([0-9]{2,4})';
  10998. $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
  10999. $character_zone = '([A-Z]{1,5})';
  11000. $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
  11001. $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';
  11002. }
  11003. if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
  11004. {
  11005. /*
  11006. Capturing subpatterns:
  11007. 1: Day name
  11008. 2: Day
  11009. 3: Month
  11010. 4: Year
  11011. 5: Hour
  11012. 6: Minute
  11013. 7: Second
  11014. 8: Timezone ±
  11015. 9: Timezone hours
  11016. 10: Timezone minutes
  11017. 11: Alphabetic timezone
  11018. */
  11019. // Find the month number
  11020. $month = $this->month[strtolower($match[3])];
  11021. // Numeric timezone
  11022. if ($match[8] !== '')
  11023. {
  11024. $timezone = $match[9] * 3600;
  11025. $timezone += $match[10] * 60;
  11026. if ($match[8] === '-')
  11027. {
  11028. $timezone = 0 - $timezone;
  11029. }
  11030. }
  11031. // Character timezone
  11032. elseif (isset($this->timezone[strtoupper($match[11])]))
  11033. {
  11034. $timezone = $this->timezone[strtoupper($match[11])];
  11035. }
  11036. // Assume everything else to be -0000
  11037. else
  11038. {
  11039. $timezone = 0;
  11040. }
  11041. // Deal with 2/3 digit years
  11042. if ($match[4] < 50)
  11043. {
  11044. $match[4] += 2000;
  11045. }
  11046. elseif ($match[4] < 1000)
  11047. {
  11048. $match[4] += 1900;
  11049. }
  11050. // Second is optional, if it is empty set it to zero
  11051. if ($match[7] !== '')
  11052. {
  11053. $second = $match[7];
  11054. }
  11055. else
  11056. {
  11057. $second = 0;
  11058. }
  11059. return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
  11060. }
  11061. else
  11062. {
  11063. return false;
  11064. }
  11065. }
  11066. /**
  11067. * Parse RFC850's date format
  11068. *
  11069. * @access protected
  11070. * @return int Timestamp
  11071. */
  11072. function date_rfc850($date)
  11073. {
  11074. static $pcre;
  11075. if (!$pcre)
  11076. {
  11077. $space = '[\x09\x20]+';
  11078. $day_name = $this->day_pcre;
  11079. $month = $this->month_pcre;
  11080. $day = '([0-9]{1,2})';
  11081. $year = $hour = $minute = $second = '([0-9]{2})';
  11082. $zone = '([A-Z]{1,5})';
  11083. $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
  11084. }
  11085. if (preg_match($pcre, $date, $match))
  11086. {
  11087. /*
  11088. Capturing subpatterns:
  11089. 1: Day name
  11090. 2: Day
  11091. 3: Month
  11092. 4: Year
  11093. 5: Hour
  11094. 6: Minute
  11095. 7: Second
  11096. 8: Timezone
  11097. */
  11098. // Month
  11099. $month = $this->month[strtolower($match[3])];
  11100. // Character timezone
  11101. if (isset($this->timezone[strtoupper($match[8])]))
  11102. {
  11103. $timezone = $this->timezone[strtoupper($match[8])];
  11104. }
  11105. // Assume everything else to be -0000
  11106. else
  11107. {
  11108. $timezone = 0;
  11109. }
  11110. // Deal with 2 digit year
  11111. if ($match[4] < 50)
  11112. {
  11113. $match[4] += 2000;
  11114. }
  11115. else
  11116. {
  11117. $match[4] += 1900;
  11118. }
  11119. return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
  11120. }
  11121. else
  11122. {
  11123. return false;
  11124. }
  11125. }
  11126. /**
  11127. * Parse C99's asctime()'s date format
  11128. *
  11129. * @access protected
  11130. * @return int Timestamp
  11131. */
  11132. function date_asctime($date)
  11133. {
  11134. static $pcre;
  11135. if (!$pcre)
  11136. {
  11137. $space = '[\x09\x20]+';
  11138. $wday_name = $this->day_pcre;
  11139. $mon_name = $this->month_pcre;
  11140. $day = '([0-9]{1,2})';
  11141. $hour = $sec = $min = '([0-9]{2})';
  11142. $year = '([0-9]{4})';
  11143. $terminator = '\x0A?\x00?';
  11144. $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
  11145. }
  11146. if (preg_match($pcre, $date, $match))
  11147. {
  11148. /*
  11149. Capturing subpatterns:
  11150. 1: Day name
  11151. 2: Month
  11152. 3: Day
  11153. 4: Hour
  11154. 5: Minute
  11155. 6: Second
  11156. 7: Year
  11157. */
  11158. $month = $this->month[strtolower($match[2])];
  11159. return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
  11160. }
  11161. else
  11162. {
  11163. return false;
  11164. }
  11165. }
  11166. /**
  11167. * Parse dates using strtotime()
  11168. *
  11169. * @access protected
  11170. * @return int Timestamp
  11171. */
  11172. function date_strtotime($date)
  11173. {
  11174. $strtotime = strtotime($date);
  11175. if ($strtotime === -1 || $strtotime === false)
  11176. {
  11177. return false;
  11178. }
  11179. else
  11180. {
  11181. return $strtotime;
  11182. }
  11183. }
  11184. }
  11185. /**
  11186. * Content-type sniffing
  11187. *
  11188. * @package SimplePie
  11189. */
  11190. class SimplePie_Content_Type_Sniffer
  11191. {
  11192. /**
  11193. * File object
  11194. *
  11195. * @var SimplePie_File
  11196. * @access private
  11197. */
  11198. var $file;
  11199. /**
  11200. * Create an instance of the class with the input file
  11201. *
  11202. * @access public
  11203. * @param SimplePie_Content_Type_Sniffer $file Input file
  11204. */
  11205. function SimplePie_Content_Type_Sniffer($file)
  11206. {
  11207. $this->file = $file;
  11208. }
  11209. /**
  11210. * Get the Content-Type of the specified file
  11211. *
  11212. * @access public
  11213. * @return string Actual Content-Type
  11214. */
  11215. function get_type()
  11216. {
  11217. if (isset($this->file->headers['content-type']))
  11218. {
  11219. if (!isset($this->file->headers['content-encoding'])
  11220. && ($this->file->headers['content-type'] === 'text/plain'
  11221. || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
  11222. || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
  11223. {
  11224. return $this->text_or_binary();
  11225. }
  11226. if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
  11227. {
  11228. $official = substr($this->file->headers['content-type'], 0, $pos);
  11229. }
  11230. else
  11231. {
  11232. $official = $this->file->headers['content-type'];
  11233. }
  11234. $official = strtolower($official);
  11235. if ($official === 'unknown/unknown'
  11236. || $official === 'application/unknown')
  11237. {
  11238. return $this->unknown();
  11239. }
  11240. elseif (substr($official, -4) === '+xml'
  11241. || $official === 'text/xml'
  11242. || $official === 'application/xml')
  11243. {
  11244. return $official;
  11245. }
  11246. elseif (substr($official, 0, 6) === 'image/')
  11247. {
  11248. if ($return = $this->image())
  11249. {
  11250. return $return;
  11251. }
  11252. else
  11253. {
  11254. return $official;
  11255. }
  11256. }
  11257. elseif ($official === 'text/html')
  11258. {
  11259. return $this->feed_or_html();
  11260. }
  11261. else
  11262. {
  11263. return $official;
  11264. }
  11265. }
  11266. else
  11267. {
  11268. return $this->unknown();
  11269. }
  11270. }
  11271. /**
  11272. * Sniff text or binary
  11273. *
  11274. * @access private
  11275. * @return string Actual Content-Type
  11276. */
  11277. function text_or_binary()
  11278. {
  11279. if (substr($this->file->body, 0, 2) === "\xFE\xFF"
  11280. || substr($this->file->body, 0, 2) === "\xFF\xFE"
  11281. || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
  11282. || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
  11283. {
  11284. return 'text/plain';
  11285. }
  11286. elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
  11287. {
  11288. return 'application/octect-stream';
  11289. }
  11290. else
  11291. {
  11292. return 'text/plain';
  11293. }
  11294. }
  11295. /**
  11296. * Sniff unknown
  11297. *
  11298. * @access private
  11299. * @return string Actual Content-Type
  11300. */
  11301. function unknown()
  11302. {
  11303. $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
  11304. if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
  11305. || strtolower(substr($this->file->body, $ws, 5)) === '<html'
  11306. || strtolower(substr($this->file->body, $ws, 7)) === '<script')
  11307. {
  11308. return 'text/html';
  11309. }
  11310. elseif (substr($this->file->body, 0, 5) === '%PDF-')
  11311. {
  11312. return 'application/pdf';
  11313. }
  11314. elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
  11315. {
  11316. return 'application/postscript';
  11317. }
  11318. elseif (substr($this->file->body, 0, 6) === 'GIF87a'
  11319. || substr($this->file->body, 0, 6) === 'GIF89a')
  11320. {
  11321. return 'image/gif';
  11322. }
  11323. elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
  11324. {
  11325. return 'image/png';
  11326. }
  11327. elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
  11328. {
  11329. return 'image/jpeg';
  11330. }
  11331. elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
  11332. {
  11333. return 'image/bmp';
  11334. }
  11335. else
  11336. {
  11337. return $this->text_or_binary();
  11338. }
  11339. }
  11340. /**
  11341. * Sniff images
  11342. *
  11343. * @access private
  11344. * @return string Actual Content-Type
  11345. */
  11346. function image()
  11347. {
  11348. if (substr($this->file->body, 0, 6) === 'GIF87a'
  11349. || substr($this->file->body, 0, 6) === 'GIF89a')
  11350. {
  11351. return 'image/gif';
  11352. }
  11353. elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
  11354. {
  11355. return 'image/png';
  11356. }
  11357. elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
  11358. {
  11359. return 'image/jpeg';
  11360. }
  11361. elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
  11362. {
  11363. return 'image/bmp';
  11364. }
  11365. else
  11366. {
  11367. return false;
  11368. }
  11369. }
  11370. /**
  11371. * Sniff HTML
  11372. *
  11373. * @access private
  11374. * @return string Actual Content-Type
  11375. */
  11376. function feed_or_html()
  11377. {
  11378. $len = strlen($this->file->body);
  11379. $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
  11380. while ($pos < $len)
  11381. {
  11382. switch ($this->file->body[$pos])
  11383. {
  11384. case "\x09":
  11385. case "\x0A":
  11386. case "\x0D":
  11387. case "\x20":
  11388. $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
  11389. continue 2;
  11390. case '<':
  11391. $pos++;
  11392. break;
  11393. default:
  11394. return 'text/html';
  11395. }
  11396. if (substr($this->file->body, $pos, 3) === '!--')
  11397. {
  11398. $pos += 3;
  11399. if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
  11400. {
  11401. $pos += 3;
  11402. }
  11403. else
  11404. {
  11405. return 'text/html';
  11406. }
  11407. }
  11408. elseif (substr($this->file->body, $pos, 1) === '!')
  11409. {
  11410. if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
  11411. {
  11412. $pos++;
  11413. }
  11414. else
  11415. {
  11416. return 'text/html';
  11417. }
  11418. }
  11419. elseif (substr($this->file->body, $pos, 1) === '?')
  11420. {
  11421. if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
  11422. {
  11423. $pos += 2;
  11424. }
  11425. else
  11426. {
  11427. return 'text/html';
  11428. }
  11429. }
  11430. elseif (substr($this->file->body, $pos, 3) === 'rss'
  11431. || substr($this->file->body, $pos, 7) === 'rdf:RDF')
  11432. {
  11433. return 'application/rss+xml';
  11434. }
  11435. elseif (substr($this->file->body, $pos, 4) === 'feed')
  11436. {
  11437. return 'application/atom+xml';
  11438. }
  11439. else
  11440. {
  11441. return 'text/html';
  11442. }
  11443. }
  11444. return 'text/html';
  11445. }
  11446. }
  11447. /**
  11448. * Parses the XML Declaration
  11449. *
  11450. * @package SimplePie
  11451. */
  11452. class SimplePie_XML_Declaration_Parser
  11453. {
  11454. /**
  11455. * XML Version
  11456. *
  11457. * @access public
  11458. * @var string
  11459. */
  11460. var $version = '1.0';
  11461. /**
  11462. * Encoding
  11463. *
  11464. * @access public
  11465. * @var string
  11466. */
  11467. var $encoding = 'UTF-8';
  11468. /**
  11469. * Standalone
  11470. *
  11471. * @access public
  11472. * @var bool
  11473. */
  11474. var $standalone = false;
  11475. /**
  11476. * Current state of the state machine
  11477. *
  11478. * @access private
  11479. * @var string
  11480. */
  11481. var $state = 'before_version_name';
  11482. /**
  11483. * Input data
  11484. *
  11485. * @access private
  11486. * @var string
  11487. */
  11488. var $data = '';
  11489. /**
  11490. * Input data length (to avoid calling strlen() everytime this is needed)
  11491. *
  11492. * @access private
  11493. * @var int
  11494. */
  11495. var $data_length = 0;
  11496. /**
  11497. * Current position of the pointer
  11498. *
  11499. * @var int
  11500. * @access private
  11501. */
  11502. var $position = 0;
  11503. /**
  11504. * Create an instance of the class with the input data
  11505. *
  11506. * @access public
  11507. * @param string $data Input data
  11508. */
  11509. function SimplePie_XML_Declaration_Parser($data)
  11510. {
  11511. $this->data = $data;
  11512. $this->data_length = strlen($this->data);
  11513. }
  11514. /**
  11515. * Parse the input data
  11516. *
  11517. * @access public
  11518. * @return bool true on success, false on failure
  11519. */
  11520. function parse()
  11521. {
  11522. while ($this->state && $this->state !== 'emit' && $this->has_data())
  11523. {
  11524. $state = $this->state;
  11525. $this->$state();
  11526. }
  11527. $this->data = '';
  11528. if ($this->state === 'emit')
  11529. {
  11530. return true;
  11531. }
  11532. else
  11533. {
  11534. $this->version = '';
  11535. $this->encoding = '';
  11536. $this->standalone = '';
  11537. return false;
  11538. }
  11539. }
  11540. /**
  11541. * Check whether there is data beyond the pointer
  11542. *
  11543. * @access private
  11544. * @return bool true if there is further data, false if not
  11545. */
  11546. function has_data()
  11547. {
  11548. return (bool) ($this->position < $this->data_length);
  11549. }
  11550. /**
  11551. * Advance past any whitespace
  11552. *
  11553. * @return int Number of whitespace characters passed
  11554. */
  11555. function skip_whitespace()
  11556. {
  11557. $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
  11558. $this->position += $whitespace;
  11559. return $whitespace;
  11560. }
  11561. /**
  11562. * Read value
  11563. */
  11564. function get_value()
  11565. {
  11566. $quote = substr($this->data, $this->position, 1);
  11567. if ($quote === '"' || $quote === "'")
  11568. {
  11569. $this->position++;
  11570. $len = strcspn($this->data, $quote, $this->position);
  11571. if ($this->has_data())
  11572. {
  11573. $value = substr($this->data, $this->position, $len);
  11574. $this->position += $len + 1;
  11575. return $value;
  11576. }
  11577. }
  11578. return false;
  11579. }
  11580. function before_version_name()
  11581. {
  11582. if ($this->skip_whitespace())
  11583. {
  11584. $this->state = 'version_name';
  11585. }
  11586. else
  11587. {
  11588. $this->state = false;
  11589. }
  11590. }
  11591. function version_name()
  11592. {
  11593. if (substr($this->data, $this->position, 7) === 'version')
  11594. {
  11595. $this->position += 7;
  11596. $this->skip_whitespace();
  11597. $this->state = 'version_equals';
  11598. }
  11599. else
  11600. {
  11601. $this->state = false;
  11602. }
  11603. }
  11604. function version_equals()
  11605. {
  11606. if (substr($this->data, $this->position, 1) === '=')
  11607. {
  11608. $this->position++;
  11609. $this->skip_whitespace();
  11610. $this->state = 'version_value';
  11611. }
  11612. else
  11613. {
  11614. $this->state = false;
  11615. }
  11616. }
  11617. function version_value()
  11618. {
  11619. if ($this->version = $this->get_value())
  11620. {
  11621. $this->skip_whitespace();
  11622. if ($this->has_data())
  11623. {
  11624. $this->state = 'encoding_name';
  11625. }
  11626. else
  11627. {
  11628. $this->state = 'emit';
  11629. }
  11630. }
  11631. else
  11632. {
  11633. $this->state = 'standalone_name';
  11634. }
  11635. }
  11636. function encoding_name()
  11637. {
  11638. if (substr($this->data, $this->position, 8) === 'encoding')
  11639. {
  11640. $this->position += 8;
  11641. $this->skip_whitespace();
  11642. $this->state = 'encoding_equals';
  11643. }
  11644. else
  11645. {
  11646. $this->state = false;
  11647. }
  11648. }
  11649. function encoding_equals()
  11650. {
  11651. if (substr($this->data, $this->position, 1) === '=')
  11652. {
  11653. $this->position++;
  11654. $this->skip_whitespace();
  11655. $this->state = 'encoding_value';
  11656. }
  11657. else
  11658. {
  11659. $this->state = false;
  11660. }
  11661. }
  11662. function encoding_value()
  11663. {
  11664. if ($this->encoding = $this->get_value())
  11665. {
  11666. $this->skip_whitespace();
  11667. if ($this->has_data())
  11668. {
  11669. $this->state = 'standalone_name';
  11670. }
  11671. else
  11672. {
  11673. $this->state = 'emit';
  11674. }
  11675. }
  11676. else
  11677. {
  11678. $this->state = false;
  11679. }
  11680. }
  11681. function standalone_name()
  11682. {
  11683. if (substr($this->data, $this->position, 10) === 'standalone')
  11684. {
  11685. $this->position += 10;
  11686. $this->skip_whitespace();
  11687. $this->state = 'standalone_equals';
  11688. }
  11689. else
  11690. {
  11691. $this->state = false;
  11692. }
  11693. }
  11694. function standalone_equals()
  11695. {
  11696. if (substr($this->data, $this->position, 1) === '=')
  11697. {
  11698. $this->position++;
  11699. $this->skip_whitespace();
  11700. $this->state = 'standalone_value';
  11701. }
  11702. else
  11703. {
  11704. $this->state = false;
  11705. }
  11706. }
  11707. function standalone_value()
  11708. {
  11709. if ($standalone = $this->get_value())
  11710. {
  11711. switch ($standalone)
  11712. {
  11713. case 'yes':
  11714. $this->standalone = true;
  11715. break;
  11716. case 'no':
  11717. $this->standalone = false;
  11718. break;
  11719. default:
  11720. $this->state = false;
  11721. return;
  11722. }
  11723. $this->skip_whitespace();
  11724. if ($this->has_data())
  11725. {
  11726. $this->state = false;
  11727. }
  11728. else
  11729. {
  11730. $this->state = 'emit';
  11731. }
  11732. }
  11733. else
  11734. {
  11735. $this->state = false;
  11736. }
  11737. }
  11738. }
  11739. class SimplePie_Locator
  11740. {
  11741. var $useragent;
  11742. var $timeout;
  11743. var $file;
  11744. var $local = array();
  11745. var $elsewhere = array();
  11746. var $file_class = 'SimplePie_File';
  11747. var $cached_entities = array();
  11748. var $http_base;
  11749. var $base;
  11750. var $base_location = 0;
  11751. var $checked_feeds = 0;
  11752. var $max_checked_feeds = 10;
  11753. var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
  11754. function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
  11755. {
  11756. $this->file =& $file;
  11757. $this->file_class = $file_class;
  11758. $this->useragent = $useragent;
  11759. $this->timeout = $timeout;
  11760. $this->max_checked_feeds = $max_checked_feeds;
  11761. $this->content_type_sniffer_class = $content_type_sniffer_class;
  11762. }
  11763. function find($type = SIMPLEPIE_LOCATOR_ALL)
  11764. {
  11765. if ($this->is_feed($this->file))
  11766. {
  11767. return $this->file;
  11768. }
  11769. if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
  11770. {
  11771. $sniffer = new $this->content_type_sniffer_class($this->file);
  11772. if ($sniffer->get_type() !== 'text/html')
  11773. {
  11774. return null;
  11775. }
  11776. }
  11777. if ($type & ~SIMPLEPIE_LOCATOR_NONE)
  11778. {
  11779. $this->get_base();
  11780. }
  11781. if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
  11782. {
  11783. return $working;
  11784. }
  11785. if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
  11786. {
  11787. if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
  11788. {
  11789. return $working;
  11790. }
  11791. if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
  11792. {
  11793. return $working;
  11794. }
  11795. if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
  11796. {
  11797. return $working;
  11798. }
  11799. if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
  11800. {
  11801. return $working;
  11802. }
  11803. }
  11804. return null;
  11805. }
  11806. function is_feed(&$file)
  11807. {
  11808. if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
  11809. {
  11810. $sniffer = new $this->content_type_sniffer_class($file);
  11811. $sniffed = $sniffer->get_type();
  11812. if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
  11813. {
  11814. return true;
  11815. }
  11816. else
  11817. {
  11818. return false;
  11819. }
  11820. }
  11821. elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
  11822. {
  11823. return true;
  11824. }
  11825. else
  11826. {
  11827. return false;
  11828. }
  11829. }
  11830. function get_base()
  11831. {
  11832. $this->http_base = $this->file->url;
  11833. $this->base = $this->http_base;
  11834. $elements = SimplePie_Misc::get_element('base', $this->file->body);
  11835. foreach ($elements as $element)
  11836. {
  11837. if ($element['attribs']['href']['data'] !== '')
  11838. {
  11839. $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
  11840. $this->base_location = $element['offset'];
  11841. break;
  11842. }
  11843. }
  11844. }
  11845. function autodiscovery()
  11846. {
  11847. $links = array_merge(SimplePie_Misc::get_element('link', $this->file->body), SimplePie_Misc::get_element('a', $this->file->body), SimplePie_Misc::get_element('area', $this->file->body));
  11848. $done = array();
  11849. foreach ($links as $link)
  11850. {
  11851. if ($this->checked_feeds == $this->max_checked_feeds)
  11852. {
  11853. break;
  11854. }
  11855. if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
  11856. {
  11857. $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
  11858. if ($this->base_location < $link['offset'])
  11859. {
  11860. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
  11861. }
  11862. else
  11863. {
  11864. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
  11865. }
  11866. if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml'))))
  11867. {
  11868. $this->checked_feeds++;
  11869. $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
  11870. if ($this->is_feed($feed))
  11871. {
  11872. return $feed;
  11873. }
  11874. }
  11875. $done[] = $href;
  11876. }
  11877. }
  11878. return null;
  11879. }
  11880. function get_links()
  11881. {
  11882. $links = SimplePie_Misc::get_element('a', $this->file->body);
  11883. foreach ($links as $link)
  11884. {
  11885. if (isset($link['attribs']['href']['data']))
  11886. {
  11887. $href = trim($link['attribs']['href']['data']);
  11888. $parsed = SimplePie_Misc::parse_url($href);
  11889. if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
  11890. {
  11891. if ($this->base_location < $link['offset'])
  11892. {
  11893. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
  11894. }
  11895. else
  11896. {
  11897. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
  11898. }
  11899. $current = SimplePie_Misc::parse_url($this->file->url);
  11900. if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
  11901. {
  11902. $this->local[] = $href;
  11903. }
  11904. else
  11905. {
  11906. $this->elsewhere[] = $href;
  11907. }
  11908. }
  11909. }
  11910. }
  11911. $this->local = array_unique($this->local);
  11912. $this->elsewhere = array_unique($this->elsewhere);
  11913. if (!empty($this->local) || !empty($this->elsewhere))
  11914. {
  11915. return true;
  11916. }
  11917. return null;
  11918. }
  11919. function extension(&$array)
  11920. {
  11921. foreach ($array as $key => $value)
  11922. {
  11923. if ($this->checked_feeds == $this->max_checked_feeds)
  11924. {
  11925. break;
  11926. }
  11927. if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
  11928. {
  11929. $this->checked_feeds++;
  11930. $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
  11931. if ($this->is_feed($feed))
  11932. {
  11933. return $feed;
  11934. }
  11935. else
  11936. {
  11937. unset($array[$key]);
  11938. }
  11939. }
  11940. }
  11941. return null;
  11942. }
  11943. function body(&$array)
  11944. {
  11945. foreach ($array as $key => $value)
  11946. {
  11947. if ($this->checked_feeds == $this->max_checked_feeds)
  11948. {
  11949. break;
  11950. }
  11951. if (preg_match('/(rss|rdf|atom|xml)/i', $value))
  11952. {
  11953. $this->checked_feeds++;
  11954. $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
  11955. if ($this->is_feed($feed))
  11956. {
  11957. return $feed;
  11958. }
  11959. else
  11960. {
  11961. unset($array[$key]);
  11962. }
  11963. }
  11964. }
  11965. return null;
  11966. }
  11967. }
  11968. class SimplePie_Parser
  11969. {
  11970. var $error_code;
  11971. var $error_string;
  11972. var $current_line;
  11973. var $current_column;
  11974. var $current_byte;
  11975. var $separator = ' ';
  11976. var $feed = false;
  11977. var $namespace = array('');
  11978. var $element = array('');
  11979. var $xml_base = array('');
  11980. var $xml_base_explicit = array(false);
  11981. var $xml_lang = array('');
  11982. var $data = array();
  11983. var $datas = array(array());
  11984. var $current_xhtml_construct = -1;
  11985. var $encoding;
  11986. function parse(&$data, $encoding)
  11987. {
  11988. // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
  11989. if (strtoupper($encoding) == 'US-ASCII')
  11990. {
  11991. $this->encoding = 'UTF-8';
  11992. }
  11993. else
  11994. {
  11995. $this->encoding = $encoding;
  11996. }
  11997. // Strip BOM:
  11998. // UTF-32 Big Endian BOM
  11999. if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
  12000. {
  12001. $data = substr($data, 4);
  12002. }
  12003. // UTF-32 Little Endian BOM
  12004. elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
  12005. {
  12006. $data = substr($data, 4);
  12007. }
  12008. // UTF-16 Big Endian BOM
  12009. elseif (substr($data, 0, 2) === "\xFE\xFF")
  12010. {
  12011. $data = substr($data, 2);
  12012. }
  12013. // UTF-16 Little Endian BOM
  12014. elseif (substr($data, 0, 2) === "\xFF\xFE")
  12015. {
  12016. $data = substr($data, 2);
  12017. }
  12018. // UTF-8 BOM
  12019. elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
  12020. {
  12021. $data = substr($data, 3);
  12022. }
  12023. if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
  12024. {
  12025. $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
  12026. if ($declaration->parse())
  12027. {
  12028. $data = substr($data, $pos + 2);
  12029. $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
  12030. }
  12031. else
  12032. {
  12033. $this->error_string = 'SimplePie bug! Please report this!';
  12034. return false;
  12035. }
  12036. }
  12037. // Work around libxml 2.7.0/2.7.1 bug, at least when in PHP 5.1+
  12038. if (version_compare(PHP_VERSION, '5.1', '>=') && (LIBXML_VERSION === 20700 || LIBXML_VERSION === 20701))
  12039. {
  12040. $data = str_replace('&lt;', '&#60;', $data);
  12041. $data = str_replace('&gt;', '&#62;', $data);
  12042. $data = str_replace('&amp;', '&#38;', $data);
  12043. $data = str_replace('&apos;', '&#39;', $data);
  12044. $data = str_replace('&quot;', '&#34;', $data);
  12045. }
  12046. $return = true;
  12047. // Create the parser
  12048. $xml = xml_parser_create_ns($this->encoding, $this->separator);
  12049. xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
  12050. xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
  12051. xml_set_object($xml, $this);
  12052. xml_set_character_data_handler($xml, 'cdata');
  12053. xml_set_element_handler($xml, 'tag_open', 'tag_close');
  12054. // Parse!
  12055. if (!xml_parse($xml, $data, true))
  12056. {
  12057. $this->error_code = xml_get_error_code($xml);
  12058. $this->error_string = xml_error_string($this->error_code);
  12059. $return = false;
  12060. }
  12061. $this->current_line = xml_get_current_line_number($xml);
  12062. $this->current_column = xml_get_current_column_number($xml);
  12063. $this->current_byte = xml_get_current_byte_index($xml);
  12064. xml_parser_free($xml);
  12065. return $return;
  12066. }
  12067. function get_error_code()
  12068. {
  12069. return $this->error_code;
  12070. }
  12071. function get_error_string()
  12072. {
  12073. return $this->error_string;
  12074. }
  12075. function get_current_line()
  12076. {
  12077. return $this->current_line;
  12078. }
  12079. function get_current_column()
  12080. {
  12081. return $this->current_column;
  12082. }
  12083. function get_current_byte()
  12084. {
  12085. return $this->current_byte;
  12086. }
  12087. function get_data()
  12088. {
  12089. return $this->data;
  12090. }
  12091. function tag_open($parser, $tag, $attributes)
  12092. {
  12093. if ($this->feed === 0)
  12094. {
  12095. return;
  12096. }
  12097. elseif ($this->feed == false)
  12098. {
  12099. if (in_array($tag, array(
  12100. SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
  12101. SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
  12102. 'rss',
  12103. SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
  12104. )))
  12105. {
  12106. $this->feed = 1;
  12107. }
  12108. }
  12109. else
  12110. {
  12111. $this->feed++;
  12112. }
  12113. list($this->namespace[], $this->element[]) = $this->split_ns($tag);
  12114. $attribs = array();
  12115. foreach ($attributes as $name => $value)
  12116. {
  12117. list($attrib_namespace, $attribute) = $this->split_ns($name);
  12118. $attribs[$attrib_namespace][$attribute] = $value;
  12119. }
  12120. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
  12121. {
  12122. $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
  12123. $this->xml_base_explicit[] = true;
  12124. }
  12125. else
  12126. {
  12127. $this->xml_base[] = end($this->xml_base);
  12128. $this->xml_base_explicit[] = end($this->xml_base_explicit);
  12129. }
  12130. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
  12131. {
  12132. $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
  12133. }
  12134. else
  12135. {
  12136. $this->xml_lang[] = end($this->xml_lang);
  12137. }
  12138. if ($this->current_xhtml_construct >= 0)
  12139. {
  12140. $this->current_xhtml_construct++;
  12141. if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
  12142. {
  12143. $this->data['data'] .= '<' . end($this->element);
  12144. if (isset($attribs['']))
  12145. {
  12146. foreach ($attribs[''] as $name => $value)
  12147. {
  12148. $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
  12149. }
  12150. }
  12151. $this->data['data'] .= '>';
  12152. }
  12153. }
  12154. else
  12155. {
  12156. $this->datas[] =& $this->data;
  12157. $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
  12158. $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));
  12159. 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')
  12160. || (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'))
  12161. {
  12162. $this->current_xhtml_construct = 0;
  12163. }
  12164. }
  12165. }
  12166. function cdata($parser, $cdata)
  12167. {
  12168. if ($this->current_xhtml_construct >= 0)
  12169. {
  12170. $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
  12171. }
  12172. elseif ($this->feed > 1)
  12173. {
  12174. $this->data['data'] .= $cdata;
  12175. }
  12176. }
  12177. function tag_close($parser, $tag)
  12178. {
  12179. if (!$this->feed)
  12180. {
  12181. return;
  12182. }
  12183. if ($this->current_xhtml_construct >= 0)
  12184. {
  12185. $this->current_xhtml_construct--;
  12186. 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')))
  12187. {
  12188. $this->data['data'] .= '</' . end($this->element) . '>';
  12189. }
  12190. }
  12191. if ($this->current_xhtml_construct == -1)
  12192. {
  12193. $this->data =& $this->datas[$this->feed];
  12194. array_pop($this->datas);
  12195. }
  12196. array_pop($this->element);
  12197. array_pop($this->namespace);
  12198. array_pop($this->xml_base);
  12199. array_pop($this->xml_base_explicit);
  12200. array_pop($this->xml_lang);
  12201. $this->feed--;
  12202. }
  12203. function split_ns($string)
  12204. {
  12205. static $cache = array();
  12206. if (!isset($cache[$string]))
  12207. {
  12208. if ($pos = strpos($string, $this->separator))
  12209. {
  12210. static $separator_length;
  12211. if (!$separator_length)
  12212. {
  12213. $separator_length = strlen($this->separator);
  12214. }
  12215. $namespace = substr($string, 0, $pos);
  12216. $local_name = substr($string, $pos + $separator_length);
  12217. if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
  12218. {
  12219. $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
  12220. }
  12221. // Normalize the Media RSS namespaces
  12222. if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
  12223. {
  12224. $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
  12225. }
  12226. $cache[$string] = array($namespace, $local_name);
  12227. }
  12228. else
  12229. {
  12230. $cache[$string] = array('', $string);
  12231. }
  12232. }
  12233. return $cache[$string];
  12234. }
  12235. }
  12236. /**
  12237. * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags
  12238. */
  12239. class SimplePie_Sanitize
  12240. {
  12241. // Private vars
  12242. var $base;
  12243. // Options
  12244. var $remove_div = true;
  12245. var $image_handler = '';
  12246. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  12247. var $encode_instead_of_strip = false;
  12248. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  12249. var $strip_comments = false;
  12250. var $output_encoding = 'UTF-8';
  12251. var $enable_cache = true;
  12252. var $cache_location = './cache';
  12253. var $cache_name_function = 'md5';
  12254. var $cache_class = 'SimplePie_Cache';
  12255. var $file_class = 'SimplePie_File';
  12256. var $timeout = 10;
  12257. var $useragent = '';
  12258. var $force_fsockopen = false;
  12259. var $replace_url_attributes = array(
  12260. 'a' => 'href',
  12261. 'area' => 'href',
  12262. 'blockquote' => 'cite',
  12263. 'del' => 'cite',
  12264. 'form' => 'action',
  12265. 'img' => array('longdesc', 'src'),
  12266. 'input' => 'src',
  12267. 'ins' => 'cite',
  12268. 'q' => 'cite'
  12269. );
  12270. function remove_div($enable = true)
  12271. {
  12272. $this->remove_div = (bool) $enable;
  12273. }
  12274. function set_image_handler($page = false)
  12275. {
  12276. if ($page)
  12277. {
  12278. $this->image_handler = (string) $page;
  12279. }
  12280. else
  12281. {
  12282. $this->image_handler = false;
  12283. }
  12284. }
  12285. function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
  12286. {
  12287. if (isset($enable_cache))
  12288. {
  12289. $this->enable_cache = (bool) $enable_cache;
  12290. }
  12291. if ($cache_location)
  12292. {
  12293. $this->cache_location = (string) $cache_location;
  12294. }
  12295. if ($cache_name_function)
  12296. {
  12297. $this->cache_name_function = (string) $cache_name_function;
  12298. }
  12299. if ($cache_class)
  12300. {
  12301. $this->cache_class = (string) $cache_class;
  12302. }
  12303. }
  12304. function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
  12305. {
  12306. if ($file_class)
  12307. {
  12308. $this->file_class = (string) $file_class;
  12309. }
  12310. if ($timeout)
  12311. {
  12312. $this->timeout = (string) $timeout;
  12313. }
  12314. if ($useragent)
  12315. {
  12316. $this->useragent = (string) $useragent;
  12317. }
  12318. if ($force_fsockopen)
  12319. {
  12320. $this->force_fsockopen = (string) $force_fsockopen;
  12321. }
  12322. }
  12323. function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
  12324. {
  12325. if ($tags)
  12326. {
  12327. if (is_array($tags))
  12328. {
  12329. $this->strip_htmltags = $tags;
  12330. }
  12331. else
  12332. {
  12333. $this->strip_htmltags = explode(',', $tags);
  12334. }
  12335. }
  12336. else
  12337. {
  12338. $this->strip_htmltags = false;
  12339. }
  12340. }
  12341. function encode_instead_of_strip($encode = false)
  12342. {
  12343. $this->encode_instead_of_strip = (bool) $encode;
  12344. }
  12345. function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
  12346. {
  12347. if ($attribs)
  12348. {
  12349. if (is_array($attribs))
  12350. {
  12351. $this->strip_attributes = $attribs;
  12352. }
  12353. else
  12354. {
  12355. $this->strip_attributes = explode(',', $attribs);
  12356. }
  12357. }
  12358. else
  12359. {
  12360. $this->strip_attributes = false;
  12361. }
  12362. }
  12363. function strip_comments($strip = false)
  12364. {
  12365. $this->strip_comments = (bool) $strip;
  12366. }
  12367. function set_output_encoding($encoding = 'UTF-8')
  12368. {
  12369. $this->output_encoding = (string) $encoding;
  12370. }
  12371. /**
  12372. * Set element/attribute key/value pairs of HTML attributes
  12373. * containing URLs that need to be resolved relative to the feed
  12374. *
  12375. * @access public
  12376. * @since 1.0
  12377. * @param array $element_attribute Element/attribute key/value pairs
  12378. */
  12379. function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
  12380. {
  12381. $this->replace_url_attributes = (array) $element_attribute;
  12382. }
  12383. function sanitize($data, $type, $base = '')
  12384. {
  12385. $data = trim($data);
  12386. if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
  12387. {
  12388. if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
  12389. {
  12390. 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))
  12391. {
  12392. $type |= SIMPLEPIE_CONSTRUCT_HTML;
  12393. }
  12394. else
  12395. {
  12396. $type |= SIMPLEPIE_CONSTRUCT_TEXT;
  12397. }
  12398. }
  12399. if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
  12400. {
  12401. $data = base64_decode($data);
  12402. }
  12403. if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
  12404. {
  12405. if ($this->remove_div)
  12406. {
  12407. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
  12408. $data = preg_replace('/<\/div>$/', '', $data);
  12409. }
  12410. else
  12411. {
  12412. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
  12413. }
  12414. }
  12415. if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
  12416. {
  12417. // Strip comments
  12418. if ($this->strip_comments)
  12419. {
  12420. $data = SimplePie_Misc::strip_comments($data);
  12421. }
  12422. // Strip out HTML tags and attributes that might cause various security problems.
  12423. // Based on recommendations by Mark Pilgrim at:
  12424. // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
  12425. if ($this->strip_htmltags)
  12426. {
  12427. foreach ($this->strip_htmltags as $tag)
  12428. {
  12429. $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
  12430. while (preg_match($pcre, $data))
  12431. {
  12432. $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
  12433. }
  12434. }
  12435. }
  12436. if ($this->strip_attributes)
  12437. {
  12438. foreach ($this->strip_attributes as $attrib)
  12439. {
  12440. $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data);
  12441. }
  12442. }
  12443. // Replace relative URLs
  12444. $this->base = $base;
  12445. foreach ($this->replace_url_attributes as $element => $attributes)
  12446. {
  12447. $data = $this->replace_urls($data, $element, $attributes);
  12448. }
  12449. // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
  12450. if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
  12451. {
  12452. $images = SimplePie_Misc::get_element('img', $data);
  12453. foreach ($images as $img)
  12454. {
  12455. if (isset($img['attribs']['src']['data']))
  12456. {
  12457. $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
  12458. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
  12459. if ($cache->load())
  12460. {
  12461. $img['attribs']['src']['data'] = $this->image_handler . $image_url;
  12462. $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
  12463. }
  12464. else
  12465. {
  12466. $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
  12467. $headers = $file->headers;
  12468. if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
  12469. {
  12470. if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  12471. {
  12472. $img['attribs']['src']['data'] = $this->image_handler . $image_url;
  12473. $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
  12474. }
  12475. else
  12476. {
  12477. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  12478. }
  12479. }
  12480. }
  12481. }
  12482. }
  12483. }
  12484. // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
  12485. $data = trim($data);
  12486. }
  12487. if ($type & SIMPLEPIE_CONSTRUCT_IRI)
  12488. {
  12489. $data = SimplePie_Misc::absolutize_url($data, $base);
  12490. }
  12491. if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
  12492. {
  12493. $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
  12494. }
  12495. if ($this->output_encoding != 'UTF-8')
  12496. {
  12497. $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
  12498. }
  12499. }
  12500. return $data;
  12501. }
  12502. function replace_urls($data, $tag, $attributes)
  12503. {
  12504. if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
  12505. {
  12506. $elements = SimplePie_Misc::get_element($tag, $data);
  12507. foreach ($elements as $element)
  12508. {
  12509. if (is_array($attributes))
  12510. {
  12511. foreach ($attributes as $attribute)
  12512. {
  12513. if (isset($element['attribs'][$attribute]['data']))
  12514. {
  12515. $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
  12516. $new_element = SimplePie_Misc::element_implode($element);
  12517. $data = str_replace($element['full'], $new_element, $data);
  12518. $element['full'] = $new_element;
  12519. }
  12520. }
  12521. }
  12522. elseif (isset($element['attribs'][$attributes]['data']))
  12523. {
  12524. $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
  12525. $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
  12526. }
  12527. }
  12528. }
  12529. return $data;
  12530. }
  12531. function do_strip_htmltags($match)
  12532. {
  12533. if ($this->encode_instead_of_strip)
  12534. {
  12535. if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  12536. {
  12537. $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
  12538. $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
  12539. return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
  12540. }
  12541. else
  12542. {
  12543. return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
  12544. }
  12545. }
  12546. elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  12547. {
  12548. return $match[4];
  12549. }
  12550. else
  12551. {
  12552. return '';
  12553. }
  12554. }
  12555. }
  12556. ?>