PageRenderTime 122ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/wp-includes/class-simplepie.php

https://bitbucket.org/Wallynm/iptb
PHP | 15002 lines | 11793 code | 1088 blank | 2121 comment | 1154 complexity | 51780e1b478a6c530f99c0d2dd482ac2 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-1.0, GPL-2.0, GPL-3.0
  1. <?php
  2. if ( !class_exists( 'SimplePie' ) ) :
  3. /**
  4. * SimplePie
  5. *
  6. * A PHP-Based RSS and Atom Feed Framework.
  7. * Takes the hard work out of managing a complete RSS/Atom solution.
  8. *
  9. * Copyright (c) 2004-2009, Ryan Parman and Geoffrey Sneddon
  10. * All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or without modification, are
  13. * permitted provided that the following conditions are met:
  14. *
  15. * * Redistributions of source code must retain the above copyright notice, this list of
  16. * conditions and the following disclaimer.
  17. *
  18. * * Redistributions in binary form must reproduce the above copyright notice, this list
  19. * of conditions and the following disclaimer in the documentation and/or other materials
  20. * provided with the distribution.
  21. *
  22. * * Neither the name of the SimplePie Team nor the names of its contributors may be used
  23. * to endorse or promote products derived from this software without specific prior
  24. * written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  27. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  28. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
  29. * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  30. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  31. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  33. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34. * POSSIBILITY OF SUCH DAMAGE.
  35. *
  36. * @package SimplePie
  37. * @version 1.2
  38. * @copyright 2004-2009 Ryan Parman, Geoffrey Sneddon
  39. * @author Ryan Parman
  40. * @author Geoffrey Sneddon
  41. * @link http://simplepie.org/ SimplePie
  42. * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
  43. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  44. * @todo phpDoc comments
  45. */
  46. /**
  47. * SimplePie Name
  48. */
  49. define('SIMPLEPIE_NAME', 'SimplePie');
  50. /**
  51. * SimplePie Version
  52. */
  53. define('SIMPLEPIE_VERSION', '1.2');
  54. /**
  55. * SimplePie Build
  56. */
  57. define('SIMPLEPIE_BUILD', '20090627192103');
  58. /**
  59. * SimplePie Website URL
  60. */
  61. define('SIMPLEPIE_URL', 'http://simplepie.org');
  62. /**
  63. * SimplePie Useragent
  64. * @see SimplePie::set_useragent()
  65. */
  66. define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
  67. /**
  68. * SimplePie Linkback
  69. */
  70. define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
  71. /**
  72. * No Autodiscovery
  73. * @see SimplePie::set_autodiscovery_level()
  74. */
  75. define('SIMPLEPIE_LOCATOR_NONE', 0);
  76. /**
  77. * Feed Link Element Autodiscovery
  78. * @see SimplePie::set_autodiscovery_level()
  79. */
  80. define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
  81. /**
  82. * Local Feed Extension Autodiscovery
  83. * @see SimplePie::set_autodiscovery_level()
  84. */
  85. define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
  86. /**
  87. * Local Feed Body Autodiscovery
  88. * @see SimplePie::set_autodiscovery_level()
  89. */
  90. define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
  91. /**
  92. * Remote Feed Extension Autodiscovery
  93. * @see SimplePie::set_autodiscovery_level()
  94. */
  95. define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
  96. /**
  97. * Remote Feed Body Autodiscovery
  98. * @see SimplePie::set_autodiscovery_level()
  99. */
  100. define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
  101. /**
  102. * All Feed Autodiscovery
  103. * @see SimplePie::set_autodiscovery_level()
  104. */
  105. define('SIMPLEPIE_LOCATOR_ALL', 31);
  106. /**
  107. * No known feed type
  108. */
  109. define('SIMPLEPIE_TYPE_NONE', 0);
  110. /**
  111. * RSS 0.90
  112. */
  113. define('SIMPLEPIE_TYPE_RSS_090', 1);
  114. /**
  115. * RSS 0.91 (Netscape)
  116. */
  117. define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
  118. /**
  119. * RSS 0.91 (Userland)
  120. */
  121. define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
  122. /**
  123. * RSS 0.91 (both Netscape and Userland)
  124. */
  125. define('SIMPLEPIE_TYPE_RSS_091', 6);
  126. /**
  127. * RSS 0.92
  128. */
  129. define('SIMPLEPIE_TYPE_RSS_092', 8);
  130. /**
  131. * RSS 0.93
  132. */
  133. define('SIMPLEPIE_TYPE_RSS_093', 16);
  134. /**
  135. * RSS 0.94
  136. */
  137. define('SIMPLEPIE_TYPE_RSS_094', 32);
  138. /**
  139. * RSS 1.0
  140. */
  141. define('SIMPLEPIE_TYPE_RSS_10', 64);
  142. /**
  143. * RSS 2.0
  144. */
  145. define('SIMPLEPIE_TYPE_RSS_20', 128);
  146. /**
  147. * RDF-based RSS
  148. */
  149. define('SIMPLEPIE_TYPE_RSS_RDF', 65);
  150. /**
  151. * Non-RDF-based RSS (truly intended as syndication format)
  152. */
  153. define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
  154. /**
  155. * All RSS
  156. */
  157. define('SIMPLEPIE_TYPE_RSS_ALL', 255);
  158. /**
  159. * Atom 0.3
  160. */
  161. define('SIMPLEPIE_TYPE_ATOM_03', 256);
  162. /**
  163. * Atom 1.0
  164. */
  165. define('SIMPLEPIE_TYPE_ATOM_10', 512);
  166. /**
  167. * All Atom
  168. */
  169. define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
  170. /**
  171. * All feed types
  172. */
  173. define('SIMPLEPIE_TYPE_ALL', 1023);
  174. /**
  175. * No construct
  176. */
  177. define('SIMPLEPIE_CONSTRUCT_NONE', 0);
  178. /**
  179. * Text construct
  180. */
  181. define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
  182. /**
  183. * HTML construct
  184. */
  185. define('SIMPLEPIE_CONSTRUCT_HTML', 2);
  186. /**
  187. * XHTML construct
  188. */
  189. define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
  190. /**
  191. * base64-encoded construct
  192. */
  193. define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
  194. /**
  195. * IRI construct
  196. */
  197. define('SIMPLEPIE_CONSTRUCT_IRI', 16);
  198. /**
  199. * A construct that might be HTML
  200. */
  201. define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
  202. /**
  203. * All constructs
  204. */
  205. define('SIMPLEPIE_CONSTRUCT_ALL', 63);
  206. /**
  207. * Don't change case
  208. */
  209. define('SIMPLEPIE_SAME_CASE', 1);
  210. /**
  211. * Change to lowercase
  212. */
  213. define('SIMPLEPIE_LOWERCASE', 2);
  214. /**
  215. * Change to uppercase
  216. */
  217. define('SIMPLEPIE_UPPERCASE', 4);
  218. /**
  219. * PCRE for HTML attributes
  220. */
  221. 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]*');
  222. /**
  223. * PCRE for XML attributes
  224. */
  225. define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
  226. /**
  227. * XML Namespace
  228. */
  229. define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
  230. /**
  231. * Atom 1.0 Namespace
  232. */
  233. define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
  234. /**
  235. * Atom 0.3 Namespace
  236. */
  237. define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
  238. /**
  239. * RDF Namespace
  240. */
  241. define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
  242. /**
  243. * RSS 0.90 Namespace
  244. */
  245. define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
  246. /**
  247. * RSS 1.0 Namespace
  248. */
  249. define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
  250. /**
  251. * RSS 1.0 Content Module Namespace
  252. */
  253. define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
  254. /**
  255. * RSS 2.0 Namespace
  256. * (Stupid, I know, but I'm certain it will confuse people less with support.)
  257. */
  258. define('SIMPLEPIE_NAMESPACE_RSS_20', '');
  259. /**
  260. * DC 1.0 Namespace
  261. */
  262. define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
  263. /**
  264. * DC 1.1 Namespace
  265. */
  266. define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
  267. /**
  268. * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
  269. */
  270. define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
  271. /**
  272. * GeoRSS Namespace
  273. */
  274. define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
  275. /**
  276. * Media RSS Namespace
  277. */
  278. define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
  279. /**
  280. * Wrong Media RSS Namespace
  281. */
  282. define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
  283. /**
  284. * iTunes RSS Namespace
  285. */
  286. define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
  287. /**
  288. * XHTML Namespace
  289. */
  290. define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
  291. /**
  292. * IANA Link Relations Registry
  293. */
  294. define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
  295. /**
  296. * Whether we're running on PHP5
  297. */
  298. define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
  299. /**
  300. * No file source
  301. */
  302. define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
  303. /**
  304. * Remote file source
  305. */
  306. define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
  307. /**
  308. * Local file source
  309. */
  310. define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
  311. /**
  312. * fsockopen() file source
  313. */
  314. define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
  315. /**
  316. * cURL file source
  317. */
  318. define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
  319. /**
  320. * file_get_contents() file source
  321. */
  322. define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
  323. /**
  324. * SimplePie
  325. *
  326. * @package SimplePie
  327. */
  328. class SimplePie
  329. {
  330. /**
  331. * @var array Raw data
  332. * @access private
  333. */
  334. var $data = array();
  335. /**
  336. * @var mixed Error string
  337. * @access private
  338. */
  339. var $error;
  340. /**
  341. * @var object Instance of SimplePie_Sanitize (or other class)
  342. * @see SimplePie::set_sanitize_class()
  343. * @access private
  344. */
  345. var $sanitize;
  346. /**
  347. * @var string SimplePie Useragent
  348. * @see SimplePie::set_useragent()
  349. * @access private
  350. */
  351. var $useragent = SIMPLEPIE_USERAGENT;
  352. /**
  353. * @var string Feed URL
  354. * @see SimplePie::set_feed_url()
  355. * @access private
  356. */
  357. var $feed_url;
  358. /**
  359. * @var object Instance of SimplePie_File to use as a feed
  360. * @see SimplePie::set_file()
  361. * @access private
  362. */
  363. var $file;
  364. /**
  365. * @var string Raw feed data
  366. * @see SimplePie::set_raw_data()
  367. * @access private
  368. */
  369. var $raw_data;
  370. /**
  371. * @var int Timeout for fetching remote files
  372. * @see SimplePie::set_timeout()
  373. * @access private
  374. */
  375. var $timeout = 10;
  376. /**
  377. * @var bool Forces fsockopen() to be used for remote files instead
  378. * of cURL, even if a new enough version is installed
  379. * @see SimplePie::force_fsockopen()
  380. * @access private
  381. */
  382. var $force_fsockopen = false;
  383. /**
  384. * @var bool Force the given data/URL to be treated as a feed no matter what
  385. * it appears like
  386. * @see SimplePie::force_feed()
  387. * @access private
  388. */
  389. var $force_feed = false;
  390. /**
  391. * @var bool Enable/Disable XML dump
  392. * @see SimplePie::enable_xml_dump()
  393. * @access private
  394. */
  395. var $xml_dump = false;
  396. /**
  397. * @var bool Enable/Disable Caching
  398. * @see SimplePie::enable_cache()
  399. * @access private
  400. */
  401. var $cache = true;
  402. /**
  403. * @var int Cache duration (in seconds)
  404. * @see SimplePie::set_cache_duration()
  405. * @access private
  406. */
  407. var $cache_duration = 3600;
  408. /**
  409. * @var int Auto-discovery cache duration (in seconds)
  410. * @see SimplePie::set_autodiscovery_cache_duration()
  411. * @access private
  412. */
  413. var $autodiscovery_cache_duration = 604800; // 7 Days.
  414. /**
  415. * @var string Cache location (relative to executing script)
  416. * @see SimplePie::set_cache_location()
  417. * @access private
  418. */
  419. var $cache_location = './cache';
  420. /**
  421. * @var string Function that creates the cache filename
  422. * @see SimplePie::set_cache_name_function()
  423. * @access private
  424. */
  425. var $cache_name_function = 'md5';
  426. /**
  427. * @var bool Reorder feed by date descending
  428. * @see SimplePie::enable_order_by_date()
  429. * @access private
  430. */
  431. var $order_by_date = true;
  432. /**
  433. * @var mixed Force input encoding to be set to the follow value
  434. * (false, or anything type-cast to false, disables this feature)
  435. * @see SimplePie::set_input_encoding()
  436. * @access private
  437. */
  438. var $input_encoding = false;
  439. /**
  440. * @var int Feed Autodiscovery Level
  441. * @see SimplePie::set_autodiscovery_level()
  442. * @access private
  443. */
  444. var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
  445. /**
  446. * @var string Class used for caching feeds
  447. * @see SimplePie::set_cache_class()
  448. * @access private
  449. */
  450. var $cache_class = 'SimplePie_Cache';
  451. /**
  452. * @var string Class used for locating feeds
  453. * @see SimplePie::set_locator_class()
  454. * @access private
  455. */
  456. var $locator_class = 'SimplePie_Locator';
  457. /**
  458. * @var string Class used for parsing feeds
  459. * @see SimplePie::set_parser_class()
  460. * @access private
  461. */
  462. var $parser_class = 'SimplePie_Parser';
  463. /**
  464. * @var string Class used for fetching feeds
  465. * @see SimplePie::set_file_class()
  466. * @access private
  467. */
  468. var $file_class = 'SimplePie_File';
  469. /**
  470. * @var string Class used for items
  471. * @see SimplePie::set_item_class()
  472. * @access private
  473. */
  474. var $item_class = 'SimplePie_Item';
  475. /**
  476. * @var string Class used for authors
  477. * @see SimplePie::set_author_class()
  478. * @access private
  479. */
  480. var $author_class = 'SimplePie_Author';
  481. /**
  482. * @var string Class used for categories
  483. * @see SimplePie::set_category_class()
  484. * @access private
  485. */
  486. var $category_class = 'SimplePie_Category';
  487. /**
  488. * @var string Class used for enclosures
  489. * @see SimplePie::set_enclosures_class()
  490. * @access private
  491. */
  492. var $enclosure_class = 'SimplePie_Enclosure';
  493. /**
  494. * @var string Class used for Media RSS <media:text> captions
  495. * @see SimplePie::set_caption_class()
  496. * @access private
  497. */
  498. var $caption_class = 'SimplePie_Caption';
  499. /**
  500. * @var string Class used for Media RSS <media:copyright>
  501. * @see SimplePie::set_copyright_class()
  502. * @access private
  503. */
  504. var $copyright_class = 'SimplePie_Copyright';
  505. /**
  506. * @var string Class used for Media RSS <media:credit>
  507. * @see SimplePie::set_credit_class()
  508. * @access private
  509. */
  510. var $credit_class = 'SimplePie_Credit';
  511. /**
  512. * @var string Class used for Media RSS <media:rating>
  513. * @see SimplePie::set_rating_class()
  514. * @access private
  515. */
  516. var $rating_class = 'SimplePie_Rating';
  517. /**
  518. * @var string Class used for Media RSS <media:restriction>
  519. * @see SimplePie::set_restriction_class()
  520. * @access private
  521. */
  522. var $restriction_class = 'SimplePie_Restriction';
  523. /**
  524. * @var string Class used for content-type sniffing
  525. * @see SimplePie::set_content_type_sniffer_class()
  526. * @access private
  527. */
  528. var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
  529. /**
  530. * @var string Class used for item sources.
  531. * @see SimplePie::set_source_class()
  532. * @access private
  533. */
  534. var $source_class = 'SimplePie_Source';
  535. /**
  536. * @var mixed Set javascript query string parameter (false, or
  537. * anything type-cast to false, disables this feature)
  538. * @see SimplePie::set_javascript()
  539. * @access private
  540. */
  541. var $javascript = 'js';
  542. /**
  543. * @var int Maximum number of feeds to check with autodiscovery
  544. * @see SimplePie::set_max_checked_feeds()
  545. * @access private
  546. */
  547. var $max_checked_feeds = 10;
  548. /**
  549. * @var array All the feeds found during the autodiscovery process
  550. * @see SimplePie::get_all_discovered_feeds()
  551. * @access private
  552. */
  553. var $all_discovered_feeds = array();
  554. /**
  555. * @var string Web-accessible path to the handler_favicon.php file.
  556. * @see SimplePie::set_favicon_handler()
  557. * @access private
  558. */
  559. var $favicon_handler = '';
  560. /**
  561. * @var string Web-accessible path to the handler_image.php file.
  562. * @see SimplePie::set_image_handler()
  563. * @access private
  564. */
  565. var $image_handler = '';
  566. /**
  567. * @var array Stores the URLs when multiple feeds are being initialized.
  568. * @see SimplePie::set_feed_url()
  569. * @access private
  570. */
  571. var $multifeed_url = array();
  572. /**
  573. * @var array Stores SimplePie objects when multiple feeds initialized.
  574. * @access private
  575. */
  576. var $multifeed_objects = array();
  577. /**
  578. * @var array Stores the get_object_vars() array for use with multifeeds.
  579. * @see SimplePie::set_feed_url()
  580. * @access private
  581. */
  582. var $config_settings = null;
  583. /**
  584. * @var integer Stores the number of items to return per-feed with multifeeds.
  585. * @see SimplePie::set_item_limit()
  586. * @access private
  587. */
  588. var $item_limit = 0;
  589. /**
  590. * @var array Stores the default attributes to be stripped by strip_attributes().
  591. * @see SimplePie::strip_attributes()
  592. * @access private
  593. */
  594. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  595. /**
  596. * @var array Stores the default tags to be stripped by strip_htmltags().
  597. * @see SimplePie::strip_htmltags()
  598. * @access private
  599. */
  600. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  601. /**
  602. * The SimplePie class contains feed level data and options
  603. *
  604. * There are two ways that you can create a new SimplePie object. The first
  605. * is by passing a feed URL as a parameter to the SimplePie constructor
  606. * (as well as optionally setting the cache location and cache expiry). This
  607. * will initialise the whole feed with all of the default settings, and you
  608. * can begin accessing methods and properties immediately.
  609. *
  610. * The second way is to create the SimplePie object with no parameters
  611. * at all. This will enable you to set configuration options. After setting
  612. * them, you must initialise the feed using $feed->init(). At that point the
  613. * object's methods and properties will be available to you. This format is
  614. * what is used throughout this documentation.
  615. *
  616. * @access public
  617. * @since 1.0 Preview Release
  618. * @param string $feed_url This is the URL you want to parse.
  619. * @param string $cache_location This is where you want the cache to be stored.
  620. * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
  621. */
  622. function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
  623. {
  624. // Other objects, instances created here so we can set options on them
  625. $this->sanitize =& new SimplePie_Sanitize;
  626. // Set options if they're passed to the constructor
  627. if ($cache_location !== null)
  628. {
  629. $this->set_cache_location($cache_location);
  630. }
  631. if ($cache_duration !== null)
  632. {
  633. $this->set_cache_duration($cache_duration);
  634. }
  635. // Only init the script if we're passed a feed URL
  636. if ($feed_url !== null)
  637. {
  638. $this->set_feed_url($feed_url);
  639. $this->init();
  640. }
  641. }
  642. /**
  643. * Used for converting object to a string
  644. */
  645. function __toString()
  646. {
  647. return md5(serialize($this->data));
  648. }
  649. /**
  650. * Remove items that link back to this before destroying this object
  651. */
  652. function __destruct()
  653. {
  654. if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
  655. {
  656. if (!empty($this->data['items']))
  657. {
  658. foreach ($this->data['items'] as $item)
  659. {
  660. $item->__destruct();
  661. }
  662. unset($item, $this->data['items']);
  663. }
  664. if (!empty($this->data['ordered_items']))
  665. {
  666. foreach ($this->data['ordered_items'] as $item)
  667. {
  668. $item->__destruct();
  669. }
  670. unset($item, $this->data['ordered_items']);
  671. }
  672. }
  673. }
  674. /**
  675. * Force the given data/URL to be treated as a feed no matter what it
  676. * appears like
  677. *
  678. * @access public
  679. * @since 1.1
  680. * @param bool $enable Force the given data/URL to be treated as a feed
  681. */
  682. function force_feed($enable = false)
  683. {
  684. $this->force_feed = (bool) $enable;
  685. }
  686. /**
  687. * This is the URL of the feed you want to parse.
  688. *
  689. * This allows you to enter the URL of the feed you want to parse, or the
  690. * website you want to try to use auto-discovery on. This takes priority
  691. * over any set raw data.
  692. *
  693. * You can set multiple feeds to mash together by passing an array instead
  694. * of a string for the $url. Remember that with each additional feed comes
  695. * additional processing and resources.
  696. *
  697. * @access public
  698. * @since 1.0 Preview Release
  699. * @param mixed $url This is the URL (or array of URLs) that you want to parse.
  700. * @see SimplePie::set_raw_data()
  701. */
  702. function set_feed_url($url)
  703. {
  704. if (is_array($url))
  705. {
  706. $this->multifeed_url = array();
  707. foreach ($url as $value)
  708. {
  709. $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
  710. }
  711. }
  712. else
  713. {
  714. $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
  715. }
  716. }
  717. /**
  718. * Provides an instance of SimplePie_File to use as a feed
  719. *
  720. * @access public
  721. * @param object &$file Instance of SimplePie_File (or subclass)
  722. * @return bool True on success, false on failure
  723. */
  724. function set_file(&$file)
  725. {
  726. if (is_a($file, 'SimplePie_File'))
  727. {
  728. $this->feed_url = $file->url;
  729. $this->file =& $file;
  730. return true;
  731. }
  732. return false;
  733. }
  734. /**
  735. * Allows you to use a string of RSS/Atom data instead of a remote feed.
  736. *
  737. * If you have a feed available as a string in PHP, you can tell SimplePie
  738. * to parse that data string instead of a remote feed. Any set feed URL
  739. * takes precedence.
  740. *
  741. * @access public
  742. * @since 1.0 Beta 3
  743. * @param string $data RSS or Atom data as a string.
  744. * @see SimplePie::set_feed_url()
  745. */
  746. function set_raw_data($data)
  747. {
  748. $this->raw_data = $data;
  749. }
  750. /**
  751. * Allows you to override the default timeout for fetching remote feeds.
  752. *
  753. * This allows you to change the maximum time the feed's server to respond
  754. * and send the feed back.
  755. *
  756. * @access public
  757. * @since 1.0 Beta 3
  758. * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
  759. */
  760. function set_timeout($timeout = 10)
  761. {
  762. $this->timeout = (int) $timeout;
  763. }
  764. /**
  765. * Forces SimplePie to use fsockopen() instead of the preferred cURL
  766. * functions.
  767. *
  768. * @access public
  769. * @since 1.0 Beta 3
  770. * @param bool $enable Force fsockopen() to be used
  771. */
  772. function force_fsockopen($enable = false)
  773. {
  774. $this->force_fsockopen = (bool) $enable;
  775. }
  776. /**
  777. * Outputs the raw XML content of the feed, after it has gone through
  778. * SimplePie's filters.
  779. *
  780. * Used only for debugging, this function will output the XML content as
  781. * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
  782. * before trying to parse it. Many parts of the feed are re-written in
  783. * memory, and in the end, you have a parsable feed. XML dump shows you the
  784. * actual XML that SimplePie tries to parse, which may or may not be very
  785. * different from the original feed.
  786. *
  787. * @access public
  788. * @since 1.0 Preview Release
  789. * @param bool $enable Enable XML dump
  790. */
  791. function enable_xml_dump($enable = false)
  792. {
  793. $this->xml_dump = (bool) $enable;
  794. }
  795. /**
  796. * Enables/disables caching in SimplePie.
  797. *
  798. * This option allows you to disable caching all-together in SimplePie.
  799. * However, disabling the cache can lead to longer load times.
  800. *
  801. * @access public
  802. * @since 1.0 Preview Release
  803. * @param bool $enable Enable caching
  804. */
  805. function enable_cache($enable = true)
  806. {
  807. $this->cache = (bool) $enable;
  808. }
  809. /**
  810. * Set the length of time (in seconds) that the contents of a feed
  811. * will be cached.
  812. *
  813. * @access public
  814. * @param int $seconds The feed content cache duration.
  815. */
  816. function set_cache_duration($seconds = 3600)
  817. {
  818. $this->cache_duration = (int) $seconds;
  819. }
  820. /**
  821. * Set the length of time (in seconds) that the autodiscovered feed
  822. * URL will be cached.
  823. *
  824. * @access public
  825. * @param int $seconds The autodiscovered feed URL cache duration.
  826. */
  827. function set_autodiscovery_cache_duration($seconds = 604800)
  828. {
  829. $this->autodiscovery_cache_duration = (int) $seconds;
  830. }
  831. /**
  832. * Set the file system location where the cached files should be stored.
  833. *
  834. * @access public
  835. * @param string $location The file system location.
  836. */
  837. function set_cache_location($location = './cache')
  838. {
  839. $this->cache_location = (string) $location;
  840. }
  841. /**
  842. * Determines whether feed items should be sorted into reverse chronological order.
  843. *
  844. * @access public
  845. * @param bool $enable Sort as reverse chronological order.
  846. */
  847. function enable_order_by_date($enable = true)
  848. {
  849. $this->order_by_date = (bool) $enable;
  850. }
  851. /**
  852. * Allows you to override the character encoding reported by the feed.
  853. *
  854. * @access public
  855. * @param string $encoding Character encoding.
  856. */
  857. function set_input_encoding($encoding = false)
  858. {
  859. if ($encoding)
  860. {
  861. $this->input_encoding = (string) $encoding;
  862. }
  863. else
  864. {
  865. $this->input_encoding = false;
  866. }
  867. }
  868. /**
  869. * Set how much feed autodiscovery to do
  870. *
  871. * @access public
  872. * @see SIMPLEPIE_LOCATOR_NONE
  873. * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
  874. * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
  875. * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
  876. * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
  877. * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
  878. * @see SIMPLEPIE_LOCATOR_ALL
  879. * @param int $level Feed Autodiscovery Level (level can be a
  880. * combination of the above constants, see bitwise OR operator)
  881. */
  882. function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
  883. {
  884. $this->autodiscovery = (int) $level;
  885. }
  886. /**
  887. * Allows you to change which class SimplePie uses for caching.
  888. * Useful when you are overloading or extending SimplePie's default classes.
  889. *
  890. * @access public
  891. * @param string $class Name of custom class.
  892. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  893. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  894. */
  895. function set_cache_class($class = 'SimplePie_Cache')
  896. {
  897. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
  898. {
  899. $this->cache_class = $class;
  900. return true;
  901. }
  902. return false;
  903. }
  904. /**
  905. * Allows you to change which class SimplePie uses for auto-discovery.
  906. * Useful when you are overloading or extending SimplePie's default classes.
  907. *
  908. * @access public
  909. * @param string $class Name of custom class.
  910. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  911. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  912. */
  913. function set_locator_class($class = 'SimplePie_Locator')
  914. {
  915. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
  916. {
  917. $this->locator_class = $class;
  918. return true;
  919. }
  920. return false;
  921. }
  922. /**
  923. * Allows you to change which class SimplePie uses for XML parsing.
  924. * Useful when you are overloading or extending SimplePie's default classes.
  925. *
  926. * @access public
  927. * @param string $class Name of custom class.
  928. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  929. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  930. */
  931. function set_parser_class($class = 'SimplePie_Parser')
  932. {
  933. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
  934. {
  935. $this->parser_class = $class;
  936. return true;
  937. }
  938. return false;
  939. }
  940. /**
  941. * Allows you to change which class SimplePie uses for remote file fetching.
  942. * Useful when you are overloading or extending SimplePie's default classes.
  943. *
  944. * @access public
  945. * @param string $class Name of custom class.
  946. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  947. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  948. */
  949. function set_file_class($class = 'SimplePie_File')
  950. {
  951. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
  952. {
  953. $this->file_class = $class;
  954. return true;
  955. }
  956. return false;
  957. }
  958. /**
  959. * Allows you to change which class SimplePie uses for data sanitization.
  960. * Useful when you are overloading or extending SimplePie's default classes.
  961. *
  962. * @access public
  963. * @param string $class Name of custom class.
  964. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  965. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  966. */
  967. function set_sanitize_class($class = 'SimplePie_Sanitize')
  968. {
  969. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
  970. {
  971. $this->sanitize =& new $class;
  972. return true;
  973. }
  974. return false;
  975. }
  976. /**
  977. * Allows you to change which class SimplePie uses for handling feed items.
  978. * Useful when you are overloading or extending SimplePie's default classes.
  979. *
  980. * @access public
  981. * @param string $class Name of custom class.
  982. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  983. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  984. */
  985. function set_item_class($class = 'SimplePie_Item')
  986. {
  987. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
  988. {
  989. $this->item_class = $class;
  990. return true;
  991. }
  992. return false;
  993. }
  994. /**
  995. * Allows you to change which class SimplePie uses for handling author data.
  996. * Useful when you are overloading or extending SimplePie's default classes.
  997. *
  998. * @access public
  999. * @param string $class Name of custom class.
  1000. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1001. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1002. */
  1003. function set_author_class($class = 'SimplePie_Author')
  1004. {
  1005. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
  1006. {
  1007. $this->author_class = $class;
  1008. return true;
  1009. }
  1010. return false;
  1011. }
  1012. /**
  1013. * Allows you to change which class SimplePie uses for handling category data.
  1014. * Useful when you are overloading or extending SimplePie's default classes.
  1015. *
  1016. * @access public
  1017. * @param string $class Name of custom class.
  1018. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1019. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1020. */
  1021. function set_category_class($class = 'SimplePie_Category')
  1022. {
  1023. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
  1024. {
  1025. $this->category_class = $class;
  1026. return true;
  1027. }
  1028. return false;
  1029. }
  1030. /**
  1031. * Allows you to change which class SimplePie uses for feed enclosures.
  1032. * Useful when you are overloading or extending SimplePie's default classes.
  1033. *
  1034. * @access public
  1035. * @param string $class Name of custom class.
  1036. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1037. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1038. */
  1039. function set_enclosure_class($class = 'SimplePie_Enclosure')
  1040. {
  1041. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
  1042. {
  1043. $this->enclosure_class = $class;
  1044. return true;
  1045. }
  1046. return false;
  1047. }
  1048. /**
  1049. * Allows you to change which class SimplePie uses for <media:text> captions
  1050. * Useful when you are overloading or extending SimplePie's default classes.
  1051. *
  1052. * @access public
  1053. * @param string $class Name of custom class.
  1054. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1055. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1056. */
  1057. function set_caption_class($class = 'SimplePie_Caption')
  1058. {
  1059. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
  1060. {
  1061. $this->caption_class = $class;
  1062. return true;
  1063. }
  1064. return false;
  1065. }
  1066. /**
  1067. * Allows you to change which class SimplePie uses for <media:copyright>
  1068. * Useful when you are overloading or extending SimplePie's default classes.
  1069. *
  1070. * @access public
  1071. * @param string $class Name of custom class.
  1072. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1073. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1074. */
  1075. function set_copyright_class($class = 'SimplePie_Copyright')
  1076. {
  1077. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
  1078. {
  1079. $this->copyright_class = $class;
  1080. return true;
  1081. }
  1082. return false;
  1083. }
  1084. /**
  1085. * Allows you to change which class SimplePie uses for <media:credit>
  1086. * Useful when you are overloading or extending SimplePie's default classes.
  1087. *
  1088. * @access public
  1089. * @param string $class Name of custom class.
  1090. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1091. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1092. */
  1093. function set_credit_class($class = 'SimplePie_Credit')
  1094. {
  1095. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
  1096. {
  1097. $this->credit_class = $class;
  1098. return true;
  1099. }
  1100. return false;
  1101. }
  1102. /**
  1103. * Allows you to change which class SimplePie uses for <media:rating>
  1104. * Useful when you are overloading or extending SimplePie's default classes.
  1105. *
  1106. * @access public
  1107. * @param string $class Name of custom class.
  1108. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1109. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1110. */
  1111. function set_rating_class($class = 'SimplePie_Rating')
  1112. {
  1113. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
  1114. {
  1115. $this->rating_class = $class;
  1116. return true;
  1117. }
  1118. return false;
  1119. }
  1120. /**
  1121. * Allows you to change which class SimplePie uses for <media:restriction>
  1122. * Useful when you are overloading or extending SimplePie's default classes.
  1123. *
  1124. * @access public
  1125. * @param string $class Name of custom class.
  1126. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1127. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1128. */
  1129. function set_restriction_class($class = 'SimplePie_Restriction')
  1130. {
  1131. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
  1132. {
  1133. $this->restriction_class = $class;
  1134. return true;
  1135. }
  1136. return false;
  1137. }
  1138. /**
  1139. * Allows you to change which class SimplePie uses for content-type sniffing.
  1140. * Useful when you are overloading or extending SimplePie's default classes.
  1141. *
  1142. * @access public
  1143. * @param string $class Name of custom class.
  1144. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1145. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1146. */
  1147. function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
  1148. {
  1149. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
  1150. {
  1151. $this->content_type_sniffer_class = $class;
  1152. return true;
  1153. }
  1154. return false;
  1155. }
  1156. /**
  1157. * Allows you to change which class SimplePie uses item sources.
  1158. * Useful when you are overloading or extending SimplePie's default classes.
  1159. *
  1160. * @access public
  1161. * @param string $class Name of custom class.
  1162. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1163. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1164. */
  1165. function set_source_class($class = 'SimplePie_Source')
  1166. {
  1167. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
  1168. {
  1169. $this->source_class = $class;
  1170. return true;
  1171. }
  1172. return false;
  1173. }
  1174. /**
  1175. * Allows you to override the default user agent string.
  1176. *
  1177. * @access public
  1178. * @param string $ua New user agent string.
  1179. */
  1180. function set_useragent($ua = SIMPLEPIE_USERAGENT)
  1181. {
  1182. $this->useragent = (string) $ua;
  1183. }
  1184. /**
  1185. * Set callback function to create cache filename with
  1186. *
  1187. * @access public
  1188. * @param mixed $function Callback function
  1189. */
  1190. function set_cache_name_function($function = 'md5')
  1191. {
  1192. if (is_callable($function))
  1193. {
  1194. $this->cache_name_function = $function;
  1195. }
  1196. }
  1197. /**
  1198. * Set javascript query string parameter
  1199. *
  1200. * @access public
  1201. * @param mixed $get Javascript query string parameter
  1202. */
  1203. function set_javascript($get = 'js')
  1204. {
  1205. if ($get)
  1206. {
  1207. $this->javascript = (string) $get;
  1208. }
  1209. else
  1210. {
  1211. $this->javascript = false;
  1212. }
  1213. }
  1214. /**
  1215. * Set options to make SP as fast as possible. Forgoes a
  1216. * substantial amount of data sanitization in favor of speed.
  1217. *
  1218. * @access public
  1219. * @param bool $set Whether to set them or not
  1220. */
  1221. function set_stupidly_fast($set = false)
  1222. {
  1223. if ($set)
  1224. {
  1225. $this->enable_order_by_date(false);
  1226. $this->remove_div(false);
  1227. $this->strip_comments(false);
  1228. $this->strip_htmltags(false);
  1229. $this->strip_attributes(false);
  1230. $this->set_image_handler(false);
  1231. }
  1232. }
  1233. /**
  1234. * Set maximum number of feeds to check with autodiscovery
  1235. *
  1236. * @access public
  1237. * @param int $max Maximum number of feeds to check
  1238. */
  1239. function set_max_checked_feeds($max = 10)
  1240. {
  1241. $this->max_checked_feeds = (int) $max;
  1242. }
  1243. function remove_div($enable = true)
  1244. {
  1245. $this->sanitize->remove_div($enable);
  1246. }
  1247. function strip_htmltags($tags = '', $encode = null)
  1248. {
  1249. if ($tags === '')
  1250. {
  1251. $tags = $this->strip_htmltags;
  1252. }
  1253. $this->sanitize->strip_htmltags($tags);
  1254. if ($encode !== null)
  1255. {
  1256. $this->sanitize->encode_instead_of_strip($tags);
  1257. }
  1258. }
  1259. function encode_instead_of_strip($enable = true)
  1260. {
  1261. $this->sanitize->encode_instead_of_strip($enable);
  1262. }
  1263. function strip_attributes($attribs = '')
  1264. {
  1265. if ($attribs === '')
  1266. {
  1267. $attribs = $this->strip_attributes;
  1268. }
  1269. $this->sanitize->strip_attributes($attribs);
  1270. }
  1271. function set_output_encoding($encoding = 'UTF-8')
  1272. {
  1273. $this->sanitize->set_output_encoding($encoding);
  1274. }
  1275. function strip_comments($strip = false)
  1276. {
  1277. $this->sanitize->strip_comments($strip);
  1278. }
  1279. /**
  1280. * Set element/attribute key/value pairs of HTML attributes
  1281. * containing URLs that need to be resolved relative to the feed
  1282. *
  1283. * @access public
  1284. * @since 1.0
  1285. * @param array $element_attribute Element/attribute key/value pairs
  1286. */
  1287. 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'))
  1288. {
  1289. $this->sanitize->set_url_replacements($element_attribute);
  1290. }
  1291. /**
  1292. * Set the handler to enable the display of cached favicons.
  1293. *
  1294. * @access public
  1295. * @param str $page Web-accessible path to the handler_favicon.php file.
  1296. * @param str $qs The query string that the value should be passed to.
  1297. */
  1298. function set_favicon_handler($page = false, $qs = 'i')
  1299. {
  1300. if ($page !== false)
  1301. {
  1302. $this->favicon_handler = $page . '?' . $qs . '=';
  1303. }
  1304. else
  1305. {
  1306. $this->favicon_handler = '';
  1307. }
  1308. }
  1309. /**
  1310. * Set the handler to enable the display of cached images.
  1311. *
  1312. * @access public
  1313. * @param str $page Web-accessible path to the handler_image.php file.
  1314. * @param str $qs The query string that the value should be passed to.
  1315. */
  1316. function set_image_handler($page = false, $qs = 'i')
  1317. {
  1318. if ($page !== false)
  1319. {
  1320. $this->sanitize->set_image_handler($page . '?' . $qs . '=');
  1321. }
  1322. else
  1323. {
  1324. $this->image_handler = '';
  1325. }
  1326. }
  1327. /**
  1328. * Set the limit for items returned per-feed with multifeeds.
  1329. *
  1330. * @access public
  1331. * @param integer $limit The maximum number of items to return.
  1332. */
  1333. function set_item_limit($limit = 0)
  1334. {
  1335. $this->item_limit = (int) $limit;
  1336. }
  1337. function init()
  1338. {
  1339. // Check absolute bare minimum requirements.
  1340. if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
  1341. {
  1342. return false;
  1343. }
  1344. // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader.
  1345. elseif (!extension_loaded('xmlreader'))
  1346. {
  1347. static $xml_is_sane = null;
  1348. if ($xml_is_sane === null)
  1349. {
  1350. $parser_check = xml_parser_create();
  1351. xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
  1352. xml_parser_free($parser_check);
  1353. $xml_is_sane = isset($values[0]['value']);
  1354. }
  1355. if (!$xml_is_sane)
  1356. {
  1357. return false;
  1358. }
  1359. }
  1360. if (isset($_GET[$this->javascript]))
  1361. {
  1362. SimplePie_Misc::output_javascript();
  1363. exit;
  1364. }
  1365. // Pass whatever was set with config options over to the sanitizer.
  1366. $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
  1367. $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
  1368. if ($this->feed_url !== null || $this->raw_data !== null)
  1369. {
  1370. $this->data = array();
  1371. $this->multifeed_objects = array();
  1372. $cache = false;
  1373. if ($this->feed_url !== null)
  1374. {
  1375. $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
  1376. // Decide whether to enable caching
  1377. if ($this->cache && $parsed_feed_url['scheme'] !== '')
  1378. {
  1379. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
  1380. }
  1381. // If it's enabled and we don't want an XML dump, use the cache
  1382. if ($cache && !$this->xml_dump)
  1383. {
  1384. // Load the Cache
  1385. $this->data = $cache->load();
  1386. if (!empty($this->data))
  1387. {
  1388. // If the cache is for an outdated build of SimplePie
  1389. if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
  1390. {
  1391. $cache->unlink();
  1392. $this->data = array();
  1393. }
  1394. // If we've hit a collision just rerun it with caching disabled
  1395. elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
  1396. {
  1397. $cache = false;
  1398. $this->data = array();
  1399. }
  1400. // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
  1401. elseif (isset($this->data['feed_url']))
  1402. {
  1403. // If the autodiscovery cache is still valid use it.
  1404. if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
  1405. {
  1406. // Do not need to do feed autodiscovery yet.
  1407. if ($this->data['feed_url'] === $this->data['url'])
  1408. {
  1409. $cache->unlink();
  1410. $this->data = array();
  1411. }
  1412. else
  1413. {
  1414. $this->set_feed_url($this->data['feed_url']);
  1415. return $this->init();
  1416. }
  1417. }
  1418. }
  1419. // Check if the cache has been updated
  1420. elseif ($cache->mtime() + $this->cache_duration < time())
  1421. {
  1422. // If we have last-modified and/or etag set
  1423. if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
  1424. {
  1425. $headers = array();
  1426. if (isset($this->data['headers']['last-modified']))
  1427. {
  1428. $headers['if-modified-since'] = $this->data['headers']['last-modified'];
  1429. }
  1430. if (isset($this->data['headers']['etag']))
  1431. {
  1432. $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
  1433. }
  1434. $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
  1435. if ($file->success)
  1436. {
  1437. if ($file->status_code === 304)
  1438. {
  1439. $cache->touch();
  1440. return true;
  1441. }
  1442. else
  1443. {
  1444. $headers = $file->headers;
  1445. }
  1446. }
  1447. else
  1448. {
  1449. unset($file);
  1450. }
  1451. }
  1452. }
  1453. // If the cache is still valid, just return true
  1454. else
  1455. {
  1456. return true;
  1457. }
  1458. }
  1459. // If the cache is empty, delete it
  1460. else
  1461. {
  1462. $cache->unlink();
  1463. $this->data = array();
  1464. }
  1465. }
  1466. // 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.
  1467. if (!isset($file))
  1468. {
  1469. if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url)
  1470. {
  1471. $file =& $this->file;
  1472. }
  1473. else
  1474. {
  1475. $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
  1476. }
  1477. }
  1478. // If the file connection has an error, set SimplePie::error to that and quit
  1479. if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
  1480. {
  1481. $this->error = $file->error;
  1482. if (!empty($this->data))
  1483. {
  1484. return true;
  1485. }
  1486. else
  1487. {
  1488. return false;
  1489. }
  1490. }
  1491. if (!$this->force_feed)
  1492. {
  1493. // Check if the supplied URL is a feed, if it isn't, look for it.
  1494. $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
  1495. if (!$locate->is_feed($file))
  1496. {
  1497. // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
  1498. unset($file);
  1499. if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))
  1500. {
  1501. if ($cache)
  1502. {
  1503. $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
  1504. if (!$cache->save($this))
  1505. {
  1506. trigger_error("$this->cache_location is not writeable", E_USER_WARNING);
  1507. }
  1508. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
  1509. }
  1510. $this->feed_url = $file->url;
  1511. }
  1512. else
  1513. {
  1514. $this->error = "A feed could not be found at $this->feed_url";
  1515. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1516. return false;
  1517. }
  1518. }
  1519. $locate = null;
  1520. }
  1521. $headers = $file->headers;
  1522. $data = $file->body;
  1523. $sniffer =& new $this->content_type_sniffer_class($file);
  1524. $sniffed = $sniffer->get_type();
  1525. }
  1526. else
  1527. {
  1528. $data = $this->raw_data;
  1529. }
  1530. // Set up array of possible encodings
  1531. $encodings = array();
  1532. // First check to see if input has been overridden.
  1533. if ($this->input_encoding !== false)
  1534. {
  1535. $encodings[] = $this->input_encoding;
  1536. }
  1537. $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
  1538. $text_types = array('text/xml', 'text/xml-external-parsed-entity');
  1539. // RFC 3023 (only applies to sniffed content)
  1540. if (isset($sniffed))
  1541. {
  1542. if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
  1543. {
  1544. if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  1545. {
  1546. $encodings[] = strtoupper($charset[1]);
  1547. }
  1548. $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
  1549. $encodings[] = 'UTF-8';
  1550. }
  1551. elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
  1552. {
  1553. if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  1554. {
  1555. $encodings[] = $charset[1];
  1556. }
  1557. $encodings[] = 'US-ASCII';
  1558. }
  1559. // Text MIME-type default
  1560. elseif (substr($sniffed, 0, 5) === 'text/')
  1561. {
  1562. $encodings[] = 'US-ASCII';
  1563. }
  1564. }
  1565. // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
  1566. $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
  1567. $encodings[] = 'UTF-8';
  1568. $encodings[] = 'ISO-8859-1';
  1569. // There's no point in trying an encoding twice
  1570. $encodings = array_unique($encodings);
  1571. // If we want the XML, just output that with the most likely encoding and quit
  1572. if ($this->xml_dump)
  1573. {
  1574. header('Content-type: text/xml; charset=' . $encodings[0]);
  1575. echo $data;
  1576. exit;
  1577. }
  1578. // Loop through each possible encoding, till we return something, or run out of possibilities
  1579. foreach ($encodings as $encoding)
  1580. {
  1581. // Change the encoding to UTF-8 (as we always use UTF-8 internally)
  1582. if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
  1583. {
  1584. // Create new parser
  1585. $parser =& new $this->parser_class();
  1586. // If it's parsed fine
  1587. if ($parser->parse($utf8_data, 'UTF-8'))
  1588. {
  1589. $this->data = $parser->get_data();
  1590. if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
  1591. {
  1592. if (isset($headers))
  1593. {
  1594. $this->data['headers'] = $headers;
  1595. }
  1596. $this->data['build'] = SIMPLEPIE_BUILD;
  1597. // Cache the file if caching is enabled
  1598. if ($cache && !$cache->save($this))
  1599. {
  1600. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1601. }
  1602. return true;
  1603. }
  1604. else
  1605. {
  1606. $this->error = "A feed could not be found at $this->feed_url";
  1607. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1608. return false;
  1609. }
  1610. }
  1611. }
  1612. }
  1613. if(isset($parser))
  1614. {
  1615. // We have an error, just set SimplePie_Misc::error to it and quit
  1616. $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
  1617. }
  1618. else
  1619. {
  1620. $this->error = 'The data could not be converted to UTF-8';
  1621. }
  1622. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1623. return false;
  1624. }
  1625. elseif (!empty($this->multifeed_url))
  1626. {
  1627. $i = 0;
  1628. $success = 0;
  1629. $this->multifeed_objects = array();
  1630. foreach ($this->multifeed_url as $url)
  1631. {
  1632. if (SIMPLEPIE_PHP5)
  1633. {
  1634. // This keyword needs to defy coding standards for PHP4 compatibility
  1635. $this->multifeed_objects[$i] = clone($this);
  1636. }
  1637. else
  1638. {
  1639. $this->multifeed_objects[$i] = $this;
  1640. }
  1641. $this->multifeed_objects[$i]->set_feed_url($url);
  1642. $success |= $this->multifeed_objects[$i]->init();
  1643. $i++;
  1644. }
  1645. return (bool) $success;
  1646. }
  1647. else
  1648. {
  1649. return false;
  1650. }
  1651. }
  1652. /**
  1653. * Return the error message for the occurred error
  1654. *
  1655. * @access public
  1656. * @return string Error message
  1657. */
  1658. function error()
  1659. {
  1660. return $this->error;
  1661. }
  1662. function get_encoding()
  1663. {
  1664. return $this->sanitize->output_encoding;
  1665. }
  1666. function handle_content_type($mime = 'text/html')
  1667. {
  1668. if (!headers_sent())
  1669. {
  1670. $header = "Content-type: $mime;";
  1671. if ($this->get_encoding())
  1672. {
  1673. $header .= ' charset=' . $this->get_encoding();
  1674. }
  1675. else
  1676. {
  1677. $header .= ' charset=UTF-8';
  1678. }
  1679. header($header);
  1680. }
  1681. }
  1682. function get_type()
  1683. {
  1684. if (!isset($this->data['type']))
  1685. {
  1686. $this->data['type'] = SIMPLEPIE_TYPE_ALL;
  1687. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
  1688. {
  1689. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
  1690. }
  1691. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
  1692. {
  1693. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
  1694. }
  1695. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
  1696. {
  1697. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
  1698. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
  1699. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
  1700. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
  1701. {
  1702. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
  1703. }
  1704. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
  1705. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
  1706. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
  1707. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
  1708. {
  1709. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
  1710. }
  1711. }
  1712. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
  1713. {
  1714. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
  1715. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
  1716. {
  1717. switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
  1718. {
  1719. case '0.91':
  1720. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
  1721. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
  1722. {
  1723. switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
  1724. {
  1725. case '0':
  1726. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
  1727. break;
  1728. case '24':
  1729. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
  1730. break;
  1731. }
  1732. }
  1733. break;
  1734. case '0.92':
  1735. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
  1736. break;
  1737. case '0.93':
  1738. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
  1739. break;
  1740. case '0.94':
  1741. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
  1742. break;
  1743. case '2.0':
  1744. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
  1745. break;
  1746. }
  1747. }
  1748. }
  1749. else
  1750. {
  1751. $this->data['type'] = SIMPLEPIE_TYPE_NONE;
  1752. }
  1753. }
  1754. return $this->data['type'];
  1755. }
  1756. /**
  1757. * Returns the URL for the favicon of the feed's website.
  1758. *
  1759. * @todo Cache atom:icon
  1760. * @access public
  1761. * @since 1.0
  1762. */
  1763. function get_favicon()
  1764. {
  1765. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  1766. {
  1767. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1768. }
  1769. elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
  1770. {
  1771. $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
  1772. if ($this->cache && $this->favicon_handler)
  1773. {
  1774. $favicon_filename = call_user_func($this->cache_name_function, $favicon);
  1775. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
  1776. if ($cache->load())
  1777. {
  1778. return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
  1779. }
  1780. else
  1781. {
  1782. $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
  1783. if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
  1784. {
  1785. $sniffer =& new $this->content_type_sniffer_class($file);
  1786. if (substr($sniffer->get_type(), 0, 6) === 'image/')
  1787. {
  1788. if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  1789. {
  1790. return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
  1791. }
  1792. else
  1793. {
  1794. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1795. return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
  1796. }
  1797. }
  1798. // not an image
  1799. else
  1800. {
  1801. return false;
  1802. }
  1803. }
  1804. }
  1805. }
  1806. else
  1807. {
  1808. return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
  1809. }
  1810. }
  1811. return false;
  1812. }
  1813. /**
  1814. * @todo If we have a perm redirect we should return the new URL
  1815. * @todo When we make the above change, let's support <itunes:new-feed-url> as well
  1816. * @todo Also, |atom:link|@rel=self
  1817. */
  1818. function subscribe_url()
  1819. {
  1820. if ($this->feed_url !== null)
  1821. {
  1822. return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
  1823. }
  1824. else
  1825. {
  1826. return null;
  1827. }
  1828. }
  1829. function subscribe_feed()
  1830. {
  1831. if ($this->feed_url !== null)
  1832. {
  1833. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
  1834. }
  1835. else
  1836. {
  1837. return null;
  1838. }
  1839. }
  1840. function subscribe_outlook()
  1841. {
  1842. if ($this->feed_url !== null)
  1843. {
  1844. return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
  1845. }
  1846. else
  1847. {
  1848. return null;
  1849. }
  1850. }
  1851. function subscribe_podcast()
  1852. {
  1853. if ($this->feed_url !== null)
  1854. {
  1855. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
  1856. }
  1857. else
  1858. {
  1859. return null;
  1860. }
  1861. }
  1862. function subscribe_itunes()
  1863. {
  1864. if ($this->feed_url !== null)
  1865. {
  1866. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
  1867. }
  1868. else
  1869. {
  1870. return null;
  1871. }
  1872. }
  1873. /**
  1874. * Creates the subscribe_* methods' return data
  1875. *
  1876. * @access private
  1877. * @param string $feed_url String to prefix to the feed URL
  1878. * @param string $site_url String to prefix to the site URL (and
  1879. * suffix to the feed URL)
  1880. * @return mixed URL if feed exists, false otherwise
  1881. */
  1882. function subscribe_service($feed_url, $site_url = null)
  1883. {
  1884. if ($this->subscribe_url())
  1885. {
  1886. $return = $feed_url . rawurlencode($this->feed_url);
  1887. if ($site_url !== null && $this->get_link() !== null)
  1888. {
  1889. $return .= $site_url . rawurlencode($this->get_link());
  1890. }
  1891. return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
  1892. }
  1893. else
  1894. {
  1895. return null;
  1896. }
  1897. }
  1898. function subscribe_aol()
  1899. {
  1900. return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
  1901. }
  1902. function subscribe_bloglines()
  1903. {
  1904. return $this->subscribe_service('http://www.bloglines.com/sub/');
  1905. }
  1906. function subscribe_eskobo()
  1907. {
  1908. return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
  1909. }
  1910. function subscribe_feedfeeds()
  1911. {
  1912. return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
  1913. }
  1914. function subscribe_feedster()
  1915. {
  1916. return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
  1917. }
  1918. function subscribe_google()
  1919. {
  1920. return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
  1921. }
  1922. function subscribe_gritwire()
  1923. {
  1924. return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
  1925. }
  1926. function subscribe_msn()
  1927. {
  1928. return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
  1929. }
  1930. function subscribe_netvibes()
  1931. {
  1932. return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
  1933. }
  1934. function subscribe_newsburst()
  1935. {
  1936. return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
  1937. }
  1938. function subscribe_newsgator()
  1939. {
  1940. return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
  1941. }
  1942. function subscribe_odeo()
  1943. {
  1944. return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
  1945. }
  1946. function subscribe_podnova()
  1947. {
  1948. return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
  1949. }
  1950. function subscribe_rojo()
  1951. {
  1952. return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
  1953. }
  1954. function subscribe_yahoo()
  1955. {
  1956. return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
  1957. }
  1958. function get_feed_tags($namespace, $tag)
  1959. {
  1960. $type = $this->get_type();
  1961. if ($type & SIMPLEPIE_TYPE_ATOM_10)
  1962. {
  1963. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
  1964. {
  1965. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
  1966. }
  1967. }
  1968. if ($type & SIMPLEPIE_TYPE_ATOM_03)
  1969. {
  1970. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
  1971. {
  1972. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
  1973. }
  1974. }
  1975. if ($type & SIMPLEPIE_TYPE_RSS_RDF)
  1976. {
  1977. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
  1978. {
  1979. return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
  1980. }
  1981. }
  1982. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  1983. {
  1984. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
  1985. {
  1986. return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
  1987. }
  1988. }
  1989. return null;
  1990. }
  1991. function get_channel_tags($namespace, $tag)
  1992. {
  1993. $type = $this->get_type();
  1994. if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
  1995. {
  1996. if ($return = $this->get_feed_tags($namespace, $tag))
  1997. {
  1998. return $return;
  1999. }
  2000. }
  2001. if ($type & SIMPLEPIE_TYPE_RSS_10)
  2002. {
  2003. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
  2004. {
  2005. if (isset($channel[0]['child'][$namespace][$tag]))
  2006. {
  2007. return $channel[0]['child'][$namespace][$tag];
  2008. }
  2009. }
  2010. }
  2011. if ($type & SIMPLEPIE_TYPE_RSS_090)
  2012. {
  2013. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
  2014. {
  2015. if (isset($channel[0]['child'][$namespace][$tag]))
  2016. {
  2017. return $channel[0]['child'][$namespace][$tag];
  2018. }
  2019. }
  2020. }
  2021. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  2022. {
  2023. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
  2024. {
  2025. if (isset($channel[0]['child'][$namespace][$tag]))
  2026. {
  2027. return $channel[0]['child'][$namespace][$tag];
  2028. }
  2029. }
  2030. }
  2031. return null;
  2032. }
  2033. function get_image_tags($namespace, $tag)
  2034. {
  2035. $type = $this->get_type();
  2036. if ($type & SIMPLEPIE_TYPE_RSS_10)
  2037. {
  2038. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
  2039. {
  2040. if (isset($image[0]['child'][$namespace][$tag]))
  2041. {
  2042. return $image[0]['child'][$namespace][$tag];
  2043. }
  2044. }
  2045. }
  2046. if ($type & SIMPLEPIE_TYPE_RSS_090)
  2047. {
  2048. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
  2049. {
  2050. if (isset($image[0]['child'][$namespace][$tag]))
  2051. {
  2052. return $image[0]['child'][$namespace][$tag];
  2053. }
  2054. }
  2055. }
  2056. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  2057. {
  2058. if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
  2059. {
  2060. if (isset($image[0]['child'][$namespace][$tag]))
  2061. {
  2062. return $image[0]['child'][$namespace][$tag];
  2063. }
  2064. }
  2065. }
  2066. return null;
  2067. }
  2068. function get_base($element = array())
  2069. {
  2070. if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
  2071. {
  2072. return $element['xml_base'];
  2073. }
  2074. elseif ($this->get_link() !== null)
  2075. {
  2076. return $this->get_link();
  2077. }
  2078. else
  2079. {
  2080. return $this->subscribe_url();
  2081. }
  2082. }
  2083. function sanitize($data, $type, $base = '')
  2084. {
  2085. return $this->sanitize->sanitize($data, $type, $base);
  2086. }
  2087. function get_title()
  2088. {
  2089. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  2090. {
  2091. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2092. }
  2093. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  2094. {
  2095. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2096. }
  2097. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2098. {
  2099. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2100. }
  2101. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2102. {
  2103. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2104. }
  2105. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  2106. {
  2107. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2108. }
  2109. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2110. {
  2111. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2112. }
  2113. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2114. {
  2115. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2116. }
  2117. else
  2118. {
  2119. return null;
  2120. }
  2121. }
  2122. function get_category($key = 0)
  2123. {
  2124. $categories = $this->get_categories();
  2125. if (isset($categories[$key]))
  2126. {
  2127. return $categories[$key];
  2128. }
  2129. else
  2130. {
  2131. return null;
  2132. }
  2133. }
  2134. function get_categories()
  2135. {
  2136. $categories = array();
  2137. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  2138. {
  2139. $term = null;
  2140. $scheme = null;
  2141. $label = null;
  2142. if (isset($category['attribs']['']['term']))
  2143. {
  2144. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  2145. }
  2146. if (isset($category['attribs']['']['scheme']))
  2147. {
  2148. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  2149. }
  2150. if (isset($category['attribs']['']['label']))
  2151. {
  2152. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  2153. }
  2154. $categories[] =& new $this->category_class($term, $scheme, $label);
  2155. }
  2156. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
  2157. {
  2158. // This is really the label, but keep this as the term also for BC.
  2159. // Label will also work on retrieving because that falls back to term.
  2160. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2161. if (isset($category['attribs']['']['domain']))
  2162. {
  2163. $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
  2164. }
  2165. else
  2166. {
  2167. $scheme = null;
  2168. }
  2169. $categories[] =& new $this->category_class($term, $scheme, null);
  2170. }
  2171. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  2172. {
  2173. $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2174. }
  2175. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  2176. {
  2177. $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2178. }
  2179. if (!empty($categories))
  2180. {
  2181. return SimplePie_Misc::array_unique($categories);
  2182. }
  2183. else
  2184. {
  2185. return null;
  2186. }
  2187. }
  2188. function get_author($key = 0)
  2189. {
  2190. $authors = $this->get_authors();
  2191. if (isset($authors[$key]))
  2192. {
  2193. return $authors[$key];
  2194. }
  2195. else
  2196. {
  2197. return null;
  2198. }
  2199. }
  2200. function get_authors()
  2201. {
  2202. $authors = array();
  2203. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  2204. {
  2205. $name = null;
  2206. $uri = null;
  2207. $email = null;
  2208. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  2209. {
  2210. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2211. }
  2212. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  2213. {
  2214. $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]));
  2215. }
  2216. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  2217. {
  2218. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2219. }
  2220. if ($name !== null || $email !== null || $uri !== null)
  2221. {
  2222. $authors[] =& new $this->author_class($name, $uri, $email);
  2223. }
  2224. }
  2225. if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  2226. {
  2227. $name = null;
  2228. $url = null;
  2229. $email = null;
  2230. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  2231. {
  2232. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2233. }
  2234. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  2235. {
  2236. $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]));
  2237. }
  2238. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  2239. {
  2240. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2241. }
  2242. if ($name !== null || $email !== null || $url !== null)
  2243. {
  2244. $authors[] =& new $this->author_class($name, $url, $email);
  2245. }
  2246. }
  2247. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  2248. {
  2249. $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2250. }
  2251. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  2252. {
  2253. $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2254. }
  2255. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  2256. {
  2257. $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2258. }
  2259. if (!empty($authors))
  2260. {
  2261. return SimplePie_Misc::array_unique($authors);
  2262. }
  2263. else
  2264. {
  2265. return null;
  2266. }
  2267. }
  2268. function get_contributor($key = 0)
  2269. {
  2270. $contributors = $this->get_contributors();
  2271. if (isset($contributors[$key]))
  2272. {
  2273. return $contributors[$key];
  2274. }
  2275. else
  2276. {
  2277. return null;
  2278. }
  2279. }
  2280. function get_contributors()
  2281. {
  2282. $contributors = array();
  2283. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  2284. {
  2285. $name = null;
  2286. $uri = null;
  2287. $email = null;
  2288. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  2289. {
  2290. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2291. }
  2292. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  2293. {
  2294. $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]));
  2295. }
  2296. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  2297. {
  2298. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2299. }
  2300. if ($name !== null || $email !== null || $uri !== null)
  2301. {
  2302. $contributors[] =& new $this->author_class($name, $uri, $email);
  2303. }
  2304. }
  2305. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  2306. {
  2307. $name = null;
  2308. $url = null;
  2309. $email = null;
  2310. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  2311. {
  2312. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2313. }
  2314. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  2315. {
  2316. $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]));
  2317. }
  2318. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  2319. {
  2320. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2321. }
  2322. if ($name !== null || $email !== null || $url !== null)
  2323. {
  2324. $contributors[] =& new $this->author_class($name, $url, $email);
  2325. }
  2326. }
  2327. if (!empty($contributors))
  2328. {
  2329. return SimplePie_Misc::array_unique($contributors);
  2330. }
  2331. else
  2332. {
  2333. return null;
  2334. }
  2335. }
  2336. function get_link($key = 0, $rel = 'alternate')
  2337. {
  2338. $links = $this->get_links($rel);
  2339. if (isset($links[$key]))
  2340. {
  2341. return $links[$key];
  2342. }
  2343. else
  2344. {
  2345. return null;
  2346. }
  2347. }
  2348. /**
  2349. * Added for parity between the parent-level and the item/entry-level.
  2350. */
  2351. function get_permalink()
  2352. {
  2353. return $this->get_link(0);
  2354. }
  2355. function get_links($rel = 'alternate')
  2356. {
  2357. if (!isset($this->data['links']))
  2358. {
  2359. $this->data['links'] = array();
  2360. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  2361. {
  2362. foreach ($links as $link)
  2363. {
  2364. if (isset($link['attribs']['']['href']))
  2365. {
  2366. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2367. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2368. }
  2369. }
  2370. }
  2371. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  2372. {
  2373. foreach ($links as $link)
  2374. {
  2375. if (isset($link['attribs']['']['href']))
  2376. {
  2377. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2378. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2379. }
  2380. }
  2381. }
  2382. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2383. {
  2384. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2385. }
  2386. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2387. {
  2388. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2389. }
  2390. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  2391. {
  2392. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2393. }
  2394. $keys = array_keys($this->data['links']);
  2395. foreach ($keys as $key)
  2396. {
  2397. if (SimplePie_Misc::is_isegment_nz_nc($key))
  2398. {
  2399. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  2400. {
  2401. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  2402. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  2403. }
  2404. else
  2405. {
  2406. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  2407. }
  2408. }
  2409. elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  2410. {
  2411. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  2412. }
  2413. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  2414. }
  2415. }
  2416. if (isset($this->data['links'][$rel]))
  2417. {
  2418. return $this->data['links'][$rel];
  2419. }
  2420. else
  2421. {
  2422. return null;
  2423. }
  2424. }
  2425. function get_all_discovered_feeds()
  2426. {
  2427. return $this->all_discovered_feeds;
  2428. }
  2429. function get_description()
  2430. {
  2431. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  2432. {
  2433. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2434. }
  2435. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  2436. {
  2437. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2438. }
  2439. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  2440. {
  2441. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2442. }
  2443. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  2444. {
  2445. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2446. }
  2447. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
  2448. {
  2449. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2450. }
  2451. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  2452. {
  2453. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2454. }
  2455. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  2456. {
  2457. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2458. }
  2459. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  2460. {
  2461. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2462. }
  2463. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  2464. {
  2465. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2466. }
  2467. else
  2468. {
  2469. return null;
  2470. }
  2471. }
  2472. function get_copyright()
  2473. {
  2474. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  2475. {
  2476. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2477. }
  2478. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
  2479. {
  2480. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2481. }
  2482. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
  2483. {
  2484. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2485. }
  2486. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  2487. {
  2488. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2489. }
  2490. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  2491. {
  2492. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2493. }
  2494. else
  2495. {
  2496. return null;
  2497. }
  2498. }
  2499. function get_language()
  2500. {
  2501. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
  2502. {
  2503. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2504. }
  2505. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  2506. {
  2507. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2508. }
  2509. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  2510. {
  2511. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2512. }
  2513. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
  2514. {
  2515. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2516. }
  2517. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
  2518. {
  2519. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2520. }
  2521. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
  2522. {
  2523. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2524. }
  2525. elseif (isset($this->data['headers']['content-language']))
  2526. {
  2527. return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
  2528. }
  2529. else
  2530. {
  2531. return null;
  2532. }
  2533. }
  2534. function get_latitude()
  2535. {
  2536. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  2537. {
  2538. return (float) $return[0]['data'];
  2539. }
  2540. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  2541. {
  2542. return (float) $match[1];
  2543. }
  2544. else
  2545. {
  2546. return null;
  2547. }
  2548. }
  2549. function get_longitude()
  2550. {
  2551. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  2552. {
  2553. return (float) $return[0]['data'];
  2554. }
  2555. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  2556. {
  2557. return (float) $return[0]['data'];
  2558. }
  2559. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  2560. {
  2561. return (float) $match[2];
  2562. }
  2563. else
  2564. {
  2565. return null;
  2566. }
  2567. }
  2568. function get_image_title()
  2569. {
  2570. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2571. {
  2572. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2573. }
  2574. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2575. {
  2576. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2577. }
  2578. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  2579. {
  2580. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2581. }
  2582. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2583. {
  2584. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2585. }
  2586. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2587. {
  2588. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2589. }
  2590. else
  2591. {
  2592. return null;
  2593. }
  2594. }
  2595. function get_image_url()
  2596. {
  2597. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  2598. {
  2599. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  2600. }
  2601. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  2602. {
  2603. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2604. }
  2605. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  2606. {
  2607. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2608. }
  2609. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
  2610. {
  2611. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2612. }
  2613. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
  2614. {
  2615. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2616. }
  2617. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2618. {
  2619. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2620. }
  2621. else
  2622. {
  2623. return null;
  2624. }
  2625. }
  2626. function get_image_link()
  2627. {
  2628. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2629. {
  2630. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2631. }
  2632. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2633. {
  2634. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2635. }
  2636. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  2637. {
  2638. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2639. }
  2640. else
  2641. {
  2642. return null;
  2643. }
  2644. }
  2645. function get_image_width()
  2646. {
  2647. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
  2648. {
  2649. return round($return[0]['data']);
  2650. }
  2651. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2652. {
  2653. return 88.0;
  2654. }
  2655. else
  2656. {
  2657. return null;
  2658. }
  2659. }
  2660. function get_image_height()
  2661. {
  2662. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
  2663. {
  2664. return round($return[0]['data']);
  2665. }
  2666. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2667. {
  2668. return 31.0;
  2669. }
  2670. else
  2671. {
  2672. return null;
  2673. }
  2674. }
  2675. function get_item_quantity($max = 0)
  2676. {
  2677. $max = (int) $max;
  2678. $qty = count($this->get_items());
  2679. if ($max === 0)
  2680. {
  2681. return $qty;
  2682. }
  2683. else
  2684. {
  2685. return ($qty > $max) ? $max : $qty;
  2686. }
  2687. }
  2688. function get_item($key = 0)
  2689. {
  2690. $items = $this->get_items();
  2691. if (isset($items[$key]))
  2692. {
  2693. return $items[$key];
  2694. }
  2695. else
  2696. {
  2697. return null;
  2698. }
  2699. }
  2700. function get_items($start = 0, $end = 0)
  2701. {
  2702. if (!isset($this->data['items']))
  2703. {
  2704. if (!empty($this->multifeed_objects))
  2705. {
  2706. $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
  2707. }
  2708. else
  2709. {
  2710. $this->data['items'] = array();
  2711. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
  2712. {
  2713. $keys = array_keys($items);
  2714. foreach ($keys as $key)
  2715. {
  2716. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2717. }
  2718. }
  2719. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
  2720. {
  2721. $keys = array_keys($items);
  2722. foreach ($keys as $key)
  2723. {
  2724. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2725. }
  2726. }
  2727. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
  2728. {
  2729. $keys = array_keys($items);
  2730. foreach ($keys as $key)
  2731. {
  2732. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2733. }
  2734. }
  2735. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
  2736. {
  2737. $keys = array_keys($items);
  2738. foreach ($keys as $key)
  2739. {
  2740. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2741. }
  2742. }
  2743. if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
  2744. {
  2745. $keys = array_keys($items);
  2746. foreach ($keys as $key)
  2747. {
  2748. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2749. }
  2750. }
  2751. }
  2752. }
  2753. if (!empty($this->data['items']))
  2754. {
  2755. // If we want to order it by date, check if all items have a date, and then sort it
  2756. if ($this->order_by_date && empty($this->multifeed_objects))
  2757. {
  2758. if (!isset($this->data['ordered_items']))
  2759. {
  2760. $do_sort = true;
  2761. foreach ($this->data['items'] as $item)
  2762. {
  2763. if (!$item->get_date('U'))
  2764. {
  2765. $do_sort = false;
  2766. break;
  2767. }
  2768. }
  2769. $item = null;
  2770. $this->data['ordered_items'] = $this->data['items'];
  2771. if ($do_sort)
  2772. {
  2773. usort($this->data['ordered_items'], array(&$this, 'sort_items'));
  2774. }
  2775. }
  2776. $items = $this->data['ordered_items'];
  2777. }
  2778. else
  2779. {
  2780. $items = $this->data['items'];
  2781. }
  2782. // Slice the data as desired
  2783. if ($end === 0)
  2784. {
  2785. return array_slice($items, $start);
  2786. }
  2787. else
  2788. {
  2789. return array_slice($items, $start, $end);
  2790. }
  2791. }
  2792. else
  2793. {
  2794. return array();
  2795. }
  2796. }
  2797. /**
  2798. * @static
  2799. */
  2800. function sort_items($a, $b)
  2801. {
  2802. return $a->get_date('U') <= $b->get_date('U');
  2803. }
  2804. /**
  2805. * @static
  2806. */
  2807. function merge_items($urls, $start = 0, $end = 0, $limit = 0)
  2808. {
  2809. if (is_array($urls) && sizeof($urls) > 0)
  2810. {
  2811. $items = array();
  2812. foreach ($urls as $arg)
  2813. {
  2814. if (is_a($arg, 'SimplePie'))
  2815. {
  2816. $items = array_merge($items, $arg->get_items(0, $limit));
  2817. }
  2818. else
  2819. {
  2820. trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
  2821. }
  2822. }
  2823. $do_sort = true;
  2824. foreach ($items as $item)
  2825. {
  2826. if (!$item->get_date('U'))
  2827. {
  2828. $do_sort = false;
  2829. break;
  2830. }
  2831. }
  2832. $item = null;
  2833. if ($do_sort)
  2834. {
  2835. usort($items, array('SimplePie', 'sort_items'));
  2836. }
  2837. if ($end === 0)
  2838. {
  2839. return array_slice($items, $start);
  2840. }
  2841. else
  2842. {
  2843. return array_slice($items, $start, $end);
  2844. }
  2845. }
  2846. else
  2847. {
  2848. trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
  2849. return array();
  2850. }
  2851. }
  2852. }
  2853. class SimplePie_Item
  2854. {
  2855. var $feed;
  2856. var $data = array();
  2857. function SimplePie_Item($feed, $data)
  2858. {
  2859. $this->feed = $feed;
  2860. $this->data = $data;
  2861. }
  2862. function __toString()
  2863. {
  2864. return md5(serialize($this->data));
  2865. }
  2866. /**
  2867. * Remove items that link back to this before destroying this object
  2868. */
  2869. function __destruct()
  2870. {
  2871. if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
  2872. {
  2873. unset($this->feed);
  2874. }
  2875. }
  2876. function get_item_tags($namespace, $tag)
  2877. {
  2878. if (isset($this->data['child'][$namespace][$tag]))
  2879. {
  2880. return $this->data['child'][$namespace][$tag];
  2881. }
  2882. else
  2883. {
  2884. return null;
  2885. }
  2886. }
  2887. function get_base($element = array())
  2888. {
  2889. return $this->feed->get_base($element);
  2890. }
  2891. function sanitize($data, $type, $base = '')
  2892. {
  2893. return $this->feed->sanitize($data, $type, $base);
  2894. }
  2895. function get_feed()
  2896. {
  2897. return $this->feed;
  2898. }
  2899. function get_id($hash = false)
  2900. {
  2901. if (!$hash)
  2902. {
  2903. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
  2904. {
  2905. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2906. }
  2907. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
  2908. {
  2909. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2910. }
  2911. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
  2912. {
  2913. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2914. }
  2915. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
  2916. {
  2917. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2918. }
  2919. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
  2920. {
  2921. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2922. }
  2923. elseif (($return = $this->get_permalink()) !== null)
  2924. {
  2925. return $return;
  2926. }
  2927. elseif (($return = $this->get_title()) !== null)
  2928. {
  2929. return $return;
  2930. }
  2931. }
  2932. if ($this->get_permalink() !== null || $this->get_title() !== null)
  2933. {
  2934. return md5($this->get_permalink() . $this->get_title());
  2935. }
  2936. else
  2937. {
  2938. return md5(serialize($this->data));
  2939. }
  2940. }
  2941. function get_title()
  2942. {
  2943. if (!isset($this->data['title']))
  2944. {
  2945. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  2946. {
  2947. $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2948. }
  2949. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  2950. {
  2951. $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2952. }
  2953. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2954. {
  2955. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2956. }
  2957. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2958. {
  2959. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2960. }
  2961. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  2962. {
  2963. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2964. }
  2965. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2966. {
  2967. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2968. }
  2969. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2970. {
  2971. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2972. }
  2973. else
  2974. {
  2975. $this->data['title'] = null;
  2976. }
  2977. }
  2978. return $this->data['title'];
  2979. }
  2980. function get_description($description_only = false)
  2981. {
  2982. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
  2983. {
  2984. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2985. }
  2986. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
  2987. {
  2988. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2989. }
  2990. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  2991. {
  2992. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2993. }
  2994. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
  2995. {
  2996. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2997. }
  2998. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  2999. {
  3000. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3001. }
  3002. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  3003. {
  3004. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3005. }
  3006. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  3007. {
  3008. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  3009. }
  3010. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  3011. {
  3012. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3013. }
  3014. elseif (!$description_only)
  3015. {
  3016. return $this->get_content(true);
  3017. }
  3018. else
  3019. {
  3020. return null;
  3021. }
  3022. }
  3023. function get_content($content_only = false)
  3024. {
  3025. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
  3026. {
  3027. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  3028. }
  3029. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
  3030. {
  3031. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  3032. }
  3033. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
  3034. {
  3035. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  3036. }
  3037. elseif (!$content_only)
  3038. {
  3039. return $this->get_description(true);
  3040. }
  3041. else
  3042. {
  3043. return null;
  3044. }
  3045. }
  3046. function get_category($key = 0)
  3047. {
  3048. $categories = $this->get_categories();
  3049. if (isset($categories[$key]))
  3050. {
  3051. return $categories[$key];
  3052. }
  3053. else
  3054. {
  3055. return null;
  3056. }
  3057. }
  3058. function get_categories()
  3059. {
  3060. $categories = array();
  3061. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  3062. {
  3063. $term = null;
  3064. $scheme = null;
  3065. $label = null;
  3066. if (isset($category['attribs']['']['term']))
  3067. {
  3068. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  3069. }
  3070. if (isset($category['attribs']['']['scheme']))
  3071. {
  3072. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3073. }
  3074. if (isset($category['attribs']['']['label']))
  3075. {
  3076. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3077. }
  3078. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  3079. }
  3080. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
  3081. {
  3082. // This is really the label, but keep this as the term also for BC.
  3083. // Label will also work on retrieving because that falls back to term.
  3084. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3085. if (isset($category['attribs']['']['domain']))
  3086. {
  3087. $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
  3088. }
  3089. else
  3090. {
  3091. $scheme = null;
  3092. }
  3093. $categories[] =& new $this->feed->category_class($term, $scheme, null);
  3094. }
  3095. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  3096. {
  3097. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3098. }
  3099. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  3100. {
  3101. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3102. }
  3103. if (!empty($categories))
  3104. {
  3105. return SimplePie_Misc::array_unique($categories);
  3106. }
  3107. else
  3108. {
  3109. return null;
  3110. }
  3111. }
  3112. function get_author($key = 0)
  3113. {
  3114. $authors = $this->get_authors();
  3115. if (isset($authors[$key]))
  3116. {
  3117. return $authors[$key];
  3118. }
  3119. else
  3120. {
  3121. return null;
  3122. }
  3123. }
  3124. function get_contributor($key = 0)
  3125. {
  3126. $contributors = $this->get_contributors();
  3127. if (isset($contributors[$key]))
  3128. {
  3129. return $contributors[$key];
  3130. }
  3131. else
  3132. {
  3133. return null;
  3134. }
  3135. }
  3136. function get_contributors()
  3137. {
  3138. $contributors = array();
  3139. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  3140. {
  3141. $name = null;
  3142. $uri = null;
  3143. $email = null;
  3144. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  3145. {
  3146. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3147. }
  3148. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  3149. {
  3150. $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]));
  3151. }
  3152. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  3153. {
  3154. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3155. }
  3156. if ($name !== null || $email !== null || $uri !== null)
  3157. {
  3158. $contributors[] =& new $this->feed->author_class($name, $uri, $email);
  3159. }
  3160. }
  3161. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  3162. {
  3163. $name = null;
  3164. $url = null;
  3165. $email = null;
  3166. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  3167. {
  3168. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3169. }
  3170. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  3171. {
  3172. $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]));
  3173. }
  3174. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  3175. {
  3176. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3177. }
  3178. if ($name !== null || $email !== null || $url !== null)
  3179. {
  3180. $contributors[] =& new $this->feed->author_class($name, $url, $email);
  3181. }
  3182. }
  3183. if (!empty($contributors))
  3184. {
  3185. return SimplePie_Misc::array_unique($contributors);
  3186. }
  3187. else
  3188. {
  3189. return null;
  3190. }
  3191. }
  3192. function get_authors()
  3193. {
  3194. $authors = array();
  3195. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  3196. {
  3197. $name = null;
  3198. $uri = null;
  3199. $email = null;
  3200. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  3201. {
  3202. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3203. }
  3204. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  3205. {
  3206. $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]));
  3207. }
  3208. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  3209. {
  3210. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3211. }
  3212. if ($name !== null || $email !== null || $uri !== null)
  3213. {
  3214. $authors[] =& new $this->feed->author_class($name, $uri, $email);
  3215. }
  3216. }
  3217. if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  3218. {
  3219. $name = null;
  3220. $url = null;
  3221. $email = null;
  3222. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  3223. {
  3224. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3225. }
  3226. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  3227. {
  3228. $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]));
  3229. }
  3230. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  3231. {
  3232. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3233. }
  3234. if ($name !== null || $email !== null || $url !== null)
  3235. {
  3236. $authors[] =& new $this->feed->author_class($name, $url, $email);
  3237. }
  3238. }
  3239. if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
  3240. {
  3241. $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3242. }
  3243. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  3244. {
  3245. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3246. }
  3247. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  3248. {
  3249. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3250. }
  3251. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  3252. {
  3253. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3254. }
  3255. if (!empty($authors))
  3256. {
  3257. return SimplePie_Misc::array_unique($authors);
  3258. }
  3259. elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
  3260. {
  3261. return $authors;
  3262. }
  3263. elseif ($authors = $this->feed->get_authors())
  3264. {
  3265. return $authors;
  3266. }
  3267. else
  3268. {
  3269. return null;
  3270. }
  3271. }
  3272. function get_copyright()
  3273. {
  3274. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  3275. {
  3276. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  3277. }
  3278. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  3279. {
  3280. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3281. }
  3282. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  3283. {
  3284. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3285. }
  3286. else
  3287. {
  3288. return null;
  3289. }
  3290. }
  3291. function get_date($date_format = 'j F Y, g:i a')
  3292. {
  3293. if (!isset($this->data['date']))
  3294. {
  3295. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
  3296. {
  3297. $this->data['date']['raw'] = $return[0]['data'];
  3298. }
  3299. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
  3300. {
  3301. $this->data['date']['raw'] = $return[0]['data'];
  3302. }
  3303. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
  3304. {
  3305. $this->data['date']['raw'] = $return[0]['data'];
  3306. }
  3307. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
  3308. {
  3309. $this->data['date']['raw'] = $return[0]['data'];
  3310. }
  3311. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
  3312. {
  3313. $this->data['date']['raw'] = $return[0]['data'];
  3314. }
  3315. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
  3316. {
  3317. $this->data['date']['raw'] = $return[0]['data'];
  3318. }
  3319. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
  3320. {
  3321. $this->data['date']['raw'] = $return[0]['data'];
  3322. }
  3323. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
  3324. {
  3325. $this->data['date']['raw'] = $return[0]['data'];
  3326. }
  3327. if (!empty($this->data['date']['raw']))
  3328. {
  3329. $parser = SimplePie_Parse_Date::get();
  3330. $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
  3331. }
  3332. else
  3333. {
  3334. $this->data['date'] = null;
  3335. }
  3336. }
  3337. if ($this->data['date'])
  3338. {
  3339. $date_format = (string) $date_format;
  3340. switch ($date_format)
  3341. {
  3342. case '':
  3343. return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
  3344. case 'U':
  3345. return $this->data['date']['parsed'];
  3346. default:
  3347. return date($date_format, $this->data['date']['parsed']);
  3348. }
  3349. }
  3350. else
  3351. {
  3352. return null;
  3353. }
  3354. }
  3355. function get_local_date($date_format = '%c')
  3356. {
  3357. if (!$date_format)
  3358. {
  3359. return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
  3360. }
  3361. elseif (($date = $this->get_date('U')) !== null)
  3362. {
  3363. return strftime($date_format, $date);
  3364. }
  3365. else
  3366. {
  3367. return null;
  3368. }
  3369. }
  3370. function get_permalink()
  3371. {
  3372. $link = $this->get_link();
  3373. $enclosure = $this->get_enclosure(0);
  3374. if ($link !== null)
  3375. {
  3376. return $link;
  3377. }
  3378. elseif ($enclosure !== null)
  3379. {
  3380. return $enclosure->get_link();
  3381. }
  3382. else
  3383. {
  3384. return null;
  3385. }
  3386. }
  3387. function get_link($key = 0, $rel = 'alternate')
  3388. {
  3389. $links = $this->get_links($rel);
  3390. if ($links[$key] !== null)
  3391. {
  3392. return $links[$key];
  3393. }
  3394. else
  3395. {
  3396. return null;
  3397. }
  3398. }
  3399. function get_links($rel = 'alternate')
  3400. {
  3401. if (!isset($this->data['links']))
  3402. {
  3403. $this->data['links'] = array();
  3404. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  3405. {
  3406. if (isset($link['attribs']['']['href']))
  3407. {
  3408. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  3409. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  3410. }
  3411. }
  3412. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  3413. {
  3414. if (isset($link['attribs']['']['href']))
  3415. {
  3416. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  3417. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  3418. }
  3419. }
  3420. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  3421. {
  3422. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3423. }
  3424. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  3425. {
  3426. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3427. }
  3428. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  3429. {
  3430. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3431. }
  3432. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
  3433. {
  3434. if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')
  3435. {
  3436. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3437. }
  3438. }
  3439. $keys = array_keys($this->data['links']);
  3440. foreach ($keys as $key)
  3441. {
  3442. if (SimplePie_Misc::is_isegment_nz_nc($key))
  3443. {
  3444. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  3445. {
  3446. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  3447. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  3448. }
  3449. else
  3450. {
  3451. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  3452. }
  3453. }
  3454. elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  3455. {
  3456. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  3457. }
  3458. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  3459. }
  3460. }
  3461. if (isset($this->data['links'][$rel]))
  3462. {
  3463. return $this->data['links'][$rel];
  3464. }
  3465. else
  3466. {
  3467. return null;
  3468. }
  3469. }
  3470. /**
  3471. * @todo Add ability to prefer one type of content over another (in a media group).
  3472. */
  3473. function get_enclosure($key = 0, $prefer = null)
  3474. {
  3475. $enclosures = $this->get_enclosures();
  3476. if (isset($enclosures[$key]))
  3477. {
  3478. return $enclosures[$key];
  3479. }
  3480. else
  3481. {
  3482. return null;
  3483. }
  3484. }
  3485. /**
  3486. * Grabs all available enclosures (podcasts, etc.)
  3487. *
  3488. * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
  3489. *
  3490. * 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.
  3491. *
  3492. * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
  3493. * @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).
  3494. */
  3495. function get_enclosures()
  3496. {
  3497. if (!isset($this->data['enclosures']))
  3498. {
  3499. $this->data['enclosures'] = array();
  3500. // Elements
  3501. $captions_parent = null;
  3502. $categories_parent = null;
  3503. $copyrights_parent = null;
  3504. $credits_parent = null;
  3505. $description_parent = null;
  3506. $duration_parent = null;
  3507. $hashes_parent = null;
  3508. $keywords_parent = null;
  3509. $player_parent = null;
  3510. $ratings_parent = null;
  3511. $restrictions_parent = null;
  3512. $thumbnails_parent = null;
  3513. $title_parent = null;
  3514. // Let's do the channel and item-level ones first, and just re-use them if we need to.
  3515. $parent = $this->get_feed();
  3516. // CAPTIONS
  3517. if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  3518. {
  3519. foreach ($captions as $caption)
  3520. {
  3521. $caption_type = null;
  3522. $caption_lang = null;
  3523. $caption_startTime = null;
  3524. $caption_endTime = null;
  3525. $caption_text = null;
  3526. if (isset($caption['attribs']['']['type']))
  3527. {
  3528. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3529. }
  3530. if (isset($caption['attribs']['']['lang']))
  3531. {
  3532. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3533. }
  3534. if (isset($caption['attribs']['']['start']))
  3535. {
  3536. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3537. }
  3538. if (isset($caption['attribs']['']['end']))
  3539. {
  3540. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3541. }
  3542. if (isset($caption['data']))
  3543. {
  3544. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3545. }
  3546. $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3547. }
  3548. }
  3549. elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  3550. {
  3551. foreach ($captions as $caption)
  3552. {
  3553. $caption_type = null;
  3554. $caption_lang = null;
  3555. $caption_startTime = null;
  3556. $caption_endTime = null;
  3557. $caption_text = null;
  3558. if (isset($caption['attribs']['']['type']))
  3559. {
  3560. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3561. }
  3562. if (isset($caption['attribs']['']['lang']))
  3563. {
  3564. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3565. }
  3566. if (isset($caption['attribs']['']['start']))
  3567. {
  3568. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3569. }
  3570. if (isset($caption['attribs']['']['end']))
  3571. {
  3572. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3573. }
  3574. if (isset($caption['data']))
  3575. {
  3576. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3577. }
  3578. $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3579. }
  3580. }
  3581. if (is_array($captions_parent))
  3582. {
  3583. $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
  3584. }
  3585. // CATEGORIES
  3586. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  3587. {
  3588. $term = null;
  3589. $scheme = null;
  3590. $label = null;
  3591. if (isset($category['data']))
  3592. {
  3593. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3594. }
  3595. if (isset($category['attribs']['']['scheme']))
  3596. {
  3597. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3598. }
  3599. else
  3600. {
  3601. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3602. }
  3603. if (isset($category['attribs']['']['label']))
  3604. {
  3605. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3606. }
  3607. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3608. }
  3609. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  3610. {
  3611. $term = null;
  3612. $scheme = null;
  3613. $label = null;
  3614. if (isset($category['data']))
  3615. {
  3616. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3617. }
  3618. if (isset($category['attribs']['']['scheme']))
  3619. {
  3620. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3621. }
  3622. else
  3623. {
  3624. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3625. }
  3626. if (isset($category['attribs']['']['label']))
  3627. {
  3628. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3629. }
  3630. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3631. }
  3632. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
  3633. {
  3634. $term = null;
  3635. $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
  3636. $label = null;
  3637. if (isset($category['attribs']['']['text']))
  3638. {
  3639. $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  3640. }
  3641. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3642. if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
  3643. {
  3644. foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
  3645. {
  3646. if (isset($subcategory['attribs']['']['text']))
  3647. {
  3648. $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  3649. }
  3650. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3651. }
  3652. }
  3653. }
  3654. if (is_array($categories_parent))
  3655. {
  3656. $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
  3657. }
  3658. // COPYRIGHT
  3659. if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  3660. {
  3661. $copyright_url = null;
  3662. $copyright_label = null;
  3663. if (isset($copyright[0]['attribs']['']['url']))
  3664. {
  3665. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3666. }
  3667. if (isset($copyright[0]['data']))
  3668. {
  3669. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3670. }
  3671. $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  3672. }
  3673. elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  3674. {
  3675. $copyright_url = null;
  3676. $copyright_label = null;
  3677. if (isset($copyright[0]['attribs']['']['url']))
  3678. {
  3679. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3680. }
  3681. if (isset($copyright[0]['data']))
  3682. {
  3683. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3684. }
  3685. $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  3686. }
  3687. // CREDITS
  3688. if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  3689. {
  3690. foreach ($credits as $credit)
  3691. {
  3692. $credit_role = null;
  3693. $credit_scheme = null;
  3694. $credit_name = null;
  3695. if (isset($credit['attribs']['']['role']))
  3696. {
  3697. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3698. }
  3699. if (isset($credit['attribs']['']['scheme']))
  3700. {
  3701. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3702. }
  3703. else
  3704. {
  3705. $credit_scheme = 'urn:ebu';
  3706. }
  3707. if (isset($credit['data']))
  3708. {
  3709. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3710. }
  3711. $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3712. }
  3713. }
  3714. elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  3715. {
  3716. foreach ($credits as $credit)
  3717. {
  3718. $credit_role = null;
  3719. $credit_scheme = null;
  3720. $credit_name = null;
  3721. if (isset($credit['attribs']['']['role']))
  3722. {
  3723. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3724. }
  3725. if (isset($credit['attribs']['']['scheme']))
  3726. {
  3727. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3728. }
  3729. else
  3730. {
  3731. $credit_scheme = 'urn:ebu';
  3732. }
  3733. if (isset($credit['data']))
  3734. {
  3735. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3736. }
  3737. $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3738. }
  3739. }
  3740. if (is_array($credits_parent))
  3741. {
  3742. $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
  3743. }
  3744. // DESCRIPTION
  3745. if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  3746. {
  3747. if (isset($description_parent[0]['data']))
  3748. {
  3749. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3750. }
  3751. }
  3752. elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  3753. {
  3754. if (isset($description_parent[0]['data']))
  3755. {
  3756. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3757. }
  3758. }
  3759. // DURATION
  3760. if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
  3761. {
  3762. $seconds = null;
  3763. $minutes = null;
  3764. $hours = null;
  3765. if (isset($duration_parent[0]['data']))
  3766. {
  3767. $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3768. if (sizeof($temp) > 0)
  3769. {
  3770. $seconds = (int) array_pop($temp);
  3771. }
  3772. if (sizeof($temp) > 0)
  3773. {
  3774. $minutes = (int) array_pop($temp);
  3775. $seconds += $minutes * 60;
  3776. }
  3777. if (sizeof($temp) > 0)
  3778. {
  3779. $hours = (int) array_pop($temp);
  3780. $seconds += $hours * 3600;
  3781. }
  3782. unset($temp);
  3783. $duration_parent = $seconds;
  3784. }
  3785. }
  3786. // HASHES
  3787. if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  3788. {
  3789. foreach ($hashes_iterator as $hash)
  3790. {
  3791. $value = null;
  3792. $algo = null;
  3793. if (isset($hash['data']))
  3794. {
  3795. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3796. }
  3797. if (isset($hash['attribs']['']['algo']))
  3798. {
  3799. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3800. }
  3801. else
  3802. {
  3803. $algo = 'md5';
  3804. }
  3805. $hashes_parent[] = $algo.':'.$value;
  3806. }
  3807. }
  3808. elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  3809. {
  3810. foreach ($hashes_iterator as $hash)
  3811. {
  3812. $value = null;
  3813. $algo = null;
  3814. if (isset($hash['data']))
  3815. {
  3816. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3817. }
  3818. if (isset($hash['attribs']['']['algo']))
  3819. {
  3820. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3821. }
  3822. else
  3823. {
  3824. $algo = 'md5';
  3825. }
  3826. $hashes_parent[] = $algo.':'.$value;
  3827. }
  3828. }
  3829. if (is_array($hashes_parent))
  3830. {
  3831. $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
  3832. }
  3833. // KEYWORDS
  3834. if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  3835. {
  3836. if (isset($keywords[0]['data']))
  3837. {
  3838. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3839. foreach ($temp as $word)
  3840. {
  3841. $keywords_parent[] = trim($word);
  3842. }
  3843. }
  3844. unset($temp);
  3845. }
  3846. elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  3847. {
  3848. if (isset($keywords[0]['data']))
  3849. {
  3850. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3851. foreach ($temp as $word)
  3852. {
  3853. $keywords_parent[] = trim($word);
  3854. }
  3855. }
  3856. unset($temp);
  3857. }
  3858. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  3859. {
  3860. if (isset($keywords[0]['data']))
  3861. {
  3862. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3863. foreach ($temp as $word)
  3864. {
  3865. $keywords_parent[] = trim($word);
  3866. }
  3867. }
  3868. unset($temp);
  3869. }
  3870. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  3871. {
  3872. if (isset($keywords[0]['data']))
  3873. {
  3874. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3875. foreach ($temp as $word)
  3876. {
  3877. $keywords_parent[] = trim($word);
  3878. }
  3879. }
  3880. unset($temp);
  3881. }
  3882. if (is_array($keywords_parent))
  3883. {
  3884. $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
  3885. }
  3886. // PLAYER
  3887. if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  3888. {
  3889. if (isset($player_parent[0]['attribs']['']['url']))
  3890. {
  3891. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3892. }
  3893. }
  3894. elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  3895. {
  3896. if (isset($player_parent[0]['attribs']['']['url']))
  3897. {
  3898. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3899. }
  3900. }
  3901. // RATINGS
  3902. if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  3903. {
  3904. foreach ($ratings as $rating)
  3905. {
  3906. $rating_scheme = null;
  3907. $rating_value = null;
  3908. if (isset($rating['attribs']['']['scheme']))
  3909. {
  3910. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3911. }
  3912. else
  3913. {
  3914. $rating_scheme = 'urn:simple';
  3915. }
  3916. if (isset($rating['data']))
  3917. {
  3918. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3919. }
  3920. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3921. }
  3922. }
  3923. elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  3924. {
  3925. foreach ($ratings as $rating)
  3926. {
  3927. $rating_scheme = 'urn:itunes';
  3928. $rating_value = null;
  3929. if (isset($rating['data']))
  3930. {
  3931. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3932. }
  3933. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3934. }
  3935. }
  3936. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  3937. {
  3938. foreach ($ratings as $rating)
  3939. {
  3940. $rating_scheme = null;
  3941. $rating_value = null;
  3942. if (isset($rating['attribs']['']['scheme']))
  3943. {
  3944. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3945. }
  3946. else
  3947. {
  3948. $rating_scheme = 'urn:simple';
  3949. }
  3950. if (isset($rating['data']))
  3951. {
  3952. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3953. }
  3954. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3955. }
  3956. }
  3957. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  3958. {
  3959. foreach ($ratings as $rating)
  3960. {
  3961. $rating_scheme = 'urn:itunes';
  3962. $rating_value = null;
  3963. if (isset($rating['data']))
  3964. {
  3965. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3966. }
  3967. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3968. }
  3969. }
  3970. if (is_array($ratings_parent))
  3971. {
  3972. $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
  3973. }
  3974. // RESTRICTIONS
  3975. if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  3976. {
  3977. foreach ($restrictions as $restriction)
  3978. {
  3979. $restriction_relationship = null;
  3980. $restriction_type = null;
  3981. $restriction_value = null;
  3982. if (isset($restriction['attribs']['']['relationship']))
  3983. {
  3984. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  3985. }
  3986. if (isset($restriction['attribs']['']['type']))
  3987. {
  3988. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3989. }
  3990. if (isset($restriction['data']))
  3991. {
  3992. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3993. }
  3994. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3995. }
  3996. }
  3997. elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  3998. {
  3999. foreach ($restrictions as $restriction)
  4000. {
  4001. $restriction_relationship = 'allow';
  4002. $restriction_type = null;
  4003. $restriction_value = 'itunes';
  4004. if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
  4005. {
  4006. $restriction_relationship = 'deny';
  4007. }
  4008. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4009. }
  4010. }
  4011. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  4012. {
  4013. foreach ($restrictions as $restriction)
  4014. {
  4015. $restriction_relationship = null;
  4016. $restriction_type = null;
  4017. $restriction_value = null;
  4018. if (isset($restriction['attribs']['']['relationship']))
  4019. {
  4020. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4021. }
  4022. if (isset($restriction['attribs']['']['type']))
  4023. {
  4024. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4025. }
  4026. if (isset($restriction['data']))
  4027. {
  4028. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4029. }
  4030. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4031. }
  4032. }
  4033. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  4034. {
  4035. foreach ($restrictions as $restriction)
  4036. {
  4037. $restriction_relationship = 'allow';
  4038. $restriction_type = null;
  4039. $restriction_value = 'itunes';
  4040. if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
  4041. {
  4042. $restriction_relationship = 'deny';
  4043. }
  4044. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4045. }
  4046. }
  4047. if (is_array($restrictions_parent))
  4048. {
  4049. $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
  4050. }
  4051. // THUMBNAILS
  4052. if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  4053. {
  4054. foreach ($thumbnails as $thumbnail)
  4055. {
  4056. if (isset($thumbnail['attribs']['']['url']))
  4057. {
  4058. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4059. }
  4060. }
  4061. }
  4062. elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  4063. {
  4064. foreach ($thumbnails as $thumbnail)
  4065. {
  4066. if (isset($thumbnail['attribs']['']['url']))
  4067. {
  4068. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4069. }
  4070. }
  4071. }
  4072. // TITLES
  4073. if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  4074. {
  4075. if (isset($title_parent[0]['data']))
  4076. {
  4077. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4078. }
  4079. }
  4080. elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  4081. {
  4082. if (isset($title_parent[0]['data']))
  4083. {
  4084. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4085. }
  4086. }
  4087. // Clear the memory
  4088. unset($parent);
  4089. // Attributes
  4090. $bitrate = null;
  4091. $channels = null;
  4092. $duration = null;
  4093. $expression = null;
  4094. $framerate = null;
  4095. $height = null;
  4096. $javascript = null;
  4097. $lang = null;
  4098. $length = null;
  4099. $medium = null;
  4100. $samplingrate = null;
  4101. $type = null;
  4102. $url = null;
  4103. $width = null;
  4104. // Elements
  4105. $captions = null;
  4106. $categories = null;
  4107. $copyrights = null;
  4108. $credits = null;
  4109. $description = null;
  4110. $hashes = null;
  4111. $keywords = null;
  4112. $player = null;
  4113. $ratings = null;
  4114. $restrictions = null;
  4115. $thumbnails = null;
  4116. $title = null;
  4117. // If we have media:group tags, loop through them.
  4118. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
  4119. {
  4120. // If we have media:content tags, loop through them.
  4121. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  4122. {
  4123. if (isset($content['attribs']['']['url']))
  4124. {
  4125. // Attributes
  4126. $bitrate = null;
  4127. $channels = null;
  4128. $duration = null;
  4129. $expression = null;
  4130. $framerate = null;
  4131. $height = null;
  4132. $javascript = null;
  4133. $lang = null;
  4134. $length = null;
  4135. $medium = null;
  4136. $samplingrate = null;
  4137. $type = null;
  4138. $url = null;
  4139. $width = null;
  4140. // Elements
  4141. $captions = null;
  4142. $categories = null;
  4143. $copyrights = null;
  4144. $credits = null;
  4145. $description = null;
  4146. $hashes = null;
  4147. $keywords = null;
  4148. $player = null;
  4149. $ratings = null;
  4150. $restrictions = null;
  4151. $thumbnails = null;
  4152. $title = null;
  4153. // Start checking the attributes of media:content
  4154. if (isset($content['attribs']['']['bitrate']))
  4155. {
  4156. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4157. }
  4158. if (isset($content['attribs']['']['channels']))
  4159. {
  4160. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  4161. }
  4162. if (isset($content['attribs']['']['duration']))
  4163. {
  4164. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  4165. }
  4166. else
  4167. {
  4168. $duration = $duration_parent;
  4169. }
  4170. if (isset($content['attribs']['']['expression']))
  4171. {
  4172. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  4173. }
  4174. if (isset($content['attribs']['']['framerate']))
  4175. {
  4176. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4177. }
  4178. if (isset($content['attribs']['']['height']))
  4179. {
  4180. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  4181. }
  4182. if (isset($content['attribs']['']['lang']))
  4183. {
  4184. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4185. }
  4186. if (isset($content['attribs']['']['fileSize']))
  4187. {
  4188. $length = ceil($content['attribs']['']['fileSize']);
  4189. }
  4190. if (isset($content['attribs']['']['medium']))
  4191. {
  4192. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  4193. }
  4194. if (isset($content['attribs']['']['samplingrate']))
  4195. {
  4196. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4197. }
  4198. if (isset($content['attribs']['']['type']))
  4199. {
  4200. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4201. }
  4202. if (isset($content['attribs']['']['width']))
  4203. {
  4204. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  4205. }
  4206. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4207. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  4208. // CAPTIONS
  4209. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4210. {
  4211. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4212. {
  4213. $caption_type = null;
  4214. $caption_lang = null;
  4215. $caption_startTime = null;
  4216. $caption_endTime = null;
  4217. $caption_text = null;
  4218. if (isset($caption['attribs']['']['type']))
  4219. {
  4220. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4221. }
  4222. if (isset($caption['attribs']['']['lang']))
  4223. {
  4224. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4225. }
  4226. if (isset($caption['attribs']['']['start']))
  4227. {
  4228. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4229. }
  4230. if (isset($caption['attribs']['']['end']))
  4231. {
  4232. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4233. }
  4234. if (isset($caption['data']))
  4235. {
  4236. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4237. }
  4238. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4239. }
  4240. if (is_array($captions))
  4241. {
  4242. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4243. }
  4244. }
  4245. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4246. {
  4247. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4248. {
  4249. $caption_type = null;
  4250. $caption_lang = null;
  4251. $caption_startTime = null;
  4252. $caption_endTime = null;
  4253. $caption_text = null;
  4254. if (isset($caption['attribs']['']['type']))
  4255. {
  4256. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4257. }
  4258. if (isset($caption['attribs']['']['lang']))
  4259. {
  4260. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4261. }
  4262. if (isset($caption['attribs']['']['start']))
  4263. {
  4264. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4265. }
  4266. if (isset($caption['attribs']['']['end']))
  4267. {
  4268. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4269. }
  4270. if (isset($caption['data']))
  4271. {
  4272. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4273. }
  4274. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4275. }
  4276. if (is_array($captions))
  4277. {
  4278. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4279. }
  4280. }
  4281. else
  4282. {
  4283. $captions = $captions_parent;
  4284. }
  4285. // CATEGORIES
  4286. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4287. {
  4288. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4289. {
  4290. $term = null;
  4291. $scheme = null;
  4292. $label = null;
  4293. if (isset($category['data']))
  4294. {
  4295. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4296. }
  4297. if (isset($category['attribs']['']['scheme']))
  4298. {
  4299. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4300. }
  4301. else
  4302. {
  4303. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4304. }
  4305. if (isset($category['attribs']['']['label']))
  4306. {
  4307. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4308. }
  4309. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4310. }
  4311. }
  4312. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4313. {
  4314. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4315. {
  4316. $term = null;
  4317. $scheme = null;
  4318. $label = null;
  4319. if (isset($category['data']))
  4320. {
  4321. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4322. }
  4323. if (isset($category['attribs']['']['scheme']))
  4324. {
  4325. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4326. }
  4327. else
  4328. {
  4329. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4330. }
  4331. if (isset($category['attribs']['']['label']))
  4332. {
  4333. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4334. }
  4335. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4336. }
  4337. }
  4338. if (is_array($categories) && is_array($categories_parent))
  4339. {
  4340. $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
  4341. }
  4342. elseif (is_array($categories))
  4343. {
  4344. $categories = array_values(SimplePie_Misc::array_unique($categories));
  4345. }
  4346. elseif (is_array($categories_parent))
  4347. {
  4348. $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
  4349. }
  4350. // COPYRIGHTS
  4351. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4352. {
  4353. $copyright_url = null;
  4354. $copyright_label = null;
  4355. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4356. {
  4357. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4358. }
  4359. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4360. {
  4361. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4362. }
  4363. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4364. }
  4365. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4366. {
  4367. $copyright_url = null;
  4368. $copyright_label = null;
  4369. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4370. {
  4371. $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4372. }
  4373. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4374. {
  4375. $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4376. }
  4377. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4378. }
  4379. else
  4380. {
  4381. $copyrights = $copyrights_parent;
  4382. }
  4383. // CREDITS
  4384. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4385. {
  4386. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4387. {
  4388. $credit_role = null;
  4389. $credit_scheme = null;
  4390. $credit_name = null;
  4391. if (isset($credit['attribs']['']['role']))
  4392. {
  4393. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4394. }
  4395. if (isset($credit['attribs']['']['scheme']))
  4396. {
  4397. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4398. }
  4399. else
  4400. {
  4401. $credit_scheme = 'urn:ebu';
  4402. }
  4403. if (isset($credit['data']))
  4404. {
  4405. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4406. }
  4407. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4408. }
  4409. if (is_array($credits))
  4410. {
  4411. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4412. }
  4413. }
  4414. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4415. {
  4416. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4417. {
  4418. $credit_role = null;
  4419. $credit_scheme = null;
  4420. $credit_name = null;
  4421. if (isset($credit['attribs']['']['role']))
  4422. {
  4423. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4424. }
  4425. if (isset($credit['attribs']['']['scheme']))
  4426. {
  4427. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4428. }
  4429. else
  4430. {
  4431. $credit_scheme = 'urn:ebu';
  4432. }
  4433. if (isset($credit['data']))
  4434. {
  4435. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4436. }
  4437. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4438. }
  4439. if (is_array($credits))
  4440. {
  4441. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4442. }
  4443. }
  4444. else
  4445. {
  4446. $credits = $credits_parent;
  4447. }
  4448. // DESCRIPTION
  4449. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4450. {
  4451. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4452. }
  4453. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4454. {
  4455. $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4456. }
  4457. else
  4458. {
  4459. $description = $description_parent;
  4460. }
  4461. // HASHES
  4462. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4463. {
  4464. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4465. {
  4466. $value = null;
  4467. $algo = null;
  4468. if (isset($hash['data']))
  4469. {
  4470. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4471. }
  4472. if (isset($hash['attribs']['']['algo']))
  4473. {
  4474. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4475. }
  4476. else
  4477. {
  4478. $algo = 'md5';
  4479. }
  4480. $hashes[] = $algo.':'.$value;
  4481. }
  4482. if (is_array($hashes))
  4483. {
  4484. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4485. }
  4486. }
  4487. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4488. {
  4489. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4490. {
  4491. $value = null;
  4492. $algo = null;
  4493. if (isset($hash['data']))
  4494. {
  4495. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4496. }
  4497. if (isset($hash['attribs']['']['algo']))
  4498. {
  4499. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4500. }
  4501. else
  4502. {
  4503. $algo = 'md5';
  4504. }
  4505. $hashes[] = $algo.':'.$value;
  4506. }
  4507. if (is_array($hashes))
  4508. {
  4509. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4510. }
  4511. }
  4512. else
  4513. {
  4514. $hashes = $hashes_parent;
  4515. }
  4516. // KEYWORDS
  4517. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4518. {
  4519. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4520. {
  4521. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4522. foreach ($temp as $word)
  4523. {
  4524. $keywords[] = trim($word);
  4525. }
  4526. unset($temp);
  4527. }
  4528. if (is_array($keywords))
  4529. {
  4530. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4531. }
  4532. }
  4533. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4534. {
  4535. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4536. {
  4537. $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4538. foreach ($temp as $word)
  4539. {
  4540. $keywords[] = trim($word);
  4541. }
  4542. unset($temp);
  4543. }
  4544. if (is_array($keywords))
  4545. {
  4546. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4547. }
  4548. }
  4549. else
  4550. {
  4551. $keywords = $keywords_parent;
  4552. }
  4553. // PLAYER
  4554. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4555. {
  4556. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4557. }
  4558. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4559. {
  4560. $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4561. }
  4562. else
  4563. {
  4564. $player = $player_parent;
  4565. }
  4566. // RATINGS
  4567. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4568. {
  4569. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4570. {
  4571. $rating_scheme = null;
  4572. $rating_value = null;
  4573. if (isset($rating['attribs']['']['scheme']))
  4574. {
  4575. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4576. }
  4577. else
  4578. {
  4579. $rating_scheme = 'urn:simple';
  4580. }
  4581. if (isset($rating['data']))
  4582. {
  4583. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4584. }
  4585. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4586. }
  4587. if (is_array($ratings))
  4588. {
  4589. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4590. }
  4591. }
  4592. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4593. {
  4594. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4595. {
  4596. $rating_scheme = null;
  4597. $rating_value = null;
  4598. if (isset($rating['attribs']['']['scheme']))
  4599. {
  4600. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4601. }
  4602. else
  4603. {
  4604. $rating_scheme = 'urn:simple';
  4605. }
  4606. if (isset($rating['data']))
  4607. {
  4608. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4609. }
  4610. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4611. }
  4612. if (is_array($ratings))
  4613. {
  4614. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4615. }
  4616. }
  4617. else
  4618. {
  4619. $ratings = $ratings_parent;
  4620. }
  4621. // RESTRICTIONS
  4622. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4623. {
  4624. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4625. {
  4626. $restriction_relationship = null;
  4627. $restriction_type = null;
  4628. $restriction_value = null;
  4629. if (isset($restriction['attribs']['']['relationship']))
  4630. {
  4631. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4632. }
  4633. if (isset($restriction['attribs']['']['type']))
  4634. {
  4635. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4636. }
  4637. if (isset($restriction['data']))
  4638. {
  4639. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4640. }
  4641. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4642. }
  4643. if (is_array($restrictions))
  4644. {
  4645. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4646. }
  4647. }
  4648. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4649. {
  4650. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4651. {
  4652. $restriction_relationship = null;
  4653. $restriction_type = null;
  4654. $restriction_value = null;
  4655. if (isset($restriction['attribs']['']['relationship']))
  4656. {
  4657. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4658. }
  4659. if (isset($restriction['attribs']['']['type']))
  4660. {
  4661. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4662. }
  4663. if (isset($restriction['data']))
  4664. {
  4665. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4666. }
  4667. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4668. }
  4669. if (is_array($restrictions))
  4670. {
  4671. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4672. }
  4673. }
  4674. else
  4675. {
  4676. $restrictions = $restrictions_parent;
  4677. }
  4678. // THUMBNAILS
  4679. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4680. {
  4681. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4682. {
  4683. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4684. }
  4685. if (is_array($thumbnails))
  4686. {
  4687. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4688. }
  4689. }
  4690. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4691. {
  4692. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4693. {
  4694. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4695. }
  4696. if (is_array($thumbnails))
  4697. {
  4698. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4699. }
  4700. }
  4701. else
  4702. {
  4703. $thumbnails = $thumbnails_parent;
  4704. }
  4705. // TITLES
  4706. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4707. {
  4708. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4709. }
  4710. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4711. {
  4712. $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4713. }
  4714. else
  4715. {
  4716. $title = $title_parent;
  4717. }
  4718. $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);
  4719. }
  4720. }
  4721. }
  4722. // If we have standalone media:content tags, loop through them.
  4723. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
  4724. {
  4725. foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  4726. {
  4727. if (isset($content['attribs']['']['url']))
  4728. {
  4729. // Attributes
  4730. $bitrate = null;
  4731. $channels = null;
  4732. $duration = null;
  4733. $expression = null;
  4734. $framerate = null;
  4735. $height = null;
  4736. $javascript = null;
  4737. $lang = null;
  4738. $length = null;
  4739. $medium = null;
  4740. $samplingrate = null;
  4741. $type = null;
  4742. $url = null;
  4743. $width = null;
  4744. // Elements
  4745. $captions = null;
  4746. $categories = null;
  4747. $copyrights = null;
  4748. $credits = null;
  4749. $description = null;
  4750. $hashes = null;
  4751. $keywords = null;
  4752. $player = null;
  4753. $ratings = null;
  4754. $restrictions = null;
  4755. $thumbnails = null;
  4756. $title = null;
  4757. // Start checking the attributes of media:content
  4758. if (isset($content['attribs']['']['bitrate']))
  4759. {
  4760. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4761. }
  4762. if (isset($content['attribs']['']['channels']))
  4763. {
  4764. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  4765. }
  4766. if (isset($content['attribs']['']['duration']))
  4767. {
  4768. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  4769. }
  4770. else
  4771. {
  4772. $duration = $duration_parent;
  4773. }
  4774. if (isset($content['attribs']['']['expression']))
  4775. {
  4776. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  4777. }
  4778. if (isset($content['attribs']['']['framerate']))
  4779. {
  4780. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4781. }
  4782. if (isset($content['attribs']['']['height']))
  4783. {
  4784. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  4785. }
  4786. if (isset($content['attribs']['']['lang']))
  4787. {
  4788. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4789. }
  4790. if (isset($content['attribs']['']['fileSize']))
  4791. {
  4792. $length = ceil($content['attribs']['']['fileSize']);
  4793. }
  4794. if (isset($content['attribs']['']['medium']))
  4795. {
  4796. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  4797. }
  4798. if (isset($content['attribs']['']['samplingrate']))
  4799. {
  4800. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4801. }
  4802. if (isset($content['attribs']['']['type']))
  4803. {
  4804. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4805. }
  4806. if (isset($content['attribs']['']['width']))
  4807. {
  4808. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  4809. }
  4810. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4811. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  4812. // CAPTIONS
  4813. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4814. {
  4815. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4816. {
  4817. $caption_type = null;
  4818. $caption_lang = null;
  4819. $caption_startTime = null;
  4820. $caption_endTime = null;
  4821. $caption_text = null;
  4822. if (isset($caption['attribs']['']['type']))
  4823. {
  4824. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4825. }
  4826. if (isset($caption['attribs']['']['lang']))
  4827. {
  4828. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4829. }
  4830. if (isset($caption['attribs']['']['start']))
  4831. {
  4832. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4833. }
  4834. if (isset($caption['attribs']['']['end']))
  4835. {
  4836. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4837. }
  4838. if (isset($caption['data']))
  4839. {
  4840. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4841. }
  4842. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4843. }
  4844. if (is_array($captions))
  4845. {
  4846. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4847. }
  4848. }
  4849. else
  4850. {
  4851. $captions = $captions_parent;
  4852. }
  4853. // CATEGORIES
  4854. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4855. {
  4856. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4857. {
  4858. $term = null;
  4859. $scheme = null;
  4860. $label = null;
  4861. if (isset($category['data']))
  4862. {
  4863. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4864. }
  4865. if (isset($category['attribs']['']['scheme']))
  4866. {
  4867. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4868. }
  4869. else
  4870. {
  4871. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4872. }
  4873. if (isset($category['attribs']['']['label']))
  4874. {
  4875. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4876. }
  4877. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4878. }
  4879. }
  4880. if (is_array($categories) && is_array($categories_parent))
  4881. {
  4882. $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
  4883. }
  4884. elseif (is_array($categories))
  4885. {
  4886. $categories = array_values(SimplePie_Misc::array_unique($categories));
  4887. }
  4888. elseif (is_array($categories_parent))
  4889. {
  4890. $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
  4891. }
  4892. else
  4893. {
  4894. $categories = null;
  4895. }
  4896. // COPYRIGHTS
  4897. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4898. {
  4899. $copyright_url = null;
  4900. $copyright_label = null;
  4901. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4902. {
  4903. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4904. }
  4905. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4906. {
  4907. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4908. }
  4909. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4910. }
  4911. else
  4912. {
  4913. $copyrights = $copyrights_parent;
  4914. }
  4915. // CREDITS
  4916. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4917. {
  4918. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4919. {
  4920. $credit_role = null;
  4921. $credit_scheme = null;
  4922. $credit_name = null;
  4923. if (isset($credit['attribs']['']['role']))
  4924. {
  4925. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4926. }
  4927. if (isset($credit['attribs']['']['scheme']))
  4928. {
  4929. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4930. }
  4931. else
  4932. {
  4933. $credit_scheme = 'urn:ebu';
  4934. }
  4935. if (isset($credit['data']))
  4936. {
  4937. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4938. }
  4939. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4940. }
  4941. if (is_array($credits))
  4942. {
  4943. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4944. }
  4945. }
  4946. else
  4947. {
  4948. $credits = $credits_parent;
  4949. }
  4950. // DESCRIPTION
  4951. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4952. {
  4953. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4954. }
  4955. else
  4956. {
  4957. $description = $description_parent;
  4958. }
  4959. // HASHES
  4960. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4961. {
  4962. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4963. {
  4964. $value = null;
  4965. $algo = null;
  4966. if (isset($hash['data']))
  4967. {
  4968. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4969. }
  4970. if (isset($hash['attribs']['']['algo']))
  4971. {
  4972. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4973. }
  4974. else
  4975. {
  4976. $algo = 'md5';
  4977. }
  4978. $hashes[] = $algo.':'.$value;
  4979. }
  4980. if (is_array($hashes))
  4981. {
  4982. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4983. }
  4984. }
  4985. else
  4986. {
  4987. $hashes = $hashes_parent;
  4988. }
  4989. // KEYWORDS
  4990. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4991. {
  4992. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4993. {
  4994. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4995. foreach ($temp as $word)
  4996. {
  4997. $keywords[] = trim($word);
  4998. }
  4999. unset($temp);
  5000. }
  5001. if (is_array($keywords))
  5002. {
  5003. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  5004. }
  5005. }
  5006. else
  5007. {
  5008. $keywords = $keywords_parent;
  5009. }
  5010. // PLAYER
  5011. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  5012. {
  5013. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  5014. }
  5015. else
  5016. {
  5017. $player = $player_parent;
  5018. }
  5019. // RATINGS
  5020. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  5021. {
  5022. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  5023. {
  5024. $rating_scheme = null;
  5025. $rating_value = null;
  5026. if (isset($rating['attribs']['']['scheme']))
  5027. {
  5028. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  5029. }
  5030. else
  5031. {
  5032. $rating_scheme = 'urn:simple';
  5033. }
  5034. if (isset($rating['data']))
  5035. {
  5036. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5037. }
  5038. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  5039. }
  5040. if (is_array($ratings))
  5041. {
  5042. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  5043. }
  5044. }
  5045. else
  5046. {
  5047. $ratings = $ratings_parent;
  5048. }
  5049. // RESTRICTIONS
  5050. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  5051. {
  5052. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  5053. {
  5054. $restriction_relationship = null;
  5055. $restriction_type = null;
  5056. $restriction_value = null;
  5057. if (isset($restriction['attribs']['']['relationship']))
  5058. {
  5059. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  5060. }
  5061. if (isset($restriction['attribs']['']['type']))
  5062. {
  5063. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5064. }
  5065. if (isset($restriction['data']))
  5066. {
  5067. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5068. }
  5069. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  5070. }
  5071. if (is_array($restrictions))
  5072. {
  5073. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  5074. }
  5075. }
  5076. else
  5077. {
  5078. $restrictions = $restrictions_parent;
  5079. }
  5080. // THUMBNAILS
  5081. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  5082. {
  5083. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  5084. {
  5085. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  5086. }
  5087. if (is_array($thumbnails))
  5088. {
  5089. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  5090. }
  5091. }
  5092. else
  5093. {
  5094. $thumbnails = $thumbnails_parent;
  5095. }
  5096. // TITLES
  5097. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  5098. {
  5099. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5100. }
  5101. else
  5102. {
  5103. $title = $title_parent;
  5104. }
  5105. $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);
  5106. }
  5107. }
  5108. }
  5109. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  5110. {
  5111. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
  5112. {
  5113. // Attributes
  5114. $bitrate = null;
  5115. $channels = null;
  5116. $duration = null;
  5117. $expression = null;
  5118. $framerate = null;
  5119. $height = null;
  5120. $javascript = null;
  5121. $lang = null;
  5122. $length = null;
  5123. $medium = null;
  5124. $samplingrate = null;
  5125. $type = null;
  5126. $url = null;
  5127. $width = null;
  5128. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5129. if (isset($link['attribs']['']['type']))
  5130. {
  5131. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5132. }
  5133. if (isset($link['attribs']['']['length']))
  5134. {
  5135. $length = ceil($link['attribs']['']['length']);
  5136. }
  5137. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5138. $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);
  5139. }
  5140. }
  5141. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  5142. {
  5143. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
  5144. {
  5145. // Attributes
  5146. $bitrate = null;
  5147. $channels = null;
  5148. $duration = null;
  5149. $expression = null;
  5150. $framerate = null;
  5151. $height = null;
  5152. $javascript = null;
  5153. $lang = null;
  5154. $length = null;
  5155. $medium = null;
  5156. $samplingrate = null;
  5157. $type = null;
  5158. $url = null;
  5159. $width = null;
  5160. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5161. if (isset($link['attribs']['']['type']))
  5162. {
  5163. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5164. }
  5165. if (isset($link['attribs']['']['length']))
  5166. {
  5167. $length = ceil($link['attribs']['']['length']);
  5168. }
  5169. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5170. $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);
  5171. }
  5172. }
  5173. if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure'))
  5174. {
  5175. if (isset($enclosure[0]['attribs']['']['url']))
  5176. {
  5177. // Attributes
  5178. $bitrate = null;
  5179. $channels = null;
  5180. $duration = null;
  5181. $expression = null;
  5182. $framerate = null;
  5183. $height = null;
  5184. $javascript = null;
  5185. $lang = null;
  5186. $length = null;
  5187. $medium = null;
  5188. $samplingrate = null;
  5189. $type = null;
  5190. $url = null;
  5191. $width = null;
  5192. $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
  5193. if (isset($enclosure[0]['attribs']['']['type']))
  5194. {
  5195. $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5196. }
  5197. if (isset($enclosure[0]['attribs']['']['length']))
  5198. {
  5199. $length = ceil($enclosure[0]['attribs']['']['length']);
  5200. }
  5201. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5202. $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);
  5203. }
  5204. }
  5205. 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))
  5206. {
  5207. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5208. $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);
  5209. }
  5210. $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
  5211. }
  5212. if (!empty($this->data['enclosures']))
  5213. {
  5214. return $this->data['enclosures'];
  5215. }
  5216. else
  5217. {
  5218. return null;
  5219. }
  5220. }
  5221. function get_latitude()
  5222. {
  5223. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  5224. {
  5225. return (float) $return[0]['data'];
  5226. }
  5227. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5228. {
  5229. return (float) $match[1];
  5230. }
  5231. else
  5232. {
  5233. return null;
  5234. }
  5235. }
  5236. function get_longitude()
  5237. {
  5238. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  5239. {
  5240. return (float) $return[0]['data'];
  5241. }
  5242. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  5243. {
  5244. return (float) $return[0]['data'];
  5245. }
  5246. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5247. {
  5248. return (float) $match[2];
  5249. }
  5250. else
  5251. {
  5252. return null;
  5253. }
  5254. }
  5255. function get_source()
  5256. {
  5257. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
  5258. {
  5259. return new $this->feed->source_class($this, $return[0]);
  5260. }
  5261. else
  5262. {
  5263. return null;
  5264. }
  5265. }
  5266. /**
  5267. * Creates the add_to_* methods' return data
  5268. *
  5269. * @access private
  5270. * @param string $item_url String to prefix to the item permalink
  5271. * @param string $title_url String to prefix to the item title
  5272. * (and suffix to the item permalink)
  5273. * @return mixed URL if feed exists, false otherwise
  5274. */
  5275. function add_to_service($item_url, $title_url = null, $summary_url = null)
  5276. {
  5277. if ($this->get_permalink() !== null)
  5278. {
  5279. $return = $item_url . rawurlencode($this->get_permalink());
  5280. if ($title_url !== null && $this->get_title() !== null)
  5281. {
  5282. $return .= $title_url . rawurlencode($this->get_title());
  5283. }
  5284. if ($summary_url !== null && $this->get_description() !== null)
  5285. {
  5286. $return .= $summary_url . rawurlencode($this->get_description());
  5287. }
  5288. return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
  5289. }
  5290. else
  5291. {
  5292. return null;
  5293. }
  5294. }
  5295. function add_to_blinklist()
  5296. {
  5297. return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
  5298. }
  5299. function add_to_blogmarks()
  5300. {
  5301. return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
  5302. }
  5303. function add_to_delicious()
  5304. {
  5305. return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
  5306. }
  5307. function add_to_digg()
  5308. {
  5309. return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
  5310. }
  5311. function add_to_furl()
  5312. {
  5313. return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
  5314. }
  5315. function add_to_magnolia()
  5316. {
  5317. return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
  5318. }
  5319. function add_to_myweb20()
  5320. {
  5321. return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
  5322. }
  5323. function add_to_newsvine()
  5324. {
  5325. return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
  5326. }
  5327. function add_to_reddit()
  5328. {
  5329. return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
  5330. }
  5331. function add_to_segnalo()
  5332. {
  5333. return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
  5334. }
  5335. function add_to_simpy()
  5336. {
  5337. return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
  5338. }
  5339. function add_to_spurl()
  5340. {
  5341. return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
  5342. }
  5343. function add_to_wists()
  5344. {
  5345. return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
  5346. }
  5347. function search_technorati()
  5348. {
  5349. return $this->add_to_service('http://www.technorati.com/search/');
  5350. }
  5351. }
  5352. class SimplePie_Source
  5353. {
  5354. var $item;
  5355. var $data = array();
  5356. function SimplePie_Source($item, $data)
  5357. {
  5358. $this->item = $item;
  5359. $this->data = $data;
  5360. }
  5361. function __toString()
  5362. {
  5363. return md5(serialize($this->data));
  5364. }
  5365. function get_source_tags($namespace, $tag)
  5366. {
  5367. if (isset($this->data['child'][$namespace][$tag]))
  5368. {
  5369. return $this->data['child'][$namespace][$tag];
  5370. }
  5371. else
  5372. {
  5373. return null;
  5374. }
  5375. }
  5376. function get_base($element = array())
  5377. {
  5378. return $this->item->get_base($element);
  5379. }
  5380. function sanitize($data, $type, $base = '')
  5381. {
  5382. return $this->item->sanitize($data, $type, $base);
  5383. }
  5384. function get_item()
  5385. {
  5386. return $this->item;
  5387. }
  5388. function get_title()
  5389. {
  5390. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  5391. {
  5392. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5393. }
  5394. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  5395. {
  5396. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5397. }
  5398. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  5399. {
  5400. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5401. }
  5402. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  5403. {
  5404. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5405. }
  5406. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  5407. {
  5408. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5409. }
  5410. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  5411. {
  5412. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5413. }
  5414. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  5415. {
  5416. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5417. }
  5418. else
  5419. {
  5420. return null;
  5421. }
  5422. }
  5423. function get_category($key = 0)
  5424. {
  5425. $categories = $this->get_categories();
  5426. if (isset($categories[$key]))
  5427. {
  5428. return $categories[$key];
  5429. }
  5430. else
  5431. {
  5432. return null;
  5433. }
  5434. }
  5435. function get_categories()
  5436. {
  5437. $categories = array();
  5438. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  5439. {
  5440. $term = null;
  5441. $scheme = null;
  5442. $label = null;
  5443. if (isset($category['attribs']['']['term']))
  5444. {
  5445. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  5446. }
  5447. if (isset($category['attribs']['']['scheme']))
  5448. {
  5449. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  5450. }
  5451. if (isset($category['attribs']['']['label']))
  5452. {
  5453. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  5454. }
  5455. $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
  5456. }
  5457. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
  5458. {
  5459. // This is really the label, but keep this as the term also for BC.
  5460. // Label will also work on retrieving because that falls back to term.
  5461. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5462. if (isset($category['attribs']['']['domain']))
  5463. {
  5464. $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
  5465. }
  5466. else
  5467. {
  5468. $scheme = null;
  5469. }
  5470. $categories[] =& new $this->item->feed->category_class($term, $scheme, null);
  5471. }
  5472. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  5473. {
  5474. $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5475. }
  5476. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  5477. {
  5478. $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5479. }
  5480. if (!empty($categories))
  5481. {
  5482. return SimplePie_Misc::array_unique($categories);
  5483. }
  5484. else
  5485. {
  5486. return null;
  5487. }
  5488. }
  5489. function get_author($key = 0)
  5490. {
  5491. $authors = $this->get_authors();
  5492. if (isset($authors[$key]))
  5493. {
  5494. return $authors[$key];
  5495. }
  5496. else
  5497. {
  5498. return null;
  5499. }
  5500. }
  5501. function get_authors()
  5502. {
  5503. $authors = array();
  5504. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  5505. {
  5506. $name = null;
  5507. $uri = null;
  5508. $email = null;
  5509. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  5510. {
  5511. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5512. }
  5513. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  5514. {
  5515. $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]));
  5516. }
  5517. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  5518. {
  5519. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5520. }
  5521. if ($name !== null || $email !== null || $uri !== null)
  5522. {
  5523. $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
  5524. }
  5525. }
  5526. if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  5527. {
  5528. $name = null;
  5529. $url = null;
  5530. $email = null;
  5531. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  5532. {
  5533. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5534. }
  5535. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  5536. {
  5537. $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]));
  5538. }
  5539. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  5540. {
  5541. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5542. }
  5543. if ($name !== null || $email !== null || $url !== null)
  5544. {
  5545. $authors[] =& new $this->item->feed->author_class($name, $url, $email);
  5546. }
  5547. }
  5548. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  5549. {
  5550. $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5551. }
  5552. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  5553. {
  5554. $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5555. }
  5556. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  5557. {
  5558. $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5559. }
  5560. if (!empty($authors))
  5561. {
  5562. return SimplePie_Misc::array_unique($authors);
  5563. }
  5564. else
  5565. {
  5566. return null;
  5567. }
  5568. }
  5569. function get_contributor($key = 0)
  5570. {
  5571. $contributors = $this->get_contributors();
  5572. if (isset($contributors[$key]))
  5573. {
  5574. return $contributors[$key];
  5575. }
  5576. else
  5577. {
  5578. return null;
  5579. }
  5580. }
  5581. function get_contributors()
  5582. {
  5583. $contributors = array();
  5584. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  5585. {
  5586. $name = null;
  5587. $uri = null;
  5588. $email = null;
  5589. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  5590. {
  5591. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5592. }
  5593. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  5594. {
  5595. $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]));
  5596. }
  5597. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  5598. {
  5599. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5600. }
  5601. if ($name !== null || $email !== null || $uri !== null)
  5602. {
  5603. $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
  5604. }
  5605. }
  5606. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  5607. {
  5608. $name = null;
  5609. $url = null;
  5610. $email = null;
  5611. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  5612. {
  5613. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5614. }
  5615. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  5616. {
  5617. $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]));
  5618. }
  5619. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  5620. {
  5621. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5622. }
  5623. if ($name !== null || $email !== null || $url !== null)
  5624. {
  5625. $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
  5626. }
  5627. }
  5628. if (!empty($contributors))
  5629. {
  5630. return SimplePie_Misc::array_unique($contributors);
  5631. }
  5632. else
  5633. {
  5634. return null;
  5635. }
  5636. }
  5637. function get_link($key = 0, $rel = 'alternate')
  5638. {
  5639. $links = $this->get_links($rel);
  5640. if (isset($links[$key]))
  5641. {
  5642. return $links[$key];
  5643. }
  5644. else
  5645. {
  5646. return null;
  5647. }
  5648. }
  5649. /**
  5650. * Added for parity between the parent-level and the item/entry-level.
  5651. */
  5652. function get_permalink()
  5653. {
  5654. return $this->get_link(0);
  5655. }
  5656. function get_links($rel = 'alternate')
  5657. {
  5658. if (!isset($this->data['links']))
  5659. {
  5660. $this->data['links'] = array();
  5661. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  5662. {
  5663. foreach ($links as $link)
  5664. {
  5665. if (isset($link['attribs']['']['href']))
  5666. {
  5667. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  5668. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5669. }
  5670. }
  5671. }
  5672. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  5673. {
  5674. foreach ($links as $link)
  5675. {
  5676. if (isset($link['attribs']['']['href']))
  5677. {
  5678. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  5679. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5680. }
  5681. }
  5682. }
  5683. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  5684. {
  5685. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5686. }
  5687. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  5688. {
  5689. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5690. }
  5691. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  5692. {
  5693. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5694. }
  5695. $keys = array_keys($this->data['links']);
  5696. foreach ($keys as $key)
  5697. {
  5698. if (SimplePie_Misc::is_isegment_nz_nc($key))
  5699. {
  5700. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  5701. {
  5702. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  5703. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  5704. }
  5705. else
  5706. {
  5707. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  5708. }
  5709. }
  5710. elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  5711. {
  5712. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  5713. }
  5714. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  5715. }
  5716. }
  5717. if (isset($this->data['links'][$rel]))
  5718. {
  5719. return $this->data['links'][$rel];
  5720. }
  5721. else
  5722. {
  5723. return null;
  5724. }
  5725. }
  5726. function get_description()
  5727. {
  5728. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  5729. {
  5730. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5731. }
  5732. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  5733. {
  5734. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5735. }
  5736. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  5737. {
  5738. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5739. }
  5740. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  5741. {
  5742. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5743. }
  5744. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
  5745. {
  5746. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5747. }
  5748. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  5749. {
  5750. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5751. }
  5752. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  5753. {
  5754. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5755. }
  5756. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  5757. {
  5758. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5759. }
  5760. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  5761. {
  5762. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5763. }
  5764. else
  5765. {
  5766. return null;
  5767. }
  5768. }
  5769. function get_copyright()
  5770. {
  5771. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  5772. {
  5773. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5774. }
  5775. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
  5776. {
  5777. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5778. }
  5779. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
  5780. {
  5781. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5782. }
  5783. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  5784. {
  5785. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5786. }
  5787. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  5788. {
  5789. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5790. }
  5791. else
  5792. {
  5793. return null;
  5794. }
  5795. }
  5796. function get_language()
  5797. {
  5798. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
  5799. {
  5800. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5801. }
  5802. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  5803. {
  5804. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5805. }
  5806. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  5807. {
  5808. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5809. }
  5810. elseif (isset($this->data['xml_lang']))
  5811. {
  5812. return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  5813. }
  5814. else
  5815. {
  5816. return null;
  5817. }
  5818. }
  5819. function get_latitude()
  5820. {
  5821. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  5822. {
  5823. return (float) $return[0]['data'];
  5824. }
  5825. elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5826. {
  5827. return (float) $match[1];
  5828. }
  5829. else
  5830. {
  5831. return null;
  5832. }
  5833. }
  5834. function get_longitude()
  5835. {
  5836. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  5837. {
  5838. return (float) $return[0]['data'];
  5839. }
  5840. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  5841. {
  5842. return (float) $return[0]['data'];
  5843. }
  5844. elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5845. {
  5846. return (float) $match[2];
  5847. }
  5848. else
  5849. {
  5850. return null;
  5851. }
  5852. }
  5853. function get_image_url()
  5854. {
  5855. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  5856. {
  5857. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  5858. }
  5859. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  5860. {
  5861. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  5862. }
  5863. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  5864. {
  5865. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  5866. }
  5867. else
  5868. {
  5869. return null;
  5870. }
  5871. }
  5872. }
  5873. class SimplePie_Author
  5874. {
  5875. var $name;
  5876. var $link;
  5877. var $email;
  5878. // Constructor, used to input the data
  5879. function SimplePie_Author($name = null, $link = null, $email = null)
  5880. {
  5881. $this->name = $name;
  5882. $this->link = $link;
  5883. $this->email = $email;
  5884. }
  5885. function __toString()
  5886. {
  5887. // There is no $this->data here
  5888. return md5(serialize($this));
  5889. }
  5890. function get_name()
  5891. {
  5892. if ($this->name !== null)
  5893. {
  5894. return $this->name;
  5895. }
  5896. else
  5897. {
  5898. return null;
  5899. }
  5900. }
  5901. function get_link()
  5902. {
  5903. if ($this->link !== null)
  5904. {
  5905. return $this->link;
  5906. }
  5907. else
  5908. {
  5909. return null;
  5910. }
  5911. }
  5912. function get_email()
  5913. {
  5914. if ($this->email !== null)
  5915. {
  5916. return $this->email;
  5917. }
  5918. else
  5919. {
  5920. return null;
  5921. }
  5922. }
  5923. }
  5924. class SimplePie_Category
  5925. {
  5926. var $term;
  5927. var $scheme;
  5928. var $label;
  5929. // Constructor, used to input the data
  5930. function SimplePie_Category($term = null, $scheme = null, $label = null)
  5931. {
  5932. $this->term = $term;
  5933. $this->scheme = $scheme;
  5934. $this->label = $label;
  5935. }
  5936. function __toString()
  5937. {
  5938. // There is no $this->data here
  5939. return md5(serialize($this));
  5940. }
  5941. function get_term()
  5942. {
  5943. if ($this->term !== null)
  5944. {
  5945. return $this->term;
  5946. }
  5947. else
  5948. {
  5949. return null;
  5950. }
  5951. }
  5952. function get_scheme()
  5953. {
  5954. if ($this->scheme !== null)
  5955. {
  5956. return $this->scheme;
  5957. }
  5958. else
  5959. {
  5960. return null;
  5961. }
  5962. }
  5963. function get_label()
  5964. {
  5965. if ($this->label !== null)
  5966. {
  5967. return $this->label;
  5968. }
  5969. else
  5970. {
  5971. return $this->get_term();
  5972. }
  5973. }
  5974. }
  5975. class SimplePie_Enclosure
  5976. {
  5977. var $bitrate;
  5978. var $captions;
  5979. var $categories;
  5980. var $channels;
  5981. var $copyright;
  5982. var $credits;
  5983. var $description;
  5984. var $duration;
  5985. var $expression;
  5986. var $framerate;
  5987. var $handler;
  5988. var $hashes;
  5989. var $height;
  5990. var $javascript;
  5991. var $keywords;
  5992. var $lang;
  5993. var $length;
  5994. var $link;
  5995. var $medium;
  5996. var $player;
  5997. var $ratings;
  5998. var $restrictions;
  5999. var $samplingrate;
  6000. var $thumbnails;
  6001. var $title;
  6002. var $type;
  6003. var $width;
  6004. // Constructor, used to input the data
  6005. 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)
  6006. {
  6007. $this->bitrate = $bitrate;
  6008. $this->captions = $captions;
  6009. $this->categories = $categories;
  6010. $this->channels = $channels;
  6011. $this->copyright = $copyright;
  6012. $this->credits = $credits;
  6013. $this->description = $description;
  6014. $this->duration = $duration;
  6015. $this->expression = $expression;
  6016. $this->framerate = $framerate;
  6017. $this->hashes = $hashes;
  6018. $this->height = $height;
  6019. $this->javascript = $javascript;
  6020. $this->keywords = $keywords;
  6021. $this->lang = $lang;
  6022. $this->length = $length;
  6023. $this->link = $link;
  6024. $this->medium = $medium;
  6025. $this->player = $player;
  6026. $this->ratings = $ratings;
  6027. $this->restrictions = $restrictions;
  6028. $this->samplingrate = $samplingrate;
  6029. $this->thumbnails = $thumbnails;
  6030. $this->title = $title;
  6031. $this->type = $type;
  6032. $this->width = $width;
  6033. if (class_exists('idna_convert'))
  6034. {
  6035. $idn =& new idna_convert;
  6036. $parsed = SimplePie_Misc::parse_url($link);
  6037. $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  6038. }
  6039. $this->handler = $this->get_handler(); // Needs to load last
  6040. }
  6041. function __toString()
  6042. {
  6043. // There is no $this->data here
  6044. return md5(serialize($this));
  6045. }
  6046. function get_bitrate()
  6047. {
  6048. if ($this->bitrate !== null)
  6049. {
  6050. return $this->bitrate;
  6051. }
  6052. else
  6053. {
  6054. return null;
  6055. }
  6056. }
  6057. function get_caption($key = 0)
  6058. {
  6059. $captions = $this->get_captions();
  6060. if (isset($captions[$key]))
  6061. {
  6062. return $captions[$key];
  6063. }
  6064. else
  6065. {
  6066. return null;
  6067. }
  6068. }
  6069. function get_captions()
  6070. {
  6071. if ($this->captions !== null)
  6072. {
  6073. return $this->captions;
  6074. }
  6075. else
  6076. {
  6077. return null;
  6078. }
  6079. }
  6080. function get_category($key = 0)
  6081. {
  6082. $categories = $this->get_categories();
  6083. if (isset($categories[$key]))
  6084. {
  6085. return $categories[$key];
  6086. }
  6087. else
  6088. {
  6089. return null;
  6090. }
  6091. }
  6092. function get_categories()
  6093. {
  6094. if ($this->categories !== null)
  6095. {
  6096. return $this->categories;
  6097. }
  6098. else
  6099. {
  6100. return null;
  6101. }
  6102. }
  6103. function get_channels()
  6104. {
  6105. if ($this->channels !== null)
  6106. {
  6107. return $this->channels;
  6108. }
  6109. else
  6110. {
  6111. return null;
  6112. }
  6113. }
  6114. function get_copyright()
  6115. {
  6116. if ($this->copyright !== null)
  6117. {
  6118. return $this->copyright;
  6119. }
  6120. else
  6121. {
  6122. return null;
  6123. }
  6124. }
  6125. function get_credit($key = 0)
  6126. {
  6127. $credits = $this->get_credits();
  6128. if (isset($credits[$key]))
  6129. {
  6130. return $credits[$key];
  6131. }
  6132. else
  6133. {
  6134. return null;
  6135. }
  6136. }
  6137. function get_credits()
  6138. {
  6139. if ($this->credits !== null)
  6140. {
  6141. return $this->credits;
  6142. }
  6143. else
  6144. {
  6145. return null;
  6146. }
  6147. }
  6148. function get_description()
  6149. {
  6150. if ($this->description !== null)
  6151. {
  6152. return $this->description;
  6153. }
  6154. else
  6155. {
  6156. return null;
  6157. }
  6158. }
  6159. function get_duration($convert = false)
  6160. {
  6161. if ($this->duration !== null)
  6162. {
  6163. if ($convert)
  6164. {
  6165. $time = SimplePie_Misc::time_hms($this->duration);
  6166. return $time;
  6167. }
  6168. else
  6169. {
  6170. return $this->duration;
  6171. }
  6172. }
  6173. else
  6174. {
  6175. return null;
  6176. }
  6177. }
  6178. function get_expression()
  6179. {
  6180. if ($this->expression !== null)
  6181. {
  6182. return $this->expression;
  6183. }
  6184. else
  6185. {
  6186. return 'full';
  6187. }
  6188. }
  6189. function get_extension()
  6190. {
  6191. if ($this->link !== null)
  6192. {
  6193. $url = SimplePie_Misc::parse_url($this->link);
  6194. if ($url['path'] !== '')
  6195. {
  6196. return pathinfo($url['path'], PATHINFO_EXTENSION);
  6197. }
  6198. }
  6199. return null;
  6200. }
  6201. function get_framerate()
  6202. {
  6203. if ($this->framerate !== null)
  6204. {
  6205. return $this->framerate;
  6206. }
  6207. else
  6208. {
  6209. return null;
  6210. }
  6211. }
  6212. function get_handler()
  6213. {
  6214. return $this->get_real_type(true);
  6215. }
  6216. function get_hash($key = 0)
  6217. {
  6218. $hashes = $this->get_hashes();
  6219. if (isset($hashes[$key]))
  6220. {
  6221. return $hashes[$key];
  6222. }
  6223. else
  6224. {
  6225. return null;
  6226. }
  6227. }
  6228. function get_hashes()
  6229. {
  6230. if ($this->hashes !== null)
  6231. {
  6232. return $this->hashes;
  6233. }
  6234. else
  6235. {
  6236. return null;
  6237. }
  6238. }
  6239. function get_height()
  6240. {
  6241. if ($this->height !== null)
  6242. {
  6243. return $this->height;
  6244. }
  6245. else
  6246. {
  6247. return null;
  6248. }
  6249. }
  6250. function get_language()
  6251. {
  6252. if ($this->lang !== null)
  6253. {
  6254. return $this->lang;
  6255. }
  6256. else
  6257. {
  6258. return null;
  6259. }
  6260. }
  6261. function get_keyword($key = 0)
  6262. {
  6263. $keywords = $this->get_keywords();
  6264. if (isset($keywords[$key]))
  6265. {
  6266. return $keywords[$key];
  6267. }
  6268. else
  6269. {
  6270. return null;
  6271. }
  6272. }
  6273. function get_keywords()
  6274. {
  6275. if ($this->keywords !== null)
  6276. {
  6277. return $this->keywords;
  6278. }
  6279. else
  6280. {
  6281. return null;
  6282. }
  6283. }
  6284. function get_length()
  6285. {
  6286. if ($this->length !== null)
  6287. {
  6288. return $this->length;
  6289. }
  6290. else
  6291. {
  6292. return null;
  6293. }
  6294. }
  6295. function get_link()
  6296. {
  6297. if ($this->link !== null)
  6298. {
  6299. return urldecode($this->link);
  6300. }
  6301. else
  6302. {
  6303. return null;
  6304. }
  6305. }
  6306. function get_medium()
  6307. {
  6308. if ($this->medium !== null)
  6309. {
  6310. return $this->medium;
  6311. }
  6312. else
  6313. {
  6314. return null;
  6315. }
  6316. }
  6317. function get_player()
  6318. {
  6319. if ($this->player !== null)
  6320. {
  6321. return $this->player;
  6322. }
  6323. else
  6324. {
  6325. return null;
  6326. }
  6327. }
  6328. function get_rating($key = 0)
  6329. {
  6330. $ratings = $this->get_ratings();
  6331. if (isset($ratings[$key]))
  6332. {
  6333. return $ratings[$key];
  6334. }
  6335. else
  6336. {
  6337. return null;
  6338. }
  6339. }
  6340. function get_ratings()
  6341. {
  6342. if ($this->ratings !== null)
  6343. {
  6344. return $this->ratings;
  6345. }
  6346. else
  6347. {
  6348. return null;
  6349. }
  6350. }
  6351. function get_restriction($key = 0)
  6352. {
  6353. $restrictions = $this->get_restrictions();
  6354. if (isset($restrictions[$key]))
  6355. {
  6356. return $restrictions[$key];
  6357. }
  6358. else
  6359. {
  6360. return null;
  6361. }
  6362. }
  6363. function get_restrictions()
  6364. {
  6365. if ($this->restrictions !== null)
  6366. {
  6367. return $this->restrictions;
  6368. }
  6369. else
  6370. {
  6371. return null;
  6372. }
  6373. }
  6374. function get_sampling_rate()
  6375. {
  6376. if ($this->samplingrate !== null)
  6377. {
  6378. return $this->samplingrate;
  6379. }
  6380. else
  6381. {
  6382. return null;
  6383. }
  6384. }
  6385. function get_size()
  6386. {
  6387. $length = $this->get_length();
  6388. if ($length !== null)
  6389. {
  6390. return round($length/1048576, 2);
  6391. }
  6392. else
  6393. {
  6394. return null;
  6395. }
  6396. }
  6397. function get_thumbnail($key = 0)
  6398. {
  6399. $thumbnails = $this->get_thumbnails();
  6400. if (isset($thumbnails[$key]))
  6401. {
  6402. return $thumbnails[$key];
  6403. }
  6404. else
  6405. {
  6406. return null;
  6407. }
  6408. }
  6409. function get_thumbnails()
  6410. {
  6411. if ($this->thumbnails !== null)
  6412. {
  6413. return $this->thumbnails;
  6414. }
  6415. else
  6416. {
  6417. return null;
  6418. }
  6419. }
  6420. function get_title()
  6421. {
  6422. if ($this->title !== null)
  6423. {
  6424. return $this->title;
  6425. }
  6426. else
  6427. {
  6428. return null;
  6429. }
  6430. }
  6431. function get_type()
  6432. {
  6433. if ($this->type !== null)
  6434. {
  6435. return $this->type;
  6436. }
  6437. else
  6438. {
  6439. return null;
  6440. }
  6441. }
  6442. function get_width()
  6443. {
  6444. if ($this->width !== null)
  6445. {
  6446. return $this->width;
  6447. }
  6448. else
  6449. {
  6450. return null;
  6451. }
  6452. }
  6453. function native_embed($options='')
  6454. {
  6455. return $this->embed($options, true);
  6456. }
  6457. /**
  6458. * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
  6459. */
  6460. function embed($options = '', $native = false)
  6461. {
  6462. // Set up defaults
  6463. $audio = '';
  6464. $video = '';
  6465. $alt = '';
  6466. $altclass = '';
  6467. $loop = 'false';
  6468. $width = 'auto';
  6469. $height = 'auto';
  6470. $bgcolor = '#ffffff';
  6471. $mediaplayer = '';
  6472. $widescreen = false;
  6473. $handler = $this->get_handler();
  6474. $type = $this->get_real_type();
  6475. // Process options and reassign values as necessary
  6476. if (is_array($options))
  6477. {
  6478. extract($options);
  6479. }
  6480. else
  6481. {
  6482. $options = explode(',', $options);
  6483. foreach($options as $option)
  6484. {
  6485. $opt = explode(':', $option, 2);
  6486. if (isset($opt[0], $opt[1]))
  6487. {
  6488. $opt[0] = trim($opt[0]);
  6489. $opt[1] = trim($opt[1]);
  6490. switch ($opt[0])
  6491. {
  6492. case 'audio':
  6493. $audio = $opt[1];
  6494. break;
  6495. case 'video':
  6496. $video = $opt[1];
  6497. break;
  6498. case 'alt':
  6499. $alt = $opt[1];
  6500. break;
  6501. case 'altclass':
  6502. $altclass = $opt[1];
  6503. break;
  6504. case 'loop':
  6505. $loop = $opt[1];
  6506. break;
  6507. case 'width':
  6508. $width = $opt[1];
  6509. break;
  6510. case 'height':
  6511. $height = $opt[1];
  6512. break;
  6513. case 'bgcolor':
  6514. $bgcolor = $opt[1];
  6515. break;
  6516. case 'mediaplayer':
  6517. $mediaplayer = $opt[1];
  6518. break;
  6519. case 'widescreen':
  6520. $widescreen = $opt[1];
  6521. break;
  6522. }
  6523. }
  6524. }
  6525. }
  6526. $mime = explode('/', $type, 2);
  6527. $mime = $mime[0];
  6528. // Process values for 'auto'
  6529. if ($width === 'auto')
  6530. {
  6531. if ($mime === 'video')
  6532. {
  6533. if ($height === 'auto')
  6534. {
  6535. $width = 480;
  6536. }
  6537. elseif ($widescreen)
  6538. {
  6539. $width = round((intval($height)/9)*16);
  6540. }
  6541. else
  6542. {
  6543. $width = round((intval($height)/3)*4);
  6544. }
  6545. }
  6546. else
  6547. {
  6548. $width = '100%';
  6549. }
  6550. }
  6551. if ($height === 'auto')
  6552. {
  6553. if ($mime === 'audio')
  6554. {
  6555. $height = 0;
  6556. }
  6557. elseif ($mime === 'video')
  6558. {
  6559. if ($width === 'auto')
  6560. {
  6561. if ($widescreen)
  6562. {
  6563. $height = 270;
  6564. }
  6565. else
  6566. {
  6567. $height = 360;
  6568. }
  6569. }
  6570. elseif ($widescreen)
  6571. {
  6572. $height = round((intval($width)/16)*9);
  6573. }
  6574. else
  6575. {
  6576. $height = round((intval($width)/4)*3);
  6577. }
  6578. }
  6579. else
  6580. {
  6581. $height = 376;
  6582. }
  6583. }
  6584. elseif ($mime === 'audio')
  6585. {
  6586. $height = 0;
  6587. }
  6588. // Set proper placeholder value
  6589. if ($mime === 'audio')
  6590. {
  6591. $placeholder = $audio;
  6592. }
  6593. elseif ($mime === 'video')
  6594. {
  6595. $placeholder = $video;
  6596. }
  6597. $embed = '';
  6598. // Make sure the JS library is included
  6599. if (!$native)
  6600. {
  6601. static $javascript_outputted = null;
  6602. if (!$javascript_outputted && $this->javascript)
  6603. {
  6604. $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
  6605. $javascript_outputted = true;
  6606. }
  6607. }
  6608. // Odeo Feed MP3's
  6609. if ($handler === 'odeo')
  6610. {
  6611. if ($native)
  6612. {
  6613. $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>';
  6614. }
  6615. else
  6616. {
  6617. $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
  6618. }
  6619. }
  6620. // Flash
  6621. elseif ($handler === 'flash')
  6622. {
  6623. if ($native)
  6624. {
  6625. $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>";
  6626. }
  6627. else
  6628. {
  6629. $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
  6630. }
  6631. }
  6632. // Flash Media Player file types.
  6633. // Preferred handler for MP3 file types.
  6634. elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
  6635. {
  6636. $height += 20;
  6637. if ($native)
  6638. {
  6639. $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>";
  6640. }
  6641. else
  6642. {
  6643. $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
  6644. }
  6645. }
  6646. // QuickTime 7 file types. Need to test with QuickTime 6.
  6647. // Only handle MP3's if the Flash Media Player is not present.
  6648. elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
  6649. {
  6650. $height += 16;
  6651. if ($native)
  6652. {
  6653. if ($placeholder !== '')
  6654. {
  6655. $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>";
  6656. }
  6657. else
  6658. {
  6659. $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>";
  6660. }
  6661. }
  6662. else
  6663. {
  6664. $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
  6665. }
  6666. }
  6667. // Windows Media
  6668. elseif ($handler === 'wmedia')
  6669. {
  6670. $height += 45;
  6671. if ($native)
  6672. {
  6673. $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>";
  6674. }
  6675. else
  6676. {
  6677. $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
  6678. }
  6679. }
  6680. // Everything else
  6681. else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
  6682. return $embed;
  6683. }
  6684. function get_real_type($find_handler = false)
  6685. {
  6686. // If it's Odeo, let's get it out of the way.
  6687. if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')
  6688. {
  6689. return 'odeo';
  6690. }
  6691. // Mime-types by handler.
  6692. $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
  6693. $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
  6694. $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
  6695. $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
  6696. $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
  6697. if ($this->get_type() !== null)
  6698. {
  6699. $type = strtolower($this->type);
  6700. }
  6701. else
  6702. {
  6703. $type = null;
  6704. }
  6705. // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
  6706. if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
  6707. {
  6708. switch (strtolower($this->get_extension()))
  6709. {
  6710. // Audio mime-types
  6711. case 'aac':
  6712. case 'adts':
  6713. $type = 'audio/acc';
  6714. break;
  6715. case 'aif':
  6716. case 'aifc':
  6717. case 'aiff':
  6718. case 'cdda':
  6719. $type = 'audio/aiff';
  6720. break;
  6721. case 'bwf':
  6722. $type = 'audio/wav';
  6723. break;
  6724. case 'kar':
  6725. case 'mid':
  6726. case 'midi':
  6727. case 'smf':
  6728. $type = 'audio/midi';
  6729. break;
  6730. case 'm4a':
  6731. $type = 'audio/x-m4a';
  6732. break;
  6733. case 'mp3':
  6734. case 'swa':
  6735. $type = 'audio/mp3';
  6736. break;
  6737. case 'wav':
  6738. $type = 'audio/wav';
  6739. break;
  6740. case 'wax':
  6741. $type = 'audio/x-ms-wax';
  6742. break;
  6743. case 'wma':
  6744. $type = 'audio/x-ms-wma';
  6745. break;
  6746. // Video mime-types
  6747. case '3gp':
  6748. case '3gpp':
  6749. $type = 'video/3gpp';
  6750. break;
  6751. case '3g2':
  6752. case '3gp2':
  6753. $type = 'video/3gpp2';
  6754. break;
  6755. case 'asf':
  6756. $type = 'video/x-ms-asf';
  6757. break;
  6758. case 'flv':
  6759. $type = 'video/x-flv';
  6760. break;
  6761. case 'm1a':
  6762. case 'm1s':
  6763. case 'm1v':
  6764. case 'm15':
  6765. case 'm75':
  6766. case 'mp2':
  6767. case 'mpa':
  6768. case 'mpeg':
  6769. case 'mpg':
  6770. case 'mpm':
  6771. case 'mpv':
  6772. $type = 'video/mpeg';
  6773. break;
  6774. case 'm4v':
  6775. $type = 'video/x-m4v';
  6776. break;
  6777. case 'mov':
  6778. case 'qt':
  6779. $type = 'video/quicktime';
  6780. break;
  6781. case 'mp4':
  6782. case 'mpg4':
  6783. $type = 'video/mp4';
  6784. break;
  6785. case 'sdv':
  6786. $type = 'video/sd-video';
  6787. break;
  6788. case 'wm':
  6789. $type = 'video/x-ms-wm';
  6790. break;
  6791. case 'wmv':
  6792. $type = 'video/x-ms-wmv';
  6793. break;
  6794. case 'wvx':
  6795. $type = 'video/x-ms-wvx';
  6796. break;
  6797. // Flash mime-types
  6798. case 'spl':
  6799. $type = 'application/futuresplash';
  6800. break;
  6801. case 'swf':
  6802. $type = 'application/x-shockwave-flash';
  6803. break;
  6804. }
  6805. }
  6806. if ($find_handler)
  6807. {
  6808. if (in_array($type, $types_flash))
  6809. {
  6810. return 'flash';
  6811. }
  6812. elseif (in_array($type, $types_fmedia))
  6813. {
  6814. return 'fmedia';
  6815. }
  6816. elseif (in_array($type, $types_quicktime))
  6817. {
  6818. return 'quicktime';
  6819. }
  6820. elseif (in_array($type, $types_wmedia))
  6821. {
  6822. return 'wmedia';
  6823. }
  6824. elseif (in_array($type, $types_mp3))
  6825. {
  6826. return 'mp3';
  6827. }
  6828. else
  6829. {
  6830. return null;
  6831. }
  6832. }
  6833. else
  6834. {
  6835. return $type;
  6836. }
  6837. }
  6838. }
  6839. class SimplePie_Caption
  6840. {
  6841. var $type;
  6842. var $lang;
  6843. var $startTime;
  6844. var $endTime;
  6845. var $text;
  6846. // Constructor, used to input the data
  6847. function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
  6848. {
  6849. $this->type = $type;
  6850. $this->lang = $lang;
  6851. $this->startTime = $startTime;
  6852. $this->endTime = $endTime;
  6853. $this->text = $text;
  6854. }
  6855. function __toString()
  6856. {
  6857. // There is no $this->data here
  6858. return md5(serialize($this));
  6859. }
  6860. function get_endtime()
  6861. {
  6862. if ($this->endTime !== null)
  6863. {
  6864. return $this->endTime;
  6865. }
  6866. else
  6867. {
  6868. return null;
  6869. }
  6870. }
  6871. function get_language()
  6872. {
  6873. if ($this->lang !== null)
  6874. {
  6875. return $this->lang;
  6876. }
  6877. else
  6878. {
  6879. return null;
  6880. }
  6881. }
  6882. function get_starttime()
  6883. {
  6884. if ($this->startTime !== null)
  6885. {
  6886. return $this->startTime;
  6887. }
  6888. else
  6889. {
  6890. return null;
  6891. }
  6892. }
  6893. function get_text()
  6894. {
  6895. if ($this->text !== null)
  6896. {
  6897. return $this->text;
  6898. }
  6899. else
  6900. {
  6901. return null;
  6902. }
  6903. }
  6904. function get_type()
  6905. {
  6906. if ($this->type !== null)
  6907. {
  6908. return $this->type;
  6909. }
  6910. else
  6911. {
  6912. return null;
  6913. }
  6914. }
  6915. }
  6916. class SimplePie_Credit
  6917. {
  6918. var $role;
  6919. var $scheme;
  6920. var $name;
  6921. // Constructor, used to input the data
  6922. function SimplePie_Credit($role = null, $scheme = null, $name = null)
  6923. {
  6924. $this->role = $role;
  6925. $this->scheme = $scheme;
  6926. $this->name = $name;
  6927. }
  6928. function __toString()
  6929. {
  6930. // There is no $this->data here
  6931. return md5(serialize($this));
  6932. }
  6933. function get_role()
  6934. {
  6935. if ($this->role !== null)
  6936. {
  6937. return $this->role;
  6938. }
  6939. else
  6940. {
  6941. return null;
  6942. }
  6943. }
  6944. function get_scheme()
  6945. {
  6946. if ($this->scheme !== null)
  6947. {
  6948. return $this->scheme;
  6949. }
  6950. else
  6951. {
  6952. return null;
  6953. }
  6954. }
  6955. function get_name()
  6956. {
  6957. if ($this->name !== null)
  6958. {
  6959. return $this->name;
  6960. }
  6961. else
  6962. {
  6963. return null;
  6964. }
  6965. }
  6966. }
  6967. class SimplePie_Copyright
  6968. {
  6969. var $url;
  6970. var $label;
  6971. // Constructor, used to input the data
  6972. function SimplePie_Copyright($url = null, $label = null)
  6973. {
  6974. $this->url = $url;
  6975. $this->label = $label;
  6976. }
  6977. function __toString()
  6978. {
  6979. // There is no $this->data here
  6980. return md5(serialize($this));
  6981. }
  6982. function get_url()
  6983. {
  6984. if ($this->url !== null)
  6985. {
  6986. return $this->url;
  6987. }
  6988. else
  6989. {
  6990. return null;
  6991. }
  6992. }
  6993. function get_attribution()
  6994. {
  6995. if ($this->label !== null)
  6996. {
  6997. return $this->label;
  6998. }
  6999. else
  7000. {
  7001. return null;
  7002. }
  7003. }
  7004. }
  7005. class SimplePie_Rating
  7006. {
  7007. var $scheme;
  7008. var $value;
  7009. // Constructor, used to input the data
  7010. function SimplePie_Rating($scheme = null, $value = null)
  7011. {
  7012. $this->scheme = $scheme;
  7013. $this->value = $value;
  7014. }
  7015. function __toString()
  7016. {
  7017. // There is no $this->data here
  7018. return md5(serialize($this));
  7019. }
  7020. function get_scheme()
  7021. {
  7022. if ($this->scheme !== null)
  7023. {
  7024. return $this->scheme;
  7025. }
  7026. else
  7027. {
  7028. return null;
  7029. }
  7030. }
  7031. function get_value()
  7032. {
  7033. if ($this->value !== null)
  7034. {
  7035. return $this->value;
  7036. }
  7037. else
  7038. {
  7039. return null;
  7040. }
  7041. }
  7042. }
  7043. class SimplePie_Restriction
  7044. {
  7045. var $relationship;
  7046. var $type;
  7047. var $value;
  7048. // Constructor, used to input the data
  7049. function SimplePie_Restriction($relationship = null, $type = null, $value = null)
  7050. {
  7051. $this->relationship = $relationship;
  7052. $this->type = $type;
  7053. $this->value = $value;
  7054. }
  7055. function __toString()
  7056. {
  7057. // There is no $this->data here
  7058. return md5(serialize($this));
  7059. }
  7060. function get_relationship()
  7061. {
  7062. if ($this->relationship !== null)
  7063. {
  7064. return $this->relationship;
  7065. }
  7066. else
  7067. {
  7068. return null;
  7069. }
  7070. }
  7071. function get_type()
  7072. {
  7073. if ($this->type !== null)
  7074. {
  7075. return $this->type;
  7076. }
  7077. else
  7078. {
  7079. return null;
  7080. }
  7081. }
  7082. function get_value()
  7083. {
  7084. if ($this->value !== null)
  7085. {
  7086. return $this->value;
  7087. }
  7088. else
  7089. {
  7090. return null;
  7091. }
  7092. }
  7093. }
  7094. /**
  7095. * @todo Move to properly supporting RFC2616 (HTTP/1.1)
  7096. */
  7097. class SimplePie_File
  7098. {
  7099. var $url;
  7100. var $useragent;
  7101. var $success = true;
  7102. var $headers = array();
  7103. var $body;
  7104. var $status_code;
  7105. var $redirects = 0;
  7106. var $error;
  7107. var $method = SIMPLEPIE_FILE_SOURCE_NONE;
  7108. function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
  7109. {
  7110. if (class_exists('idna_convert'))
  7111. {
  7112. $idn =& new idna_convert;
  7113. $parsed = SimplePie_Misc::parse_url($url);
  7114. $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  7115. }
  7116. $this->url = $url;
  7117. $this->useragent = $useragent;
  7118. if (preg_match('/^http(s)?:\/\//i', $url))
  7119. {
  7120. if ($useragent === null)
  7121. {
  7122. $useragent = ini_get('user_agent');
  7123. $this->useragent = $useragent;
  7124. }
  7125. if (!is_array($headers))
  7126. {
  7127. $headers = array();
  7128. }
  7129. if (!$force_fsockopen && function_exists('curl_exec'))
  7130. {
  7131. $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
  7132. $fp = curl_init();
  7133. $headers2 = array();
  7134. foreach ($headers as $key => $value)
  7135. {
  7136. $headers2[] = "$key: $value";
  7137. }
  7138. if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
  7139. {
  7140. curl_setopt($fp, CURLOPT_ENCODING, '');
  7141. }
  7142. curl_setopt($fp, CURLOPT_URL, $url);
  7143. curl_setopt($fp, CURLOPT_HEADER, 1);
  7144. curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
  7145. curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
  7146. curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
  7147. curl_setopt($fp, CURLOPT_REFERER, $url);
  7148. curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
  7149. curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
  7150. if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
  7151. {
  7152. curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
  7153. curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
  7154. }
  7155. $this->headers = curl_exec($fp);
  7156. if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
  7157. {
  7158. curl_setopt($fp, CURLOPT_ENCODING, 'none');
  7159. $this->headers = curl_exec($fp);
  7160. }
  7161. if (curl_errno($fp))
  7162. {
  7163. $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
  7164. $this->success = false;
  7165. }
  7166. else
  7167. {
  7168. $info = curl_getinfo($fp);
  7169. curl_close($fp);
  7170. $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
  7171. $this->headers = array_pop($this->headers);
  7172. $parser =& new SimplePie_HTTP_Parser($this->headers);
  7173. if ($parser->parse())
  7174. {
  7175. $this->headers = $parser->headers;
  7176. $this->body = $parser->body;
  7177. $this->status_code = $parser->status_code;
  7178. if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  7179. {
  7180. $this->redirects++;
  7181. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  7182. return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  7183. }
  7184. }
  7185. }
  7186. }
  7187. else
  7188. {
  7189. $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
  7190. $url_parts = parse_url($url);
  7191. if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
  7192. {
  7193. $url_parts['host'] = "ssl://$url_parts[host]";
  7194. $url_parts['port'] = 443;
  7195. }
  7196. if (!isset($url_parts['port']))
  7197. {
  7198. $url_parts['port'] = 80;
  7199. }
  7200. $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
  7201. if (!$fp)
  7202. {
  7203. $this->error = 'fsockopen error: ' . $errstr;
  7204. $this->success = false;
  7205. }
  7206. else
  7207. {
  7208. stream_set_timeout($fp, $timeout);
  7209. if (isset($url_parts['path']))
  7210. {
  7211. if (isset($url_parts['query']))
  7212. {
  7213. $get = "$url_parts[path]?$url_parts[query]";
  7214. }
  7215. else
  7216. {
  7217. $get = $url_parts['path'];
  7218. }
  7219. }
  7220. else
  7221. {
  7222. $get = '/';
  7223. }
  7224. $out = "GET $get HTTP/1.0\r\n";
  7225. $out .= "Host: $url_parts[host]\r\n";
  7226. $out .= "User-Agent: $useragent\r\n";
  7227. if (extension_loaded('zlib'))
  7228. {
  7229. $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
  7230. }
  7231. if (isset($url_parts['user']) && isset($url_parts['pass']))
  7232. {
  7233. $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
  7234. }
  7235. foreach ($headers as $key => $value)
  7236. {
  7237. $out .= "$key: $value\r\n";
  7238. }
  7239. $out .= "Connection: Close\r\n\r\n";
  7240. fwrite($fp, $out);
  7241. $info = stream_get_meta_data($fp);
  7242. $this->headers = '';
  7243. while (!$info['eof'] && !$info['timed_out'])
  7244. {
  7245. $this->headers .= fread($fp, 1160);
  7246. $info = stream_get_meta_data($fp);
  7247. }
  7248. if (!$info['timed_out'])
  7249. {
  7250. $parser =& new SimplePie_HTTP_Parser($this->headers);
  7251. if ($parser->parse())
  7252. {
  7253. $this->headers = $parser->headers;
  7254. $this->body = $parser->body;
  7255. $this->status_code = $parser->status_code;
  7256. if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  7257. {
  7258. $this->redirects++;
  7259. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  7260. return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  7261. }
  7262. if (isset($this->headers['content-encoding']))
  7263. {
  7264. // Hey, we act dumb elsewhere, so let's do that here too
  7265. switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
  7266. {
  7267. case 'gzip':
  7268. case 'x-gzip':
  7269. $decoder =& new SimplePie_gzdecode($this->body);
  7270. if (!$decoder->parse())
  7271. {
  7272. $this->error = 'Unable to decode HTTP "gzip" stream';
  7273. $this->success = false;
  7274. }
  7275. else
  7276. {
  7277. $this->body = $decoder->data;
  7278. }
  7279. break;
  7280. case 'deflate':
  7281. if (($body = gzuncompress($this->body)) === false)
  7282. {
  7283. if (($body = gzinflate($this->body)) === false)
  7284. {
  7285. $this->error = 'Unable to decode HTTP "deflate" stream';
  7286. $this->success = false;
  7287. }
  7288. }
  7289. $this->body = $body;
  7290. break;
  7291. default:
  7292. $this->error = 'Unknown content coding';
  7293. $this->success = false;
  7294. }
  7295. }
  7296. }
  7297. }
  7298. else
  7299. {
  7300. $this->error = 'fsocket timed out';
  7301. $this->success = false;
  7302. }
  7303. fclose($fp);
  7304. }
  7305. }
  7306. }
  7307. else
  7308. {
  7309. $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
  7310. if (!$this->body = file_get_contents($url))
  7311. {
  7312. $this->error = 'file_get_contents could not read the file';
  7313. $this->success = false;
  7314. }
  7315. }
  7316. }
  7317. }
  7318. /**
  7319. * HTTP Response Parser
  7320. *
  7321. * @package SimplePie
  7322. */
  7323. class SimplePie_HTTP_Parser
  7324. {
  7325. /**
  7326. * HTTP Version
  7327. *
  7328. * @access public
  7329. * @var float
  7330. */
  7331. var $http_version = 0.0;
  7332. /**
  7333. * Status code
  7334. *
  7335. * @access public
  7336. * @var int
  7337. */
  7338. var $status_code = 0;
  7339. /**
  7340. * Reason phrase
  7341. *
  7342. * @access public
  7343. * @var string
  7344. */
  7345. var $reason = '';
  7346. /**
  7347. * Key/value pairs of the headers
  7348. *
  7349. * @access public
  7350. * @var array
  7351. */
  7352. var $headers = array();
  7353. /**
  7354. * Body of the response
  7355. *
  7356. * @access public
  7357. * @var string
  7358. */
  7359. var $body = '';
  7360. /**
  7361. * Current state of the state machine
  7362. *
  7363. * @access private
  7364. * @var string
  7365. */
  7366. var $state = 'http_version';
  7367. /**
  7368. * Input data
  7369. *
  7370. * @access private
  7371. * @var string
  7372. */
  7373. var $data = '';
  7374. /**
  7375. * Input data length (to avoid calling strlen() everytime this is needed)
  7376. *
  7377. * @access private
  7378. * @var int
  7379. */
  7380. var $data_length = 0;
  7381. /**
  7382. * Current position of the pointer
  7383. *
  7384. * @var int
  7385. * @access private
  7386. */
  7387. var $position = 0;
  7388. /**
  7389. * Name of the hedaer currently being parsed
  7390. *
  7391. * @access private
  7392. * @var string
  7393. */
  7394. var $name = '';
  7395. /**
  7396. * Value of the hedaer currently being parsed
  7397. *
  7398. * @access private
  7399. * @var string
  7400. */
  7401. var $value = '';
  7402. /**
  7403. * Create an instance of the class with the input data
  7404. *
  7405. * @access public
  7406. * @param string $data Input data
  7407. */
  7408. function SimplePie_HTTP_Parser($data)
  7409. {
  7410. $this->data = $data;
  7411. $this->data_length = strlen($this->data);
  7412. }
  7413. /**
  7414. * Parse the input data
  7415. *
  7416. * @access public
  7417. * @return bool true on success, false on failure
  7418. */
  7419. function parse()
  7420. {
  7421. while ($this->state && $this->state !== 'emit' && $this->has_data())
  7422. {
  7423. $state = $this->state;
  7424. $this->$state();
  7425. }
  7426. $this->data = '';
  7427. if ($this->state === 'emit' || $this->state === 'body')
  7428. {
  7429. return true;
  7430. }
  7431. else
  7432. {
  7433. $this->http_version = '';
  7434. $this->status_code = '';
  7435. $this->reason = '';
  7436. $this->headers = array();
  7437. $this->body = '';
  7438. return false;
  7439. }
  7440. }
  7441. /**
  7442. * Check whether there is data beyond the pointer
  7443. *
  7444. * @access private
  7445. * @return bool true if there is further data, false if not
  7446. */
  7447. function has_data()
  7448. {
  7449. return (bool) ($this->position < $this->data_length);
  7450. }
  7451. /**
  7452. * See if the next character is LWS
  7453. *
  7454. * @access private
  7455. * @return bool true if the next character is LWS, false if not
  7456. */
  7457. function is_linear_whitespace()
  7458. {
  7459. return (bool) ($this->data[$this->position] === "\x09"
  7460. || $this->data[$this->position] === "\x20"
  7461. || ($this->data[$this->position] === "\x0A"
  7462. && isset($this->data[$this->position + 1])
  7463. && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
  7464. }
  7465. /**
  7466. * Parse the HTTP version
  7467. *
  7468. * @access private
  7469. */
  7470. function http_version()
  7471. {
  7472. if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
  7473. {
  7474. $len = strspn($this->data, '0123456789.', 5);
  7475. $this->http_version = substr($this->data, 5, $len);
  7476. $this->position += 5 + $len;
  7477. if (substr_count($this->http_version, '.') <= 1)
  7478. {
  7479. $this->http_version = (float) $this->http_version;
  7480. $this->position += strspn($this->data, "\x09\x20", $this->position);
  7481. $this->state = 'status';
  7482. }
  7483. else
  7484. {
  7485. $this->state = false;
  7486. }
  7487. }
  7488. else
  7489. {
  7490. $this->state = false;
  7491. }
  7492. }
  7493. /**
  7494. * Parse the status code
  7495. *
  7496. * @access private
  7497. */
  7498. function status()
  7499. {
  7500. if ($len = strspn($this->data, '0123456789', $this->position))
  7501. {
  7502. $this->status_code = (int) substr($this->data, $this->position, $len);
  7503. $this->position += $len;
  7504. $this->state = 'reason';
  7505. }
  7506. else
  7507. {
  7508. $this->state = false;
  7509. }
  7510. }
  7511. /**
  7512. * Parse the reason phrase
  7513. *
  7514. * @access private
  7515. */
  7516. function reason()
  7517. {
  7518. $len = strcspn($this->data, "\x0A", $this->position);
  7519. $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
  7520. $this->position += $len + 1;
  7521. $this->state = 'new_line';
  7522. }
  7523. /**
  7524. * Deal with a new line, shifting data around as needed
  7525. *
  7526. * @access private
  7527. */
  7528. function new_line()
  7529. {
  7530. $this->value = trim($this->value, "\x0D\x20");
  7531. if ($this->name !== '' && $this->value !== '')
  7532. {
  7533. $this->name = strtolower($this->name);
  7534. if (isset($this->headers[$this->name]))
  7535. {
  7536. $this->headers[$this->name] .= ', ' . $this->value;
  7537. }
  7538. else
  7539. {
  7540. $this->headers[$this->name] = $this->value;
  7541. }
  7542. }
  7543. $this->name = '';
  7544. $this->value = '';
  7545. if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
  7546. {
  7547. $this->position += 2;
  7548. $this->state = 'body';
  7549. }
  7550. elseif ($this->data[$this->position] === "\x0A")
  7551. {
  7552. $this->position++;
  7553. $this->state = 'body';
  7554. }
  7555. else
  7556. {
  7557. $this->state = 'name';
  7558. }
  7559. }
  7560. /**
  7561. * Parse a header name
  7562. *
  7563. * @access private
  7564. */
  7565. function name()
  7566. {
  7567. $len = strcspn($this->data, "\x0A:", $this->position);
  7568. if (isset($this->data[$this->position + $len]))
  7569. {
  7570. if ($this->data[$this->position + $len] === "\x0A")
  7571. {
  7572. $this->position += $len;
  7573. $this->state = 'new_line';
  7574. }
  7575. else
  7576. {
  7577. $this->name = substr($this->data, $this->position, $len);
  7578. $this->position += $len + 1;
  7579. $this->state = 'value';
  7580. }
  7581. }
  7582. else
  7583. {
  7584. $this->state = false;
  7585. }
  7586. }
  7587. /**
  7588. * Parse LWS, replacing consecutive LWS characters with a single space
  7589. *
  7590. * @access private
  7591. */
  7592. function linear_whitespace()
  7593. {
  7594. do
  7595. {
  7596. if (substr($this->data, $this->position, 2) === "\x0D\x0A")
  7597. {
  7598. $this->position += 2;
  7599. }
  7600. elseif ($this->data[$this->position] === "\x0A")
  7601. {
  7602. $this->position++;
  7603. }
  7604. $this->position += strspn($this->data, "\x09\x20", $this->position);
  7605. } while ($this->has_data() && $this->is_linear_whitespace());
  7606. $this->value .= "\x20";
  7607. }
  7608. /**
  7609. * See what state to move to while within non-quoted header values
  7610. *
  7611. * @access private
  7612. */
  7613. function value()
  7614. {
  7615. if ($this->is_linear_whitespace())
  7616. {
  7617. $this->linear_whitespace();
  7618. }
  7619. else
  7620. {
  7621. switch ($this->data[$this->position])
  7622. {
  7623. case '"':
  7624. $this->position++;
  7625. $this->state = 'quote';
  7626. break;
  7627. case "\x0A":
  7628. $this->position++;
  7629. $this->state = 'new_line';
  7630. break;
  7631. default:
  7632. $this->state = 'value_char';
  7633. break;
  7634. }
  7635. }
  7636. }
  7637. /**
  7638. * Parse a header value while outside quotes
  7639. *
  7640. * @access private
  7641. */
  7642. function value_char()
  7643. {
  7644. $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
  7645. $this->value .= substr($this->data, $this->position, $len);
  7646. $this->position += $len;
  7647. $this->state = 'value';
  7648. }
  7649. /**
  7650. * See what state to move to while within quoted header values
  7651. *
  7652. * @access private
  7653. */
  7654. function quote()
  7655. {
  7656. if ($this->is_linear_whitespace())
  7657. {
  7658. $this->linear_whitespace();
  7659. }
  7660. else
  7661. {
  7662. switch ($this->data[$this->position])
  7663. {
  7664. case '"':
  7665. $this->position++;
  7666. $this->state = 'value';
  7667. break;
  7668. case "\x0A":
  7669. $this->position++;
  7670. $this->state = 'new_line';
  7671. break;
  7672. case '\\':
  7673. $this->position++;
  7674. $this->state = 'quote_escaped';
  7675. break;
  7676. default:
  7677. $this->state = 'quote_char';
  7678. break;
  7679. }
  7680. }
  7681. }
  7682. /**
  7683. * Parse a header value while within quotes
  7684. *
  7685. * @access private
  7686. */
  7687. function quote_char()
  7688. {
  7689. $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
  7690. $this->value .= substr($this->data, $this->position, $len);
  7691. $this->position += $len;
  7692. $this->state = 'value';
  7693. }
  7694. /**
  7695. * Parse an escaped character within quotes
  7696. *
  7697. * @access private
  7698. */
  7699. function quote_escaped()
  7700. {
  7701. $this->value .= $this->data[$this->position];
  7702. $this->position++;
  7703. $this->state = 'quote';
  7704. }
  7705. /**
  7706. * Parse the body
  7707. *
  7708. * @access private
  7709. */
  7710. function body()
  7711. {
  7712. $this->body = substr($this->data, $this->position);
  7713. $this->state = 'emit';
  7714. }
  7715. }
  7716. /**
  7717. * gzdecode
  7718. *
  7719. * @package SimplePie
  7720. */
  7721. class SimplePie_gzdecode
  7722. {
  7723. /**
  7724. * Compressed data
  7725. *
  7726. * @access private
  7727. * @see gzdecode::$data
  7728. */
  7729. var $compressed_data;
  7730. /**
  7731. * Size of compressed data
  7732. *
  7733. * @access private
  7734. */
  7735. var $compressed_size;
  7736. /**
  7737. * Minimum size of a valid gzip string
  7738. *
  7739. * @access private
  7740. */
  7741. var $min_compressed_size = 18;
  7742. /**
  7743. * Current position of pointer
  7744. *
  7745. * @access private
  7746. */
  7747. var $position = 0;
  7748. /**
  7749. * Flags (FLG)
  7750. *
  7751. * @access private
  7752. */
  7753. var $flags;
  7754. /**
  7755. * Uncompressed data
  7756. *
  7757. * @access public
  7758. * @see gzdecode::$compressed_data
  7759. */
  7760. var $data;
  7761. /**
  7762. * Modified time
  7763. *
  7764. * @access public
  7765. */
  7766. var $MTIME;
  7767. /**
  7768. * Extra Flags
  7769. *
  7770. * @access public
  7771. */
  7772. var $XFL;
  7773. /**
  7774. * Operating System
  7775. *
  7776. * @access public
  7777. */
  7778. var $OS;
  7779. /**
  7780. * Subfield ID 1
  7781. *
  7782. * @access public
  7783. * @see gzdecode::$extra_field
  7784. * @see gzdecode::$SI2
  7785. */
  7786. var $SI1;
  7787. /**
  7788. * Subfield ID 2
  7789. *
  7790. * @access public
  7791. * @see gzdecode::$extra_field
  7792. * @see gzdecode::$SI1
  7793. */
  7794. var $SI2;
  7795. /**
  7796. * Extra field content
  7797. *
  7798. * @access public
  7799. * @see gzdecode::$SI1
  7800. * @see gzdecode::$SI2
  7801. */
  7802. var $extra_field;
  7803. /**
  7804. * Original filename
  7805. *
  7806. * @access public
  7807. */
  7808. var $filename;
  7809. /**
  7810. * Human readable comment
  7811. *
  7812. * @access public
  7813. */
  7814. var $comment;
  7815. /**
  7816. * Don't allow anything to be set
  7817. *
  7818. * @access public
  7819. */
  7820. function __set($name, $value)
  7821. {
  7822. trigger_error("Cannot write property $name", E_USER_ERROR);
  7823. }
  7824. /**
  7825. * Set the compressed string and related properties
  7826. *
  7827. * @access public
  7828. */
  7829. function SimplePie_gzdecode($data)
  7830. {
  7831. $this->compressed_data = $data;
  7832. $this->compressed_size = strlen($data);
  7833. }
  7834. /**
  7835. * Decode the GZIP stream
  7836. *
  7837. * @access public
  7838. */
  7839. function parse()
  7840. {
  7841. if ($this->compressed_size >= $this->min_compressed_size)
  7842. {
  7843. // Check ID1, ID2, and CM
  7844. if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
  7845. {
  7846. return false;
  7847. }
  7848. // Get the FLG (FLaGs)
  7849. $this->flags = ord($this->compressed_data[3]);
  7850. // FLG bits above (1 << 4) are reserved
  7851. if ($this->flags > 0x1F)
  7852. {
  7853. return false;
  7854. }
  7855. // Advance the pointer after the above
  7856. $this->position += 4;
  7857. // MTIME
  7858. $mtime = substr($this->compressed_data, $this->position, 4);
  7859. // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
  7860. if (current(unpack('S', "\x00\x01")) === 1)
  7861. {
  7862. $mtime = strrev($mtime);
  7863. }
  7864. $this->MTIME = current(unpack('l', $mtime));
  7865. $this->position += 4;
  7866. // Get the XFL (eXtra FLags)
  7867. $this->XFL = ord($this->compressed_data[$this->position++]);
  7868. // Get the OS (Operating System)
  7869. $this->OS = ord($this->compressed_data[$this->position++]);
  7870. // Parse the FEXTRA
  7871. if ($this->flags & 4)
  7872. {
  7873. // Read subfield IDs
  7874. $this->SI1 = $this->compressed_data[$this->position++];
  7875. $this->SI2 = $this->compressed_data[$this->position++];
  7876. // SI2 set to zero is reserved for future use
  7877. if ($this->SI2 === "\x00")
  7878. {
  7879. return false;
  7880. }
  7881. // Get the length of the extra field
  7882. $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
  7883. $position += 2;
  7884. // Check the length of the string is still valid
  7885. $this->min_compressed_size += $len + 4;
  7886. if ($this->compressed_size >= $this->min_compressed_size)
  7887. {
  7888. // Set the extra field to the given data
  7889. $this->extra_field = substr($this->compressed_data, $this->position, $len);
  7890. $this->position += $len;
  7891. }
  7892. else
  7893. {
  7894. return false;
  7895. }
  7896. }
  7897. // Parse the FNAME
  7898. if ($this->flags & 8)
  7899. {
  7900. // Get the length of the filename
  7901. $len = strcspn($this->compressed_data, "\x00", $this->position);
  7902. // Check the length of the string is still valid
  7903. $this->min_compressed_size += $len + 1;
  7904. if ($this->compressed_size >= $this->min_compressed_size)
  7905. {
  7906. // Set the original filename to the given string
  7907. $this->filename = substr($this->compressed_data, $this->position, $len);
  7908. $this->position += $len + 1;
  7909. }
  7910. else
  7911. {
  7912. return false;
  7913. }
  7914. }
  7915. // Parse the FCOMMENT
  7916. if ($this->flags & 16)
  7917. {
  7918. // Get the length of the comment
  7919. $len = strcspn($this->compressed_data, "\x00", $this->position);
  7920. // Check the length of the string is still valid
  7921. $this->min_compressed_size += $len + 1;
  7922. if ($this->compressed_size >= $this->min_compressed_size)
  7923. {
  7924. // Set the original comment to the given string
  7925. $this->comment = substr($this->compressed_data, $this->position, $len);
  7926. $this->position += $len + 1;
  7927. }
  7928. else
  7929. {
  7930. return false;
  7931. }
  7932. }
  7933. // Parse the FHCRC
  7934. if ($this->flags & 2)
  7935. {
  7936. // Check the length of the string is still valid
  7937. $this->min_compressed_size += $len + 2;
  7938. if ($this->compressed_size >= $this->min_compressed_size)
  7939. {
  7940. // Read the CRC
  7941. $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
  7942. // Check the CRC matches
  7943. if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
  7944. {
  7945. $this->position += 2;
  7946. }
  7947. else
  7948. {
  7949. return false;
  7950. }
  7951. }
  7952. else
  7953. {
  7954. return false;
  7955. }
  7956. }
  7957. // Decompress the actual data
  7958. if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
  7959. {
  7960. return false;
  7961. }
  7962. else
  7963. {
  7964. $this->position = $this->compressed_size - 8;
  7965. }
  7966. // Check CRC of data
  7967. $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
  7968. $this->position += 4;
  7969. /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
  7970. {
  7971. return false;
  7972. }*/
  7973. // Check ISIZE of data
  7974. $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
  7975. $this->position += 4;
  7976. if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
  7977. {
  7978. return false;
  7979. }
  7980. // Wow, against all odds, we've actually got a valid gzip string
  7981. return true;
  7982. }
  7983. else
  7984. {
  7985. return false;
  7986. }
  7987. }
  7988. }
  7989. class SimplePie_Cache
  7990. {
  7991. /**
  7992. * Don't call the constructor. Please.
  7993. *
  7994. * @access private
  7995. */
  7996. function SimplePie_Cache()
  7997. {
  7998. trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
  7999. }
  8000. /**
  8001. * Create a new SimplePie_Cache object
  8002. *
  8003. * @static
  8004. * @access public
  8005. */
  8006. function create($location, $filename, $extension)
  8007. {
  8008. $location_iri =& new SimplePie_IRI($location);
  8009. switch ($location_iri->get_scheme())
  8010. {
  8011. case 'mysql':
  8012. if (extension_loaded('mysql'))
  8013. {
  8014. return new SimplePie_Cache_MySQL($location_iri, $filename, $extension);
  8015. }
  8016. break;
  8017. default:
  8018. return new SimplePie_Cache_File($location, $filename, $extension);
  8019. }
  8020. }
  8021. }
  8022. class SimplePie_Cache_File
  8023. {
  8024. var $location;
  8025. var $filename;
  8026. var $extension;
  8027. var $name;
  8028. function SimplePie_Cache_File($location, $filename, $extension)
  8029. {
  8030. $this->location = $location;
  8031. $this->filename = $filename;
  8032. $this->extension = $extension;
  8033. $this->name = "$this->location/$this->filename.$this->extension";
  8034. }
  8035. function save($data)
  8036. {
  8037. if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
  8038. {
  8039. if (is_a($data, 'SimplePie'))
  8040. {
  8041. $data = $data->data;
  8042. }
  8043. $data = serialize($data);
  8044. if (function_exists('file_put_contents'))
  8045. {
  8046. return (bool) file_put_contents($this->name, $data);
  8047. }
  8048. else
  8049. {
  8050. $fp = fopen($this->name, 'wb');
  8051. if ($fp)
  8052. {
  8053. fwrite($fp, $data);
  8054. fclose($fp);
  8055. return true;
  8056. }
  8057. }
  8058. }
  8059. return false;
  8060. }
  8061. function load()
  8062. {
  8063. if (file_exists($this->name) && is_readable($this->name))
  8064. {
  8065. return unserialize(file_get_contents($this->name));
  8066. }
  8067. return false;
  8068. }
  8069. function mtime()
  8070. {
  8071. if (file_exists($this->name))
  8072. {
  8073. return filemtime($this->name);
  8074. }
  8075. return false;
  8076. }
  8077. function touch()
  8078. {
  8079. if (file_exists($this->name))
  8080. {
  8081. return touch($this->name);
  8082. }
  8083. return false;
  8084. }
  8085. function unlink()
  8086. {
  8087. if (file_exists($this->name))
  8088. {
  8089. return unlink($this->name);
  8090. }
  8091. return false;
  8092. }
  8093. }
  8094. class SimplePie_Cache_DB
  8095. {
  8096. function prepare_simplepie_object_for_cache($data)
  8097. {
  8098. $items = $data->get_items();
  8099. $items_by_id = array();
  8100. if (!empty($items))
  8101. {
  8102. foreach ($items as $item)
  8103. {
  8104. $items_by_id[$item->get_id()] = $item;
  8105. }
  8106. if (count($items_by_id) !== count($items))
  8107. {
  8108. $items_by_id = array();
  8109. foreach ($items as $item)
  8110. {
  8111. $items_by_id[$item->get_id(true)] = $item;
  8112. }
  8113. }
  8114. if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
  8115. {
  8116. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
  8117. }
  8118. elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
  8119. {
  8120. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
  8121. }
  8122. elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
  8123. {
  8124. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
  8125. }
  8126. elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
  8127. {
  8128. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
  8129. }
  8130. else
  8131. {
  8132. $channel = null;
  8133. }
  8134. if ($channel !== null)
  8135. {
  8136. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
  8137. {
  8138. unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
  8139. }
  8140. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
  8141. {
  8142. unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
  8143. }
  8144. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
  8145. {
  8146. unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
  8147. }
  8148. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
  8149. {
  8150. unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
  8151. }
  8152. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
  8153. {
  8154. unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
  8155. }
  8156. }
  8157. if (isset($data->data['items']))
  8158. {
  8159. unset($data->data['items']);
  8160. }
  8161. if (isset($data->data['ordered_items']))
  8162. {
  8163. unset($data->data['ordered_items']);
  8164. }
  8165. }
  8166. return array(serialize($data->data), $items_by_id);
  8167. }
  8168. }
  8169. class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
  8170. {
  8171. var $mysql;
  8172. var $options;
  8173. var $id;
  8174. function SimplePie_Cache_MySQL($mysql_location, $name, $extension)
  8175. {
  8176. $host = $mysql_location->get_host();
  8177. if (SimplePie_Misc::stripos($host, 'unix(') === 0 && substr($host, -1) === ')')
  8178. {
  8179. $server = ':' . substr($host, 5, -1);
  8180. }
  8181. else
  8182. {
  8183. $server = $host;
  8184. if ($mysql_location->get_port() !== null)
  8185. {
  8186. $server .= ':' . $mysql_location->get_port();
  8187. }
  8188. }
  8189. if (strpos($mysql_location->get_userinfo(), ':') !== false)
  8190. {
  8191. list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2);
  8192. }
  8193. else
  8194. {
  8195. $username = $mysql_location->get_userinfo();
  8196. $password = null;
  8197. }
  8198. if ($this->mysql = mysql_connect($server, $username, $password))
  8199. {
  8200. $this->id = $name . $extension;
  8201. $this->options = SimplePie_Misc::parse_str($mysql_location->get_query());
  8202. if (!isset($this->options['prefix'][0]))
  8203. {
  8204. $this->options['prefix'][0] = '';
  8205. }
  8206. if (mysql_select_db(ltrim($mysql_location->get_path(), '/'))
  8207. && mysql_query('SET NAMES utf8')
  8208. && ($query = mysql_unbuffered_query('SHOW TABLES')))
  8209. {
  8210. $db = array();
  8211. while ($row = mysql_fetch_row($query))
  8212. {
  8213. $db[] = $row[0];
  8214. }
  8215. if (!in_array($this->options['prefix'][0] . 'cache_data', $db))
  8216. {
  8217. if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))'))
  8218. {
  8219. $this->mysql = null;
  8220. }
  8221. }
  8222. if (!in_array($this->options['prefix'][0] . 'items', $db))
  8223. {
  8224. if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))'))
  8225. {
  8226. $this->mysql = null;
  8227. }
  8228. }
  8229. }
  8230. else
  8231. {
  8232. $this->mysql = null;
  8233. }
  8234. }
  8235. }
  8236. function save($data)
  8237. {
  8238. if ($this->mysql)
  8239. {
  8240. $feed_id = "'" . mysql_real_escape_string($this->id) . "'";
  8241. if (is_a($data, 'SimplePie'))
  8242. {
  8243. if (SIMPLEPIE_PHP5)
  8244. {
  8245. // This keyword needs to defy coding standards for PHP4 compatibility
  8246. $data = clone($data);
  8247. }
  8248. $prepared = $this->prepare_simplepie_object_for_cache($data);
  8249. if ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
  8250. {
  8251. if (mysql_num_rows($query))
  8252. {
  8253. $items = count($prepared[1]);
  8254. if ($items)
  8255. {
  8256. $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
  8257. }
  8258. else
  8259. {
  8260. $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
  8261. }
  8262. if (!mysql_query($sql, $this->mysql))
  8263. {
  8264. return false;
  8265. }
  8266. }
  8267. elseif (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(' . $feed_id . ', ' . count($prepared[1]) . ', \'' . mysql_real_escape_string($prepared[0]) . '\', ' . time() . ')', $this->mysql))
  8268. {
  8269. return false;
  8270. }
  8271. $ids = array_keys($prepared[1]);
  8272. if (!empty($ids))
  8273. {
  8274. foreach ($ids as $id)
  8275. {
  8276. $database_ids[] = mysql_real_escape_string($id);
  8277. }
  8278. if ($query = mysql_unbuffered_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'items` WHERE `id` = \'' . implode('\' OR `id` = \'', $database_ids) . '\' AND `feed_id` = ' . $feed_id, $this->mysql))
  8279. {
  8280. $existing_ids = array();
  8281. while ($row = mysql_fetch_row($query))
  8282. {
  8283. $existing_ids[] = $row[0];
  8284. }
  8285. $new_ids = array_diff($ids, $existing_ids);
  8286. foreach ($new_ids as $new_id)
  8287. {
  8288. if (!($date = $prepared[1][$new_id]->get_date('U')))
  8289. {
  8290. $date = time();
  8291. }
  8292. if (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(' . $feed_id . ', \'' . mysql_real_escape_string($new_id) . '\', \'' . mysql_real_escape_string(serialize($prepared[1][$new_id]->data)) . '\', ' . $date . ')', $this->mysql))
  8293. {
  8294. return false;
  8295. }
  8296. }
  8297. return true;
  8298. }
  8299. }
  8300. else
  8301. {
  8302. return true;
  8303. }
  8304. }
  8305. }
  8306. elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
  8307. {
  8308. if (mysql_num_rows($query))
  8309. {
  8310. if (mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = 0, `data` = \'' . mysql_real_escape_string(serialize($data)) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id, $this->mysql))
  8311. {
  8312. return true;
  8313. }
  8314. }
  8315. elseif (mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(\'' . mysql_real_escape_string($this->id) . '\', 0, \'' . mysql_real_escape_string(serialize($data)) . '\', ' . time() . ')', $this->mysql))
  8316. {
  8317. return true;
  8318. }
  8319. }
  8320. }
  8321. return false;
  8322. }
  8323. function load()
  8324. {
  8325. if ($this->mysql && ($query = mysql_query('SELECT `items`, `data` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
  8326. {
  8327. $data = unserialize($row[1]);
  8328. if (isset($this->options['items'][0]))
  8329. {
  8330. $items = (int) $this->options['items'][0];
  8331. }
  8332. else
  8333. {
  8334. $items = (int) $row[0];
  8335. }
  8336. if ($items !== 0)
  8337. {
  8338. if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
  8339. {
  8340. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
  8341. }
  8342. elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
  8343. {
  8344. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
  8345. }
  8346. elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
  8347. {
  8348. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
  8349. }
  8350. elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
  8351. {
  8352. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
  8353. }
  8354. else
  8355. {
  8356. $feed = null;
  8357. }
  8358. if ($feed !== null)
  8359. {
  8360. $sql = 'SELECT `data` FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . '\' ORDER BY `posted` DESC';
  8361. if ($items > 0)
  8362. {
  8363. $sql .= ' LIMIT ' . $items;
  8364. }
  8365. if ($query = mysql_unbuffered_query($sql, $this->mysql))
  8366. {
  8367. while ($row = mysql_fetch_row($query))
  8368. {
  8369. $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row[0]);
  8370. }
  8371. }
  8372. else
  8373. {
  8374. return false;
  8375. }
  8376. }
  8377. }
  8378. return $data;
  8379. }
  8380. return false;
  8381. }
  8382. function mtime()
  8383. {
  8384. if ($this->mysql && ($query = mysql_query('SELECT `mtime` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
  8385. {
  8386. return $row[0];
  8387. }
  8388. else
  8389. {
  8390. return false;
  8391. }
  8392. }
  8393. function touch()
  8394. {
  8395. if ($this->mysql && ($query = mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `mtime` = ' . time() . ' WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && mysql_affected_rows($this->mysql))
  8396. {
  8397. return true;
  8398. }
  8399. else
  8400. {
  8401. return false;
  8402. }
  8403. }
  8404. function unlink()
  8405. {
  8406. if ($this->mysql && ($query = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($query2 = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)))
  8407. {
  8408. return true;
  8409. }
  8410. else
  8411. {
  8412. return false;
  8413. }
  8414. }
  8415. }
  8416. class SimplePie_Misc
  8417. {
  8418. function time_hms($seconds)
  8419. {
  8420. $time = '';
  8421. $hours = floor($seconds / 3600);
  8422. $remainder = $seconds % 3600;
  8423. if ($hours > 0)
  8424. {
  8425. $time .= $hours.':';
  8426. }
  8427. $minutes = floor($remainder / 60);
  8428. $seconds = $remainder % 60;
  8429. if ($minutes < 10 && $hours > 0)
  8430. {
  8431. $minutes = '0' . $minutes;
  8432. }
  8433. if ($seconds < 10)
  8434. {
  8435. $seconds = '0' . $seconds;
  8436. }
  8437. $time .= $minutes.':';
  8438. $time .= $seconds;
  8439. return $time;
  8440. }
  8441. function absolutize_url($relative, $base)
  8442. {
  8443. $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);
  8444. return $iri->get_iri();
  8445. }
  8446. function remove_dot_segments($input)
  8447. {
  8448. $output = '';
  8449. while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
  8450. {
  8451. // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
  8452. if (strpos($input, '../') === 0)
  8453. {
  8454. $input = substr($input, 3);
  8455. }
  8456. elseif (strpos($input, './') === 0)
  8457. {
  8458. $input = substr($input, 2);
  8459. }
  8460. // 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,
  8461. elseif (strpos($input, '/./') === 0)
  8462. {
  8463. $input = substr_replace($input, '/', 0, 3);
  8464. }
  8465. elseif ($input === '/.')
  8466. {
  8467. $input = '/';
  8468. }
  8469. // 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,
  8470. elseif (strpos($input, '/../') === 0)
  8471. {
  8472. $input = substr_replace($input, '/', 0, 4);
  8473. $output = substr_replace($output, '', strrpos($output, '/'));
  8474. }
  8475. elseif ($input === '/..')
  8476. {
  8477. $input = '/';
  8478. $output = substr_replace($output, '', strrpos($output, '/'));
  8479. }
  8480. // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
  8481. elseif ($input === '.' || $input === '..')
  8482. {
  8483. $input = '';
  8484. }
  8485. // 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
  8486. elseif (($pos = strpos($input, '/', 1)) !== false)
  8487. {
  8488. $output .= substr($input, 0, $pos);
  8489. $input = substr_replace($input, '', 0, $pos);
  8490. }
  8491. else
  8492. {
  8493. $output .= $input;
  8494. $input = '';
  8495. }
  8496. }
  8497. return $output . $input;
  8498. }
  8499. function get_element($realname, $string)
  8500. {
  8501. $return = array();
  8502. $name = preg_quote($realname, '/');
  8503. if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
  8504. {
  8505. for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
  8506. {
  8507. $return[$i]['tag'] = $realname;
  8508. $return[$i]['full'] = $matches[$i][0][0];
  8509. $return[$i]['offset'] = $matches[$i][0][1];
  8510. if (strlen($matches[$i][3][0]) <= 2)
  8511. {
  8512. $return[$i]['self_closing'] = true;
  8513. }
  8514. else
  8515. {
  8516. $return[$i]['self_closing'] = false;
  8517. $return[$i]['content'] = $matches[$i][4][0];
  8518. }
  8519. $return[$i]['attribs'] = array();
  8520. 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))
  8521. {
  8522. for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
  8523. {
  8524. if (count($attribs[$j]) === 2)
  8525. {
  8526. $attribs[$j][2] = $attribs[$j][1];
  8527. }
  8528. $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
  8529. }
  8530. }
  8531. }
  8532. }
  8533. return $return;
  8534. }
  8535. function element_implode($element)
  8536. {
  8537. $full = "<$element[tag]";
  8538. foreach ($element['attribs'] as $key => $value)
  8539. {
  8540. $key = strtolower($key);
  8541. $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
  8542. }
  8543. if ($element['self_closing'])
  8544. {
  8545. $full .= ' />';
  8546. }
  8547. else
  8548. {
  8549. $full .= ">$element[content]</$element[tag]>";
  8550. }
  8551. return $full;
  8552. }
  8553. function error($message, $level, $file, $line)
  8554. {
  8555. if ((ini_get('error_reporting') & $level) > 0)
  8556. {
  8557. switch ($level)
  8558. {
  8559. case E_USER_ERROR:
  8560. $note = 'PHP Error';
  8561. break;
  8562. case E_USER_WARNING:
  8563. $note = 'PHP Warning';
  8564. break;
  8565. case E_USER_NOTICE:
  8566. $note = 'PHP Notice';
  8567. break;
  8568. default:
  8569. $note = 'Unknown Error';
  8570. break;
  8571. }
  8572. error_log("$note: $message in $file on line $line", 0);
  8573. }
  8574. return $message;
  8575. }
  8576. /**
  8577. * If a file has been cached, retrieve and display it.
  8578. *
  8579. * This is most useful for caching images (get_favicon(), etc.),
  8580. * however it works for all cached files. This WILL NOT display ANY
  8581. * file/image/page/whatever, but rather only display what has already
  8582. * been cached by SimplePie.
  8583. *
  8584. * @access public
  8585. * @see SimplePie::get_favicon()
  8586. * @param str $identifier_url URL that is used to identify the content.
  8587. * This may or may not be the actual URL of the live content.
  8588. * @param str $cache_location Location of SimplePie's cache. Defaults
  8589. * to './cache'.
  8590. * @param str $cache_extension The file extension that the file was
  8591. * cached with. Defaults to 'spc'.
  8592. * @param str $cache_class Name of the cache-handling class being used
  8593. * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
  8594. * as-is unless you've overloaded the class.
  8595. * @param str $cache_name_function Obsolete. Exists for backwards
  8596. * compatibility reasons only.
  8597. */
  8598. function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
  8599. {
  8600. $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
  8601. if ($file = $cache->load())
  8602. {
  8603. if (isset($file['headers']['content-type']))
  8604. {
  8605. header('Content-type:' . $file['headers']['content-type']);
  8606. }
  8607. else
  8608. {
  8609. header('Content-type: application/octet-stream');
  8610. }
  8611. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  8612. echo $file['body'];
  8613. exit;
  8614. }
  8615. die('Cached file for ' . $identifier_url . ' cannot be found.');
  8616. }
  8617. function fix_protocol($url, $http = 1)
  8618. {
  8619. $url = SimplePie_Misc::normalize_url($url);
  8620. $parsed = SimplePie_Misc::parse_url($url);
  8621. if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
  8622. {
  8623. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
  8624. }
  8625. if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
  8626. {
  8627. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
  8628. }
  8629. if ($http === 2 && $parsed['scheme'] !== '')
  8630. {
  8631. return "feed:$url";
  8632. }
  8633. elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
  8634. {
  8635. return substr_replace($url, 'podcast', 0, 4);
  8636. }
  8637. elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
  8638. {
  8639. return substr_replace($url, 'itpc', 0, 4);
  8640. }
  8641. else
  8642. {
  8643. return $url;
  8644. }
  8645. }
  8646. function parse_url($url)
  8647. {
  8648. $iri =& new SimplePie_IRI($url);
  8649. return array(
  8650. 'scheme' => (string) $iri->get_scheme(),
  8651. 'authority' => (string) $iri->get_authority(),
  8652. 'path' => (string) $iri->get_path(),
  8653. 'query' => (string) $iri->get_query(),
  8654. 'fragment' => (string) $iri->get_fragment()
  8655. );
  8656. }
  8657. function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
  8658. {
  8659. $iri =& new SimplePie_IRI('');
  8660. $iri->set_scheme($scheme);
  8661. $iri->set_authority($authority);
  8662. $iri->set_path($path);
  8663. $iri->set_query($query);
  8664. $iri->set_fragment($fragment);
  8665. return $iri->get_iri();
  8666. }
  8667. function normalize_url($url)
  8668. {
  8669. $iri =& new SimplePie_IRI($url);
  8670. return $iri->get_iri();
  8671. }
  8672. function percent_encoding_normalization($match)
  8673. {
  8674. $integer = hexdec($match[1]);
  8675. if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
  8676. {
  8677. return chr($integer);
  8678. }
  8679. else
  8680. {
  8681. return strtoupper($match[0]);
  8682. }
  8683. }
  8684. /**
  8685. * Remove bad UTF-8 bytes
  8686. *
  8687. * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
  8688. * FAQ: Multilingual Forms (modified to include full ASCII range)
  8689. *
  8690. * @author Geoffrey Sneddon
  8691. * @see http://www.w3.org/International/questions/qa-forms-utf-8
  8692. * @param string $str String to remove bad UTF-8 bytes from
  8693. * @return string UTF-8 string
  8694. */
  8695. function utf8_bad_replace($str)
  8696. {
  8697. if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
  8698. {
  8699. return $return;
  8700. }
  8701. elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
  8702. {
  8703. return $return;
  8704. }
  8705. 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))
  8706. {
  8707. return implode("\xEF\xBF\xBD", $matches[0]);
  8708. }
  8709. elseif ($str !== '')
  8710. {
  8711. return "\xEF\xBF\xBD";
  8712. }
  8713. else
  8714. {
  8715. return '';
  8716. }
  8717. }
  8718. /**
  8719. * Converts a Windows-1252 encoded string to a UTF-8 encoded string
  8720. *
  8721. * @static
  8722. * @access public
  8723. * @param string $string Windows-1252 encoded string
  8724. * @return string UTF-8 encoded string
  8725. */
  8726. function windows_1252_to_utf8($string)
  8727. {
  8728. 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");
  8729. return strtr($string, $convert_table);
  8730. }
  8731. function change_encoding($data, $input, $output)
  8732. {
  8733. $input = SimplePie_Misc::encoding($input);
  8734. $output = SimplePie_Misc::encoding($output);
  8735. // We fail to fail on non US-ASCII bytes
  8736. if ($input === 'US-ASCII')
  8737. {
  8738. static $non_ascii_octects = '';
  8739. if (!$non_ascii_octects)
  8740. {
  8741. for ($i = 0x80; $i <= 0xFF; $i++)
  8742. {
  8743. $non_ascii_octects .= chr($i);
  8744. }
  8745. }
  8746. $data = substr($data, 0, strcspn($data, $non_ascii_octects));
  8747. }
  8748. // This is first, as behaviour of this is completely predictable
  8749. if ($input === 'windows-1252' && $output === 'UTF-8')
  8750. {
  8751. return SimplePie_Misc::windows_1252_to_utf8($data);
  8752. }
  8753. // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
  8754. elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && ($return = @mb_convert_encoding($data, $output, $input)))
  8755. {
  8756. return $return;
  8757. }
  8758. // This is last, as behaviour of this varies with OS userland and PHP version
  8759. elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
  8760. {
  8761. return $return;
  8762. }
  8763. // If we can't do anything, just fail
  8764. else
  8765. {
  8766. return false;
  8767. }
  8768. }
  8769. function encoding($charset)
  8770. {
  8771. // Normalization from UTS #22
  8772. switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
  8773. {
  8774. case 'adobestandardencoding':
  8775. case 'csadobestandardencoding':
  8776. return 'Adobe-Standard-Encoding';
  8777. case 'adobesymbolencoding':
  8778. case 'cshppsmath':
  8779. return 'Adobe-Symbol-Encoding';
  8780. case 'ami1251':
  8781. case 'amiga1251':
  8782. return 'Amiga-1251';
  8783. case 'ansix31101983':
  8784. case 'csat5001983':
  8785. case 'csiso99naplps':
  8786. case 'isoir99':
  8787. case 'naplps':
  8788. return 'ANSI_X3.110-1983';
  8789. case 'arabic7':
  8790. case 'asmo449':
  8791. case 'csiso89asmo449':
  8792. case 'iso9036':
  8793. case 'isoir89':
  8794. return 'ASMO_449';
  8795. case 'big5':
  8796. case 'csbig5':
  8797. case 'xxbig5':
  8798. return 'Big5';
  8799. case 'big5hkscs':
  8800. return 'Big5-HKSCS';
  8801. case 'bocu1':
  8802. case 'csbocu1':
  8803. return 'BOCU-1';
  8804. case 'brf':
  8805. case 'csbrf':
  8806. return 'BRF';
  8807. case 'bs4730':
  8808. case 'csiso4unitedkingdom':
  8809. case 'gb':
  8810. case 'iso646gb':
  8811. case 'isoir4':
  8812. case 'uk':
  8813. return 'BS_4730';
  8814. case 'bsviewdata':
  8815. case 'csiso47bsviewdata':
  8816. case 'isoir47':
  8817. return 'BS_viewdata';
  8818. case 'cesu8':
  8819. case 'cscesu8':
  8820. return 'CESU-8';
  8821. case 'ca':
  8822. case 'csa71':
  8823. case 'csaz243419851':
  8824. case 'csiso121canadian1':
  8825. case 'iso646ca':
  8826. case 'isoir121':
  8827. return 'CSA_Z243.4-1985-1';
  8828. case 'csa72':
  8829. case 'csaz243419852':
  8830. case 'csiso122canadian2':
  8831. case 'iso646ca2':
  8832. case 'isoir122':
  8833. return 'CSA_Z243.4-1985-2';
  8834. case 'csaz24341985gr':
  8835. case 'csiso123csaz24341985gr':
  8836. case 'isoir123':
  8837. return 'CSA_Z243.4-1985-gr';
  8838. case 'csiso139csn369103':
  8839. case 'csn369103':
  8840. case 'isoir139':
  8841. return 'CSN_369103';
  8842. case 'csdecmcs':
  8843. case 'dec':
  8844. case 'decmcs':
  8845. return 'DEC-MCS';
  8846. case 'csiso21german':
  8847. case 'de':
  8848. case 'din66003':
  8849. case 'iso646de':
  8850. case 'isoir21':
  8851. return 'DIN_66003';
  8852. case 'csdkus':
  8853. case 'dkus':
  8854. return 'dk-us';
  8855. case 'csiso646danish':
  8856. case 'dk':
  8857. case 'ds2089':
  8858. case 'iso646dk':
  8859. return 'DS_2089';
  8860. case 'csibmebcdicatde':
  8861. case 'ebcdicatde':
  8862. return 'EBCDIC-AT-DE';
  8863. case 'csebcdicatdea':
  8864. case 'ebcdicatdea':
  8865. return 'EBCDIC-AT-DE-A';
  8866. case 'csebcdiccafr':
  8867. case 'ebcdiccafr':
  8868. return 'EBCDIC-CA-FR';
  8869. case 'csebcdicdkno':
  8870. case 'ebcdicdkno':
  8871. return 'EBCDIC-DK-NO';
  8872. case 'csebcdicdknoa':
  8873. case 'ebcdicdknoa':
  8874. return 'EBCDIC-DK-NO-A';
  8875. case 'csebcdices':
  8876. case 'ebcdices':
  8877. return 'EBCDIC-ES';
  8878. case 'csebcdicesa':
  8879. case 'ebcdicesa':
  8880. return 'EBCDIC-ES-A';
  8881. case 'csebcdicess':
  8882. case 'ebcdicess':
  8883. return 'EBCDIC-ES-S';
  8884. case 'csebcdicfise':
  8885. case 'ebcdicfise':
  8886. return 'EBCDIC-FI-SE';
  8887. case 'csebcdicfisea':
  8888. case 'ebcdicfisea':
  8889. return 'EBCDIC-FI-SE-A';
  8890. case 'csebcdicfr':
  8891. case 'ebcdicfr':
  8892. return 'EBCDIC-FR';
  8893. case 'csebcdicit':
  8894. case 'ebcdicit':
  8895. return 'EBCDIC-IT';
  8896. case 'csebcdicpt':
  8897. case 'ebcdicpt':
  8898. return 'EBCDIC-PT';
  8899. case 'csebcdicuk':
  8900. case 'ebcdicuk':
  8901. return 'EBCDIC-UK';
  8902. case 'csebcdicus':
  8903. case 'ebcdicus':
  8904. return 'EBCDIC-US';
  8905. case 'csiso111ecmacyrillic':
  8906. case 'ecmacyrillic':
  8907. case 'isoir111':
  8908. case 'koi8e':
  8909. return 'ECMA-cyrillic';
  8910. case 'csiso17spanish':
  8911. case 'es':
  8912. case 'iso646es':
  8913. case 'isoir17':
  8914. return 'ES';
  8915. case 'csiso85spanish2':
  8916. case 'es2':
  8917. case 'iso646es2':
  8918. case 'isoir85':
  8919. return 'ES2';
  8920. case 'cseucfixwidjapanese':
  8921. case 'extendedunixcodefixedwidthforjapanese':
  8922. return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
  8923. case 'cseucpkdfmtjapanese':
  8924. case 'eucjp':
  8925. case 'extendedunixcodepackedformatforjapanese':
  8926. return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
  8927. case 'gb18030':
  8928. return 'GB18030';
  8929. case 'chinese':
  8930. case 'cp936':
  8931. case 'csgb2312':
  8932. case 'csiso58gb231280':
  8933. case 'gb2312':
  8934. case 'gb231280':
  8935. case 'gbk':
  8936. case 'isoir58':
  8937. case 'ms936':
  8938. case 'windows936':
  8939. return 'GBK';
  8940. case 'cn':
  8941. case 'csiso57gb1988':
  8942. case 'gb198880':
  8943. case 'iso646cn':
  8944. case 'isoir57':
  8945. return 'GB_1988-80';
  8946. case 'csiso153gost1976874':
  8947. case 'gost1976874':
  8948. case 'isoir153':
  8949. case 'stsev35888':
  8950. return 'GOST_19768-74';
  8951. case 'csiso150':
  8952. case 'csiso150greekccitt':
  8953. case 'greekccitt':
  8954. case 'isoir150':
  8955. return 'greek-ccitt';
  8956. case 'csiso88greek7':
  8957. case 'greek7':
  8958. case 'isoir88':
  8959. return 'greek7';
  8960. case 'csiso18greek7old':
  8961. case 'greek7old':
  8962. case 'isoir18':
  8963. return 'greek7-old';
  8964. case 'cshpdesktop':
  8965. case 'hpdesktop':
  8966. return 'HP-DeskTop';
  8967. case 'cshplegal':
  8968. case 'hplegal':
  8969. return 'HP-Legal';
  8970. case 'cshpmath8':
  8971. case 'hpmath8':
  8972. return 'HP-Math8';
  8973. case 'cshppifont':
  8974. case 'hppifont':
  8975. return 'HP-Pi-font';
  8976. case 'cshproman8':
  8977. case 'hproman8':
  8978. case 'r8':
  8979. case 'roman8':
  8980. return 'hp-roman8';
  8981. case 'hzgb2312':
  8982. return 'HZ-GB-2312';
  8983. case 'csibmsymbols':
  8984. case 'ibmsymbols':
  8985. return 'IBM-Symbols';
  8986. case 'csibmthai':
  8987. case 'ibmthai':
  8988. return 'IBM-Thai';
  8989. case 'ccsid858':
  8990. case 'cp858':
  8991. case 'ibm858':
  8992. case 'pcmultilingual850euro':
  8993. return 'IBM00858';
  8994. case 'ccsid924':
  8995. case 'cp924':
  8996. case 'ebcdiclatin9euro':
  8997. case 'ibm924':
  8998. return 'IBM00924';
  8999. case 'ccsid1140':
  9000. case 'cp1140':
  9001. case 'ebcdicus37euro':
  9002. case 'ibm1140':
  9003. return 'IBM01140';
  9004. case 'ccsid1141':
  9005. case 'cp1141':
  9006. case 'ebcdicde273euro':
  9007. case 'ibm1141':
  9008. return 'IBM01141';
  9009. case 'ccsid1142':
  9010. case 'cp1142':
  9011. case 'ebcdicdk277euro':
  9012. case 'ebcdicno277euro':
  9013. case 'ibm1142':
  9014. return 'IBM01142';
  9015. case 'ccsid1143':
  9016. case 'cp1143':
  9017. case 'ebcdicfi278euro':
  9018. case 'ebcdicse278euro':
  9019. case 'ibm1143':
  9020. return 'IBM01143';
  9021. case 'ccsid1144':
  9022. case 'cp1144':
  9023. case 'ebcdicit280euro':
  9024. case 'ibm1144':
  9025. return 'IBM01144';
  9026. case 'ccsid1145':
  9027. case 'cp1145':
  9028. case 'ebcdices284euro':
  9029. case 'ibm1145':
  9030. return 'IBM01145';
  9031. case 'ccsid1146':
  9032. case 'cp1146':
  9033. case 'ebcdicgb285euro':
  9034. case 'ibm1146':
  9035. return 'IBM01146';
  9036. case 'ccsid1147':
  9037. case 'cp1147':
  9038. case 'ebcdicfr297euro':
  9039. case 'ibm1147':
  9040. return 'IBM01147';
  9041. case 'ccsid1148':
  9042. case 'cp1148':
  9043. case 'ebcdicinternational500euro':
  9044. case 'ibm1148':
  9045. return 'IBM01148';
  9046. case 'ccsid1149':
  9047. case 'cp1149':
  9048. case 'ebcdicis871euro':
  9049. case 'ibm1149':
  9050. return 'IBM01149';
  9051. case 'cp37':
  9052. case 'csibm37':
  9053. case 'ebcdiccpca':
  9054. case 'ebcdiccpnl':
  9055. case 'ebcdiccpus':
  9056. case 'ebcdiccpwt':
  9057. case 'ibm37':
  9058. return 'IBM037';
  9059. case 'cp38':
  9060. case 'csibm38':
  9061. case 'ebcdicint':
  9062. case 'ibm38':
  9063. return 'IBM038';
  9064. case 'cp273':
  9065. case 'csibm273':
  9066. case 'ibm273':
  9067. return 'IBM273';
  9068. case 'cp274':
  9069. case 'csibm274':
  9070. case 'ebcdicbe':
  9071. case 'ibm274':
  9072. return 'IBM274';
  9073. case 'cp275':
  9074. case 'csibm275':
  9075. case 'ebcdicbr':
  9076. case 'ibm275':
  9077. return 'IBM275';
  9078. case 'csibm277':
  9079. case 'ebcdiccpdk':
  9080. case 'ebcdiccpno':
  9081. case 'ibm277':
  9082. return 'IBM277';
  9083. case 'cp278':
  9084. case 'csibm278':
  9085. case 'ebcdiccpfi':
  9086. case 'ebcdiccpse':
  9087. case 'ibm278':
  9088. return 'IBM278';
  9089. case 'cp280':
  9090. case 'csibm280':
  9091. case 'ebcdiccpit':
  9092. case 'ibm280':
  9093. return 'IBM280';
  9094. case 'cp281':
  9095. case 'csibm281':
  9096. case 'ebcdicjpe':
  9097. case 'ibm281':
  9098. return 'IBM281';
  9099. case 'cp284':
  9100. case 'csibm284':
  9101. case 'ebcdiccpes':
  9102. case 'ibm284':
  9103. return 'IBM284';
  9104. case 'cp285':
  9105. case 'csibm285':
  9106. case 'ebcdiccpgb':
  9107. case 'ibm285':
  9108. return 'IBM285';
  9109. case 'cp290':
  9110. case 'csibm290':
  9111. case 'ebcdicjpkana':
  9112. case 'ibm290':
  9113. return 'IBM290';
  9114. case 'cp297':
  9115. case 'csibm297':
  9116. case 'ebcdiccpfr':
  9117. case 'ibm297':
  9118. return 'IBM297';
  9119. case 'cp420':
  9120. case 'csibm420':
  9121. case 'ebcdiccpar1':
  9122. case 'ibm420':
  9123. return 'IBM420';
  9124. case 'cp423':
  9125. case 'csibm423':
  9126. case 'ebcdiccpgr':
  9127. case 'ibm423':
  9128. return 'IBM423';
  9129. case 'cp424':
  9130. case 'csibm424':
  9131. case 'ebcdiccphe':
  9132. case 'ibm424':
  9133. return 'IBM424';
  9134. case '437':
  9135. case 'cp437':
  9136. case 'cspc8codepage437':
  9137. case 'ibm437':
  9138. return 'IBM437';
  9139. case 'cp500':
  9140. case 'csibm500':
  9141. case 'ebcdiccpbe':
  9142. case 'ebcdiccpch':
  9143. case 'ibm500':
  9144. return 'IBM500';
  9145. case 'cp775':
  9146. case 'cspc775baltic':
  9147. case 'ibm775':
  9148. return 'IBM775';
  9149. case '850':
  9150. case 'cp850':
  9151. case 'cspc850multilingual':
  9152. case 'ibm850':
  9153. return 'IBM850';
  9154. case '851':
  9155. case 'cp851':
  9156. case 'csibm851':
  9157. case 'ibm851':
  9158. return 'IBM851';
  9159. case '852':
  9160. case 'cp852':
  9161. case 'cspcp852':
  9162. case 'ibm852':
  9163. return 'IBM852';
  9164. case '855':
  9165. case 'cp855':
  9166. case 'csibm855':
  9167. case 'ibm855':
  9168. return 'IBM855';
  9169. case '857':
  9170. case 'cp857':
  9171. case 'csibm857':
  9172. case 'ibm857':
  9173. return 'IBM857';
  9174. case '860':
  9175. case 'cp860':
  9176. case 'csibm860':
  9177. case 'ibm860':
  9178. return 'IBM860';
  9179. case '861':
  9180. case 'cp861':
  9181. case 'cpis':
  9182. case 'csibm861':
  9183. case 'ibm861':
  9184. return 'IBM861';
  9185. case '862':
  9186. case 'cp862':
  9187. case 'cspc862latinhebrew':
  9188. case 'ibm862':
  9189. return 'IBM862';
  9190. case '863':
  9191. case 'cp863':
  9192. case 'csibm863':
  9193. case 'ibm863':
  9194. return 'IBM863';
  9195. case 'cp864':
  9196. case 'csibm864':
  9197. case 'ibm864':
  9198. return 'IBM864';
  9199. case '865':
  9200. case 'cp865':
  9201. case 'csibm865':
  9202. case 'ibm865':
  9203. return 'IBM865';
  9204. case '866':
  9205. case 'cp866':
  9206. case 'csibm866':
  9207. case 'ibm866':
  9208. return 'IBM866';
  9209. case 'cp868':
  9210. case 'cpar':
  9211. case 'csibm868':
  9212. case 'ibm868':
  9213. return 'IBM868';
  9214. case '869':
  9215. case 'cp869':
  9216. case 'cpgr':
  9217. case 'csibm869':
  9218. case 'ibm869':
  9219. return 'IBM869';
  9220. case 'cp870':
  9221. case 'csibm870':
  9222. case 'ebcdiccproece':
  9223. case 'ebcdiccpyu':
  9224. case 'ibm870':
  9225. return 'IBM870';
  9226. case 'cp871':
  9227. case 'csibm871':
  9228. case 'ebcdiccpis':
  9229. case 'ibm871':
  9230. return 'IBM871';
  9231. case 'cp880':
  9232. case 'csibm880':
  9233. case 'ebcdiccyrillic':
  9234. case 'ibm880':
  9235. return 'IBM880';
  9236. case 'cp891':
  9237. case 'csibm891':
  9238. case 'ibm891':
  9239. return 'IBM891';
  9240. case 'cp903':
  9241. case 'csibm903':
  9242. case 'ibm903':
  9243. return 'IBM903';
  9244. case '904':
  9245. case 'cp904':
  9246. case 'csibbm904':
  9247. case 'ibm904':
  9248. return 'IBM904';
  9249. case 'cp905':
  9250. case 'csibm905':
  9251. case 'ebcdiccptr':
  9252. case 'ibm905':
  9253. return 'IBM905';
  9254. case 'cp918':
  9255. case 'csibm918':
  9256. case 'ebcdiccpar2':
  9257. case 'ibm918':
  9258. return 'IBM918';
  9259. case 'cp1026':
  9260. case 'csibm1026':
  9261. case 'ibm1026':
  9262. return 'IBM1026';
  9263. case 'ibm1047':
  9264. return 'IBM1047';
  9265. case 'csiso143iecp271':
  9266. case 'iecp271':
  9267. case 'isoir143':
  9268. return 'IEC_P27-1';
  9269. case 'csiso49inis':
  9270. case 'inis':
  9271. case 'isoir49':
  9272. return 'INIS';
  9273. case 'csiso50inis8':
  9274. case 'inis8':
  9275. case 'isoir50':
  9276. return 'INIS-8';
  9277. case 'csiso51iniscyrillic':
  9278. case 'iniscyrillic':
  9279. case 'isoir51':
  9280. return 'INIS-cyrillic';
  9281. case 'csinvariant':
  9282. case 'invariant':
  9283. return 'INVARIANT';
  9284. case 'iso2022cn':
  9285. return 'ISO-2022-CN';
  9286. case 'iso2022cnext':
  9287. return 'ISO-2022-CN-EXT';
  9288. case 'csiso2022jp':
  9289. case 'iso2022jp':
  9290. return 'ISO-2022-JP';
  9291. case 'csiso2022jp2':
  9292. case 'iso2022jp2':
  9293. return 'ISO-2022-JP-2';
  9294. case 'csiso2022kr':
  9295. case 'iso2022kr':
  9296. return 'ISO-2022-KR';
  9297. case 'cswindows30latin1':
  9298. case 'iso88591windows30latin1':
  9299. return 'ISO-8859-1-Windows-3.0-Latin-1';
  9300. case 'cswindows31latin1':
  9301. case 'iso88591windows31latin1':
  9302. return 'ISO-8859-1-Windows-3.1-Latin-1';
  9303. case 'csisolatin2':
  9304. case 'iso88592':
  9305. case 'iso885921987':
  9306. case 'isoir101':
  9307. case 'l2':
  9308. case 'latin2':
  9309. return 'ISO-8859-2';
  9310. case 'cswindows31latin2':
  9311. case 'iso88592windowslatin2':
  9312. return 'ISO-8859-2-Windows-Latin-2';
  9313. case 'csisolatin3':
  9314. case 'iso88593':
  9315. case 'iso885931988':
  9316. case 'isoir109':
  9317. case 'l3':
  9318. case 'latin3':
  9319. return 'ISO-8859-3';
  9320. case 'csisolatin4':
  9321. case 'iso88594':
  9322. case 'iso885941988':
  9323. case 'isoir110':
  9324. case 'l4':
  9325. case 'latin4':
  9326. return 'ISO-8859-4';
  9327. case 'csisolatincyrillic':
  9328. case 'cyrillic':
  9329. case 'iso88595':
  9330. case 'iso885951988':
  9331. case 'isoir144':
  9332. return 'ISO-8859-5';
  9333. case 'arabic':
  9334. case 'asmo708':
  9335. case 'csisolatinarabic':
  9336. case 'ecma114':
  9337. case 'iso88596':
  9338. case 'iso885961987':
  9339. case 'isoir127':
  9340. return 'ISO-8859-6';
  9341. case 'csiso88596e':
  9342. case 'iso88596e':
  9343. return 'ISO-8859-6-E';
  9344. case 'csiso88596i':
  9345. case 'iso88596i':
  9346. return 'ISO-8859-6-I';
  9347. case 'csisolatingreek':
  9348. case 'ecma118':
  9349. case 'elot928':
  9350. case 'greek':
  9351. case 'greek8':
  9352. case 'iso88597':
  9353. case 'iso885971987':
  9354. case 'isoir126':
  9355. return 'ISO-8859-7';
  9356. case 'csisolatinhebrew':
  9357. case 'hebrew':
  9358. case 'iso88598':
  9359. case 'iso885981988':
  9360. case 'isoir138':
  9361. return 'ISO-8859-8';
  9362. case 'csiso88598e':
  9363. case 'iso88598e':
  9364. return 'ISO-8859-8-E';
  9365. case 'csiso88598i':
  9366. case 'iso88598i':
  9367. return 'ISO-8859-8-I';
  9368. case 'cswindows31latin5':
  9369. case 'iso88599windowslatin5':
  9370. return 'ISO-8859-9-Windows-Latin-5';
  9371. case 'csisolatin6':
  9372. case 'iso885910':
  9373. case 'iso8859101992':
  9374. case 'isoir157':
  9375. case 'l6':
  9376. case 'latin6':
  9377. return 'ISO-8859-10';
  9378. case 'iso885913':
  9379. return 'ISO-8859-13';
  9380. case 'iso885914':
  9381. case 'iso8859141998':
  9382. case 'isoceltic':
  9383. case 'isoir199':
  9384. case 'l8':
  9385. case 'latin8':
  9386. return 'ISO-8859-14';
  9387. case 'iso885915':
  9388. case 'latin9':
  9389. return 'ISO-8859-15';
  9390. case 'iso885916':
  9391. case 'iso8859162001':
  9392. case 'isoir226':
  9393. case 'l10':
  9394. case 'latin10':
  9395. return 'ISO-8859-16';
  9396. case 'iso10646j1':
  9397. return 'ISO-10646-J-1';
  9398. case 'csunicode':
  9399. case 'iso10646ucs2':
  9400. return 'ISO-10646-UCS-2';
  9401. case 'csucs4':
  9402. case 'iso10646ucs4':
  9403. return 'ISO-10646-UCS-4';
  9404. case 'csunicodeascii':
  9405. case 'iso10646ucsbasic':
  9406. return 'ISO-10646-UCS-Basic';
  9407. case 'csunicodelatin1':
  9408. case 'iso10646':
  9409. case 'iso10646unicodelatin1':
  9410. return 'ISO-10646-Unicode-Latin1';
  9411. case 'csiso10646utf1':
  9412. case 'iso10646utf1':
  9413. return 'ISO-10646-UTF-1';
  9414. case 'csiso115481':
  9415. case 'iso115481':
  9416. case 'isotr115481':
  9417. return 'ISO-11548-1';
  9418. case 'csiso90':
  9419. case 'isoir90':
  9420. return 'iso-ir-90';
  9421. case 'csunicodeibm1261':
  9422. case 'isounicodeibm1261':
  9423. return 'ISO-Unicode-IBM-1261';
  9424. case 'csunicodeibm1264':
  9425. case 'isounicodeibm1264':
  9426. return 'ISO-Unicode-IBM-1264';
  9427. case 'csunicodeibm1265':
  9428. case 'isounicodeibm1265':
  9429. return 'ISO-Unicode-IBM-1265';
  9430. case 'csunicodeibm1268':
  9431. case 'isounicodeibm1268':
  9432. return 'ISO-Unicode-IBM-1268';
  9433. case 'csunicodeibm1276':
  9434. case 'isounicodeibm1276':
  9435. return 'ISO-Unicode-IBM-1276';
  9436. case 'csiso646basic1983':
  9437. case 'iso646basic1983':
  9438. case 'ref':
  9439. return 'ISO_646.basic:1983';
  9440. case 'csiso2intlrefversion':
  9441. case 'irv':
  9442. case 'iso646irv1983':
  9443. case 'isoir2':
  9444. return 'ISO_646.irv:1983';
  9445. case 'csiso2033':
  9446. case 'e13b':
  9447. case 'iso20331983':
  9448. case 'isoir98':
  9449. return 'ISO_2033-1983';
  9450. case 'csiso5427cyrillic':
  9451. case 'iso5427':
  9452. case 'isoir37':
  9453. return 'ISO_5427';
  9454. case 'iso5427cyrillic1981':
  9455. case 'iso54271981':
  9456. case 'isoir54':
  9457. return 'ISO_5427:1981';
  9458. case 'csiso5428greek':
  9459. case 'iso54281980':
  9460. case 'isoir55':
  9461. return 'ISO_5428:1980';
  9462. case 'csiso6937add':
  9463. case 'iso6937225':
  9464. case 'isoir152':
  9465. return 'ISO_6937-2-25';
  9466. case 'csisotextcomm':
  9467. case 'iso69372add':
  9468. case 'isoir142':
  9469. return 'ISO_6937-2-add';
  9470. case 'csiso8859supp':
  9471. case 'iso8859supp':
  9472. case 'isoir154':
  9473. case 'latin125':
  9474. return 'ISO_8859-supp';
  9475. case 'csiso10367box':
  9476. case 'iso10367box':
  9477. case 'isoir155':
  9478. return 'ISO_10367-box';
  9479. case 'csiso15italian':
  9480. case 'iso646it':
  9481. case 'isoir15':
  9482. case 'it':
  9483. return 'IT';
  9484. case 'csiso13jisc6220jp':
  9485. case 'isoir13':
  9486. case 'jisc62201969':
  9487. case 'jisc62201969jp':
  9488. case 'katakana':
  9489. case 'x2017':
  9490. return 'JIS_C6220-1969-jp';
  9491. case 'csiso14jisc6220ro':
  9492. case 'iso646jp':
  9493. case 'isoir14':
  9494. case 'jisc62201969ro':
  9495. case 'jp':
  9496. return 'JIS_C6220-1969-ro';
  9497. case 'csiso42jisc62261978':
  9498. case 'isoir42':
  9499. case 'jisc62261978':
  9500. return 'JIS_C6226-1978';
  9501. case 'csiso87jisx208':
  9502. case 'isoir87':
  9503. case 'jisc62261983':
  9504. case 'jisx2081983':
  9505. case 'x208':
  9506. return 'JIS_C6226-1983';
  9507. case 'csiso91jisc62291984a':
  9508. case 'isoir91':
  9509. case 'jisc62291984a':
  9510. case 'jpocra':
  9511. return 'JIS_C6229-1984-a';
  9512. case 'csiso92jisc62991984b':
  9513. case 'iso646jpocrb':
  9514. case 'isoir92':
  9515. case 'jisc62291984b':
  9516. case 'jpocrb':
  9517. return 'JIS_C6229-1984-b';
  9518. case 'csiso93jis62291984badd':
  9519. case 'isoir93':
  9520. case 'jisc62291984badd':
  9521. case 'jpocrbadd':
  9522. return 'JIS_C6229-1984-b-add';
  9523. case 'csiso94jis62291984hand':
  9524. case 'isoir94':
  9525. case 'jisc62291984hand':
  9526. case 'jpocrhand':
  9527. return 'JIS_C6229-1984-hand';
  9528. case 'csiso95jis62291984handadd':
  9529. case 'isoir95':
  9530. case 'jisc62291984handadd':
  9531. case 'jpocrhandadd':
  9532. return 'JIS_C6229-1984-hand-add';
  9533. case 'csiso96jisc62291984kana':
  9534. case 'isoir96':
  9535. case 'jisc62291984kana':
  9536. return 'JIS_C6229-1984-kana';
  9537. case 'csjisencoding':
  9538. case 'jisencoding':
  9539. return 'JIS_Encoding';
  9540. case 'cshalfwidthkatakana':
  9541. case 'jisx201':
  9542. case 'x201':
  9543. return 'JIS_X0201';
  9544. case 'csiso159jisx2121990':
  9545. case 'isoir159':
  9546. case 'jisx2121990':
  9547. case 'x212':
  9548. return 'JIS_X0212-1990';
  9549. case 'csiso141jusib1002':
  9550. case 'iso646yu':
  9551. case 'isoir141':
  9552. case 'js':
  9553. case 'jusib1002':
  9554. case 'yu':
  9555. return 'JUS_I.B1.002';
  9556. case 'csiso147macedonian':
  9557. case 'isoir147':
  9558. case 'jusib1003mac':
  9559. case 'macedonian':
  9560. return 'JUS_I.B1.003-mac';
  9561. case 'csiso146serbian':
  9562. case 'isoir146':
  9563. case 'jusib1003serb':
  9564. case 'serbian':
  9565. return 'JUS_I.B1.003-serb';
  9566. case 'koi7switched':
  9567. return 'KOI7-switched';
  9568. case 'cskoi8r':
  9569. case 'koi8r':
  9570. return 'KOI8-R';
  9571. case 'koi8u':
  9572. return 'KOI8-U';
  9573. case 'csksc5636':
  9574. case 'iso646kr':
  9575. case 'ksc5636':
  9576. return 'KSC5636';
  9577. case 'cskz1048':
  9578. case 'kz1048':
  9579. case 'rk1048':
  9580. case 'strk10482002':
  9581. return 'KZ-1048';
  9582. case 'csiso19latingreek':
  9583. case 'isoir19':
  9584. case 'latingreek':
  9585. return 'latin-greek';
  9586. case 'csiso27latingreek1':
  9587. case 'isoir27':
  9588. case 'latingreek1':
  9589. return 'Latin-greek-1';
  9590. case 'csiso158lap':
  9591. case 'isoir158':
  9592. case 'lap':
  9593. case 'latinlap':
  9594. return 'latin-lap';
  9595. case 'csmacintosh':
  9596. case 'mac':
  9597. case 'macintosh':
  9598. return 'macintosh';
  9599. case 'csmicrosoftpublishing':
  9600. case 'microsoftpublishing':
  9601. return 'Microsoft-Publishing';
  9602. case 'csmnem':
  9603. case 'mnem':
  9604. return 'MNEM';
  9605. case 'csmnemonic':
  9606. case 'mnemonic':
  9607. return 'MNEMONIC';
  9608. case 'csiso86hungarian':
  9609. case 'hu':
  9610. case 'iso646hu':
  9611. case 'isoir86':
  9612. case 'msz77953':
  9613. return 'MSZ_7795.3';
  9614. case 'csnatsdano':
  9615. case 'isoir91':
  9616. case 'natsdano':
  9617. return 'NATS-DANO';
  9618. case 'csnatsdanoadd':
  9619. case 'isoir92':
  9620. case 'natsdanoadd':
  9621. return 'NATS-DANO-ADD';
  9622. case 'csnatssefi':
  9623. case 'isoir81':
  9624. case 'natssefi':
  9625. return 'NATS-SEFI';
  9626. case 'csnatssefiadd':
  9627. case 'isoir82':
  9628. case 'natssefiadd':
  9629. return 'NATS-SEFI-ADD';
  9630. case 'csiso151cuba':
  9631. case 'cuba':
  9632. case 'iso646cu':
  9633. case 'isoir151':
  9634. case 'ncnc1081':
  9635. return 'NC_NC00-10:81';
  9636. case 'csiso69french':
  9637. case 'fr':
  9638. case 'iso646fr':
  9639. case 'isoir69':
  9640. case 'nfz62010':
  9641. return 'NF_Z_62-010';
  9642. case 'csiso25french':
  9643. case 'iso646fr1':
  9644. case 'isoir25':
  9645. case 'nfz620101973':
  9646. return 'NF_Z_62-010_(1973)';
  9647. case 'csiso60danishnorwegian':
  9648. case 'csiso60norwegian1':
  9649. case 'iso646no':
  9650. case 'isoir60':
  9651. case 'no':
  9652. case 'ns45511':
  9653. return 'NS_4551-1';
  9654. case 'csiso61norwegian2':
  9655. case 'iso646no2':
  9656. case 'isoir61':
  9657. case 'no2':
  9658. case 'ns45512':
  9659. return 'NS_4551-2';
  9660. case 'osdebcdicdf3irv':
  9661. return 'OSD_EBCDIC_DF03_IRV';
  9662. case 'osdebcdicdf41':
  9663. return 'OSD_EBCDIC_DF04_1';
  9664. case 'osdebcdicdf415':
  9665. return 'OSD_EBCDIC_DF04_15';
  9666. case 'cspc8danishnorwegian':
  9667. case 'pc8danishnorwegian':
  9668. return 'PC8-Danish-Norwegian';
  9669. case 'cspc8turkish':
  9670. case 'pc8turkish':
  9671. return 'PC8-Turkish';
  9672. case 'csiso16portuguese':
  9673. case 'iso646pt':
  9674. case 'isoir16':
  9675. case 'pt':
  9676. return 'PT';
  9677. case 'csiso84portuguese2':
  9678. case 'iso646pt2':
  9679. case 'isoir84':
  9680. case 'pt2':
  9681. return 'PT2';
  9682. case 'cp154':
  9683. case 'csptcp154':
  9684. case 'cyrillicasian':
  9685. case 'pt154':
  9686. case 'ptcp154':
  9687. return 'PTCP154';
  9688. case 'scsu':
  9689. return 'SCSU';
  9690. case 'csiso10swedish':
  9691. case 'fi':
  9692. case 'iso646fi':
  9693. case 'iso646se':
  9694. case 'isoir10':
  9695. case 'se':
  9696. case 'sen850200b':
  9697. return 'SEN_850200_B';
  9698. case 'csiso11swedishfornames':
  9699. case 'iso646se2':
  9700. case 'isoir11':
  9701. case 'se2':
  9702. case 'sen850200c':
  9703. return 'SEN_850200_C';
  9704. case 'csshiftjis':
  9705. case 'mskanji':
  9706. case 'shiftjis':
  9707. return 'Shift_JIS';
  9708. case 'csiso102t617bit':
  9709. case 'isoir102':
  9710. case 't617bit':
  9711. return 'T.61-7bit';
  9712. case 'csiso103t618bit':
  9713. case 'isoir103':
  9714. case 't61':
  9715. case 't618bit':
  9716. return 'T.61-8bit';
  9717. case 'csiso128t101g2':
  9718. case 'isoir128':
  9719. case 't101g2':
  9720. return 'T.101-G2';
  9721. case 'cstscii':
  9722. case 'tscii':
  9723. return 'TSCII';
  9724. case 'csunicode11':
  9725. case 'unicode11':
  9726. return 'UNICODE-1-1';
  9727. case 'csunicode11utf7':
  9728. case 'unicode11utf7':
  9729. return 'UNICODE-1-1-UTF-7';
  9730. case 'csunknown8bit':
  9731. case 'unknown8bit':
  9732. return 'UNKNOWN-8BIT';
  9733. case 'ansix341968':
  9734. case 'ansix341986':
  9735. case 'ascii':
  9736. case 'cp367':
  9737. case 'csascii':
  9738. case 'ibm367':
  9739. case 'iso646irv1991':
  9740. case 'iso646us':
  9741. case 'isoir6':
  9742. case 'us':
  9743. case 'usascii':
  9744. return 'US-ASCII';
  9745. case 'csusdk':
  9746. case 'usdk':
  9747. return 'us-dk';
  9748. case 'utf7':
  9749. return 'UTF-7';
  9750. case 'utf8':
  9751. return 'UTF-8';
  9752. case 'utf16':
  9753. return 'UTF-16';
  9754. case 'utf16be':
  9755. return 'UTF-16BE';
  9756. case 'utf16le':
  9757. return 'UTF-16LE';
  9758. case 'utf32':
  9759. return 'UTF-32';
  9760. case 'utf32be':
  9761. return 'UTF-32BE';
  9762. case 'utf32le':
  9763. return 'UTF-32LE';
  9764. case 'csventurainternational':
  9765. case 'venturainternational':
  9766. return 'Ventura-International';
  9767. case 'csventuramath':
  9768. case 'venturamath':
  9769. return 'Ventura-Math';
  9770. case 'csventuraus':
  9771. case 'venturaus':
  9772. return 'Ventura-US';
  9773. case 'csiso70videotexsupp1':
  9774. case 'isoir70':
  9775. case 'videotexsuppl':
  9776. return 'videotex-suppl';
  9777. case 'csviqr':
  9778. case 'viqr':
  9779. return 'VIQR';
  9780. case 'csviscii':
  9781. case 'viscii':
  9782. return 'VISCII';
  9783. case 'cswindows31j':
  9784. case 'windows31j':
  9785. return 'Windows-31J';
  9786. case 'iso885911':
  9787. case 'tis620':
  9788. return 'windows-874';
  9789. case 'cseuckr':
  9790. case 'csksc56011987':
  9791. case 'euckr':
  9792. case 'isoir149':
  9793. case 'korean':
  9794. case 'ksc5601':
  9795. case 'ksc56011987':
  9796. case 'ksc56011989':
  9797. case 'windows949':
  9798. return 'windows-949';
  9799. case 'windows1250':
  9800. return 'windows-1250';
  9801. case 'windows1251':
  9802. return 'windows-1251';
  9803. case 'cp819':
  9804. case 'csisolatin1':
  9805. case 'ibm819':
  9806. case 'iso88591':
  9807. case 'iso885911987':
  9808. case 'isoir100':
  9809. case 'l1':
  9810. case 'latin1':
  9811. case 'windows1252':
  9812. return 'windows-1252';
  9813. case 'windows1253':
  9814. return 'windows-1253';
  9815. case 'csisolatin5':
  9816. case 'iso88599':
  9817. case 'iso885991989':
  9818. case 'isoir148':
  9819. case 'l5':
  9820. case 'latin5':
  9821. case 'windows1254':
  9822. return 'windows-1254';
  9823. case 'windows1255':
  9824. return 'windows-1255';
  9825. case 'windows1256':
  9826. return 'windows-1256';
  9827. case 'windows1257':
  9828. return 'windows-1257';
  9829. case 'windows1258':
  9830. return 'windows-1258';
  9831. default:
  9832. return $charset;
  9833. }
  9834. }
  9835. function get_curl_version()
  9836. {
  9837. if (is_array($curl = curl_version()))
  9838. {
  9839. $curl = $curl['version'];
  9840. }
  9841. elseif (substr($curl, 0, 5) === 'curl/')
  9842. {
  9843. $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
  9844. }
  9845. elseif (substr($curl, 0, 8) === 'libcurl/')
  9846. {
  9847. $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
  9848. }
  9849. else
  9850. {
  9851. $curl = 0;
  9852. }
  9853. return $curl;
  9854. }
  9855. function is_subclass_of($class1, $class2)
  9856. {
  9857. if (func_num_args() !== 2)
  9858. {
  9859. trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
  9860. }
  9861. elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
  9862. {
  9863. return is_subclass_of($class1, $class2);
  9864. }
  9865. elseif (is_string($class1) && is_string($class2))
  9866. {
  9867. if (class_exists($class1))
  9868. {
  9869. if (class_exists($class2))
  9870. {
  9871. $class2 = strtolower($class2);
  9872. while ($class1 = strtolower(get_parent_class($class1)))
  9873. {
  9874. if ($class1 === $class2)
  9875. {
  9876. return true;
  9877. }
  9878. }
  9879. }
  9880. }
  9881. else
  9882. {
  9883. trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
  9884. }
  9885. }
  9886. return false;
  9887. }
  9888. /**
  9889. * Strip HTML comments
  9890. *
  9891. * @access public
  9892. * @param string $data Data to strip comments from
  9893. * @return string Comment stripped string
  9894. */
  9895. function strip_comments($data)
  9896. {
  9897. $output = '';
  9898. while (($start = strpos($data, '<!--')) !== false)
  9899. {
  9900. $output .= substr($data, 0, $start);
  9901. if (($end = strpos($data, '-->', $start)) !== false)
  9902. {
  9903. $data = substr_replace($data, '', 0, $end + 3);
  9904. }
  9905. else
  9906. {
  9907. $data = '';
  9908. }
  9909. }
  9910. return $output . $data;
  9911. }
  9912. function parse_date($dt)
  9913. {
  9914. $parser = SimplePie_Parse_Date::get();
  9915. return $parser->parse($dt);
  9916. }
  9917. /**
  9918. * Decode HTML entities
  9919. *
  9920. * @static
  9921. * @access public
  9922. * @param string $data Input data
  9923. * @return string Output data
  9924. */
  9925. function entities_decode($data)
  9926. {
  9927. $decoder =& new SimplePie_Decode_HTML_Entities($data);
  9928. return $decoder->parse();
  9929. }
  9930. /**
  9931. * Remove RFC822 comments
  9932. *
  9933. * @access public
  9934. * @param string $data Data to strip comments from
  9935. * @return string Comment stripped string
  9936. */
  9937. function uncomment_rfc822($string)
  9938. {
  9939. $string = (string) $string;
  9940. $position = 0;
  9941. $length = strlen($string);
  9942. $depth = 0;
  9943. $output = '';
  9944. while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
  9945. {
  9946. $output .= substr($string, $position, $pos - $position);
  9947. $position = $pos + 1;
  9948. if ($string[$pos - 1] !== '\\')
  9949. {
  9950. $depth++;
  9951. while ($depth && $position < $length)
  9952. {
  9953. $position += strcspn($string, '()', $position);
  9954. if ($string[$position - 1] === '\\')
  9955. {
  9956. $position++;
  9957. continue;
  9958. }
  9959. elseif (isset($string[$position]))
  9960. {
  9961. switch ($string[$position])
  9962. {
  9963. case '(':
  9964. $depth++;
  9965. break;
  9966. case ')':
  9967. $depth--;
  9968. break;
  9969. }
  9970. $position++;
  9971. }
  9972. else
  9973. {
  9974. break;
  9975. }
  9976. }
  9977. }
  9978. else
  9979. {
  9980. $output .= '(';
  9981. }
  9982. }
  9983. $output .= substr($string, $position);
  9984. return $output;
  9985. }
  9986. function parse_mime($mime)
  9987. {
  9988. if (($pos = strpos($mime, ';')) === false)
  9989. {
  9990. return trim($mime);
  9991. }
  9992. else
  9993. {
  9994. return trim(substr($mime, 0, $pos));
  9995. }
  9996. }
  9997. function htmlspecialchars_decode($string, $quote_style)
  9998. {
  9999. if (function_exists('htmlspecialchars_decode'))
  10000. {
  10001. return htmlspecialchars_decode($string, $quote_style);
  10002. }
  10003. else
  10004. {
  10005. return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
  10006. }
  10007. }
  10008. function atom_03_construct_type($attribs)
  10009. {
  10010. if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
  10011. {
  10012. $mode = SIMPLEPIE_CONSTRUCT_BASE64;
  10013. }
  10014. else
  10015. {
  10016. $mode = SIMPLEPIE_CONSTRUCT_NONE;
  10017. }
  10018. if (isset($attribs['']['type']))
  10019. {
  10020. switch (strtolower(trim($attribs['']['type'])))
  10021. {
  10022. case 'text':
  10023. case 'text/plain':
  10024. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  10025. case 'html':
  10026. case 'text/html':
  10027. return SIMPLEPIE_CONSTRUCT_HTML | $mode;
  10028. case 'xhtml':
  10029. case 'application/xhtml+xml':
  10030. return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
  10031. default:
  10032. return SIMPLEPIE_CONSTRUCT_NONE | $mode;
  10033. }
  10034. }
  10035. else
  10036. {
  10037. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  10038. }
  10039. }
  10040. function atom_10_construct_type($attribs)
  10041. {
  10042. if (isset($attribs['']['type']))
  10043. {
  10044. switch (strtolower(trim($attribs['']['type'])))
  10045. {
  10046. case 'text':
  10047. return SIMPLEPIE_CONSTRUCT_TEXT;
  10048. case 'html':
  10049. return SIMPLEPIE_CONSTRUCT_HTML;
  10050. case 'xhtml':
  10051. return SIMPLEPIE_CONSTRUCT_XHTML;
  10052. default:
  10053. return SIMPLEPIE_CONSTRUCT_NONE;
  10054. }
  10055. }
  10056. return SIMPLEPIE_CONSTRUCT_TEXT;
  10057. }
  10058. function atom_10_content_construct_type($attribs)
  10059. {
  10060. if (isset($attribs['']['type']))
  10061. {
  10062. $type = strtolower(trim($attribs['']['type']));
  10063. switch ($type)
  10064. {
  10065. case 'text':
  10066. return SIMPLEPIE_CONSTRUCT_TEXT;
  10067. case 'html':
  10068. return SIMPLEPIE_CONSTRUCT_HTML;
  10069. case 'xhtml':
  10070. return SIMPLEPIE_CONSTRUCT_XHTML;
  10071. }
  10072. if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
  10073. {
  10074. return SIMPLEPIE_CONSTRUCT_NONE;
  10075. }
  10076. else
  10077. {
  10078. return SIMPLEPIE_CONSTRUCT_BASE64;
  10079. }
  10080. }
  10081. else
  10082. {
  10083. return SIMPLEPIE_CONSTRUCT_TEXT;
  10084. }
  10085. }
  10086. function is_isegment_nz_nc($string)
  10087. {
  10088. 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);
  10089. }
  10090. function space_seperated_tokens($string)
  10091. {
  10092. $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
  10093. $string_length = strlen($string);
  10094. $position = strspn($string, $space_characters);
  10095. $tokens = array();
  10096. while ($position < $string_length)
  10097. {
  10098. $len = strcspn($string, $space_characters, $position);
  10099. $tokens[] = substr($string, $position, $len);
  10100. $position += $len;
  10101. $position += strspn($string, $space_characters, $position);
  10102. }
  10103. return $tokens;
  10104. }
  10105. function array_unique($array)
  10106. {
  10107. if (version_compare(PHP_VERSION, '5.2', '>='))
  10108. {
  10109. return array_unique($array);
  10110. }
  10111. else
  10112. {
  10113. $array = (array) $array;
  10114. $new_array = array();
  10115. $new_array_strings = array();
  10116. foreach ($array as $key => $value)
  10117. {
  10118. if (is_object($value))
  10119. {
  10120. if (method_exists($value, '__toString'))
  10121. {
  10122. $cmp = $value->__toString();
  10123. }
  10124. else
  10125. {
  10126. trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
  10127. }
  10128. }
  10129. elseif (is_array($value))
  10130. {
  10131. $cmp = (string) reset($value);
  10132. }
  10133. else
  10134. {
  10135. $cmp = (string) $value;
  10136. }
  10137. if (!in_array($cmp, $new_array_strings))
  10138. {
  10139. $new_array[$key] = $value;
  10140. $new_array_strings[] = $cmp;
  10141. }
  10142. }
  10143. return $new_array;
  10144. }
  10145. }
  10146. /**
  10147. * Converts a unicode codepoint to a UTF-8 character
  10148. *
  10149. * @static
  10150. * @access public
  10151. * @param int $codepoint Unicode codepoint
  10152. * @return string UTF-8 character
  10153. */
  10154. function codepoint_to_utf8($codepoint)
  10155. {
  10156. $codepoint = (int) $codepoint;
  10157. if ($codepoint < 0)
  10158. {
  10159. return false;
  10160. }
  10161. else if ($codepoint <= 0x7f)
  10162. {
  10163. return chr($codepoint);
  10164. }
  10165. else if ($codepoint <= 0x7ff)
  10166. {
  10167. return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
  10168. }
  10169. else if ($codepoint <= 0xffff)
  10170. {
  10171. return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  10172. }
  10173. else if ($codepoint <= 0x10ffff)
  10174. {
  10175. return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  10176. }
  10177. else
  10178. {
  10179. // U+FFFD REPLACEMENT CHARACTER
  10180. return "\xEF\xBF\xBD";
  10181. }
  10182. }
  10183. /**
  10184. * Re-implementation of PHP 5's stripos()
  10185. *
  10186. * Returns the numeric position of the first occurrence of needle in the
  10187. * haystack string.
  10188. *
  10189. * @static
  10190. * @access string
  10191. * @param object $haystack
  10192. * @param string $needle Note that the needle may be a string of one or more
  10193. * characters. If needle is not a string, it is converted to an integer
  10194. * and applied as the ordinal value of a character.
  10195. * @param int $offset The optional offset parameter allows you to specify which
  10196. * character in haystack to start searching. The position returned is still
  10197. * relative to the beginning of haystack.
  10198. * @return bool If needle is not found, stripos() will return boolean false.
  10199. */
  10200. function stripos($haystack, $needle, $offset = 0)
  10201. {
  10202. if (function_exists('stripos'))
  10203. {
  10204. return stripos($haystack, $needle, $offset);
  10205. }
  10206. else
  10207. {
  10208. if (is_string($needle))
  10209. {
  10210. $needle = strtolower($needle);
  10211. }
  10212. elseif (is_int($needle) || is_bool($needle) || is_double($needle))
  10213. {
  10214. $needle = strtolower(chr($needle));
  10215. }
  10216. else
  10217. {
  10218. trigger_error('needle is not a string or an integer', E_USER_WARNING);
  10219. return false;
  10220. }
  10221. return strpos(strtolower($haystack), $needle, $offset);
  10222. }
  10223. }
  10224. /**
  10225. * Similar to parse_str()
  10226. *
  10227. * Returns an associative array of name/value pairs, where the value is an
  10228. * array of values that have used the same name
  10229. *
  10230. * @static
  10231. * @access string
  10232. * @param string $str The input string.
  10233. * @return array
  10234. */
  10235. function parse_str($str)
  10236. {
  10237. $return = array();
  10238. $str = explode('&', $str);
  10239. foreach ($str as $section)
  10240. {
  10241. if (strpos($section, '=') !== false)
  10242. {
  10243. list($name, $value) = explode('=', $section, 2);
  10244. $return[urldecode($name)][] = urldecode($value);
  10245. }
  10246. else
  10247. {
  10248. $return[urldecode($section)][] = null;
  10249. }
  10250. }
  10251. return $return;
  10252. }
  10253. /**
  10254. * Detect XML encoding, as per XML 1.0 Appendix F.1
  10255. *
  10256. * @todo Add support for EBCDIC
  10257. * @param string $data XML data
  10258. * @return array Possible encodings
  10259. */
  10260. function xml_encoding($data)
  10261. {
  10262. // UTF-32 Big Endian BOM
  10263. if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
  10264. {
  10265. $encoding[] = 'UTF-32BE';
  10266. }
  10267. // UTF-32 Little Endian BOM
  10268. elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
  10269. {
  10270. $encoding[] = 'UTF-32LE';
  10271. }
  10272. // UTF-16 Big Endian BOM
  10273. elseif (substr($data, 0, 2) === "\xFE\xFF")
  10274. {
  10275. $encoding[] = 'UTF-16BE';
  10276. }
  10277. // UTF-16 Little Endian BOM
  10278. elseif (substr($data, 0, 2) === "\xFF\xFE")
  10279. {
  10280. $encoding[] = 'UTF-16LE';
  10281. }
  10282. // UTF-8 BOM
  10283. elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
  10284. {
  10285. $encoding[] = 'UTF-8';
  10286. }
  10287. // UTF-32 Big Endian Without BOM
  10288. 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")
  10289. {
  10290. if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
  10291. {
  10292. $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
  10293. if ($parser->parse())
  10294. {
  10295. $encoding[] = $parser->encoding;
  10296. }
  10297. }
  10298. $encoding[] = 'UTF-32BE';
  10299. }
  10300. // UTF-32 Little Endian Without BOM
  10301. 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")
  10302. {
  10303. if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
  10304. {
  10305. $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
  10306. if ($parser->parse())
  10307. {
  10308. $encoding[] = $parser->encoding;
  10309. }
  10310. }
  10311. $encoding[] = 'UTF-32LE';
  10312. }
  10313. // UTF-16 Big Endian Without BOM
  10314. elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
  10315. {
  10316. if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
  10317. {
  10318. $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
  10319. if ($parser->parse())
  10320. {
  10321. $encoding[] = $parser->encoding;
  10322. }
  10323. }
  10324. $encoding[] = 'UTF-16BE';
  10325. }
  10326. // UTF-16 Little Endian Without BOM
  10327. elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
  10328. {
  10329. if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
  10330. {
  10331. $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
  10332. if ($parser->parse())
  10333. {
  10334. $encoding[] = $parser->encoding;
  10335. }
  10336. }
  10337. $encoding[] = 'UTF-16LE';
  10338. }
  10339. // US-ASCII (or superset)
  10340. elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
  10341. {
  10342. if ($pos = strpos($data, "\x3F\x3E"))
  10343. {
  10344. $parser =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
  10345. if ($parser->parse())
  10346. {
  10347. $encoding[] = $parser->encoding;
  10348. }
  10349. }
  10350. $encoding[] = 'UTF-8';
  10351. }
  10352. // Fallback to UTF-8
  10353. else
  10354. {
  10355. $encoding[] = 'UTF-8';
  10356. }
  10357. return $encoding;
  10358. }
  10359. function output_javascript()
  10360. {
  10361. if (function_exists('ob_gzhandler'))
  10362. {
  10363. ob_start('ob_gzhandler');
  10364. }
  10365. header('Content-type: text/javascript; charset: UTF-8');
  10366. header('Cache-Control: must-revalidate');
  10367. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  10368. ?>
  10369. function embed_odeo(link) {
  10370. 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>');
  10371. }
  10372. function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
  10373. if (placeholder != '') {
  10374. 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>');
  10375. }
  10376. else {
  10377. 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>');
  10378. }
  10379. }
  10380. function embed_flash(bgcolor, width, height, link, loop, type) {
  10381. 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>');
  10382. }
  10383. function embed_flv(width, height, link, placeholder, loop, player) {
  10384. 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>');
  10385. }
  10386. function embed_wmedia(width, height, link) {
  10387. document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
  10388. }
  10389. <?php
  10390. }
  10391. }
  10392. /**
  10393. * Decode HTML Entities
  10394. *
  10395. * This implements HTML5 as of revision 967 (2007-06-28)
  10396. *
  10397. * @package SimplePie
  10398. */
  10399. class SimplePie_Decode_HTML_Entities
  10400. {
  10401. /**
  10402. * Data to be parsed
  10403. *
  10404. * @access private
  10405. * @var string
  10406. */
  10407. var $data = '';
  10408. /**
  10409. * Currently consumed bytes
  10410. *
  10411. * @access private
  10412. * @var string
  10413. */
  10414. var $consumed = '';
  10415. /**
  10416. * Position of the current byte being parsed
  10417. *
  10418. * @access private
  10419. * @var int
  10420. */
  10421. var $position = 0;
  10422. /**
  10423. * Create an instance of the class with the input data
  10424. *
  10425. * @access public
  10426. * @param string $data Input data
  10427. */
  10428. function SimplePie_Decode_HTML_Entities($data)
  10429. {
  10430. $this->data = $data;
  10431. }
  10432. /**
  10433. * Parse the input data
  10434. *
  10435. * @access public
  10436. * @return string Output data
  10437. */
  10438. function parse()
  10439. {
  10440. while (($this->position = strpos($this->data, '&', $this->position)) !== false)
  10441. {
  10442. $this->consume();
  10443. $this->entity();
  10444. $this->consumed = '';
  10445. }
  10446. return $this->data;
  10447. }
  10448. /**
  10449. * Consume the next byte
  10450. *
  10451. * @access private
  10452. * @return mixed The next byte, or false, if there is no more data
  10453. */
  10454. function consume()
  10455. {
  10456. if (isset($this->data[$this->position]))
  10457. {
  10458. $this->consumed .= $this->data[$this->position];
  10459. return $this->data[$this->position++];
  10460. }
  10461. else
  10462. {
  10463. return false;
  10464. }
  10465. }
  10466. /**
  10467. * Consume a range of characters
  10468. *
  10469. * @access private
  10470. * @param string $chars Characters to consume
  10471. * @return mixed A series of characters that match the range, or false
  10472. */
  10473. function consume_range($chars)
  10474. {
  10475. if ($len = strspn($this->data, $chars, $this->position))
  10476. {
  10477. $data = substr($this->data, $this->position, $len);
  10478. $this->consumed .= $data;
  10479. $this->position += $len;
  10480. return $data;
  10481. }
  10482. else
  10483. {
  10484. return false;
  10485. }
  10486. }
  10487. /**
  10488. * Unconsume one byte
  10489. *
  10490. * @access private
  10491. */
  10492. function unconsume()
  10493. {
  10494. $this->consumed = substr($this->consumed, 0, -1);
  10495. $this->position--;
  10496. }
  10497. /**
  10498. * Decode an entity
  10499. *
  10500. * @access private
  10501. */
  10502. function entity()
  10503. {
  10504. switch ($this->consume())
  10505. {
  10506. case "\x09":
  10507. case "\x0A":
  10508. case "\x0B":
  10509. case "\x0B":
  10510. case "\x0C":
  10511. case "\x20":
  10512. case "\x3C":
  10513. case "\x26":
  10514. case false:
  10515. break;
  10516. case "\x23":
  10517. switch ($this->consume())
  10518. {
  10519. case "\x78":
  10520. case "\x58":
  10521. $range = '0123456789ABCDEFabcdef';
  10522. $hex = true;
  10523. break;
  10524. default:
  10525. $range = '0123456789';
  10526. $hex = false;
  10527. $this->unconsume();
  10528. break;
  10529. }
  10530. if ($codepoint = $this->consume_range($range))
  10531. {
  10532. 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");
  10533. if ($hex)
  10534. {
  10535. $codepoint = hexdec($codepoint);
  10536. }
  10537. else
  10538. {
  10539. $codepoint = intval($codepoint);
  10540. }
  10541. if (isset($windows_1252_specials[$codepoint]))
  10542. {
  10543. $replacement = $windows_1252_specials[$codepoint];
  10544. }
  10545. else
  10546. {
  10547. $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
  10548. }
  10549. if (!in_array($this->consume(), array(';', false), true))
  10550. {
  10551. $this->unconsume();
  10552. }
  10553. $consumed_length = strlen($this->consumed);
  10554. $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
  10555. $this->position += strlen($replacement) - $consumed_length;
  10556. }
  10557. break;
  10558. default:
  10559. 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");
  10560. for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
  10561. {
  10562. $consumed = substr($this->consumed, 1);
  10563. if (isset($entities[$consumed]))
  10564. {
  10565. $match = $consumed;
  10566. }
  10567. }
  10568. if ($match !== null)
  10569. {
  10570. $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
  10571. $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
  10572. }
  10573. break;
  10574. }
  10575. }
  10576. }
  10577. /**
  10578. * IRI parser/serialiser
  10579. *
  10580. * @package SimplePie
  10581. */
  10582. class SimplePie_IRI
  10583. {
  10584. /**
  10585. * Scheme
  10586. *
  10587. * @access private
  10588. * @var string
  10589. */
  10590. var $scheme;
  10591. /**
  10592. * User Information
  10593. *
  10594. * @access private
  10595. * @var string
  10596. */
  10597. var $userinfo;
  10598. /**
  10599. * Host
  10600. *
  10601. * @access private
  10602. * @var string
  10603. */
  10604. var $host;
  10605. /**
  10606. * Port
  10607. *
  10608. * @access private
  10609. * @var string
  10610. */
  10611. var $port;
  10612. /**
  10613. * Path
  10614. *
  10615. * @access private
  10616. * @var string
  10617. */
  10618. var $path;
  10619. /**
  10620. * Query
  10621. *
  10622. * @access private
  10623. * @var string
  10624. */
  10625. var $query;
  10626. /**
  10627. * Fragment
  10628. *
  10629. * @access private
  10630. * @var string
  10631. */
  10632. var $fragment;
  10633. /**
  10634. * Whether the object represents a valid IRI
  10635. *
  10636. * @access private
  10637. * @var array
  10638. */
  10639. var $valid = array();
  10640. /**
  10641. * Return the entire IRI when you try and read the object as a string
  10642. *
  10643. * @access public
  10644. * @return string
  10645. */
  10646. function __toString()
  10647. {
  10648. return $this->get_iri();
  10649. }
  10650. /**
  10651. * Create a new IRI object, from a specified string
  10652. *
  10653. * @access public
  10654. * @param string $iri
  10655. * @return SimplePie_IRI
  10656. */
  10657. function SimplePie_IRI($iri)
  10658. {
  10659. $iri = (string) $iri;
  10660. if ($iri !== '')
  10661. {
  10662. $parsed = $this->parse_iri($iri);
  10663. $this->set_scheme($parsed['scheme']);
  10664. $this->set_authority($parsed['authority']);
  10665. $this->set_path($parsed['path']);
  10666. $this->set_query($parsed['query']);
  10667. $this->set_fragment($parsed['fragment']);
  10668. }
  10669. }
  10670. /**
  10671. * Create a new IRI object by resolving a relative IRI
  10672. *
  10673. * @static
  10674. * @access public
  10675. * @param SimplePie_IRI $base Base IRI
  10676. * @param string $relative Relative IRI
  10677. * @return SimplePie_IRI
  10678. */
  10679. function absolutize($base, $relative)
  10680. {
  10681. $relative = (string) $relative;
  10682. if ($relative !== '')
  10683. {
  10684. $relative =& new SimplePie_IRI($relative);
  10685. if ($relative->get_scheme() !== null)
  10686. {
  10687. $target = $relative;
  10688. }
  10689. elseif ($base->get_iri() !== null)
  10690. {
  10691. if ($relative->get_authority() !== null)
  10692. {
  10693. $target = $relative;
  10694. $target->set_scheme($base->get_scheme());
  10695. }
  10696. else
  10697. {
  10698. $target =& new SimplePie_IRI('');
  10699. $target->set_scheme($base->get_scheme());
  10700. $target->set_userinfo($base->get_userinfo());
  10701. $target->set_host($base->get_host());
  10702. $target->set_port($base->get_port());
  10703. if ($relative->get_path() !== null)
  10704. {
  10705. if (strpos($relative->get_path(), '/') === 0)
  10706. {
  10707. $target->set_path($relative->get_path());
  10708. }
  10709. elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)
  10710. {
  10711. $target->set_path('/' . $relative->get_path());
  10712. }
  10713. elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
  10714. {
  10715. $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());
  10716. }
  10717. else
  10718. {
  10719. $target->set_path($relative->get_path());
  10720. }
  10721. $target->set_query($relative->get_query());
  10722. }
  10723. else
  10724. {
  10725. $target->set_path($base->get_path());
  10726. if ($relative->get_query() !== null)
  10727. {
  10728. $target->set_query($relative->get_query());
  10729. }
  10730. elseif ($base->get_query() !== null)
  10731. {
  10732. $target->set_query($base->get_query());
  10733. }
  10734. }
  10735. }
  10736. $target->set_fragment($relative->get_fragment());
  10737. }
  10738. else
  10739. {
  10740. // No base URL, just return the relative URL
  10741. $target = $relative;
  10742. }
  10743. }
  10744. else
  10745. {
  10746. $target = $base;
  10747. }
  10748. return $target;
  10749. }
  10750. /**
  10751. * Parse an IRI into scheme/authority/path/query/fragment segments
  10752. *
  10753. * @access private
  10754. * @param string $iri
  10755. * @return array
  10756. */
  10757. function parse_iri($iri)
  10758. {
  10759. preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
  10760. for ($i = count($match); $i <= 9; $i++)
  10761. {
  10762. $match[$i] = '';
  10763. }
  10764. return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
  10765. }
  10766. /**
  10767. * Remove dot segments from a path
  10768. *
  10769. * @access private
  10770. * @param string $input
  10771. * @return string
  10772. */
  10773. function remove_dot_segments($input)
  10774. {
  10775. $output = '';
  10776. while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
  10777. {
  10778. // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
  10779. if (strpos($input, '../') === 0)
  10780. {
  10781. $input = substr($input, 3);
  10782. }
  10783. elseif (strpos($input, './') === 0)
  10784. {
  10785. $input = substr($input, 2);
  10786. }
  10787. // 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,
  10788. elseif (strpos($input, '/./') === 0)
  10789. {
  10790. $input = substr_replace($input, '/', 0, 3);
  10791. }
  10792. elseif ($input === '/.')
  10793. {
  10794. $input = '/';
  10795. }
  10796. // 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,
  10797. elseif (strpos($input, '/../') === 0)
  10798. {
  10799. $input = substr_replace($input, '/', 0, 4);
  10800. $output = substr_replace($output, '', strrpos($output, '/'));
  10801. }
  10802. elseif ($input === '/..')
  10803. {
  10804. $input = '/';
  10805. $output = substr_replace($output, '', strrpos($output, '/'));
  10806. }
  10807. // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
  10808. elseif ($input === '.' || $input === '..')
  10809. {
  10810. $input = '';
  10811. }
  10812. // 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
  10813. elseif (($pos = strpos($input, '/', 1)) !== false)
  10814. {
  10815. $output .= substr($input, 0, $pos);
  10816. $input = substr_replace($input, '', 0, $pos);
  10817. }
  10818. else
  10819. {
  10820. $output .= $input;
  10821. $input = '';
  10822. }
  10823. }
  10824. return $output . $input;
  10825. }
  10826. /**
  10827. * Replace invalid character with percent encoding
  10828. *
  10829. * @access private
  10830. * @param string $string Input string
  10831. * @param string $valid_chars Valid characters
  10832. * @param int $case Normalise case
  10833. * @return string
  10834. */
  10835. function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE)
  10836. {
  10837. // Normalise case
  10838. if ($case & SIMPLEPIE_LOWERCASE)
  10839. {
  10840. $string = strtolower($string);
  10841. }
  10842. elseif ($case & SIMPLEPIE_UPPERCASE)
  10843. {
  10844. $string = strtoupper($string);
  10845. }
  10846. // Store position and string length (to avoid constantly recalculating this)
  10847. $position = 0;
  10848. $strlen = strlen($string);
  10849. // Loop as long as we have invalid characters, advancing the position to the next invalid character
  10850. while (($position += strspn($string, $valid_chars, $position)) < $strlen)
  10851. {
  10852. // If we have a % character
  10853. if ($string[$position] === '%')
  10854. {
  10855. // If we have a pct-encoded section
  10856. if ($position + 2 < $strlen && strspn($string, '0123456789ABCDEFabcdef', $position + 1, 2) === 2)
  10857. {
  10858. // Get the the represented character
  10859. $chr = chr(hexdec(substr($string, $position + 1, 2)));
  10860. // If the character is valid, replace the pct-encoded with the actual character while normalising case
  10861. if (strpos($valid_chars, $chr) !== false)
  10862. {
  10863. if ($case & SIMPLEPIE_LOWERCASE)
  10864. {
  10865. $chr = strtolower($chr);
  10866. }
  10867. elseif ($case & SIMPLEPIE_UPPERCASE)
  10868. {
  10869. $chr = strtoupper($chr);
  10870. }
  10871. $string = substr_replace($string, $chr, $position, 3);
  10872. $strlen -= 2;
  10873. $position++;
  10874. }
  10875. // Otherwise just normalise the pct-encoded to uppercase
  10876. else
  10877. {
  10878. $string = substr_replace($string, strtoupper(substr($string, $position + 1, 2)), $position + 1, 2);
  10879. $position += 3;
  10880. }
  10881. }
  10882. // If we don't have a pct-encoded section, just replace the % with its own esccaped form
  10883. else
  10884. {
  10885. $string = substr_replace($string, '%25', $position, 1);
  10886. $strlen += 2;
  10887. $position += 3;
  10888. }
  10889. }
  10890. // If we have an invalid character, change into its pct-encoded form
  10891. else
  10892. {
  10893. $replacement = sprintf("%%%02X", ord($string[$position]));
  10894. $string = str_replace($string[$position], $replacement, $string);
  10895. $strlen = strlen($string);
  10896. }
  10897. }
  10898. return $string;
  10899. }
  10900. /**
  10901. * Check if the object represents a valid IRI
  10902. *
  10903. * @access public
  10904. * @return bool
  10905. */
  10906. function is_valid()
  10907. {
  10908. return array_sum($this->valid) === count($this->valid);
  10909. }
  10910. /**
  10911. * Set the scheme. Returns true on success, false on failure (if there are
  10912. * any invalid characters).
  10913. *
  10914. * @access public
  10915. * @param string $scheme
  10916. * @return bool
  10917. */
  10918. function set_scheme($scheme)
  10919. {
  10920. if ($scheme === null || $scheme === '')
  10921. {
  10922. $this->scheme = null;
  10923. }
  10924. else
  10925. {
  10926. $len = strlen($scheme);
  10927. switch (true)
  10928. {
  10929. case $len > 1:
  10930. if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
  10931. {
  10932. $this->scheme = null;
  10933. $this->valid[__FUNCTION__] = false;
  10934. return false;
  10935. }
  10936. case $len > 0:
  10937. if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
  10938. {
  10939. $this->scheme = null;
  10940. $this->valid[__FUNCTION__] = false;
  10941. return false;
  10942. }
  10943. }
  10944. $this->scheme = strtolower($scheme);
  10945. }
  10946. $this->valid[__FUNCTION__] = true;
  10947. return true;
  10948. }
  10949. /**
  10950. * Set the authority. Returns true on success, false on failure (if there are
  10951. * any invalid characters).
  10952. *
  10953. * @access public
  10954. * @param string $authority
  10955. * @return bool
  10956. */
  10957. function set_authority($authority)
  10958. {
  10959. if (($userinfo_end = strrpos($authority, '@')) !== false)
  10960. {
  10961. $userinfo = substr($authority, 0, $userinfo_end);
  10962. $authority = substr($authority, $userinfo_end + 1);
  10963. }
  10964. else
  10965. {
  10966. $userinfo = null;
  10967. }
  10968. if (($port_start = strpos($authority, ':')) !== false)
  10969. {
  10970. $port = substr($authority, $port_start + 1);
  10971. $authority = substr($authority, 0, $port_start);
  10972. }
  10973. else
  10974. {
  10975. $port = null;
  10976. }
  10977. return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
  10978. }
  10979. /**
  10980. * Set the userinfo.
  10981. *
  10982. * @access public
  10983. * @param string $userinfo
  10984. * @return bool
  10985. */
  10986. function set_userinfo($userinfo)
  10987. {
  10988. if ($userinfo === null || $userinfo === '')
  10989. {
  10990. $this->userinfo = null;
  10991. }
  10992. else
  10993. {
  10994. $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
  10995. }
  10996. $this->valid[__FUNCTION__] = true;
  10997. return true;
  10998. }
  10999. /**
  11000. * Set the host. Returns true on success, false on failure (if there are
  11001. * any invalid characters).
  11002. *
  11003. * @access public
  11004. * @param string $host
  11005. * @return bool
  11006. */
  11007. function set_host($host)
  11008. {
  11009. if ($host === null || $host === '')
  11010. {
  11011. $this->host = null;
  11012. $this->valid[__FUNCTION__] = true;
  11013. return true;
  11014. }
  11015. elseif ($host[0] === '[' && substr($host, -1) === ']')
  11016. {
  11017. if (Net_IPv6::checkIPv6(substr($host, 1, -1)))
  11018. {
  11019. $this->host = $host;
  11020. $this->valid[__FUNCTION__] = true;
  11021. return true;
  11022. }
  11023. else
  11024. {
  11025. $this->host = null;
  11026. $this->valid[__FUNCTION__] = false;
  11027. return false;
  11028. }
  11029. }
  11030. else
  11031. {
  11032. $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);
  11033. $this->valid[__FUNCTION__] = true;
  11034. return true;
  11035. }
  11036. }
  11037. /**
  11038. * Set the port. Returns true on success, false on failure (if there are
  11039. * any invalid characters).
  11040. *
  11041. * @access public
  11042. * @param string $port
  11043. * @return bool
  11044. */
  11045. function set_port($port)
  11046. {
  11047. if ($port === null || $port === '')
  11048. {
  11049. $this->port = null;
  11050. $this->valid[__FUNCTION__] = true;
  11051. return true;
  11052. }
  11053. elseif (strspn($port, '0123456789') === strlen($port))
  11054. {
  11055. $this->port = (int) $port;
  11056. $this->valid[__FUNCTION__] = true;
  11057. return true;
  11058. }
  11059. else
  11060. {
  11061. $this->port = null;
  11062. $this->valid[__FUNCTION__] = false;
  11063. return false;
  11064. }
  11065. }
  11066. /**
  11067. * Set the path.
  11068. *
  11069. * @access public
  11070. * @param string $path
  11071. * @return bool
  11072. */
  11073. function set_path($path)
  11074. {
  11075. if ($path === null || $path === '')
  11076. {
  11077. $this->path = null;
  11078. $this->valid[__FUNCTION__] = true;
  11079. return true;
  11080. }
  11081. elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)
  11082. {
  11083. $this->path = null;
  11084. $this->valid[__FUNCTION__] = false;
  11085. return false;
  11086. }
  11087. else
  11088. {
  11089. $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
  11090. if ($this->scheme !== null)
  11091. {
  11092. $this->path = $this->remove_dot_segments($this->path);
  11093. }
  11094. $this->valid[__FUNCTION__] = true;
  11095. return true;
  11096. }
  11097. }
  11098. /**
  11099. * Set the query.
  11100. *
  11101. * @access public
  11102. * @param string $query
  11103. * @return bool
  11104. */
  11105. function set_query($query)
  11106. {
  11107. if ($query === null || $query === '')
  11108. {
  11109. $this->query = null;
  11110. }
  11111. else
  11112. {
  11113. $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
  11114. }
  11115. $this->valid[__FUNCTION__] = true;
  11116. return true;
  11117. }
  11118. /**
  11119. * Set the fragment.
  11120. *
  11121. * @access public
  11122. * @param string $fragment
  11123. * @return bool
  11124. */
  11125. function set_fragment($fragment)
  11126. {
  11127. if ($fragment === null || $fragment === '')
  11128. {
  11129. $this->fragment = null;
  11130. }
  11131. else
  11132. {
  11133. $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
  11134. }
  11135. $this->valid[__FUNCTION__] = true;
  11136. return true;
  11137. }
  11138. /**
  11139. * Get the complete IRI
  11140. *
  11141. * @access public
  11142. * @return string
  11143. */
  11144. function get_iri()
  11145. {
  11146. $iri = '';
  11147. if ($this->scheme !== null)
  11148. {
  11149. $iri .= $this->scheme . ':';
  11150. }
  11151. if (($authority = $this->get_authority()) !== null)
  11152. {
  11153. $iri .= '//' . $authority;
  11154. }
  11155. if ($this->path !== null)
  11156. {
  11157. $iri .= $this->path;
  11158. }
  11159. if ($this->query !== null)
  11160. {
  11161. $iri .= '?' . $this->query;
  11162. }
  11163. if ($this->fragment !== null)
  11164. {
  11165. $iri .= '#' . $this->fragment;
  11166. }
  11167. if ($iri !== '')
  11168. {
  11169. return $iri;
  11170. }
  11171. else
  11172. {
  11173. return null;
  11174. }
  11175. }
  11176. /**
  11177. * Get the scheme
  11178. *
  11179. * @access public
  11180. * @return string
  11181. */
  11182. function get_scheme()
  11183. {
  11184. return $this->scheme;
  11185. }
  11186. /**
  11187. * Get the complete authority
  11188. *
  11189. * @access public
  11190. * @return string
  11191. */
  11192. function get_authority()
  11193. {
  11194. $authority = '';
  11195. if ($this->userinfo !== null)
  11196. {
  11197. $authority .= $this->userinfo . '@';
  11198. }
  11199. if ($this->host !== null)
  11200. {
  11201. $authority .= $this->host;
  11202. }
  11203. if ($this->port !== null)
  11204. {
  11205. $authority .= ':' . $this->port;
  11206. }
  11207. if ($authority !== '')
  11208. {
  11209. return $authority;
  11210. }
  11211. else
  11212. {
  11213. return null;
  11214. }
  11215. }
  11216. /**
  11217. * Get the user information
  11218. *
  11219. * @access public
  11220. * @return string
  11221. */
  11222. function get_userinfo()
  11223. {
  11224. return $this->userinfo;
  11225. }
  11226. /**
  11227. * Get the host
  11228. *
  11229. * @access public
  11230. * @return string
  11231. */
  11232. function get_host()
  11233. {
  11234. return $this->host;
  11235. }
  11236. /**
  11237. * Get the port
  11238. *
  11239. * @access public
  11240. * @return string
  11241. */
  11242. function get_port()
  11243. {
  11244. return $this->port;
  11245. }
  11246. /**
  11247. * Get the path
  11248. *
  11249. * @access public
  11250. * @return string
  11251. */
  11252. function get_path()
  11253. {
  11254. return $this->path;
  11255. }
  11256. /**
  11257. * Get the query
  11258. *
  11259. * @access public
  11260. * @return string
  11261. */
  11262. function get_query()
  11263. {
  11264. return $this->query;
  11265. }
  11266. /**
  11267. * Get the fragment
  11268. *
  11269. * @access public
  11270. * @return string
  11271. */
  11272. function get_fragment()
  11273. {
  11274. return $this->fragment;
  11275. }
  11276. }
  11277. /**
  11278. * Class to validate and to work with IPv6 addresses.
  11279. *
  11280. * @package SimplePie
  11281. * @copyright 2003-2005 The PHP Group
  11282. * @license http://www.opensource.org/licenses/bsd-license.php
  11283. * @link http://pear.php.net/package/Net_IPv6
  11284. * @author Alexander Merz <alexander.merz@web.de>
  11285. * @author elfrink at introweb dot nl
  11286. * @author Josh Peck <jmp at joshpeck dot org>
  11287. * @author Geoffrey Sneddon <geoffers@gmail.com>
  11288. */
  11289. class SimplePie_Net_IPv6
  11290. {
  11291. /**
  11292. * Removes a possible existing netmask specification of an IP address.
  11293. *
  11294. * @param string $ip the (compressed) IP as Hex representation
  11295. * @return string the IP the without netmask
  11296. * @since 1.1.0
  11297. * @access public
  11298. * @static
  11299. */
  11300. function removeNetmaskSpec($ip)
  11301. {
  11302. if (strpos($ip, '/') !== false)
  11303. {
  11304. list($addr, $nm) = explode('/', $ip);
  11305. }
  11306. else
  11307. {
  11308. $addr = $ip;
  11309. }
  11310. return $addr;
  11311. }
  11312. /**
  11313. * Uncompresses an IPv6 address
  11314. *
  11315. * RFC 2373 allows you to compress zeros in an address to '::'. This
  11316. * function expects an valid IPv6 address and expands the '::' to
  11317. * the required zeros.
  11318. *
  11319. * Example: FF01::101 -> FF01:0:0:0:0:0:0:101
  11320. * ::1 -> 0:0:0:0:0:0:0:1
  11321. *
  11322. * @access public
  11323. * @static
  11324. * @param string $ip a valid IPv6-address (hex format)
  11325. * @return string the uncompressed IPv6-address (hex format)
  11326. */
  11327. function Uncompress($ip)
  11328. {
  11329. $uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip);
  11330. $c1 = -1;
  11331. $c2 = -1;
  11332. if (strpos($ip, '::') !== false)
  11333. {
  11334. list($ip1, $ip2) = explode('::', $ip);
  11335. if ($ip1 === '')
  11336. {
  11337. $c1 = -1;
  11338. }
  11339. else
  11340. {
  11341. $pos = 0;
  11342. if (($pos = substr_count($ip1, ':')) > 0)
  11343. {
  11344. $c1 = $pos;
  11345. }
  11346. else
  11347. {
  11348. $c1 = 0;
  11349. }
  11350. }
  11351. if ($ip2 === '')
  11352. {
  11353. $c2 = -1;
  11354. }
  11355. else
  11356. {
  11357. $pos = 0;
  11358. if (($pos = substr_count($ip2, ':')) > 0)
  11359. {
  11360. $c2 = $pos;
  11361. }
  11362. else
  11363. {
  11364. $c2 = 0;
  11365. }
  11366. }
  11367. if (strstr($ip2, '.'))
  11368. {
  11369. $c2++;
  11370. }
  11371. // ::
  11372. if ($c1 === -1 && $c2 === -1)
  11373. {
  11374. $uip = '0:0:0:0:0:0:0:0';
  11375. }
  11376. // ::xxx
  11377. else if ($c1 === -1)
  11378. {
  11379. $fill = str_repeat('0:', 7 - $c2);
  11380. $uip = str_replace('::', $fill, $uip);
  11381. }
  11382. // xxx::
  11383. else if ($c2 === -1)
  11384. {
  11385. $fill = str_repeat(':0', 7 - $c1);
  11386. $uip = str_replace('::', $fill, $uip);
  11387. }
  11388. // xxx::xxx
  11389. else
  11390. {
  11391. $fill = str_repeat(':0:', 6 - $c2 - $c1);
  11392. $uip = str_replace('::', $fill, $uip);
  11393. $uip = str_replace('::', ':', $uip);
  11394. }
  11395. }
  11396. return $uip;
  11397. }
  11398. /**
  11399. * Splits an IPv6 address into the IPv6 and a possible IPv4 part
  11400. *
  11401. * RFC 2373 allows you to note the last two parts of an IPv6 address as
  11402. * an IPv4 compatible address
  11403. *
  11404. * Example: 0:0:0:0:0:0:13.1.68.3
  11405. * 0:0:0:0:0:FFFF:129.144.52.38
  11406. *
  11407. * @access public
  11408. * @static
  11409. * @param string $ip a valid IPv6-address (hex format)
  11410. * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)
  11411. */
  11412. function SplitV64($ip)
  11413. {
  11414. $ip = SimplePie_Net_IPv6::Uncompress($ip);
  11415. if (strstr($ip, '.'))
  11416. {
  11417. $pos = strrpos($ip, ':');
  11418. $ip[$pos] = '_';
  11419. $ipPart = explode('_', $ip);
  11420. return $ipPart;
  11421. }
  11422. else
  11423. {
  11424. return array($ip, '');
  11425. }
  11426. }
  11427. /**
  11428. * Checks an IPv6 address
  11429. *
  11430. * Checks if the given IP is IPv6-compatible
  11431. *
  11432. * @access public
  11433. * @static
  11434. * @param string $ip a valid IPv6-address
  11435. * @return bool true if $ip is an IPv6 address
  11436. */
  11437. function checkIPv6($ip)
  11438. {
  11439. $ipPart = SimplePie_Net_IPv6::SplitV64($ip);
  11440. $count = 0;
  11441. if (!empty($ipPart[0]))
  11442. {
  11443. $ipv6 = explode(':', $ipPart[0]);
  11444. for ($i = 0; $i < count($ipv6); $i++)
  11445. {
  11446. $dec = hexdec($ipv6[$i]);
  11447. $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));
  11448. if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))
  11449. {
  11450. $count++;
  11451. }
  11452. }
  11453. if ($count === 8)
  11454. {
  11455. return true;
  11456. }
  11457. elseif ($count === 6 && !empty($ipPart[1]))
  11458. {
  11459. $ipv4 = explode('.', $ipPart[1]);
  11460. $count = 0;
  11461. foreach ($ipv4 as $ipv4_part)
  11462. {
  11463. if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))
  11464. {
  11465. $count++;
  11466. }
  11467. }
  11468. if ($count === 4)
  11469. {
  11470. return true;
  11471. }
  11472. }
  11473. else
  11474. {
  11475. return false;
  11476. }
  11477. }
  11478. else
  11479. {
  11480. return false;
  11481. }
  11482. }
  11483. }
  11484. /**
  11485. * Date Parser
  11486. *
  11487. * @package SimplePie
  11488. */
  11489. class SimplePie_Parse_Date
  11490. {
  11491. /**
  11492. * Input data
  11493. *
  11494. * @access protected
  11495. * @var string
  11496. */
  11497. var $date;
  11498. /**
  11499. * List of days, calendar day name => ordinal day number in the week
  11500. *
  11501. * @access protected
  11502. * @var array
  11503. */
  11504. var $day = array(
  11505. // English
  11506. 'mon' => 1,
  11507. 'monday' => 1,
  11508. 'tue' => 2,
  11509. 'tuesday' => 2,
  11510. 'wed' => 3,
  11511. 'wednesday' => 3,
  11512. 'thu' => 4,
  11513. 'thursday' => 4,
  11514. 'fri' => 5,
  11515. 'friday' => 5,
  11516. 'sat' => 6,
  11517. 'saturday' => 6,
  11518. 'sun' => 7,
  11519. 'sunday' => 7,
  11520. // Dutch
  11521. 'maandag' => 1,
  11522. 'dinsdag' => 2,
  11523. 'woensdag' => 3,
  11524. 'donderdag' => 4,
  11525. 'vrijdag' => 5,
  11526. 'zaterdag' => 6,
  11527. 'zondag' => 7,
  11528. // French
  11529. 'lundi' => 1,
  11530. 'mardi' => 2,
  11531. 'mercredi' => 3,
  11532. 'jeudi' => 4,
  11533. 'vendredi' => 5,
  11534. 'samedi' => 6,
  11535. 'dimanche' => 7,
  11536. // German
  11537. 'montag' => 1,
  11538. 'dienstag' => 2,
  11539. 'mittwoch' => 3,
  11540. 'donnerstag' => 4,
  11541. 'freitag' => 5,
  11542. 'samstag' => 6,
  11543. 'sonnabend' => 6,
  11544. 'sonntag' => 7,
  11545. // Italian
  11546. 'lunedì' => 1,
  11547. 'martedì' => 2,
  11548. 'mercoledì' => 3,
  11549. 'giovedì' => 4,
  11550. 'venerdì' => 5,
  11551. 'sabato' => 6,
  11552. 'domenica' => 7,
  11553. // Spanish
  11554. 'lunes' => 1,
  11555. 'martes' => 2,
  11556. 'miércoles' => 3,
  11557. 'jueves' => 4,
  11558. 'viernes' => 5,
  11559. 'sábado' => 6,
  11560. 'domingo' => 7,
  11561. // Finnish
  11562. 'maanantai' => 1,
  11563. 'tiistai' => 2,
  11564. 'keskiviikko' => 3,
  11565. 'torstai' => 4,
  11566. 'perjantai' => 5,
  11567. 'lauantai' => 6,
  11568. 'sunnuntai' => 7,
  11569. // Hungarian
  11570. 'hétfő' => 1,
  11571. 'kedd' => 2,
  11572. 'szerda' => 3,
  11573. 'csütörtok' => 4,
  11574. 'péntek' => 5,
  11575. 'szombat' => 6,
  11576. 'vasárnap' => 7,
  11577. // Greek
  11578. 'Δευ' => 1,
  11579. 'Τρι' => 2,
  11580. 'Τετ' => 3,
  11581. 'Πεμ' => 4,
  11582. 'Παρ' => 5,
  11583. 'Σαβ' => 6,
  11584. 'Κυρ' => 7,
  11585. );
  11586. /**
  11587. * List of months, calendar month name => calendar month number
  11588. *
  11589. * @access protected
  11590. * @var array
  11591. */
  11592. var $month = array(
  11593. // English
  11594. 'jan' => 1,
  11595. 'january' => 1,
  11596. 'feb' => 2,
  11597. 'february' => 2,
  11598. 'mar' => 3,
  11599. 'march' => 3,
  11600. 'apr' => 4,
  11601. 'april' => 4,
  11602. 'may' => 5,
  11603. // No long form of May
  11604. 'jun' => 6,
  11605. 'june' => 6,
  11606. 'jul' => 7,
  11607. 'july' => 7,
  11608. 'aug' => 8,
  11609. 'august' => 8,
  11610. 'sep' => 9,
  11611. 'september' => 8,
  11612. 'oct' => 10,
  11613. 'october' => 10,
  11614. 'nov' => 11,
  11615. 'november' => 11,
  11616. 'dec' => 12,
  11617. 'december' => 12,
  11618. // Dutch
  11619. 'januari' => 1,
  11620. 'februari' => 2,
  11621. 'maart' => 3,
  11622. 'april' => 4,
  11623. 'mei' => 5,
  11624. 'juni' => 6,
  11625. 'juli' => 7,
  11626. 'augustus' => 8,
  11627. 'september' => 9,
  11628. 'oktober' => 10,
  11629. 'november' => 11,
  11630. 'december' => 12,
  11631. // French
  11632. 'janvier' => 1,
  11633. 'février' => 2,
  11634. 'mars' => 3,
  11635. 'avril' => 4,
  11636. 'mai' => 5,
  11637. 'juin' => 6,
  11638. 'juillet' => 7,
  11639. 'août' => 8,
  11640. 'septembre' => 9,
  11641. 'octobre' => 10,
  11642. 'novembre' => 11,
  11643. 'décembre' => 12,
  11644. // German
  11645. 'januar' => 1,
  11646. 'februar' => 2,
  11647. 'märz' => 3,
  11648. 'april' => 4,
  11649. 'mai' => 5,
  11650. 'juni' => 6,
  11651. 'juli' => 7,
  11652. 'august' => 8,
  11653. 'september' => 9,
  11654. 'oktober' => 10,
  11655. 'november' => 11,
  11656. 'dezember' => 12,
  11657. // Italian
  11658. 'gennaio' => 1,
  11659. 'febbraio' => 2,
  11660. 'marzo' => 3,
  11661. 'aprile' => 4,
  11662. 'maggio' => 5,
  11663. 'giugno' => 6,
  11664. 'luglio' => 7,
  11665. 'agosto' => 8,
  11666. 'settembre' => 9,
  11667. 'ottobre' => 10,
  11668. 'novembre' => 11,
  11669. 'dicembre' => 12,
  11670. // Spanish
  11671. 'enero' => 1,
  11672. 'febrero' => 2,
  11673. 'marzo' => 3,
  11674. 'abril' => 4,
  11675. 'mayo' => 5,
  11676. 'junio' => 6,
  11677. 'julio' => 7,
  11678. 'agosto' => 8,
  11679. 'septiembre' => 9,
  11680. 'setiembre' => 9,
  11681. 'octubre' => 10,
  11682. 'noviembre' => 11,
  11683. 'diciembre' => 12,
  11684. // Finnish
  11685. 'tammikuu' => 1,
  11686. 'helmikuu' => 2,
  11687. 'maaliskuu' => 3,
  11688. 'huhtikuu' => 4,
  11689. 'toukokuu' => 5,
  11690. 'kesäkuu' => 6,
  11691. 'heinäkuu' => 7,
  11692. 'elokuu' => 8,
  11693. 'suuskuu' => 9,
  11694. 'lokakuu' => 10,
  11695. 'marras' => 11,
  11696. 'joulukuu' => 12,
  11697. // Hungarian
  11698. 'január' => 1,
  11699. 'február' => 2,
  11700. 'március' => 3,
  11701. 'április' => 4,
  11702. 'május' => 5,
  11703. 'június' => 6,
  11704. 'július' => 7,
  11705. 'augusztus' => 8,
  11706. 'szeptember' => 9,
  11707. 'október' => 10,
  11708. 'november' => 11,
  11709. 'december' => 12,
  11710. // Greek
  11711. 'Ιαν' => 1,
  11712. 'Φεβ' => 2,
  11713. 'Μάώ' => 3,
  11714. 'Μαώ' => 3,
  11715. 'Απρ' => 4,
  11716. 'Μάι' => 5,
  11717. 'Μαϊ' => 5,
  11718. 'Μαι' => 5,
  11719. 'Ιούν' => 6,
  11720. 'Ιον' => 6,
  11721. 'Ιούλ' => 7,
  11722. 'Ιολ' => 7,
  11723. 'Αύγ' => 8,
  11724. 'Αυγ' => 8,
  11725. 'Σεπ' => 9,
  11726. 'Οκτ' => 10,
  11727. 'Νοέ' => 11,
  11728. 'Δεκ' => 12,
  11729. );
  11730. /**
  11731. * List of timezones, abbreviation => offset from UTC
  11732. *
  11733. * @access protected
  11734. * @var array
  11735. */
  11736. var $timezone = array(
  11737. 'ACDT' => 37800,
  11738. 'ACIT' => 28800,
  11739. 'ACST' => 34200,
  11740. 'ACT' => -18000,
  11741. 'ACWDT' => 35100,
  11742. 'ACWST' => 31500,
  11743. 'AEDT' => 39600,
  11744. 'AEST' => 36000,
  11745. 'AFT' => 16200,
  11746. 'AKDT' => -28800,
  11747. 'AKST' => -32400,
  11748. 'AMDT' => 18000,
  11749. 'AMT' => -14400,
  11750. 'ANAST' => 46800,
  11751. 'ANAT' => 43200,
  11752. 'ART' => -10800,
  11753. 'AZOST' => -3600,
  11754. 'AZST' => 18000,
  11755. 'AZT' => 14400,
  11756. 'BIOT' => 21600,
  11757. 'BIT' => -43200,
  11758. 'BOT' => -14400,
  11759. 'BRST' => -7200,
  11760. 'BRT' => -10800,
  11761. 'BST' => 3600,
  11762. 'BTT' => 21600,
  11763. 'CAST' => 18000,
  11764. 'CAT' => 7200,
  11765. 'CCT' => 23400,
  11766. 'CDT' => -18000,
  11767. 'CEDT' => 7200,
  11768. 'CET' => 3600,
  11769. 'CGST' => -7200,
  11770. 'CGT' => -10800,
  11771. 'CHADT' => 49500,
  11772. 'CHAST' => 45900,
  11773. 'CIST' => -28800,
  11774. 'CKT' => -36000,
  11775. 'CLDT' => -10800,
  11776. 'CLST' => -14400,
  11777. 'COT' => -18000,
  11778. 'CST' => -21600,
  11779. 'CVT' => -3600,
  11780. 'CXT' => 25200,
  11781. 'DAVT' => 25200,
  11782. 'DTAT' => 36000,
  11783. 'EADT' => -18000,
  11784. 'EAST' => -21600,
  11785. 'EAT' => 10800,
  11786. 'ECT' => -18000,
  11787. 'EDT' => -14400,
  11788. 'EEST' => 10800,
  11789. 'EET' => 7200,
  11790. 'EGT' => -3600,
  11791. 'EKST' => 21600,
  11792. 'EST' => -18000,
  11793. 'FJT' => 43200,
  11794. 'FKDT' => -10800,
  11795. 'FKST' => -14400,
  11796. 'FNT' => -7200,
  11797. 'GALT' => -21600,
  11798. 'GEDT' => 14400,
  11799. 'GEST' => 10800,
  11800. 'GFT' => -10800,
  11801. 'GILT' => 43200,
  11802. 'GIT' => -32400,
  11803. 'GST' => 14400,
  11804. 'GST' => -7200,
  11805. 'GYT' => -14400,
  11806. 'HAA' => -10800,
  11807. 'HAC' => -18000,
  11808. 'HADT' => -32400,
  11809. 'HAE' => -14400,
  11810. 'HAP' => -25200,
  11811. 'HAR' => -21600,
  11812. 'HAST' => -36000,
  11813. 'HAT' => -9000,
  11814. 'HAY' => -28800,
  11815. 'HKST' => 28800,
  11816. 'HMT' => 18000,
  11817. 'HNA' => -14400,
  11818. 'HNC' => -21600,
  11819. 'HNE' => -18000,
  11820. 'HNP' => -28800,
  11821. 'HNR' => -25200,
  11822. 'HNT' => -12600,
  11823. 'HNY' => -32400,
  11824. 'IRDT' => 16200,
  11825. 'IRKST' => 32400,
  11826. 'IRKT' => 28800,
  11827. 'IRST' => 12600,
  11828. 'JFDT' => -10800,
  11829. 'JFST' => -14400,
  11830. 'JST' => 32400,
  11831. 'KGST' => 21600,
  11832. 'KGT' => 18000,
  11833. 'KOST' => 39600,
  11834. 'KOVST' => 28800,
  11835. 'KOVT' => 25200,
  11836. 'KRAST' => 28800,
  11837. 'KRAT' => 25200,
  11838. 'KST' => 32400,
  11839. 'LHDT' => 39600,
  11840. 'LHST' => 37800,
  11841. 'LINT' => 50400,
  11842. 'LKT' => 21600,
  11843. 'MAGST' => 43200,
  11844. 'MAGT' => 39600,
  11845. 'MAWT' => 21600,
  11846. 'MDT' => -21600,
  11847. 'MESZ' => 7200,
  11848. 'MEZ' => 3600,
  11849. 'MHT' => 43200,
  11850. 'MIT' => -34200,
  11851. 'MNST' => 32400,
  11852. 'MSDT' => 14400,
  11853. 'MSST' => 10800,
  11854. 'MST' => -25200,
  11855. 'MUT' => 14400,
  11856. 'MVT' => 18000,
  11857. 'MYT' => 28800,
  11858. 'NCT' => 39600,
  11859. 'NDT' => -9000,
  11860. 'NFT' => 41400,
  11861. 'NMIT' => 36000,
  11862. 'NOVST' => 25200,
  11863. 'NOVT' => 21600,
  11864. 'NPT' => 20700,
  11865. 'NRT' => 43200,
  11866. 'NST' => -12600,
  11867. 'NUT' => -39600,
  11868. 'NZDT' => 46800,
  11869. 'NZST' => 43200,
  11870. 'OMSST' => 25200,
  11871. 'OMST' => 21600,
  11872. 'PDT' => -25200,
  11873. 'PET' => -18000,
  11874. 'PETST' => 46800,
  11875. 'PETT' => 43200,
  11876. 'PGT' => 36000,
  11877. 'PHOT' => 46800,
  11878. 'PHT' => 28800,
  11879. 'PKT' => 18000,
  11880. 'PMDT' => -7200,
  11881. 'PMST' => -10800,
  11882. 'PONT' => 39600,
  11883. 'PST' => -28800,
  11884. 'PWT' => 32400,
  11885. 'PYST' => -10800,
  11886. 'PYT' => -14400,
  11887. 'RET' => 14400,
  11888. 'ROTT' => -10800,
  11889. 'SAMST' => 18000,
  11890. 'SAMT' => 14400,
  11891. 'SAST' => 7200,
  11892. 'SBT' => 39600,
  11893. 'SCDT' => 46800,
  11894. 'SCST' => 43200,
  11895. 'SCT' => 14400,
  11896. 'SEST' => 3600,
  11897. 'SGT' => 28800,
  11898. 'SIT' => 28800,
  11899. 'SRT' => -10800,
  11900. 'SST' => -39600,
  11901. 'SYST' => 10800,
  11902. 'SYT' => 7200,
  11903. 'TFT' => 18000,
  11904. 'THAT' => -36000,
  11905. 'TJT' => 18000,
  11906. 'TKT' => -36000,
  11907. 'TMT' => 18000,
  11908. 'TOT' => 46800,
  11909. 'TPT' => 32400,
  11910. 'TRUT' => 36000,
  11911. 'TVT' => 43200,
  11912. 'TWT' => 28800,
  11913. 'UYST' => -7200,
  11914. 'UYT' => -10800,
  11915. 'UZT' => 18000,
  11916. 'VET' => -14400,
  11917. 'VLAST' => 39600,
  11918. 'VLAT' => 36000,
  11919. 'VOST' => 21600,
  11920. 'VUT' => 39600,
  11921. 'WAST' => 7200,
  11922. 'WAT' => 3600,
  11923. 'WDT' => 32400,
  11924. 'WEST' => 3600,
  11925. 'WFT' => 43200,
  11926. 'WIB' => 25200,
  11927. 'WIT' => 32400,
  11928. 'WITA' => 28800,
  11929. 'WKST' => 18000,
  11930. 'WST' => 28800,
  11931. 'YAKST' => 36000,
  11932. 'YAKT' => 32400,
  11933. 'YAPT' => 36000,
  11934. 'YEKST' => 21600,
  11935. 'YEKT' => 18000,
  11936. );
  11937. /**
  11938. * Cached PCRE for SimplePie_Parse_Date::$day
  11939. *
  11940. * @access protected
  11941. * @var string
  11942. */
  11943. var $day_pcre;
  11944. /**
  11945. * Cached PCRE for SimplePie_Parse_Date::$month
  11946. *
  11947. * @access protected
  11948. * @var string
  11949. */
  11950. var $month_pcre;
  11951. /**
  11952. * Array of user-added callback methods
  11953. *
  11954. * @access private
  11955. * @var array
  11956. */
  11957. var $built_in = array();
  11958. /**
  11959. * Array of user-added callback methods
  11960. *
  11961. * @access private
  11962. * @var array
  11963. */
  11964. var $user = array();
  11965. /**
  11966. * Create new SimplePie_Parse_Date object, and set self::day_pcre,
  11967. * self::month_pcre, and self::built_in
  11968. *
  11969. * @access private
  11970. */
  11971. function SimplePie_Parse_Date()
  11972. {
  11973. $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
  11974. $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
  11975. static $cache;
  11976. if (!isset($cache[get_class($this)]))
  11977. {
  11978. $all_methods = get_class_methods($this);
  11979. foreach ($all_methods as $method)
  11980. {
  11981. if (strtolower(substr($method, 0, 5)) === 'date_')
  11982. {
  11983. $cache[get_class($this)][] = $method;
  11984. }
  11985. }
  11986. }
  11987. foreach ($cache[get_class($this)] as $method)
  11988. {
  11989. $this->built_in[] = $method;
  11990. }
  11991. }
  11992. /**
  11993. * Get the object
  11994. *
  11995. * @access public
  11996. */
  11997. function get()
  11998. {
  11999. static $object;
  12000. if (!$object)
  12001. {
  12002. $object =& new SimplePie_Parse_Date;
  12003. }
  12004. return $object;
  12005. }
  12006. /**
  12007. * Parse a date
  12008. *
  12009. * @final
  12010. * @access public
  12011. * @param string $date Date to parse
  12012. * @return int Timestamp corresponding to date string, or false on failure
  12013. */
  12014. function parse($date)
  12015. {
  12016. foreach ($this->user as $method)
  12017. {
  12018. if (($returned = call_user_func($method, $date)) !== false)
  12019. {
  12020. return $returned;
  12021. }
  12022. }
  12023. foreach ($this->built_in as $method)
  12024. {
  12025. if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
  12026. {
  12027. return $returned;
  12028. }
  12029. }
  12030. return false;
  12031. }
  12032. /**
  12033. * Add a callback method to parse a date
  12034. *
  12035. * @final
  12036. * @access public
  12037. * @param callback $callback
  12038. */
  12039. function add_callback($callback)
  12040. {
  12041. if (is_callable($callback))
  12042. {
  12043. $this->user[] = $callback;
  12044. }
  12045. else
  12046. {
  12047. trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
  12048. }
  12049. }
  12050. /**
  12051. * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
  12052. * well as allowing any of upper or lower case "T", horizontal tabs, or
  12053. * spaces to be used as the time seperator (including more than one))
  12054. *
  12055. * @access protected
  12056. * @return int Timestamp
  12057. */
  12058. function date_w3cdtf($date)
  12059. {
  12060. static $pcre;
  12061. if (!$pcre)
  12062. {
  12063. $year = '([0-9]{4})';
  12064. $month = $day = $hour = $minute = $second = '([0-9]{2})';
  12065. $decimal = '([0-9]*)';
  12066. $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
  12067. $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
  12068. }
  12069. if (preg_match($pcre, $date, $match))
  12070. {
  12071. /*
  12072. Capturing subpatterns:
  12073. 1: Year
  12074. 2: Month
  12075. 3: Day
  12076. 4: Hour
  12077. 5: Minute
  12078. 6: Second
  12079. 7: Decimal fraction of a second
  12080. 8: Zulu
  12081. 9: Timezone ±
  12082. 10: Timezone hours
  12083. 11: Timezone minutes
  12084. */
  12085. // Fill in empty matches
  12086. for ($i = count($match); $i <= 3; $i++)
  12087. {
  12088. $match[$i] = '1';
  12089. }
  12090. for ($i = count($match); $i <= 7; $i++)
  12091. {
  12092. $match[$i] = '0';
  12093. }
  12094. // Numeric timezone
  12095. if (isset($match[9]) && $match[9] !== '')
  12096. {
  12097. $timezone = $match[10] * 3600;
  12098. $timezone += $match[11] * 60;
  12099. if ($match[9] === '-')
  12100. {
  12101. $timezone = 0 - $timezone;
  12102. }
  12103. }
  12104. else
  12105. {
  12106. $timezone = 0;
  12107. }
  12108. // Convert the number of seconds to an integer, taking decimals into account
  12109. $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
  12110. return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
  12111. }
  12112. else
  12113. {
  12114. return false;
  12115. }
  12116. }
  12117. /**
  12118. * Remove RFC822 comments
  12119. *
  12120. * @access protected
  12121. * @param string $data Data to strip comments from
  12122. * @return string Comment stripped string
  12123. */
  12124. function remove_rfc2822_comments($string)
  12125. {
  12126. $string = (string) $string;
  12127. $position = 0;
  12128. $length = strlen($string);
  12129. $depth = 0;
  12130. $output = '';
  12131. while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
  12132. {
  12133. $output .= substr($string, $position, $pos - $position);
  12134. $position = $pos + 1;
  12135. if ($string[$pos - 1] !== '\\')
  12136. {
  12137. $depth++;
  12138. while ($depth && $position < $length)
  12139. {
  12140. $position += strcspn($string, '()', $position);
  12141. if ($string[$position - 1] === '\\')
  12142. {
  12143. $position++;
  12144. continue;
  12145. }
  12146. elseif (isset($string[$position]))
  12147. {
  12148. switch ($string[$position])
  12149. {
  12150. case '(':
  12151. $depth++;
  12152. break;
  12153. case ')':
  12154. $depth--;
  12155. break;
  12156. }
  12157. $position++;
  12158. }
  12159. else
  12160. {
  12161. break;
  12162. }
  12163. }
  12164. }
  12165. else
  12166. {
  12167. $output .= '(';
  12168. }
  12169. }
  12170. $output .= substr($string, $position);
  12171. return $output;
  12172. }
  12173. /**
  12174. * Parse RFC2822's date format
  12175. *
  12176. * @access protected
  12177. * @return int Timestamp
  12178. */
  12179. function date_rfc2822($date)
  12180. {
  12181. static $pcre;
  12182. if (!$pcre)
  12183. {
  12184. $wsp = '[\x09\x20]';
  12185. $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
  12186. $optional_fws = $fws . '?';
  12187. $day_name = $this->day_pcre;
  12188. $month = $this->month_pcre;
  12189. $day = '([0-9]{1,2})';
  12190. $hour = $minute = $second = '([0-9]{2})';
  12191. $year = '([0-9]{2,4})';
  12192. $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
  12193. $character_zone = '([A-Z]{1,5})';
  12194. $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
  12195. $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';
  12196. }
  12197. if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
  12198. {
  12199. /*
  12200. Capturing subpatterns:
  12201. 1: Day name
  12202. 2: Day
  12203. 3: Month
  12204. 4: Year
  12205. 5: Hour
  12206. 6: Minute
  12207. 7: Second
  12208. 8: Timezone ±
  12209. 9: Timezone hours
  12210. 10: Timezone minutes
  12211. 11: Alphabetic timezone
  12212. */
  12213. // Find the month number
  12214. $month = $this->month[strtolower($match[3])];
  12215. // Numeric timezone
  12216. if ($match[8] !== '')
  12217. {
  12218. $timezone = $match[9] * 3600;
  12219. $timezone += $match[10] * 60;
  12220. if ($match[8] === '-')
  12221. {
  12222. $timezone = 0 - $timezone;
  12223. }
  12224. }
  12225. // Character timezone
  12226. elseif (isset($this->timezone[strtoupper($match[11])]))
  12227. {
  12228. $timezone = $this->timezone[strtoupper($match[11])];
  12229. }
  12230. // Assume everything else to be -0000
  12231. else
  12232. {
  12233. $timezone = 0;
  12234. }
  12235. // Deal with 2/3 digit years
  12236. if ($match[4] < 50)
  12237. {
  12238. $match[4] += 2000;
  12239. }
  12240. elseif ($match[4] < 1000)
  12241. {
  12242. $match[4] += 1900;
  12243. }
  12244. // Second is optional, if it is empty set it to zero
  12245. if ($match[7] !== '')
  12246. {
  12247. $second = $match[7];
  12248. }
  12249. else
  12250. {
  12251. $second = 0;
  12252. }
  12253. return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
  12254. }
  12255. else
  12256. {
  12257. return false;
  12258. }
  12259. }
  12260. /**
  12261. * Parse RFC850's date format
  12262. *
  12263. * @access protected
  12264. * @return int Timestamp
  12265. */
  12266. function date_rfc850($date)
  12267. {
  12268. static $pcre;
  12269. if (!$pcre)
  12270. {
  12271. $space = '[\x09\x20]+';
  12272. $day_name = $this->day_pcre;
  12273. $month = $this->month_pcre;
  12274. $day = '([0-9]{1,2})';
  12275. $year = $hour = $minute = $second = '([0-9]{2})';
  12276. $zone = '([A-Z]{1,5})';
  12277. $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
  12278. }
  12279. if (preg_match($pcre, $date, $match))
  12280. {
  12281. /*
  12282. Capturing subpatterns:
  12283. 1: Day name
  12284. 2: Day
  12285. 3: Month
  12286. 4: Year
  12287. 5: Hour
  12288. 6: Minute
  12289. 7: Second
  12290. 8: Timezone
  12291. */
  12292. // Month
  12293. $month = $this->month[strtolower($match[3])];
  12294. // Character timezone
  12295. if (isset($this->timezone[strtoupper($match[8])]))
  12296. {
  12297. $timezone = $this->timezone[strtoupper($match[8])];
  12298. }
  12299. // Assume everything else to be -0000
  12300. else
  12301. {
  12302. $timezone = 0;
  12303. }
  12304. // Deal with 2 digit year
  12305. if ($match[4] < 50)
  12306. {
  12307. $match[4] += 2000;
  12308. }
  12309. else
  12310. {
  12311. $match[4] += 1900;
  12312. }
  12313. return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
  12314. }
  12315. else
  12316. {
  12317. return false;
  12318. }
  12319. }
  12320. /**
  12321. * Parse C99's asctime()'s date format
  12322. *
  12323. * @access protected
  12324. * @return int Timestamp
  12325. */
  12326. function date_asctime($date)
  12327. {
  12328. static $pcre;
  12329. if (!$pcre)
  12330. {
  12331. $space = '[\x09\x20]+';
  12332. $wday_name = $this->day_pcre;
  12333. $mon_name = $this->month_pcre;
  12334. $day = '([0-9]{1,2})';
  12335. $hour = $sec = $min = '([0-9]{2})';
  12336. $year = '([0-9]{4})';
  12337. $terminator = '\x0A?\x00?';
  12338. $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
  12339. }
  12340. if (preg_match($pcre, $date, $match))
  12341. {
  12342. /*
  12343. Capturing subpatterns:
  12344. 1: Day name
  12345. 2: Month
  12346. 3: Day
  12347. 4: Hour
  12348. 5: Minute
  12349. 6: Second
  12350. 7: Year
  12351. */
  12352. $month = $this->month[strtolower($match[2])];
  12353. return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
  12354. }
  12355. else
  12356. {
  12357. return false;
  12358. }
  12359. }
  12360. /**
  12361. * Parse dates using strtotime()
  12362. *
  12363. * @access protected
  12364. * @return int Timestamp
  12365. */
  12366. function date_strtotime($date)
  12367. {
  12368. $strtotime = strtotime($date);
  12369. if ($strtotime === -1 || $strtotime === false)
  12370. {
  12371. return false;
  12372. }
  12373. else
  12374. {
  12375. return $strtotime;
  12376. }
  12377. }
  12378. }
  12379. /**
  12380. * Content-type sniffing
  12381. *
  12382. * @package SimplePie
  12383. */
  12384. class SimplePie_Content_Type_Sniffer
  12385. {
  12386. /**
  12387. * File object
  12388. *
  12389. * @var SimplePie_File
  12390. * @access private
  12391. */
  12392. var $file;
  12393. /**
  12394. * Create an instance of the class with the input file
  12395. *
  12396. * @access public
  12397. * @param SimplePie_Content_Type_Sniffer $file Input file
  12398. */
  12399. function SimplePie_Content_Type_Sniffer($file)
  12400. {
  12401. $this->file = $file;
  12402. }
  12403. /**
  12404. * Get the Content-Type of the specified file
  12405. *
  12406. * @access public
  12407. * @return string Actual Content-Type
  12408. */
  12409. function get_type()
  12410. {
  12411. if (isset($this->file->headers['content-type']))
  12412. {
  12413. if (!isset($this->file->headers['content-encoding'])
  12414. && ($this->file->headers['content-type'] === 'text/plain'
  12415. || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
  12416. || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
  12417. {
  12418. return $this->text_or_binary();
  12419. }
  12420. if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
  12421. {
  12422. $official = substr($this->file->headers['content-type'], 0, $pos);
  12423. }
  12424. else
  12425. {
  12426. $official = $this->file->headers['content-type'];
  12427. }
  12428. $official = strtolower($official);
  12429. if ($official === 'unknown/unknown'
  12430. || $official === 'application/unknown')
  12431. {
  12432. return $this->unknown();
  12433. }
  12434. elseif (substr($official, -4) === '+xml'
  12435. || $official === 'text/xml'
  12436. || $official === 'application/xml')
  12437. {
  12438. return $official;
  12439. }
  12440. elseif (substr($official, 0, 6) === 'image/')
  12441. {
  12442. if ($return = $this->image())
  12443. {
  12444. return $return;
  12445. }
  12446. else
  12447. {
  12448. return $official;
  12449. }
  12450. }
  12451. elseif ($official === 'text/html')
  12452. {
  12453. return $this->feed_or_html();
  12454. }
  12455. else
  12456. {
  12457. return $official;
  12458. }
  12459. }
  12460. else
  12461. {
  12462. return $this->unknown();
  12463. }
  12464. }
  12465. /**
  12466. * Sniff text or binary
  12467. *
  12468. * @access private
  12469. * @return string Actual Content-Type
  12470. */
  12471. function text_or_binary()
  12472. {
  12473. if (substr($this->file->body, 0, 2) === "\xFE\xFF"
  12474. || substr($this->file->body, 0, 2) === "\xFF\xFE"
  12475. || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
  12476. || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
  12477. {
  12478. return 'text/plain';
  12479. }
  12480. elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
  12481. {
  12482. return 'application/octect-stream';
  12483. }
  12484. else
  12485. {
  12486. return 'text/plain';
  12487. }
  12488. }
  12489. /**
  12490. * Sniff unknown
  12491. *
  12492. * @access private
  12493. * @return string Actual Content-Type
  12494. */
  12495. function unknown()
  12496. {
  12497. $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
  12498. if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
  12499. || strtolower(substr($this->file->body, $ws, 5)) === '<html'
  12500. || strtolower(substr($this->file->body, $ws, 7)) === '<script')
  12501. {
  12502. return 'text/html';
  12503. }
  12504. elseif (substr($this->file->body, 0, 5) === '%PDF-')
  12505. {
  12506. return 'application/pdf';
  12507. }
  12508. elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
  12509. {
  12510. return 'application/postscript';
  12511. }
  12512. elseif (substr($this->file->body, 0, 6) === 'GIF87a'
  12513. || substr($this->file->body, 0, 6) === 'GIF89a')
  12514. {
  12515. return 'image/gif';
  12516. }
  12517. elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
  12518. {
  12519. return 'image/png';
  12520. }
  12521. elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
  12522. {
  12523. return 'image/jpeg';
  12524. }
  12525. elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
  12526. {
  12527. return 'image/bmp';
  12528. }
  12529. else
  12530. {
  12531. return $this->text_or_binary();
  12532. }
  12533. }
  12534. /**
  12535. * Sniff images
  12536. *
  12537. * @access private
  12538. * @return string Actual Content-Type
  12539. */
  12540. function image()
  12541. {
  12542. if (substr($this->file->body, 0, 6) === 'GIF87a'
  12543. || substr($this->file->body, 0, 6) === 'GIF89a')
  12544. {
  12545. return 'image/gif';
  12546. }
  12547. elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
  12548. {
  12549. return 'image/png';
  12550. }
  12551. elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
  12552. {
  12553. return 'image/jpeg';
  12554. }
  12555. elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
  12556. {
  12557. return 'image/bmp';
  12558. }
  12559. else
  12560. {
  12561. return false;
  12562. }
  12563. }
  12564. /**
  12565. * Sniff HTML
  12566. *
  12567. * @access private
  12568. * @return string Actual Content-Type
  12569. */
  12570. function feed_or_html()
  12571. {
  12572. $len = strlen($this->file->body);
  12573. $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
  12574. while ($pos < $len)
  12575. {
  12576. switch ($this->file->body[$pos])
  12577. {
  12578. case "\x09":
  12579. case "\x0A":
  12580. case "\x0D":
  12581. case "\x20":
  12582. $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
  12583. continue 2;
  12584. case '<':
  12585. $pos++;
  12586. break;
  12587. default:
  12588. return 'text/html';
  12589. }
  12590. if (substr($this->file->body, $pos, 3) === '!--')
  12591. {
  12592. $pos += 3;
  12593. if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
  12594. {
  12595. $pos += 3;
  12596. }
  12597. else
  12598. {
  12599. return 'text/html';
  12600. }
  12601. }
  12602. elseif (substr($this->file->body, $pos, 1) === '!')
  12603. {
  12604. if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
  12605. {
  12606. $pos++;
  12607. }
  12608. else
  12609. {
  12610. return 'text/html';
  12611. }
  12612. }
  12613. elseif (substr($this->file->body, $pos, 1) === '?')
  12614. {
  12615. if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
  12616. {
  12617. $pos += 2;
  12618. }
  12619. else
  12620. {
  12621. return 'text/html';
  12622. }
  12623. }
  12624. elseif (substr($this->file->body, $pos, 3) === 'rss'
  12625. || substr($this->file->body, $pos, 7) === 'rdf:RDF')
  12626. {
  12627. return 'application/rss+xml';
  12628. }
  12629. elseif (substr($this->file->body, $pos, 4) === 'feed')
  12630. {
  12631. return 'application/atom+xml';
  12632. }
  12633. else
  12634. {
  12635. return 'text/html';
  12636. }
  12637. }
  12638. return 'text/html';
  12639. }
  12640. }
  12641. /**
  12642. * Parses the XML Declaration
  12643. *
  12644. * @package SimplePie
  12645. */
  12646. class SimplePie_XML_Declaration_Parser
  12647. {
  12648. /**
  12649. * XML Version
  12650. *
  12651. * @access public
  12652. * @var string
  12653. */
  12654. var $version = '1.0';
  12655. /**
  12656. * Encoding
  12657. *
  12658. * @access public
  12659. * @var string
  12660. */
  12661. var $encoding = 'UTF-8';
  12662. /**
  12663. * Standalone
  12664. *
  12665. * @access public
  12666. * @var bool
  12667. */
  12668. var $standalone = false;
  12669. /**
  12670. * Current state of the state machine
  12671. *
  12672. * @access private
  12673. * @var string
  12674. */
  12675. var $state = 'before_version_name';
  12676. /**
  12677. * Input data
  12678. *
  12679. * @access private
  12680. * @var string
  12681. */
  12682. var $data = '';
  12683. /**
  12684. * Input data length (to avoid calling strlen() everytime this is needed)
  12685. *
  12686. * @access private
  12687. * @var int
  12688. */
  12689. var $data_length = 0;
  12690. /**
  12691. * Current position of the pointer
  12692. *
  12693. * @var int
  12694. * @access private
  12695. */
  12696. var $position = 0;
  12697. /**
  12698. * Create an instance of the class with the input data
  12699. *
  12700. * @access public
  12701. * @param string $data Input data
  12702. */
  12703. function SimplePie_XML_Declaration_Parser($data)
  12704. {
  12705. $this->data = $data;
  12706. $this->data_length = strlen($this->data);
  12707. }
  12708. /**
  12709. * Parse the input data
  12710. *
  12711. * @access public
  12712. * @return bool true on success, false on failure
  12713. */
  12714. function parse()
  12715. {
  12716. while ($this->state && $this->state !== 'emit' && $this->has_data())
  12717. {
  12718. $state = $this->state;
  12719. $this->$state();
  12720. }
  12721. $this->data = '';
  12722. if ($this->state === 'emit')
  12723. {
  12724. return true;
  12725. }
  12726. else
  12727. {
  12728. $this->version = '';
  12729. $this->encoding = '';
  12730. $this->standalone = '';
  12731. return false;
  12732. }
  12733. }
  12734. /**
  12735. * Check whether there is data beyond the pointer
  12736. *
  12737. * @access private
  12738. * @return bool true if there is further data, false if not
  12739. */
  12740. function has_data()
  12741. {
  12742. return (bool) ($this->position < $this->data_length);
  12743. }
  12744. /**
  12745. * Advance past any whitespace
  12746. *
  12747. * @return int Number of whitespace characters passed
  12748. */
  12749. function skip_whitespace()
  12750. {
  12751. $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
  12752. $this->position += $whitespace;
  12753. return $whitespace;
  12754. }
  12755. /**
  12756. * Read value
  12757. */
  12758. function get_value()
  12759. {
  12760. $quote = substr($this->data, $this->position, 1);
  12761. if ($quote === '"' || $quote === "'")
  12762. {
  12763. $this->position++;
  12764. $len = strcspn($this->data, $quote, $this->position);
  12765. if ($this->has_data())
  12766. {
  12767. $value = substr($this->data, $this->position, $len);
  12768. $this->position += $len + 1;
  12769. return $value;
  12770. }
  12771. }
  12772. return false;
  12773. }
  12774. function before_version_name()
  12775. {
  12776. if ($this->skip_whitespace())
  12777. {
  12778. $this->state = 'version_name';
  12779. }
  12780. else
  12781. {
  12782. $this->state = false;
  12783. }
  12784. }
  12785. function version_name()
  12786. {
  12787. if (substr($this->data, $this->position, 7) === 'version')
  12788. {
  12789. $this->position += 7;
  12790. $this->skip_whitespace();
  12791. $this->state = 'version_equals';
  12792. }
  12793. else
  12794. {
  12795. $this->state = false;
  12796. }
  12797. }
  12798. function version_equals()
  12799. {
  12800. if (substr($this->data, $this->position, 1) === '=')
  12801. {
  12802. $this->position++;
  12803. $this->skip_whitespace();
  12804. $this->state = 'version_value';
  12805. }
  12806. else
  12807. {
  12808. $this->state = false;
  12809. }
  12810. }
  12811. function version_value()
  12812. {
  12813. if ($this->version = $this->get_value())
  12814. {
  12815. $this->skip_whitespace();
  12816. if ($this->has_data())
  12817. {
  12818. $this->state = 'encoding_name';
  12819. }
  12820. else
  12821. {
  12822. $this->state = 'emit';
  12823. }
  12824. }
  12825. else
  12826. {
  12827. $this->state = 'standalone_name';
  12828. }
  12829. }
  12830. function encoding_name()
  12831. {
  12832. if (substr($this->data, $this->position, 8) === 'encoding')
  12833. {
  12834. $this->position += 8;
  12835. $this->skip_whitespace();
  12836. $this->state = 'encoding_equals';
  12837. }
  12838. else
  12839. {
  12840. $this->state = false;
  12841. }
  12842. }
  12843. function encoding_equals()
  12844. {
  12845. if (substr($this->data, $this->position, 1) === '=')
  12846. {
  12847. $this->position++;
  12848. $this->skip_whitespace();
  12849. $this->state = 'encoding_value';
  12850. }
  12851. else
  12852. {
  12853. $this->state = false;
  12854. }
  12855. }
  12856. function encoding_value()
  12857. {
  12858. if ($this->encoding = $this->get_value())
  12859. {
  12860. $this->skip_whitespace();
  12861. if ($this->has_data())
  12862. {
  12863. $this->state = 'standalone_name';
  12864. }
  12865. else
  12866. {
  12867. $this->state = 'emit';
  12868. }
  12869. }
  12870. else
  12871. {
  12872. $this->state = false;
  12873. }
  12874. }
  12875. function standalone_name()
  12876. {
  12877. if (substr($this->data, $this->position, 10) === 'standalone')
  12878. {
  12879. $this->position += 10;
  12880. $this->skip_whitespace();
  12881. $this->state = 'standalone_equals';
  12882. }
  12883. else
  12884. {
  12885. $this->state = false;
  12886. }
  12887. }
  12888. function standalone_equals()
  12889. {
  12890. if (substr($this->data, $this->position, 1) === '=')
  12891. {
  12892. $this->position++;
  12893. $this->skip_whitespace();
  12894. $this->state = 'standalone_value';
  12895. }
  12896. else
  12897. {
  12898. $this->state = false;
  12899. }
  12900. }
  12901. function standalone_value()
  12902. {
  12903. if ($standalone = $this->get_value())
  12904. {
  12905. switch ($standalone)
  12906. {
  12907. case 'yes':
  12908. $this->standalone = true;
  12909. break;
  12910. case 'no':
  12911. $this->standalone = false;
  12912. break;
  12913. default:
  12914. $this->state = false;
  12915. return;
  12916. }
  12917. $this->skip_whitespace();
  12918. if ($this->has_data())
  12919. {
  12920. $this->state = false;
  12921. }
  12922. else
  12923. {
  12924. $this->state = 'emit';
  12925. }
  12926. }
  12927. else
  12928. {
  12929. $this->state = false;
  12930. }
  12931. }
  12932. }
  12933. class SimplePie_Locator
  12934. {
  12935. var $useragent;
  12936. var $timeout;
  12937. var $file;
  12938. var $local = array();
  12939. var $elsewhere = array();
  12940. var $file_class = 'SimplePie_File';
  12941. var $cached_entities = array();
  12942. var $http_base;
  12943. var $base;
  12944. var $base_location = 0;
  12945. var $checked_feeds = 0;
  12946. var $max_checked_feeds = 10;
  12947. var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
  12948. function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
  12949. {
  12950. $this->file =& $file;
  12951. $this->file_class = $file_class;
  12952. $this->useragent = $useragent;
  12953. $this->timeout = $timeout;
  12954. $this->max_checked_feeds = $max_checked_feeds;
  12955. $this->content_type_sniffer_class = $content_type_sniffer_class;
  12956. }
  12957. function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
  12958. {
  12959. if ($this->is_feed($this->file))
  12960. {
  12961. return $this->file;
  12962. }
  12963. if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
  12964. {
  12965. $sniffer =& new $this->content_type_sniffer_class($this->file);
  12966. if ($sniffer->get_type() !== 'text/html')
  12967. {
  12968. return null;
  12969. }
  12970. }
  12971. if ($type & ~SIMPLEPIE_LOCATOR_NONE)
  12972. {
  12973. $this->get_base();
  12974. }
  12975. if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
  12976. {
  12977. return $working[0];
  12978. }
  12979. if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
  12980. {
  12981. if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
  12982. {
  12983. return $working;
  12984. }
  12985. if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
  12986. {
  12987. return $working;
  12988. }
  12989. if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
  12990. {
  12991. return $working;
  12992. }
  12993. if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
  12994. {
  12995. return $working;
  12996. }
  12997. }
  12998. return null;
  12999. }
  13000. function is_feed(&$file)
  13001. {
  13002. if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
  13003. {
  13004. $sniffer =& new $this->content_type_sniffer_class($file);
  13005. $sniffed = $sniffer->get_type();
  13006. if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
  13007. {
  13008. return true;
  13009. }
  13010. else
  13011. {
  13012. return false;
  13013. }
  13014. }
  13015. elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
  13016. {
  13017. return true;
  13018. }
  13019. else
  13020. {
  13021. return false;
  13022. }
  13023. }
  13024. function get_base()
  13025. {
  13026. $this->http_base = $this->file->url;
  13027. $this->base = $this->http_base;
  13028. $elements = SimplePie_Misc::get_element('base', $this->file->body);
  13029. foreach ($elements as $element)
  13030. {
  13031. if ($element['attribs']['href']['data'] !== '')
  13032. {
  13033. $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
  13034. $this->base_location = $element['offset'];
  13035. break;
  13036. }
  13037. }
  13038. }
  13039. function autodiscovery()
  13040. {
  13041. $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));
  13042. $done = array();
  13043. $feeds = array();
  13044. foreach ($links as $link)
  13045. {
  13046. if ($this->checked_feeds === $this->max_checked_feeds)
  13047. {
  13048. break;
  13049. }
  13050. if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
  13051. {
  13052. $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
  13053. if ($this->base_location < $link['offset'])
  13054. {
  13055. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
  13056. }
  13057. else
  13058. {
  13059. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
  13060. }
  13061. 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'))) && !isset($feeds[$href]))
  13062. {
  13063. $this->checked_feeds++;
  13064. $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
  13065. if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
  13066. {
  13067. $feeds[$href] = $feed;
  13068. }
  13069. }
  13070. $done[] = $href;
  13071. }
  13072. }
  13073. if (!empty($feeds))
  13074. {
  13075. return array_values($feeds);
  13076. }
  13077. else {
  13078. return null;
  13079. }
  13080. }
  13081. function get_links()
  13082. {
  13083. $links = SimplePie_Misc::get_element('a', $this->file->body);
  13084. foreach ($links as $link)
  13085. {
  13086. if (isset($link['attribs']['href']['data']))
  13087. {
  13088. $href = trim($link['attribs']['href']['data']);
  13089. $parsed = SimplePie_Misc::parse_url($href);
  13090. if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
  13091. {
  13092. if ($this->base_location < $link['offset'])
  13093. {
  13094. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
  13095. }
  13096. else
  13097. {
  13098. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
  13099. }
  13100. $current = SimplePie_Misc::parse_url($this->file->url);
  13101. if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
  13102. {
  13103. $this->local[] = $href;
  13104. }
  13105. else
  13106. {
  13107. $this->elsewhere[] = $href;
  13108. }
  13109. }
  13110. }
  13111. }
  13112. $this->local = array_unique($this->local);
  13113. $this->elsewhere = array_unique($this->elsewhere);
  13114. if (!empty($this->local) || !empty($this->elsewhere))
  13115. {
  13116. return true;
  13117. }
  13118. return null;
  13119. }
  13120. function extension(&$array)
  13121. {
  13122. foreach ($array as $key => $value)
  13123. {
  13124. if ($this->checked_feeds === $this->max_checked_feeds)
  13125. {
  13126. break;
  13127. }
  13128. if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
  13129. {
  13130. $this->checked_feeds++;
  13131. $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
  13132. if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
  13133. {
  13134. return $feed;
  13135. }
  13136. else
  13137. {
  13138. unset($array[$key]);
  13139. }
  13140. }
  13141. }
  13142. return null;
  13143. }
  13144. function body(&$array)
  13145. {
  13146. foreach ($array as $key => $value)
  13147. {
  13148. if ($this->checked_feeds === $this->max_checked_feeds)
  13149. {
  13150. break;
  13151. }
  13152. if (preg_match('/(rss|rdf|atom|xml)/i', $value))
  13153. {
  13154. $this->checked_feeds++;
  13155. $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
  13156. if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
  13157. {
  13158. return $feed;
  13159. }
  13160. else
  13161. {
  13162. unset($array[$key]);
  13163. }
  13164. }
  13165. }
  13166. return null;
  13167. }
  13168. }
  13169. class SimplePie_Parser
  13170. {
  13171. var $error_code;
  13172. var $error_string;
  13173. var $current_line;
  13174. var $current_column;
  13175. var $current_byte;
  13176. var $separator = ' ';
  13177. var $namespace = array('');
  13178. var $element = array('');
  13179. var $xml_base = array('');
  13180. var $xml_base_explicit = array(false);
  13181. var $xml_lang = array('');
  13182. var $data = array();
  13183. var $datas = array(array());
  13184. var $current_xhtml_construct = -1;
  13185. var $encoding;
  13186. function parse(&$data, $encoding)
  13187. {
  13188. // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
  13189. if (strtoupper($encoding) === 'US-ASCII')
  13190. {
  13191. $this->encoding = 'UTF-8';
  13192. }
  13193. else
  13194. {
  13195. $this->encoding = $encoding;
  13196. }
  13197. // Strip BOM:
  13198. // UTF-32 Big Endian BOM
  13199. if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
  13200. {
  13201. $data = substr($data, 4);
  13202. }
  13203. // UTF-32 Little Endian BOM
  13204. elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
  13205. {
  13206. $data = substr($data, 4);
  13207. }
  13208. // UTF-16 Big Endian BOM
  13209. elseif (substr($data, 0, 2) === "\xFE\xFF")
  13210. {
  13211. $data = substr($data, 2);
  13212. }
  13213. // UTF-16 Little Endian BOM
  13214. elseif (substr($data, 0, 2) === "\xFF\xFE")
  13215. {
  13216. $data = substr($data, 2);
  13217. }
  13218. // UTF-8 BOM
  13219. elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
  13220. {
  13221. $data = substr($data, 3);
  13222. }
  13223. if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
  13224. {
  13225. $declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
  13226. if ($declaration->parse())
  13227. {
  13228. $data = substr($data, $pos + 2);
  13229. $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
  13230. }
  13231. else
  13232. {
  13233. $this->error_string = 'SimplePie bug! Please report this!';
  13234. return false;
  13235. }
  13236. }
  13237. $return = true;
  13238. static $xml_is_sane = null;
  13239. if ($xml_is_sane === null)
  13240. {
  13241. $parser_check = xml_parser_create();
  13242. xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
  13243. xml_parser_free($parser_check);
  13244. $xml_is_sane = isset($values[0]['value']);
  13245. }
  13246. // Create the parser
  13247. if ($xml_is_sane)
  13248. {
  13249. $xml = xml_parser_create_ns($this->encoding, $this->separator);
  13250. xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
  13251. xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
  13252. xml_set_object($xml, $this);
  13253. xml_set_character_data_handler($xml, 'cdata');
  13254. xml_set_element_handler($xml, 'tag_open', 'tag_close');
  13255. // Parse!
  13256. if (!xml_parse($xml, $data, true))
  13257. {
  13258. $this->error_code = xml_get_error_code($xml);
  13259. $this->error_string = xml_error_string($this->error_code);
  13260. $return = false;
  13261. }
  13262. $this->current_line = xml_get_current_line_number($xml);
  13263. $this->current_column = xml_get_current_column_number($xml);
  13264. $this->current_byte = xml_get_current_byte_index($xml);
  13265. xml_parser_free($xml);
  13266. return $return;
  13267. }
  13268. else
  13269. {
  13270. libxml_clear_errors();
  13271. $xml =& new XMLReader();
  13272. $xml->xml($data);
  13273. while (@$xml->read())
  13274. {
  13275. switch ($xml->nodeType)
  13276. {
  13277. case constant('XMLReader::END_ELEMENT'):
  13278. if ($xml->namespaceURI !== '')
  13279. {
  13280. $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
  13281. }
  13282. else
  13283. {
  13284. $tagName = $xml->localName;
  13285. }
  13286. $this->tag_close(null, $tagName);
  13287. break;
  13288. case constant('XMLReader::ELEMENT'):
  13289. $empty = $xml->isEmptyElement;
  13290. if ($xml->namespaceURI !== '')
  13291. {
  13292. $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
  13293. }
  13294. else
  13295. {
  13296. $tagName = $xml->localName;
  13297. }
  13298. $attributes = array();
  13299. while ($xml->moveToNextAttribute())
  13300. {
  13301. if ($xml->namespaceURI !== '')
  13302. {
  13303. $attrName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
  13304. }
  13305. else
  13306. {
  13307. $attrName = $xml->localName;
  13308. }
  13309. $attributes[$attrName] = $xml->value;
  13310. }
  13311. $this->tag_open(null, $tagName, $attributes);
  13312. if ($empty)
  13313. {
  13314. $this->tag_close(null, $tagName);
  13315. }
  13316. break;
  13317. case constant('XMLReader::TEXT'):
  13318. case constant('XMLReader::CDATA'):
  13319. $this->cdata(null, $xml->value);
  13320. break;
  13321. }
  13322. }
  13323. if ($error = libxml_get_last_error())
  13324. {
  13325. $this->error_code = $error->code;
  13326. $this->error_string = $error->message;
  13327. $this->current_line = $error->line;
  13328. $this->current_column = $error->column;
  13329. return false;
  13330. }
  13331. else
  13332. {
  13333. return true;
  13334. }
  13335. }
  13336. }
  13337. function get_error_code()
  13338. {
  13339. return $this->error_code;
  13340. }
  13341. function get_error_string()
  13342. {
  13343. return $this->error_string;
  13344. }
  13345. function get_current_line()
  13346. {
  13347. return $this->current_line;
  13348. }
  13349. function get_current_column()
  13350. {
  13351. return $this->current_column;
  13352. }
  13353. function get_current_byte()
  13354. {
  13355. return $this->current_byte;
  13356. }
  13357. function get_data()
  13358. {
  13359. return $this->data;
  13360. }
  13361. function tag_open($parser, $tag, $attributes)
  13362. {
  13363. list($this->namespace[], $this->element[]) = $this->split_ns($tag);
  13364. $attribs = array();
  13365. foreach ($attributes as $name => $value)
  13366. {
  13367. list($attrib_namespace, $attribute) = $this->split_ns($name);
  13368. $attribs[$attrib_namespace][$attribute] = $value;
  13369. }
  13370. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
  13371. {
  13372. $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
  13373. $this->xml_base_explicit[] = true;
  13374. }
  13375. else
  13376. {
  13377. $this->xml_base[] = end($this->xml_base);
  13378. $this->xml_base_explicit[] = end($this->xml_base_explicit);
  13379. }
  13380. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
  13381. {
  13382. $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
  13383. }
  13384. else
  13385. {
  13386. $this->xml_lang[] = end($this->xml_lang);
  13387. }
  13388. if ($this->current_xhtml_construct >= 0)
  13389. {
  13390. $this->current_xhtml_construct++;
  13391. if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
  13392. {
  13393. $this->data['data'] .= '<' . end($this->element);
  13394. if (isset($attribs['']))
  13395. {
  13396. foreach ($attribs[''] as $name => $value)
  13397. {
  13398. $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
  13399. }
  13400. }
  13401. $this->data['data'] .= '>';
  13402. }
  13403. }
  13404. else
  13405. {
  13406. $this->datas[] =& $this->data;
  13407. $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
  13408. $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));
  13409. 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')
  13410. || (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'))
  13411. {
  13412. $this->current_xhtml_construct = 0;
  13413. }
  13414. }
  13415. }
  13416. function cdata($parser, $cdata)
  13417. {
  13418. if ($this->current_xhtml_construct >= 0)
  13419. {
  13420. $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
  13421. }
  13422. else
  13423. {
  13424. $this->data['data'] .= $cdata;
  13425. }
  13426. }
  13427. function tag_close($parser, $tag)
  13428. {
  13429. if ($this->current_xhtml_construct >= 0)
  13430. {
  13431. $this->current_xhtml_construct--;
  13432. 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')))
  13433. {
  13434. $this->data['data'] .= '</' . end($this->element) . '>';
  13435. }
  13436. }
  13437. if ($this->current_xhtml_construct === -1)
  13438. {
  13439. $this->data =& $this->datas[count($this->datas) - 1];
  13440. array_pop($this->datas);
  13441. }
  13442. array_pop($this->element);
  13443. array_pop($this->namespace);
  13444. array_pop($this->xml_base);
  13445. array_pop($this->xml_base_explicit);
  13446. array_pop($this->xml_lang);
  13447. }
  13448. function split_ns($string)
  13449. {
  13450. static $cache = array();
  13451. if (!isset($cache[$string]))
  13452. {
  13453. if ($pos = strpos($string, $this->separator))
  13454. {
  13455. static $separator_length;
  13456. if (!$separator_length)
  13457. {
  13458. $separator_length = strlen($this->separator);
  13459. }
  13460. $namespace = substr($string, 0, $pos);
  13461. $local_name = substr($string, $pos + $separator_length);
  13462. if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
  13463. {
  13464. $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
  13465. }
  13466. // Normalize the Media RSS namespaces
  13467. if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
  13468. {
  13469. $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
  13470. }
  13471. $cache[$string] = array($namespace, $local_name);
  13472. }
  13473. else
  13474. {
  13475. $cache[$string] = array('', $string);
  13476. }
  13477. }
  13478. return $cache[$string];
  13479. }
  13480. }
  13481. /**
  13482. * @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
  13483. */
  13484. class SimplePie_Sanitize
  13485. {
  13486. // Private vars
  13487. var $base;
  13488. // Options
  13489. var $remove_div = true;
  13490. var $image_handler = '';
  13491. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  13492. var $encode_instead_of_strip = false;
  13493. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  13494. var $strip_comments = false;
  13495. var $output_encoding = 'UTF-8';
  13496. var $enable_cache = true;
  13497. var $cache_location = './cache';
  13498. var $cache_name_function = 'md5';
  13499. var $cache_class = 'SimplePie_Cache';
  13500. var $file_class = 'SimplePie_File';
  13501. var $timeout = 10;
  13502. var $useragent = '';
  13503. var $force_fsockopen = false;
  13504. var $replace_url_attributes = array(
  13505. 'a' => 'href',
  13506. 'area' => 'href',
  13507. 'blockquote' => 'cite',
  13508. 'del' => 'cite',
  13509. 'form' => 'action',
  13510. 'img' => array('longdesc', 'src'),
  13511. 'input' => 'src',
  13512. 'ins' => 'cite',
  13513. 'q' => 'cite'
  13514. );
  13515. function remove_div($enable = true)
  13516. {
  13517. $this->remove_div = (bool) $enable;
  13518. }
  13519. function set_image_handler($page = false)
  13520. {
  13521. if ($page)
  13522. {
  13523. $this->image_handler = (string) $page;
  13524. }
  13525. else
  13526. {
  13527. $this->image_handler = false;
  13528. }
  13529. }
  13530. function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
  13531. {
  13532. if (isset($enable_cache))
  13533. {
  13534. $this->enable_cache = (bool) $enable_cache;
  13535. }
  13536. if ($cache_location)
  13537. {
  13538. $this->cache_location = (string) $cache_location;
  13539. }
  13540. if ($cache_name_function)
  13541. {
  13542. $this->cache_name_function = (string) $cache_name_function;
  13543. }
  13544. if ($cache_class)
  13545. {
  13546. $this->cache_class = (string) $cache_class;
  13547. }
  13548. }
  13549. function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
  13550. {
  13551. if ($file_class)
  13552. {
  13553. $this->file_class = (string) $file_class;
  13554. }
  13555. if ($timeout)
  13556. {
  13557. $this->timeout = (string) $timeout;
  13558. }
  13559. if ($useragent)
  13560. {
  13561. $this->useragent = (string) $useragent;
  13562. }
  13563. if ($force_fsockopen)
  13564. {
  13565. $this->force_fsockopen = (string) $force_fsockopen;
  13566. }
  13567. }
  13568. function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
  13569. {
  13570. if ($tags)
  13571. {
  13572. if (is_array($tags))
  13573. {
  13574. $this->strip_htmltags = $tags;
  13575. }
  13576. else
  13577. {
  13578. $this->strip_htmltags = explode(',', $tags);
  13579. }
  13580. }
  13581. else
  13582. {
  13583. $this->strip_htmltags = false;
  13584. }
  13585. }
  13586. function encode_instead_of_strip($encode = false)
  13587. {
  13588. $this->encode_instead_of_strip = (bool) $encode;
  13589. }
  13590. function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
  13591. {
  13592. if ($attribs)
  13593. {
  13594. if (is_array($attribs))
  13595. {
  13596. $this->strip_attributes = $attribs;
  13597. }
  13598. else
  13599. {
  13600. $this->strip_attributes = explode(',', $attribs);
  13601. }
  13602. }
  13603. else
  13604. {
  13605. $this->strip_attributes = false;
  13606. }
  13607. }
  13608. function strip_comments($strip = false)
  13609. {
  13610. $this->strip_comments = (bool) $strip;
  13611. }
  13612. function set_output_encoding($encoding = 'UTF-8')
  13613. {
  13614. $this->output_encoding = (string) $encoding;
  13615. }
  13616. /**
  13617. * Set element/attribute key/value pairs of HTML attributes
  13618. * containing URLs that need to be resolved relative to the feed
  13619. *
  13620. * @access public
  13621. * @since 1.0
  13622. * @param array $element_attribute Element/attribute key/value pairs
  13623. */
  13624. 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'))
  13625. {
  13626. $this->replace_url_attributes = (array) $element_attribute;
  13627. }
  13628. function sanitize($data, $type, $base = '')
  13629. {
  13630. $data = trim($data);
  13631. if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
  13632. {
  13633. if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
  13634. {
  13635. 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))
  13636. {
  13637. $type |= SIMPLEPIE_CONSTRUCT_HTML;
  13638. }
  13639. else
  13640. {
  13641. $type |= SIMPLEPIE_CONSTRUCT_TEXT;
  13642. }
  13643. }
  13644. if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
  13645. {
  13646. $data = base64_decode($data);
  13647. }
  13648. if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
  13649. {
  13650. if ($this->remove_div)
  13651. {
  13652. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
  13653. $data = preg_replace('/<\/div>$/', '', $data);
  13654. }
  13655. else
  13656. {
  13657. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
  13658. }
  13659. }
  13660. if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
  13661. {
  13662. // Strip comments
  13663. if ($this->strip_comments)
  13664. {
  13665. $data = SimplePie_Misc::strip_comments($data);
  13666. }
  13667. // Strip out HTML tags and attributes that might cause various security problems.
  13668. // Based on recommendations by Mark Pilgrim at:
  13669. // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
  13670. if ($this->strip_htmltags)
  13671. {
  13672. foreach ($this->strip_htmltags as $tag)
  13673. {
  13674. $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
  13675. while (preg_match($pcre, $data))
  13676. {
  13677. $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
  13678. }
  13679. }
  13680. }
  13681. if ($this->strip_attributes)
  13682. {
  13683. foreach ($this->strip_attributes as $attrib)
  13684. {
  13685. $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);
  13686. }
  13687. }
  13688. // Replace relative URLs
  13689. $this->base = $base;
  13690. foreach ($this->replace_url_attributes as $element => $attributes)
  13691. {
  13692. $data = $this->replace_urls($data, $element, $attributes);
  13693. }
  13694. // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
  13695. if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
  13696. {
  13697. $images = SimplePie_Misc::get_element('img', $data);
  13698. foreach ($images as $img)
  13699. {
  13700. if (isset($img['attribs']['src']['data']))
  13701. {
  13702. $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
  13703. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
  13704. if ($cache->load())
  13705. {
  13706. $img['attribs']['src']['data'] = $this->image_handler . $image_url;
  13707. $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
  13708. }
  13709. else
  13710. {
  13711. $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
  13712. $headers = $file->headers;
  13713. if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
  13714. {
  13715. if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  13716. {
  13717. $img['attribs']['src']['data'] = $this->image_handler . $image_url;
  13718. $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
  13719. }
  13720. else
  13721. {
  13722. trigger_error("$this->cache_location is not writeable", E_USER_WARNING);
  13723. }
  13724. }
  13725. }
  13726. }
  13727. }
  13728. }
  13729. // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
  13730. $data = trim($data);
  13731. }
  13732. if ($type & SIMPLEPIE_CONSTRUCT_IRI)
  13733. {
  13734. $data = SimplePie_Misc::absolutize_url($data, $base);
  13735. }
  13736. if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
  13737. {
  13738. $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
  13739. }
  13740. if ($this->output_encoding !== 'UTF-8')
  13741. {
  13742. $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
  13743. }
  13744. }
  13745. return $data;
  13746. }
  13747. function replace_urls($data, $tag, $attributes)
  13748. {
  13749. if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
  13750. {
  13751. $elements = SimplePie_Misc::get_element($tag, $data);
  13752. foreach ($elements as $element)
  13753. {
  13754. if (is_array($attributes))
  13755. {
  13756. foreach ($attributes as $attribute)
  13757. {
  13758. if (isset($element['attribs'][$attribute]['data']))
  13759. {
  13760. $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
  13761. $new_element = SimplePie_Misc::element_implode($element);
  13762. $data = str_replace($element['full'], $new_element, $data);
  13763. $element['full'] = $new_element;
  13764. }
  13765. }
  13766. }
  13767. elseif (isset($element['attribs'][$attributes]['data']))
  13768. {
  13769. $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
  13770. $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
  13771. }
  13772. }
  13773. }
  13774. return $data;
  13775. }
  13776. function do_strip_htmltags($match)
  13777. {
  13778. if ($this->encode_instead_of_strip)
  13779. {
  13780. if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  13781. {
  13782. $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
  13783. $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
  13784. return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
  13785. }
  13786. else
  13787. {
  13788. return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
  13789. }
  13790. }
  13791. elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  13792. {
  13793. return $match[4];
  13794. }
  13795. else
  13796. {
  13797. return '';
  13798. }
  13799. }
  13800. }
  13801. endif;
  13802. ?>