PageRenderTime 57ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/administrator/modules/mod_jw_srfr/simplepie.inc

https://bitbucket.org/dgough/annamaria-daneswood-25102012
PHP | 10841 lines | 9218 code | 513 blank | 1110 comment | 768 complexity | 7313f3c28e580431f79386ed42e8d271 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * SimplePie
  4. *
  5. * A PHP-Based RSS and Atom Feed Framework.
  6. * Takes the hard work out of managing a complete RSS/Atom solution.
  7. *
  8. * Copyright (c) 2004-2007, Ryan Parman and Geoffrey Sneddon
  9. * All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without modification, are
  12. * permitted provided that the following conditions are met:
  13. *
  14. * * Redistributions of source code must retain the above copyright notice, this list of
  15. * conditions and the following disclaimer.
  16. *
  17. * * Redistributions in binary form must reproduce the above copyright notice, this list
  18. * of conditions and the following disclaimer in the documentation and/or other materials
  19. * provided with the distribution.
  20. *
  21. * * Neither the name of the SimplePie Team nor the names of its contributors may be used
  22. * to endorse or promote products derived from this software without specific prior
  23. * written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  26. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  27. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
  28. * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  30. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  32. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. *
  35. * @package SimplePie
  36. * @version "Razzleberry"
  37. * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
  38. * @author Ryan Parman
  39. * @author Geoffrey Sneddon
  40. * @link http://simplepie.org/ SimplePie
  41. * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
  42. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  43. * @todo phpDoc comments
  44. */
  45. /**
  46. * SimplePie Name
  47. */
  48. define('SIMPLEPIE_NAME', 'SimplePie');
  49. /**
  50. * SimplePie Version
  51. */
  52. define('SIMPLEPIE_VERSION', '1.0.1');
  53. /**
  54. * SimplePie Build
  55. * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::parse_date() only every load of simplepie.inc)
  56. */
  57. define('SIMPLEPIE_BUILD', 20070719221955);
  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. * PCRE for HTML attributes
  208. */
  209. define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[a-z0-9\-._:]*)))?)*)\s*');
  210. /**
  211. * PCRE for XML attributes
  212. */
  213. define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
  214. /**
  215. * XML Namespace
  216. */
  217. define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
  218. /**
  219. * Atom 1.0 Namespace
  220. */
  221. define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
  222. /**
  223. * Atom 0.3 Namespace
  224. */
  225. define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
  226. /**
  227. * RDF Namespace
  228. */
  229. define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
  230. /**
  231. * RSS 0.90 Namespace
  232. */
  233. define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
  234. /**
  235. * RSS 1.0 Namespace
  236. */
  237. define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
  238. /**
  239. * RSS 1.0 Content Module Namespace
  240. */
  241. define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/administrator/modules/content/');
  242. /**
  243. * DC 1.0 Namespace
  244. */
  245. define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
  246. /**
  247. * DC 1.1 Namespace
  248. */
  249. define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
  250. /**
  251. * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
  252. */
  253. define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
  254. /**
  255. * GeoRSS Namespace
  256. */
  257. define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
  258. /**
  259. * Media RSS Namespace
  260. */
  261. define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
  262. /**
  263. * iTunes RSS Namespace
  264. */
  265. define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
  266. /**
  267. * XHTML Namespace
  268. */
  269. define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
  270. /**
  271. * IANA Link Relations Registry
  272. */
  273. define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
  274. /**
  275. * Whether we're running on PHP5
  276. */
  277. define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
  278. /**
  279. * SimplePie
  280. *
  281. * @package SimplePie
  282. * @version "Razzleberry"
  283. * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
  284. * @author Ryan Parman
  285. * @author Geoffrey Sneddon
  286. * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
  287. */
  288. class SimplePie
  289. {
  290. /**
  291. * @var array Raw data
  292. * @access private
  293. */
  294. var $data = array();
  295. /**
  296. * @var mixed Error string
  297. * @access private
  298. */
  299. var $error;
  300. /**
  301. * @var object Instance of SimplePie_Sanitize (or other class)
  302. * @see SimplePie::set_sanitize_class()
  303. * @access private
  304. */
  305. var $sanitize;
  306. /**
  307. * @var string SimplePie Useragent
  308. * @see SimplePie::set_useragent()
  309. * @access private
  310. */
  311. var $useragent = SIMPLEPIE_USERAGENT;
  312. /**
  313. * @var string Feed URL
  314. * @see SimplePie::set_feed_url()
  315. * @access private
  316. */
  317. var $feed_url;
  318. /**
  319. * @var object Instance of SimplePie_File to use as a feed
  320. * @see SimplePie::set_file()
  321. * @access private
  322. */
  323. var $file;
  324. /**
  325. * @var string Raw feed data
  326. * @see SimplePie::set_raw_data()
  327. * @access private
  328. */
  329. var $raw_data;
  330. /**
  331. * @var int Timeout for fetching remote files
  332. * @see SimplePie::set_timeout()
  333. * @access private
  334. */
  335. var $timeout = 10;
  336. /**
  337. * @var bool Forces fsockopen() to be used for remote files instead
  338. * of cURL, even if a new enough version is installed
  339. * @see SimplePie::force_fsockopen()
  340. * @access private
  341. */
  342. var $force_fsockopen = false;
  343. /**
  344. * @var bool Enable/Disable XML dump
  345. * @see SimplePie::enable_xml_dump()
  346. * @access private
  347. */
  348. var $xml_dump = false;
  349. /**
  350. * @var bool Enable/Disable Caching
  351. * @see SimplePie::enable_cache()
  352. * @access private
  353. */
  354. var $cache = true;
  355. /**
  356. * @var int Cache duration (in seconds)
  357. * @see SimplePie::set_cache_duration()
  358. * @access private
  359. */
  360. var $cache_duration = 3600;
  361. /**
  362. * @var int Auto-discovery cache duration (in seconds)
  363. * @see SimplePie::set_autodiscovery_cache_duration()
  364. * @access private
  365. */
  366. var $autodiscovery_cache_duration = 604800; // 7 Days.
  367. /**
  368. * @var string Cache location (relative to executing script)
  369. * @see SimplePie::set_cache_location()
  370. * @access private
  371. */
  372. var $cache_location = './cache';
  373. /**
  374. * @var string Function that creates the cache filename
  375. * @see SimplePie::set_cache_name_function()
  376. * @access private
  377. */
  378. var $cache_name_function = 'md5';
  379. /**
  380. * @var bool Reorder feed by date descending
  381. * @see SimplePie::enable_order_by_date()
  382. * @access private
  383. */
  384. var $order_by_date = true;
  385. /**
  386. * @var mixed Force input encoding to be set to the follow value
  387. * (false, or anything type-cast to false, disables this feature)
  388. * @see SimplePie::set_input_encoding()
  389. * @access private
  390. */
  391. var $input_encoding = false;
  392. /**
  393. * @var int Feed Autodiscovery Level
  394. * @see SimplePie::set_autodiscovery_level()
  395. * @access private
  396. */
  397. var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
  398. /**
  399. * @var string Class used for caching feeds
  400. * @see SimplePie::set_cache_class()
  401. * @access private
  402. */
  403. var $cache_class = 'SimplePie_Cache';
  404. /**
  405. * @var string Class used for locating feeds
  406. * @see SimplePie::set_locator_class()
  407. * @access private
  408. */
  409. var $locator_class = 'SimplePie_Locator';
  410. /**
  411. * @var string Class used for parsing feeds
  412. * @see SimplePie::set_parser_class()
  413. * @access private
  414. */
  415. var $parser_class = 'SimplePie_Parser';
  416. /**
  417. * @var string Class used for fetching feeds
  418. * @see SimplePie::set_file_class()
  419. * @access private
  420. */
  421. var $file_class = 'SimplePie_File';
  422. /**
  423. * @var string Class used for items
  424. * @see SimplePie::set_item_class()
  425. * @access private
  426. */
  427. var $item_class = 'SimplePie_Item';
  428. /**
  429. * @var string Class used for authors
  430. * @see SimplePie::set_author_class()
  431. * @access private
  432. */
  433. var $author_class = 'SimplePie_Author';
  434. /**
  435. * @var string Class used for categories
  436. * @see SimplePie::set_category_class()
  437. * @access private
  438. */
  439. var $category_class = 'SimplePie_Category';
  440. /**
  441. * @var string Class used for enclosures
  442. * @see SimplePie::set_enclosures_class()
  443. * @access private
  444. */
  445. var $enclosure_class = 'SimplePie_Enclosure';
  446. /**
  447. * @var string Class used for Media RSS <media:text> captions
  448. * @see SimplePie::set_caption_class()
  449. * @access private
  450. */
  451. var $caption_class = 'SimplePie_Caption';
  452. /**
  453. * @var string Class used for Media RSS <media:copyright>
  454. * @see SimplePie::set_copyright_class()
  455. * @access private
  456. */
  457. var $copyright_class = 'SimplePie_Copyright';
  458. /**
  459. * @var string Class used for Media RSS <media:credit>
  460. * @see SimplePie::set_credit_class()
  461. * @access private
  462. */
  463. var $credit_class = 'SimplePie_Credit';
  464. /**
  465. * @var string Class used for Media RSS <media:rating>
  466. * @see SimplePie::set_rating_class()
  467. * @access private
  468. */
  469. var $rating_class = 'SimplePie_Rating';
  470. /**
  471. * @var string Class used for Media RSS <media:restriction>
  472. * @see SimplePie::set_restriction_class()
  473. * @access private
  474. */
  475. var $restriction_class = 'SimplePie_Restriction';
  476. /**
  477. * @var mixed Set javascript query string parameter (false, or
  478. * anything type-cast to false, disables this feature)
  479. * @see SimplePie::set_javascript()
  480. * @access private
  481. */
  482. var $javascript = 'js';
  483. /**
  484. * @var int Maximum number of feeds to check with autodiscovery
  485. * @see SimplePie::set_max_checked_feeds()
  486. * @access private
  487. */
  488. var $max_checked_feeds = 10;
  489. /**
  490. * @var string Web-accessible path to the handler_favicon.php file.
  491. * @see SimplePie::set_favicon_handler()
  492. * @access private
  493. */
  494. var $favicon_handler = '';
  495. /**
  496. * @var string Web-accessible path to the handler_image.php file.
  497. * @see SimplePie::set_image_handler()
  498. * @access private
  499. */
  500. var $image_handler = '';
  501. /**
  502. * @var array Stores the URLs when multiple feeds are being initialized.
  503. * @see SimplePie::set_feed_url()
  504. * @access private
  505. */
  506. var $multifeed_url = array();
  507. /**
  508. * @var array Stores SimplePie objects when multiple feeds initialized.
  509. * @access private
  510. */
  511. var $multifeed_objects = array();
  512. /**
  513. * @var array Stores the get_object_vars() array for use with multifeeds.
  514. * @see SimplePie::set_feed_url()
  515. * @access private
  516. */
  517. var $config_settings = null;
  518. /**
  519. * @var array Stores the default attributes to be stripped by strip_attributes().
  520. * @see SimplePie::strip_attributes()
  521. * @access private
  522. */
  523. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  524. /**
  525. * @var array Stores the default tags to be stripped by strip_htmltags().
  526. * @see SimplePie::strip_htmltags()
  527. * @access private
  528. */
  529. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  530. /**
  531. * The SimplePie class contains feed level data and options
  532. *
  533. * There are two ways that you can create a new SimplePie object. The first
  534. * is by passing a feed URL as a parameter to the SimplePie constructor
  535. * (as well as optionally setting the cache location and cache expiry). This
  536. * will initialise the whole feed with all of the default settings, and you
  537. * can begin accessing methods and properties immediately.
  538. *
  539. * The second way is to create the SimplePie object with no parameters
  540. * at all. This will enable you to set configuration options. After setting
  541. * them, you must initialise the feed using $feed->init(). At that point the
  542. * object's methods and properties will be available to you. This format is
  543. * what is used throughout this documentation.
  544. *
  545. * @access public
  546. * @since 1.0 Preview Release
  547. * @param string $feed_url This is the URL you want to parse.
  548. * @param string $cache_location This is where you want the cache to be stored.
  549. * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
  550. */
  551. function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
  552. {
  553. // Other objects, instances created here so we can set options on them
  554. $this->sanitize =& new SimplePie_Sanitize;
  555. // Set options if they're passed to the constructor
  556. if ($cache_location !== null)
  557. {
  558. $this->set_cache_location($cache_location);
  559. }
  560. if ($cache_duration !== null)
  561. {
  562. $this->set_cache_duration($cache_duration);
  563. }
  564. // Only init the script if we're passed a feed URL
  565. if ($feed_url !== null)
  566. {
  567. $this->set_feed_url($feed_url);
  568. $this->init();
  569. }
  570. }
  571. /**
  572. * Used for converting object to a string
  573. */
  574. function __toString()
  575. {
  576. return md5(serialize($this->data));
  577. }
  578. /**
  579. * This is the URL of the feed you want to parse.
  580. *
  581. * This allows you to enter the URL of the feed you want to parse, or the
  582. * website you want to try to use auto-discovery on. This takes priority
  583. * over any set raw data.
  584. *
  585. * You can set multiple feeds to mash together by passing an array instead
  586. * of a string for the $url. Remember that with each additional feed comes
  587. * additional processing and resources.
  588. *
  589. * @access public
  590. * @since 1.0 Preview Release
  591. * @param mixed $url This is the URL (or array of URLs) that you want to parse.
  592. * @see SimplePie::set_raw_data()
  593. */
  594. function set_feed_url($url)
  595. {
  596. if (is_array($url))
  597. {
  598. $this->multifeed_url = array();
  599. foreach ($url as $value)
  600. {
  601. $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
  602. }
  603. }
  604. else
  605. {
  606. $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
  607. }
  608. }
  609. /**
  610. * Provides an instance of SimplePie_File to use as a feed
  611. *
  612. * @access public
  613. * @param object &$file Instance of SimplePie_File (or subclass)
  614. * @return bool True on success, false on failure
  615. */
  616. function set_file(&$file)
  617. {
  618. if (SimplePie_Misc::is_a($file, 'SimplePie_File'))
  619. {
  620. $this->feed_url = $file->url;
  621. $this->file =& $file;
  622. return true;
  623. }
  624. return false;
  625. }
  626. /**
  627. * Allows you to use a string of RSS/Atom data instead of a remote feed.
  628. *
  629. * If you have a feed available as a string in PHP, you can tell SimplePie
  630. * to parse that data string instead of a remote feed. Any set feed URL
  631. * takes precedence.
  632. *
  633. * @access public
  634. * @since 1.0 Beta 3
  635. * @param string $data RSS or Atom data as a string.
  636. * @see SimplePie::set_feed_url()
  637. */
  638. function set_raw_data($data)
  639. {
  640. $this->raw_data = trim($data);
  641. }
  642. /**
  643. * Allows you to override the default timeout for fetching remote feeds.
  644. *
  645. * This allows you to change the maximum time the feed's server to respond
  646. * and send the feed back.
  647. *
  648. * @access public
  649. * @since 1.0 Beta 3
  650. * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
  651. */
  652. function set_timeout($timeout = 10)
  653. {
  654. $this->timeout = (int) $timeout;
  655. }
  656. /**
  657. * Forces SimplePie to use fsockopen() instead of the preferred cURL
  658. * functions.
  659. *
  660. * @access public
  661. * @since 1.0 Beta 3
  662. * @param bool $enable Force fsockopen() to be used
  663. */
  664. function force_fsockopen($enable = false)
  665. {
  666. $this->force_fsockopen = (bool) $enable;
  667. }
  668. /**
  669. * Outputs the raw XML content of the feed, after it has gone through
  670. * SimplePie's filters.
  671. *
  672. * Used only for debugging, this function will output the XML content as
  673. * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
  674. * before trying to parse it. Many parts of the feed are re-written in
  675. * memory, and in the end, you have a parsable feed. XML dump shows you the
  676. * actual XML that SimplePie tries to parse, which may or may not be very
  677. * different from the original feed.
  678. *
  679. * @access public
  680. * @since 1.0 Preview Release
  681. * @param bool $enable Enable XML dump
  682. */
  683. function enable_xml_dump($enable = false)
  684. {
  685. $this->xml_dump = (bool) $enable;
  686. }
  687. /**
  688. * Enables/disables caching in SimplePie.
  689. *
  690. * This option allows you to disable caching all-together in SimplePie.
  691. * However, disabling the cache can lead to longer load times.
  692. *
  693. * @access public
  694. * @since 1.0 Preview Release
  695. * @param bool $enable Enable caching
  696. */
  697. function enable_cache($enable = true)
  698. {
  699. $this->cache = (bool) $enable;
  700. }
  701. /**
  702. * Set the length of time (in seconds) that the contents of a feed
  703. * will be cached.
  704. *
  705. * @access public
  706. * @param int $seconds The feed content cache duration.
  707. */
  708. function set_cache_duration($seconds = 3600)
  709. {
  710. $this->cache_duration = (int) $seconds;
  711. }
  712. /**
  713. * Set the length of time (in seconds) that the autodiscovered feed
  714. * URL will be cached.
  715. *
  716. * @access public
  717. * @param int $seconds The autodiscovered feed URL cache duration.
  718. */
  719. function set_autodiscovery_cache_duration($seconds = 604800)
  720. {
  721. $this->autodiscovery_cache_duration = (int) $seconds;
  722. }
  723. /**
  724. * Set the file system location where the cached files should be stored.
  725. *
  726. * @access public
  727. * @param string $location The file system location.
  728. */
  729. function set_cache_location($location = './cache')
  730. {
  731. $this->cache_location = (string) $location;
  732. }
  733. /**
  734. * Determines whether feed items should be sorted into reverse chronological order.
  735. *
  736. * @access public
  737. * @param bool $enable Sort as reverse chronological order.
  738. */
  739. function enable_order_by_date($enable = true)
  740. {
  741. $this->order_by_date = (bool) $enable;
  742. }
  743. /**
  744. * Allows you to override the character encoding reported by the feed.
  745. *
  746. * @access public
  747. * @param string $encoding Character encoding.
  748. */
  749. function set_input_encoding($encoding = false)
  750. {
  751. if ($encoding)
  752. {
  753. $this->input_encoding = (string) $encoding;
  754. }
  755. else
  756. {
  757. $this->input_encoding = false;
  758. }
  759. }
  760. /**
  761. * Set how much feed autodiscovery to do
  762. *
  763. * @access public
  764. * @see SIMPLEPIE_LOCATOR_NONE
  765. * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
  766. * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
  767. * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
  768. * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
  769. * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
  770. * @see SIMPLEPIE_LOCATOR_ALL
  771. * @param int $level Feed Autodiscovery Level (level can be a
  772. * combination of the above constants, see bitwise OR operator)
  773. */
  774. function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
  775. {
  776. $this->autodiscovery = (int) $level;
  777. }
  778. /**
  779. * Allows you to change which class SimplePie uses for caching.
  780. * Useful when you are overloading or extending SimplePie's default classes.
  781. *
  782. * @access public
  783. * @param string $class Name of custom class.
  784. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  785. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  786. */
  787. function set_cache_class($class = 'SimplePie_Cache')
  788. {
  789. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
  790. {
  791. $this->cache_class = $class;
  792. return true;
  793. }
  794. return false;
  795. }
  796. /**
  797. * Allows you to change which class SimplePie uses for auto-discovery.
  798. * Useful when you are overloading or extending SimplePie's default classes.
  799. *
  800. * @access public
  801. * @param string $class Name of custom class.
  802. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  803. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  804. */
  805. function set_locator_class($class = 'SimplePie_Locator')
  806. {
  807. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
  808. {
  809. $this->locator_class = $class;
  810. return true;
  811. }
  812. return false;
  813. }
  814. /**
  815. * Allows you to change which class SimplePie uses for XML parsing.
  816. * Useful when you are overloading or extending SimplePie's default classes.
  817. *
  818. * @access public
  819. * @param string $class Name of custom class.
  820. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  821. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  822. */
  823. function set_parser_class($class = 'SimplePie_Parser')
  824. {
  825. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
  826. {
  827. $this->parser_class = $class;
  828. return true;
  829. }
  830. return false;
  831. }
  832. /**
  833. * Allows you to change which class SimplePie uses for remote file fetching.
  834. * Useful when you are overloading or extending SimplePie's default classes.
  835. *
  836. * @access public
  837. * @param string $class Name of custom class.
  838. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  839. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  840. */
  841. function set_file_class($class = 'SimplePie_File')
  842. {
  843. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
  844. {
  845. $this->file_class = $class;
  846. return true;
  847. }
  848. return false;
  849. }
  850. /**
  851. * Allows you to change which class SimplePie uses for data sanitization.
  852. * Useful when you are overloading or extending SimplePie's default classes.
  853. *
  854. * @access public
  855. * @param string $class Name of custom class.
  856. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  857. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  858. */
  859. function set_sanitize_class($class = 'SimplePie_Sanitize')
  860. {
  861. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
  862. {
  863. $this->sanitize =& new $class;
  864. return true;
  865. }
  866. return false;
  867. }
  868. /**
  869. * Allows you to change which class SimplePie uses for handling feed items.
  870. * Useful when you are overloading or extending SimplePie's default classes.
  871. *
  872. * @access public
  873. * @param string $class Name of custom class.
  874. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  875. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  876. */
  877. function set_item_class($class = 'SimplePie_Item')
  878. {
  879. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
  880. {
  881. $this->item_class = $class;
  882. return true;
  883. }
  884. return false;
  885. }
  886. /**
  887. * Allows you to change which class SimplePie uses for handling author data.
  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_author_class($class = 'SimplePie_Author')
  896. {
  897. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
  898. {
  899. $this->author_class = $class;
  900. return true;
  901. }
  902. return false;
  903. }
  904. /**
  905. * Allows you to change which class SimplePie uses for handling category data.
  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_category_class($class = 'SimplePie_Category')
  914. {
  915. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
  916. {
  917. $this->category_class = $class;
  918. return true;
  919. }
  920. return false;
  921. }
  922. /**
  923. * Allows you to change which class SimplePie uses for feed enclosures.
  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_enclosure_class($class = 'SimplePie_Enclosure')
  932. {
  933. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
  934. {
  935. $this->enclosure_class = $class;
  936. return true;
  937. }
  938. return false;
  939. }
  940. /**
  941. * Allows you to change which class SimplePie uses for <media:text> captions
  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_caption_class($class = 'SimplePie_Caption')
  950. {
  951. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
  952. {
  953. $this->caption_class = $class;
  954. return true;
  955. }
  956. return false;
  957. }
  958. /**
  959. * Allows you to change which class SimplePie uses for <media:copyright>
  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_copyright_class($class = 'SimplePie_Copyright')
  968. {
  969. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
  970. {
  971. $this->copyright_class = $class;
  972. return true;
  973. }
  974. return false;
  975. }
  976. /**
  977. * Allows you to change which class SimplePie uses for <media:credit>
  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_credit_class($class = 'SimplePie_Credit')
  986. {
  987. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
  988. {
  989. $this->credit_class = $class;
  990. return true;
  991. }
  992. return false;
  993. }
  994. /**
  995. * Allows you to change which class SimplePie uses for <media:rating>
  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_rating_class($class = 'SimplePie_Rating')
  1004. {
  1005. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
  1006. {
  1007. $this->rating_class = $class;
  1008. return true;
  1009. }
  1010. return false;
  1011. }
  1012. /**
  1013. * Allows you to change which class SimplePie uses for <media:restriction>
  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_restriction_class($class = 'SimplePie_Restriction')
  1022. {
  1023. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
  1024. {
  1025. $this->restriction_class = $class;
  1026. return true;
  1027. }
  1028. return false;
  1029. }
  1030. /**
  1031. * Allows you to override the default user agent string.
  1032. *
  1033. * @access public
  1034. * @param string $ua New user agent string.
  1035. */
  1036. function set_useragent($ua = SIMPLEPIE_USERAGENT)
  1037. {
  1038. $this->useragent = (string) $ua;
  1039. }
  1040. /**
  1041. * Set callback function to create cache filename with
  1042. *
  1043. * @access public
  1044. * @param mixed $function Callback function
  1045. */
  1046. function set_cache_name_function($function = 'md5')
  1047. {
  1048. if (is_callable($function))
  1049. {
  1050. $this->cache_name_function = $function;
  1051. }
  1052. }
  1053. /**
  1054. * Set javascript query string parameter
  1055. *
  1056. * @access public
  1057. * @param mixed $get Javascript query string parameter
  1058. */
  1059. function set_javascript($get = 'js')
  1060. {
  1061. if ($get)
  1062. {
  1063. $this->javascript = (string) $get;
  1064. }
  1065. else
  1066. {
  1067. $this->javascript = false;
  1068. }
  1069. }
  1070. /**
  1071. * Set options to make SP as fast as possible. Forgoes a
  1072. * substantial amount of data sanitization in favor of speed.
  1073. *
  1074. * @access public
  1075. * @param bool $set Whether to set them or not
  1076. */
  1077. function set_stupidly_fast($set = false)
  1078. {
  1079. if ($set)
  1080. {
  1081. $this->enable_order_by_date(false);
  1082. $this->remove_div(false);
  1083. $this->strip_comments(false);
  1084. $this->strip_htmltags(false);
  1085. $this->strip_attributes(false);
  1086. $this->set_image_handler(false);
  1087. }
  1088. }
  1089. /**
  1090. * Set maximum number of feeds to check with autodiscovery
  1091. *
  1092. * @access public
  1093. * @param int $max Maximum number of feeds to check
  1094. */
  1095. function set_max_checked_feeds($max = 10)
  1096. {
  1097. $this->max_checked_feeds = (int) $max;
  1098. }
  1099. function remove_div($enable = true)
  1100. {
  1101. $this->sanitize->remove_div($enable);
  1102. }
  1103. function strip_htmltags($tags = '', $encode = null)
  1104. {
  1105. if ($tags === '')
  1106. {
  1107. $tags = $this->strip_htmltags;
  1108. }
  1109. $this->sanitize->strip_htmltags($tags);
  1110. if ($encode !== null)
  1111. {
  1112. $this->sanitize->encode_instead_of_strip($tags);
  1113. }
  1114. }
  1115. function encode_instead_of_strip($enable = true)
  1116. {
  1117. $this->sanitize->encode_instead_of_strip($enable);
  1118. }
  1119. function strip_attributes($attribs = '')
  1120. {
  1121. if ($attribs === '')
  1122. {
  1123. $attribs = $this->strip_attributes;
  1124. }
  1125. $this->sanitize->strip_attributes($attribs);
  1126. }
  1127. function set_output_encoding($encoding = 'UTF-8')
  1128. {
  1129. $this->sanitize->set_output_encoding($encoding);
  1130. }
  1131. function strip_comments($strip = false)
  1132. {
  1133. $this->sanitize->strip_comments($strip);
  1134. }
  1135. /**
  1136. * Set element/attribute key/value pairs of HTML attributes
  1137. * containing URLs that need to be resolved relative to the feed
  1138. *
  1139. * @access public
  1140. * @since 1.0
  1141. * @param array $element_attribute Element/attribute key/value pairs
  1142. */
  1143. 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'))
  1144. {
  1145. $this->sanitize->set_url_replacements($element_attribute);
  1146. }
  1147. /**
  1148. * Set the handler to enable the display of cached favicons.
  1149. *
  1150. * @access public
  1151. * @param str $page Web-accessible path to the handler_favicon.php file.
  1152. * @param str $qs The query string that the value should be passed to.
  1153. */
  1154. function set_favicon_handler($page = false, $qs = 'i')
  1155. {
  1156. if ($page != false)
  1157. {
  1158. $this->favicon_handler = $page . '?' . $qs . '=';
  1159. }
  1160. else
  1161. {
  1162. $this->favicon_handler = '';
  1163. }
  1164. }
  1165. /**
  1166. * Set the handler to enable the display of cached images.
  1167. *
  1168. * @access public
  1169. * @param str $page Web-accessible path to the handler_image.php file.
  1170. * @param str $qs The query string that the value should be passed to.
  1171. */
  1172. function set_image_handler($page = false, $qs = 'i')
  1173. {
  1174. if ($page != false)
  1175. {
  1176. $this->sanitize->set_image_handler($page . '?' . $qs . '=');
  1177. }
  1178. else
  1179. {
  1180. $this->image_handler = '';
  1181. }
  1182. }
  1183. function init()
  1184. {
  1185. if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.1.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
  1186. {
  1187. return false;
  1188. }
  1189. if (isset($_GET[$this->javascript]))
  1190. {
  1191. if (function_exists('ob_gzhandler'))
  1192. {
  1193. ob_start('ob_gzhandler');
  1194. }
  1195. header('Content-type: text/javascript; charset: UTF-8');
  1196. header('Cache-Control: must-revalidate');
  1197. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  1198. ?>
  1199. function embed_odeo(link) {
  1200. 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>');
  1201. }
  1202. function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
  1203. if (placeholder != '') {
  1204. 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>');
  1205. }
  1206. else {
  1207. 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>');
  1208. }
  1209. }
  1210. function embed_flash(bgcolor, width, height, link, loop, type) {
  1211. 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>');
  1212. }
  1213. function embed_flv(width, height, link, placeholder, loop, player) {
  1214. 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>');
  1215. }
  1216. function embed_wmedia(width, height, link) {
  1217. document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
  1218. }
  1219. <?php
  1220. exit;
  1221. }
  1222. // Pass whatever was set with config options over to the sanitizer.
  1223. $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
  1224. $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
  1225. if ($this->feed_url !== null || $this->raw_data !== null)
  1226. {
  1227. $this->data = array();
  1228. $this->multifeed_objects = array();
  1229. $cache = false;
  1230. if ($this->feed_url !== null)
  1231. {
  1232. $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
  1233. // Decide whether to enable caching
  1234. if ($this->cache && $parsed_feed_url['scheme'] !== '')
  1235. {
  1236. $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
  1237. }
  1238. // If it's enabled and we don't want an XML dump, use the cache
  1239. if ($cache && !$this->xml_dump)
  1240. {
  1241. // Load the Cache
  1242. $this->data = $cache->load();
  1243. if (!empty($this->data))
  1244. {
  1245. // If the cache is for an outdated build of SimplePie
  1246. if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
  1247. {
  1248. $cache->unlink();
  1249. $this->data = array();
  1250. }
  1251. // If we've hit a collision just rerun it with caching disabled
  1252. elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
  1253. {
  1254. $cache = false;
  1255. $this->data = array();
  1256. }
  1257. // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
  1258. elseif (isset($this->data['feed_url']))
  1259. {
  1260. // If the autodiscovery cache is still valid use it.
  1261. if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
  1262. {
  1263. // Do not need to do feed autodiscovery yet.
  1264. if ($this->data['feed_url'] == $this->data['url'])
  1265. {
  1266. $cache->unlink();
  1267. $this->data = array();
  1268. }
  1269. else
  1270. {
  1271. $this->set_feed_url($this->data['feed_url']);
  1272. return $this->init();
  1273. }
  1274. }
  1275. }
  1276. // Check if the cache has been updated
  1277. elseif ($cache->mtime() + $this->cache_duration < time())
  1278. {
  1279. // If we have last-modified and/or etag set
  1280. if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
  1281. {
  1282. $headers = array();
  1283. if (isset($this->data['headers']['last-modified']))
  1284. {
  1285. $headers['if-modified-since'] = $this->data['headers']['last-modified'];
  1286. }
  1287. if (isset($this->data['headers']['etag']))
  1288. {
  1289. $headers['if-none-match'] = $this->data['headers']['etag'];
  1290. }
  1291. $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
  1292. if ($file->success)
  1293. {
  1294. if ($file->status_code == 304)
  1295. {
  1296. $cache->touch();
  1297. return true;
  1298. }
  1299. else
  1300. {
  1301. $headers = $file->headers;
  1302. }
  1303. }
  1304. else
  1305. {
  1306. unset($file);
  1307. }
  1308. }
  1309. }
  1310. // If the cache is still valid, just return true
  1311. else
  1312. {
  1313. return true;
  1314. }
  1315. }
  1316. // If the cache is empty, delete it
  1317. else
  1318. {
  1319. $cache->unlink();
  1320. $this->data = array();
  1321. }
  1322. }
  1323. // 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.
  1324. if (!isset($file))
  1325. {
  1326. if (SimplePie_Misc::is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
  1327. {
  1328. $file =& $this->file;
  1329. }
  1330. else
  1331. {
  1332. $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
  1333. }
  1334. }
  1335. // If the file connection has an error, set SimplePie::error to that and quit
  1336. if (!$file->success)
  1337. {
  1338. $this->error = $file->error;
  1339. if (!empty($this->data))
  1340. {
  1341. return true;
  1342. }
  1343. else
  1344. {
  1345. return false;
  1346. }
  1347. }
  1348. // Check if the supplied URL is a feed, if it isn't, look for it.
  1349. $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds);
  1350. if (!$locate->is_feed($file))
  1351. {
  1352. // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
  1353. unset($file);
  1354. if ($file = $locate->find($this->autodiscovery))
  1355. {
  1356. if ($cache)
  1357. {
  1358. if (!$cache->save(array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD)))
  1359. {
  1360. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1361. }
  1362. $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
  1363. }
  1364. $this->feed_url = $file->url;
  1365. }
  1366. else
  1367. {
  1368. $this->error = "A feed could not be found at $this->feed_url";
  1369. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1370. return false;
  1371. }
  1372. }
  1373. $locate = null;
  1374. $headers = $file->headers;
  1375. $data = trim($file->body);
  1376. unset($file);
  1377. }
  1378. else
  1379. {
  1380. $data = $this->raw_data;
  1381. }
  1382. // First check to see if input has been overridden.
  1383. if ($this->input_encoding !== false)
  1384. {
  1385. $encoding = $this->input_encoding;
  1386. }
  1387. // Second try HTTP headers
  1388. elseif (isset($headers['content-type']) && preg_match('/;[\x09\x20]*charset=([^;]*)/i', $headers['content-type'], $charset))
  1389. {
  1390. $encoding = $charset[1];
  1391. }
  1392. // Then prolog, if at the very start of the document
  1393. elseif (preg_match("/^<\?xml[\x20\x9\xD\xA]+version([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"1.0\"|'1.0'|\"1.1\"|'1.1')[\x20\x9\xD\xA]+encoding([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"[A-Za-z][A-Za-z0-9._\-]*\"|'[A-Za-z][A-Za-z0-9._\-]*')([\x20\x9\xD\xA]+standalone([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"(yes|no)\"|'(yes|no)'))?([\x20\x9\xD\xA]+)?\?>/", $data, $prolog))
  1394. {
  1395. $encoding = substr($prolog[6], 1, -1);
  1396. }
  1397. // UTF-32 Big Endian BOM
  1398. elseif (strpos($data, "\x0\x0\xFE\xFF") === 0)
  1399. {
  1400. $encoding = 'UTF-32be';
  1401. }
  1402. // UTF-32 Little Endian BOM
  1403. elseif (strpos($data, "\xFF\xFE\x0\x0") === 0)
  1404. {
  1405. $encoding = 'UTF-32';
  1406. }
  1407. // UTF-16 Big Endian BOM
  1408. elseif (strpos($data, "\xFE\xFF") === 0)
  1409. {
  1410. $encoding = 'UTF-16be';
  1411. }
  1412. // UTF-16 Little Endian BOM
  1413. elseif (strpos($data, "\xFF\xFE") === 0)
  1414. {
  1415. $encoding = 'UTF-16le';
  1416. }
  1417. // UTF-8 BOM
  1418. elseif (strpos($data, "\xEF\xBB\xBF") === 0)
  1419. {
  1420. $encoding = 'UTF-8';
  1421. }
  1422. // Fallback to the default (US-ASCII for text/xml, ISO-8859-1 for text/* MIME types, UTF-8 otherwise)
  1423. elseif (isset($headers['content-type']) && strtolower(SimplePie_Misc::parse_mime($headers['content-type'])) == 'text/xml')
  1424. {
  1425. $encoding = 'US-ASCII';
  1426. }
  1427. elseif (isset($headers['content-type']) && SimplePie_Misc::stripos(SimplePie_Misc::parse_mime($headers['content-type']), 'text/') === 0)
  1428. {
  1429. $encoding = 'ISO-8859-1';
  1430. }
  1431. else
  1432. {
  1433. $encoding = 'UTF-8';
  1434. }
  1435. // Change the encoding to UTF-8 (as we always use UTF-8 internally)
  1436. if ($encoding != 'UTF-8')
  1437. {
  1438. $data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8');
  1439. }
  1440. // Strip illegal characters
  1441. $data = SimplePie_Misc::utf8_bad_replace($data);
  1442. $parser =& new $this->parser_class();
  1443. $parser->pre_process($data, 'UTF-8');
  1444. // If we want the XML, just output that and quit
  1445. if ($this->xml_dump)
  1446. {
  1447. header('Content-type: text/xml; charset=UTF-8');
  1448. echo $data;
  1449. exit;
  1450. }
  1451. // If it's parsed fine
  1452. elseif ($parser->parse($data))
  1453. {
  1454. unset($data);
  1455. $this->data = $parser->get_data();
  1456. if (isset($this->data['child']))
  1457. {
  1458. if (isset($headers))
  1459. {
  1460. $this->data['headers'] = $headers;
  1461. }
  1462. $this->data['build'] = SIMPLEPIE_BUILD;
  1463. // Cache the file if caching is enabled
  1464. if ($cache && !$cache->save($this->data))
  1465. {
  1466. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1467. }
  1468. return true;
  1469. }
  1470. else
  1471. {
  1472. $this->error = "A feed could not be found at $this->feed_url";
  1473. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1474. return false;
  1475. }
  1476. }
  1477. // If we have an error, just set SimplePie::error to it and quit
  1478. else
  1479. {
  1480. $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
  1481. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1482. return false;
  1483. }
  1484. }
  1485. elseif (!empty($this->multifeed_url))
  1486. {
  1487. $i = 0;
  1488. $success = 0;
  1489. $this->multifeed_objects = array();
  1490. foreach ($this->multifeed_url as $url)
  1491. {
  1492. if (SIMPLEPIE_PHP5)
  1493. {
  1494. // This keyword needs to defy coding standards for PHP4 compatibility
  1495. $this->multifeed_objects[$i] = clone($this);
  1496. }
  1497. else
  1498. {
  1499. $this->multifeed_objects[$i] = $this;
  1500. }
  1501. $this->multifeed_objects[$i]->set_feed_url($url);
  1502. $success |= $this->multifeed_objects[$i]->init();
  1503. $i++;
  1504. }
  1505. return (bool) $success;
  1506. }
  1507. else
  1508. {
  1509. return false;
  1510. }
  1511. }
  1512. /**
  1513. * Return the error message for the occured error
  1514. *
  1515. * @access public
  1516. * @return string Error message
  1517. */
  1518. function error()
  1519. {
  1520. return $this->error;
  1521. }
  1522. function get_encoding()
  1523. {
  1524. return $this->sanitize->output_encoding;
  1525. }
  1526. function handle_content_type($mime = 'text/html')
  1527. {
  1528. if (!headers_sent())
  1529. {
  1530. $header = "Content-type: $mime;";
  1531. if ($this->get_encoding())
  1532. {
  1533. $header .= ' charset=' . $this->get_encoding();
  1534. }
  1535. else
  1536. {
  1537. $header .= ' charset=UTF-8';
  1538. }
  1539. header($header);
  1540. }
  1541. }
  1542. function get_type()
  1543. {
  1544. if (!isset($this->data['type']))
  1545. {
  1546. $this->data['type'] = SIMPLEPIE_TYPE_ALL;
  1547. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
  1548. {
  1549. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
  1550. }
  1551. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
  1552. {
  1553. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
  1554. }
  1555. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
  1556. {
  1557. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
  1558. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
  1559. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
  1560. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
  1561. {
  1562. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
  1563. }
  1564. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
  1565. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
  1566. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
  1567. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
  1568. {
  1569. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
  1570. }
  1571. }
  1572. elseif (isset($this->data['child']['']['rss']))
  1573. {
  1574. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
  1575. if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
  1576. {
  1577. switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
  1578. {
  1579. case '0.91':
  1580. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
  1581. if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
  1582. {
  1583. switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
  1584. {
  1585. case '0':
  1586. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
  1587. break;
  1588. case '24':
  1589. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
  1590. break;
  1591. }
  1592. }
  1593. break;
  1594. case '0.92':
  1595. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
  1596. break;
  1597. case '0.93':
  1598. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
  1599. break;
  1600. case '0.94':
  1601. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
  1602. break;
  1603. case '2.0':
  1604. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
  1605. break;
  1606. }
  1607. }
  1608. }
  1609. else
  1610. {
  1611. $this->data['type'] = SIMPLEPIE_TYPE_NONE;
  1612. }
  1613. }
  1614. return $this->data['type'];
  1615. }
  1616. /**
  1617. * Returns the URL for the favicon of the feed's website.
  1618. *
  1619. * @access public
  1620. * @since 1.0
  1621. */
  1622. function get_favicon()
  1623. {
  1624. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  1625. {
  1626. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1627. }
  1628. elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
  1629. {
  1630. $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
  1631. if ($this->cache && $this->favicon_handler)
  1632. {
  1633. $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $favicon), 'spi');
  1634. if ($cache->load())
  1635. {
  1636. return $this->sanitize($this->favicon_handler . rawurlencode($favicon), SIMPLEPIE_CONSTRUCT_IRI);
  1637. }
  1638. else
  1639. {
  1640. $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
  1641. if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
  1642. {
  1643. if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  1644. {
  1645. return $this->sanitize($this->favicon_handler . rawurlencode($favicon), SIMPLEPIE_CONSTRUCT_IRI);
  1646. }
  1647. else
  1648. {
  1649. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1650. return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
  1651. }
  1652. }
  1653. }
  1654. }
  1655. else
  1656. {
  1657. return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
  1658. }
  1659. }
  1660. return false;
  1661. }
  1662. /**
  1663. * @todo If we have a perm redirect we should return the new URL
  1664. * @todo When we make the above change, let's support <itunes:new-feed-url> as well
  1665. * @todo Also, |atom:link|@rel=self
  1666. */
  1667. function subscribe_url()
  1668. {
  1669. if ($this->feed_url !== null)
  1670. {
  1671. return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
  1672. }
  1673. else
  1674. {
  1675. return null;
  1676. }
  1677. }
  1678. function subscribe_feed()
  1679. {
  1680. if ($this->feed_url !== null)
  1681. {
  1682. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
  1683. }
  1684. else
  1685. {
  1686. return null;
  1687. }
  1688. }
  1689. function subscribe_outlook()
  1690. {
  1691. if ($this->feed_url !== null)
  1692. {
  1693. return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
  1694. }
  1695. else
  1696. {
  1697. return null;
  1698. }
  1699. }
  1700. function subscribe_podcast()
  1701. {
  1702. if ($this->feed_url !== null)
  1703. {
  1704. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
  1705. }
  1706. else
  1707. {
  1708. return null;
  1709. }
  1710. }
  1711. function subscribe_itunes()
  1712. {
  1713. if ($this->feed_url !== null)
  1714. {
  1715. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
  1716. }
  1717. else
  1718. {
  1719. return null;
  1720. }
  1721. }
  1722. /**
  1723. * Creates the subscribe_* methods' return data
  1724. *
  1725. * @access private
  1726. * @param string $feed_url String to prefix to the feed URL
  1727. * @param string $site_url String to prefix to the site URL (and
  1728. * suffix to the feed URL)
  1729. * @return mixed URL if feed exists, false otherwise
  1730. */
  1731. function subscribe_service($feed_url, $site_url = null)
  1732. {
  1733. if ($this->subscribe_url())
  1734. {
  1735. $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->subscribe_url());
  1736. if ($site_url !== null && $this->get_link() !== null)
  1737. {
  1738. $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
  1739. }
  1740. return $return;
  1741. }
  1742. else
  1743. {
  1744. return null;
  1745. }
  1746. }
  1747. function subscribe_aol()
  1748. {
  1749. return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
  1750. }
  1751. function subscribe_bloglines()
  1752. {
  1753. return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
  1754. }
  1755. function subscribe_eskobo()
  1756. {
  1757. return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
  1758. }
  1759. function subscribe_feedfeeds()
  1760. {
  1761. return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
  1762. }
  1763. function subscribe_feedster()
  1764. {
  1765. return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
  1766. }
  1767. function subscribe_google()
  1768. {
  1769. return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
  1770. }
  1771. function subscribe_gritwire()
  1772. {
  1773. return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
  1774. }
  1775. function subscribe_msn()
  1776. {
  1777. return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
  1778. }
  1779. function subscribe_netvibes()
  1780. {
  1781. return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
  1782. }
  1783. function subscribe_newsburst()
  1784. {
  1785. return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
  1786. }
  1787. function subscribe_newsgator()
  1788. {
  1789. return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
  1790. }
  1791. function subscribe_odeo()
  1792. {
  1793. return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
  1794. }
  1795. function subscribe_podnova()
  1796. {
  1797. return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
  1798. }
  1799. function subscribe_rojo()
  1800. {
  1801. return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
  1802. }
  1803. function subscribe_yahoo()
  1804. {
  1805. return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
  1806. }
  1807. function get_feed_tags($namespace, $tag)
  1808. {
  1809. $type = $this->get_type();
  1810. if ($type & SIMPLEPIE_TYPE_ATOM_10)
  1811. {
  1812. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
  1813. {
  1814. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
  1815. }
  1816. }
  1817. if ($type & SIMPLEPIE_TYPE_ATOM_03)
  1818. {
  1819. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
  1820. {
  1821. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
  1822. }
  1823. }
  1824. if ($type & SIMPLEPIE_TYPE_RSS_RDF)
  1825. {
  1826. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
  1827. {
  1828. return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
  1829. }
  1830. }
  1831. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  1832. {
  1833. if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
  1834. {
  1835. return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
  1836. }
  1837. }
  1838. return null;
  1839. }
  1840. function get_channel_tags($namespace, $tag)
  1841. {
  1842. $type = $this->get_type();
  1843. if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
  1844. {
  1845. if ($return = $this->get_feed_tags($namespace, $tag))
  1846. {
  1847. return $return;
  1848. }
  1849. }
  1850. if ($type & SIMPLEPIE_TYPE_RSS_10)
  1851. {
  1852. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
  1853. {
  1854. if (isset($channel[0]['child'][$namespace][$tag]))
  1855. {
  1856. return $channel[0]['child'][$namespace][$tag];
  1857. }
  1858. }
  1859. }
  1860. if ($type & SIMPLEPIE_TYPE_RSS_090)
  1861. {
  1862. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
  1863. {
  1864. if (isset($channel[0]['child'][$namespace][$tag]))
  1865. {
  1866. return $channel[0]['child'][$namespace][$tag];
  1867. }
  1868. }
  1869. }
  1870. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  1871. {
  1872. if ($channel = $this->get_feed_tags('', 'channel'))
  1873. {
  1874. if (isset($channel[0]['child'][$namespace][$tag]))
  1875. {
  1876. return $channel[0]['child'][$namespace][$tag];
  1877. }
  1878. }
  1879. }
  1880. return null;
  1881. }
  1882. function get_image_tags($namespace, $tag)
  1883. {
  1884. $type = $this->get_type();
  1885. if ($type & SIMPLEPIE_TYPE_RSS_10)
  1886. {
  1887. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
  1888. {
  1889. if (isset($image[0]['child'][$namespace][$tag]))
  1890. {
  1891. return $image[0]['child'][$namespace][$tag];
  1892. }
  1893. }
  1894. }
  1895. if ($type & SIMPLEPIE_TYPE_RSS_090)
  1896. {
  1897. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
  1898. {
  1899. if (isset($image[0]['child'][$namespace][$tag]))
  1900. {
  1901. return $image[0]['child'][$namespace][$tag];
  1902. }
  1903. }
  1904. }
  1905. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  1906. {
  1907. if ($image = $this->get_channel_tags('', 'image'))
  1908. {
  1909. if (isset($image[0]['child'][$namespace][$tag]))
  1910. {
  1911. return $image[0]['child'][$namespace][$tag];
  1912. }
  1913. }
  1914. }
  1915. return null;
  1916. }
  1917. function get_base($element = array())
  1918. {
  1919. if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
  1920. {
  1921. return $element['xml_base'];
  1922. }
  1923. elseif ($this->get_link() !== null)
  1924. {
  1925. return $this->get_link();
  1926. }
  1927. elseif (isset($this->data['headers']['content-location']))
  1928. {
  1929. return SimplePie_Misc::absolutize_url($this->data['headers']['content-location'], $this->subscribe_url());
  1930. }
  1931. else
  1932. {
  1933. return $this->subscribe_url();
  1934. }
  1935. }
  1936. function sanitize($data, $type, $base = '')
  1937. {
  1938. return $this->sanitize->sanitize($data, $type, $base);
  1939. }
  1940. function get_title()
  1941. {
  1942. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  1943. {
  1944. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  1945. }
  1946. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  1947. {
  1948. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  1949. }
  1950. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  1951. {
  1952. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  1953. }
  1954. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  1955. {
  1956. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  1957. }
  1958. elseif ($return = $this->get_channel_tags('', 'title'))
  1959. {
  1960. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  1961. }
  1962. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  1963. {
  1964. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1965. }
  1966. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  1967. {
  1968. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  1969. }
  1970. else
  1971. {
  1972. return null;
  1973. }
  1974. }
  1975. function get_link($key = 0, $rel = 'alternate')
  1976. {
  1977. $links = $this->get_links($rel);
  1978. if (isset($links[$key]))
  1979. {
  1980. return $links[$key];
  1981. }
  1982. else
  1983. {
  1984. return null;
  1985. }
  1986. }
  1987. /**
  1988. * Added for parity between the parent-level and the item/entry-level.
  1989. */
  1990. function get_permalink()
  1991. {
  1992. return $this->get_link(0);
  1993. }
  1994. function get_links($rel = 'alternate')
  1995. {
  1996. if (!isset($this->data['links']))
  1997. {
  1998. $this->data['links'] = array();
  1999. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  2000. {
  2001. foreach ($links as $link)
  2002. {
  2003. if (isset($link['attribs']['']['href']))
  2004. {
  2005. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2006. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2007. }
  2008. }
  2009. }
  2010. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  2011. {
  2012. foreach ($links as $link)
  2013. {
  2014. if (isset($link['attribs']['']['href']))
  2015. {
  2016. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2017. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2018. }
  2019. }
  2020. }
  2021. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2022. {
  2023. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2024. }
  2025. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2026. {
  2027. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2028. }
  2029. if ($links = $this->get_channel_tags('', 'link'))
  2030. {
  2031. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2032. }
  2033. $keys = array_keys($this->data['links']);
  2034. foreach ($keys as $key)
  2035. {
  2036. if (SimplePie_Misc::is_isegment_nz_nc($key))
  2037. {
  2038. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  2039. {
  2040. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  2041. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  2042. }
  2043. else
  2044. {
  2045. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  2046. }
  2047. }
  2048. elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  2049. {
  2050. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  2051. }
  2052. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  2053. }
  2054. }
  2055. if (isset($this->data['links'][$rel]))
  2056. {
  2057. return $this->data['links'][$rel];
  2058. }
  2059. else
  2060. {
  2061. return null;
  2062. }
  2063. }
  2064. function get_description()
  2065. {
  2066. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  2067. {
  2068. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2069. }
  2070. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  2071. {
  2072. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2073. }
  2074. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  2075. {
  2076. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2077. }
  2078. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  2079. {
  2080. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2081. }
  2082. elseif ($return = $this->get_channel_tags('', 'description'))
  2083. {
  2084. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2085. }
  2086. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  2087. {
  2088. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2089. }
  2090. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  2091. {
  2092. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2093. }
  2094. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  2095. {
  2096. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2097. }
  2098. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  2099. {
  2100. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2101. }
  2102. else
  2103. {
  2104. return null;
  2105. }
  2106. }
  2107. function get_copyright()
  2108. {
  2109. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  2110. {
  2111. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2112. }
  2113. elseif ($return = $this->get_channel_tags('', 'copyright'))
  2114. {
  2115. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2116. }
  2117. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  2118. {
  2119. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2120. }
  2121. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  2122. {
  2123. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2124. }
  2125. else
  2126. {
  2127. return null;
  2128. }
  2129. }
  2130. function get_language()
  2131. {
  2132. if ($return = $this->get_channel_tags('', 'language'))
  2133. {
  2134. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2135. }
  2136. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  2137. {
  2138. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2139. }
  2140. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  2141. {
  2142. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2143. }
  2144. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
  2145. {
  2146. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2147. }
  2148. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
  2149. {
  2150. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2151. }
  2152. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
  2153. {
  2154. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2155. }
  2156. elseif (isset($this->data['headers']['content-language']))
  2157. {
  2158. return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
  2159. }
  2160. else
  2161. {
  2162. return null;
  2163. }
  2164. }
  2165. function get_latitude()
  2166. {
  2167. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  2168. {
  2169. return (float) $return[0]['data'];
  2170. }
  2171. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  2172. {
  2173. return (float) $match[1];
  2174. }
  2175. else
  2176. {
  2177. return null;
  2178. }
  2179. }
  2180. function get_longitude()
  2181. {
  2182. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  2183. {
  2184. return (float) $return[0]['data'];
  2185. }
  2186. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  2187. {
  2188. return (float) $return[0]['data'];
  2189. }
  2190. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  2191. {
  2192. return (float) $match[2];
  2193. }
  2194. else
  2195. {
  2196. return null;
  2197. }
  2198. }
  2199. function get_image_title()
  2200. {
  2201. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2202. {
  2203. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2204. }
  2205. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2206. {
  2207. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2208. }
  2209. elseif ($return = $this->get_image_tags('', 'title'))
  2210. {
  2211. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2212. }
  2213. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2214. {
  2215. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2216. }
  2217. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2218. {
  2219. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2220. }
  2221. else
  2222. {
  2223. return null;
  2224. }
  2225. }
  2226. function get_image_url()
  2227. {
  2228. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  2229. {
  2230. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  2231. }
  2232. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  2233. {
  2234. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2235. }
  2236. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  2237. {
  2238. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2239. }
  2240. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
  2241. {
  2242. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2243. }
  2244. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
  2245. {
  2246. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2247. }
  2248. elseif ($return = $this->get_image_tags('', 'url'))
  2249. {
  2250. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2251. }
  2252. else
  2253. {
  2254. return null;
  2255. }
  2256. }
  2257. function get_image_link()
  2258. {
  2259. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2260. {
  2261. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2262. }
  2263. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2264. {
  2265. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2266. }
  2267. elseif ($return = $this->get_image_tags('', 'link'))
  2268. {
  2269. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2270. }
  2271. else
  2272. {
  2273. return null;
  2274. }
  2275. }
  2276. function get_image_width()
  2277. {
  2278. if ($return = $this->get_image_tags('', 'width'))
  2279. {
  2280. return round($return[0]['data']);
  2281. }
  2282. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
  2283. {
  2284. return 88.0;
  2285. }
  2286. else
  2287. {
  2288. return null;
  2289. }
  2290. }
  2291. function get_image_height()
  2292. {
  2293. if ($return = $this->get_image_tags('', 'height'))
  2294. {
  2295. return round($return[0]['data']);
  2296. }
  2297. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
  2298. {
  2299. return 31.0;
  2300. }
  2301. else
  2302. {
  2303. return null;
  2304. }
  2305. }
  2306. function get_item_quantity($max = 0)
  2307. {
  2308. $qty = count($this->get_items());
  2309. if ($max == 0)
  2310. {
  2311. return $qty;
  2312. }
  2313. else
  2314. {
  2315. return ($qty > $max) ? $max : $qty;
  2316. }
  2317. }
  2318. function get_item($key = 0)
  2319. {
  2320. $items = $this->get_items();
  2321. if (isset($items[$key]))
  2322. {
  2323. return $items[$key];
  2324. }
  2325. else
  2326. {
  2327. return null;
  2328. }
  2329. }
  2330. function get_items($start = 0, $end = 0)
  2331. {
  2332. if (!empty($this->multifeed_objects))
  2333. {
  2334. return SimplePie::merge_items($this->multifeed_objects, $start, $end);
  2335. }
  2336. elseif (!isset($this->data['items']))
  2337. {
  2338. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
  2339. {
  2340. $keys = array_keys($items);
  2341. foreach ($keys as $key)
  2342. {
  2343. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2344. }
  2345. }
  2346. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
  2347. {
  2348. $keys = array_keys($items);
  2349. foreach ($keys as $key)
  2350. {
  2351. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2352. }
  2353. }
  2354. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
  2355. {
  2356. $keys = array_keys($items);
  2357. foreach ($keys as $key)
  2358. {
  2359. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2360. }
  2361. }
  2362. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
  2363. {
  2364. $keys = array_keys($items);
  2365. foreach ($keys as $key)
  2366. {
  2367. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2368. }
  2369. }
  2370. if ($items = $this->get_channel_tags('', 'item'))
  2371. {
  2372. $keys = array_keys($items);
  2373. foreach ($keys as $key)
  2374. {
  2375. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2376. }
  2377. }
  2378. }
  2379. if (!empty($this->data['items']))
  2380. {
  2381. // If we want to order it by date, check if all items have a date, and then sort it
  2382. if ($this->order_by_date)
  2383. {
  2384. if (!isset($this->data['ordered_items']))
  2385. {
  2386. $do_sort = true;
  2387. foreach ($this->data['items'] as $item)
  2388. {
  2389. if (!$item->get_date('U'))
  2390. {
  2391. $do_sort = false;
  2392. break;
  2393. }
  2394. }
  2395. $item = null;
  2396. $this->data['ordered_items'] = $this->data['items'];
  2397. if ($do_sort)
  2398. {
  2399. usort($this->data['ordered_items'], array(&$this, 'sort_items'));
  2400. }
  2401. }
  2402. $items = $this->data['ordered_items'];
  2403. }
  2404. else
  2405. {
  2406. $items = $this->data['items'];
  2407. }
  2408. // Slice the data as desired
  2409. if ($end == 0)
  2410. {
  2411. return array_slice($items, $start);
  2412. }
  2413. else
  2414. {
  2415. return array_slice($items, $start, $end);
  2416. }
  2417. }
  2418. else
  2419. {
  2420. return array();
  2421. }
  2422. }
  2423. function sort_items($a, $b)
  2424. {
  2425. return $a->get_date('U') <= $b->get_date('U');
  2426. }
  2427. function merge_items($urls, $start = 0, $end = 0)
  2428. {
  2429. if (is_array($urls) && sizeof($urls) > 0)
  2430. {
  2431. $items = array();
  2432. foreach ($urls as $arg)
  2433. {
  2434. if (SimplePie_Misc::is_a($arg, 'SimplePie'))
  2435. {
  2436. $items = array_merge($items, $arg->get_items());
  2437. }
  2438. else
  2439. {
  2440. trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
  2441. }
  2442. }
  2443. $do_sort = true;
  2444. foreach ($items as $item)
  2445. {
  2446. if (!$item->get_date('U'))
  2447. {
  2448. $do_sort = false;
  2449. break;
  2450. }
  2451. }
  2452. $item = null;
  2453. if ($do_sort)
  2454. {
  2455. usort($items, array('SimplePie', 'sort_items'));
  2456. }
  2457. if ($end == 0)
  2458. {
  2459. return array_slice($items, $start);
  2460. }
  2461. else
  2462. {
  2463. return array_slice($items, $start, $end);
  2464. }
  2465. }
  2466. else
  2467. {
  2468. trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
  2469. return array();
  2470. }
  2471. }
  2472. }
  2473. class SimplePie_Item
  2474. {
  2475. var $feed;
  2476. var $data = array();
  2477. function SimplePie_Item($feed, $data)
  2478. {
  2479. $this->feed = $feed;
  2480. $this->data = $data;
  2481. }
  2482. function __toString()
  2483. {
  2484. return md5(serialize($this->data));
  2485. }
  2486. function get_item_tags($namespace, $tag)
  2487. {
  2488. if (isset($this->data['child'][$namespace][$tag]))
  2489. {
  2490. return $this->data['child'][$namespace][$tag];
  2491. }
  2492. else
  2493. {
  2494. return null;
  2495. }
  2496. }
  2497. function get_base($element = array())
  2498. {
  2499. return $this->feed->get_base($element);
  2500. }
  2501. function sanitize($data, $type, $base = '')
  2502. {
  2503. return $this->feed->sanitize($data, $type, $base);
  2504. }
  2505. function get_feed()
  2506. {
  2507. return $this->feed;
  2508. }
  2509. function get_id($hash = false)
  2510. {
  2511. if ($hash)
  2512. {
  2513. return $this->__toString();
  2514. }
  2515. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
  2516. {
  2517. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2518. }
  2519. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
  2520. {
  2521. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2522. }
  2523. elseif ($return = $this->get_item_tags('', 'guid'))
  2524. {
  2525. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2526. }
  2527. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
  2528. {
  2529. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2530. }
  2531. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
  2532. {
  2533. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2534. }
  2535. elseif (($return = $this->get_permalink()) !== null)
  2536. {
  2537. return $return;
  2538. }
  2539. elseif (($return = $this->get_title()) !== null)
  2540. {
  2541. return $return;
  2542. }
  2543. else
  2544. {
  2545. return $this->__toString();
  2546. }
  2547. }
  2548. function get_title()
  2549. {
  2550. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  2551. {
  2552. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2553. }
  2554. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  2555. {
  2556. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2557. }
  2558. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2559. {
  2560. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2561. }
  2562. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2563. {
  2564. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2565. }
  2566. elseif ($return = $this->get_item_tags('', 'title'))
  2567. {
  2568. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2569. }
  2570. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2571. {
  2572. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2573. }
  2574. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2575. {
  2576. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2577. }
  2578. else
  2579. {
  2580. return null;
  2581. }
  2582. }
  2583. function get_description($description_only = false)
  2584. {
  2585. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
  2586. {
  2587. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2588. }
  2589. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
  2590. {
  2591. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2592. }
  2593. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  2594. {
  2595. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2596. }
  2597. elseif ($return = $this->get_item_tags('', 'description'))
  2598. {
  2599. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2600. }
  2601. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  2602. {
  2603. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2604. }
  2605. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  2606. {
  2607. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2608. }
  2609. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  2610. {
  2611. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2612. }
  2613. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  2614. {
  2615. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2616. }
  2617. elseif (!$description_only)
  2618. {
  2619. return $this->get_content(true);
  2620. }
  2621. else
  2622. {
  2623. return null;
  2624. }
  2625. }
  2626. function get_content($content_only = false)
  2627. {
  2628. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
  2629. {
  2630. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2631. }
  2632. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
  2633. {
  2634. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2635. }
  2636. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
  2637. {
  2638. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2639. }
  2640. elseif (!$content_only)
  2641. {
  2642. return $this->get_description(true);
  2643. }
  2644. else
  2645. {
  2646. return null;
  2647. }
  2648. }
  2649. function get_category($key = 0)
  2650. {
  2651. $categories = $this->get_categories();
  2652. if (isset($categories[$key]))
  2653. {
  2654. return $categories[$key];
  2655. }
  2656. else
  2657. {
  2658. return null;
  2659. }
  2660. }
  2661. function get_categories()
  2662. {
  2663. $categories = array();
  2664. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  2665. {
  2666. $term = null;
  2667. $scheme = null;
  2668. $label = null;
  2669. if (isset($category['attribs']['']['term']))
  2670. {
  2671. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  2672. }
  2673. if (isset($category['attribs']['']['scheme']))
  2674. {
  2675. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  2676. }
  2677. if (isset($category['attribs']['']['label']))
  2678. {
  2679. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  2680. }
  2681. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  2682. }
  2683. foreach ((array) $this->get_item_tags('', 'category') as $category)
  2684. {
  2685. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2686. }
  2687. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  2688. {
  2689. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2690. }
  2691. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  2692. {
  2693. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2694. }
  2695. if (!empty($categories))
  2696. {
  2697. return SimplePie_Misc::array_unique($categories);
  2698. }
  2699. else
  2700. {
  2701. return null;
  2702. }
  2703. }
  2704. function get_author($key = 0)
  2705. {
  2706. $authors = $this->get_authors();
  2707. if (isset($authors[$key]))
  2708. {
  2709. return $authors[$key];
  2710. }
  2711. else
  2712. {
  2713. return null;
  2714. }
  2715. }
  2716. /**
  2717. * @todo Atom inheritance (item author, source author, feed author)
  2718. */
  2719. function get_authors()
  2720. {
  2721. $authors = array();
  2722. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  2723. {
  2724. $name = null;
  2725. $uri = null;
  2726. $email = null;
  2727. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  2728. {
  2729. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2730. }
  2731. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  2732. {
  2733. $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]));
  2734. }
  2735. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  2736. {
  2737. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2738. }
  2739. if ($name !== null || $email !== null || $uri !== null)
  2740. {
  2741. $authors[] =& new $this->feed->author_class($name, $uri, $email);
  2742. }
  2743. }
  2744. if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  2745. {
  2746. $name = null;
  2747. $url = null;
  2748. $email = null;
  2749. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  2750. {
  2751. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2752. }
  2753. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  2754. {
  2755. $uri = $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]));
  2756. }
  2757. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  2758. {
  2759. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2760. }
  2761. if ($name !== null || $email !== null || $uri !== null)
  2762. {
  2763. $authors[] =& new $this->feed->author_class($name, $url, $email);
  2764. }
  2765. }
  2766. if ($author = $this->get_item_tags('', 'author'))
  2767. {
  2768. $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  2769. }
  2770. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  2771. {
  2772. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2773. }
  2774. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  2775. {
  2776. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2777. }
  2778. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  2779. {
  2780. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2781. }
  2782. if (!empty($authors))
  2783. {
  2784. return SimplePie_Misc::array_unique($authors);
  2785. }
  2786. else
  2787. {
  2788. return null;
  2789. }
  2790. }
  2791. function get_date($date_format = 'j F Y, g:i a')
  2792. {
  2793. if (!isset($this->data['date']))
  2794. {
  2795. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
  2796. {
  2797. $this->data['date']['raw'] = $return[0]['data'];
  2798. }
  2799. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
  2800. {
  2801. $this->data['date']['raw'] = $return[0]['data'];
  2802. }
  2803. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
  2804. {
  2805. $this->data['date']['raw'] = $return[0]['data'];
  2806. }
  2807. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
  2808. {
  2809. $this->data['date']['raw'] = $return[0]['data'];
  2810. }
  2811. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
  2812. {
  2813. $this->data['date']['raw'] = $return[0]['data'];
  2814. }
  2815. elseif ($return = $this->get_item_tags('', 'pubDate'))
  2816. {
  2817. $this->data['date']['raw'] = $return[0]['data'];
  2818. }
  2819. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
  2820. {
  2821. $this->data['date']['raw'] = $return[0]['data'];
  2822. }
  2823. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
  2824. {
  2825. $this->data['date']['raw'] = $return[0]['data'];
  2826. }
  2827. if (!empty($this->data['date']['raw']))
  2828. {
  2829. $this->data['date']['parsed'] = SimplePie_Misc::parse_date($this->data['date']['raw']);
  2830. }
  2831. else
  2832. {
  2833. $this->data['date'] = null;
  2834. }
  2835. }
  2836. if ($this->data['date'])
  2837. {
  2838. $date_format = (string) $date_format;
  2839. switch ($date_format)
  2840. {
  2841. case '':
  2842. return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
  2843. case 'U':
  2844. return $this->data['date']['parsed'];
  2845. default:
  2846. return date($date_format, $this->data['date']['parsed']);
  2847. }
  2848. }
  2849. else
  2850. {
  2851. return null;
  2852. }
  2853. }
  2854. function get_local_date($date_format = '%c')
  2855. {
  2856. if (!$date_format)
  2857. {
  2858. return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
  2859. }
  2860. elseif (($date = $this->get_date('U')) !== null)
  2861. {
  2862. return strftime($date_format, $date);
  2863. }
  2864. else
  2865. {
  2866. return null;
  2867. }
  2868. }
  2869. function get_permalink()
  2870. {
  2871. $link = $this->get_link();
  2872. $enclosure = $this->get_enclosure(0);
  2873. if ($link !== null)
  2874. {
  2875. return $link;
  2876. }
  2877. elseif ($enclosure !== null)
  2878. {
  2879. return $enclosure->get_link();
  2880. }
  2881. else
  2882. {
  2883. return null;
  2884. }
  2885. }
  2886. function get_link($key = 0, $rel = 'alternate')
  2887. {
  2888. $links = $this->get_links($rel);
  2889. if ($links[$key] !== null)
  2890. {
  2891. return $links[$key];
  2892. }
  2893. else
  2894. {
  2895. return null;
  2896. }
  2897. }
  2898. function get_links($rel = 'alternate')
  2899. {
  2900. if (!isset($this->data['links']))
  2901. {
  2902. $this->data['links'] = array();
  2903. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  2904. {
  2905. if (isset($link['attribs']['']['href']))
  2906. {
  2907. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2908. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2909. }
  2910. }
  2911. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  2912. {
  2913. if (isset($link['attribs']['']['href']))
  2914. {
  2915. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2916. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2917. }
  2918. }
  2919. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2920. {
  2921. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2922. }
  2923. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2924. {
  2925. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2926. }
  2927. if ($links = $this->get_item_tags('', 'link'))
  2928. {
  2929. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2930. }
  2931. if ($links = $this->get_item_tags('', 'guid'))
  2932. {
  2933. if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
  2934. {
  2935. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2936. }
  2937. }
  2938. $keys = array_keys($this->data['links']);
  2939. foreach ($keys as $key)
  2940. {
  2941. if (SimplePie_Misc::is_isegment_nz_nc($key))
  2942. {
  2943. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  2944. {
  2945. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  2946. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  2947. }
  2948. else
  2949. {
  2950. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  2951. }
  2952. }
  2953. elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  2954. {
  2955. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  2956. }
  2957. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  2958. }
  2959. }
  2960. if (isset($this->data['links'][$rel]))
  2961. {
  2962. return $this->data['links'][$rel];
  2963. }
  2964. else
  2965. {
  2966. return null;
  2967. }
  2968. }
  2969. /**
  2970. * @todo Add ability to prefer one type of content over another (in a media group).
  2971. */
  2972. function get_enclosure($key = 0, $prefer = null)
  2973. {
  2974. $enclosures = $this->get_enclosures();
  2975. if (isset($enclosures[$key]))
  2976. {
  2977. return $enclosures[$key];
  2978. }
  2979. else
  2980. {
  2981. return null;
  2982. }
  2983. }
  2984. /**
  2985. * Grabs all available enclosures (podcasts, etc.)
  2986. *
  2987. * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
  2988. *
  2989. * 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.
  2990. *
  2991. * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
  2992. * @todo Add support for itunes: tags. These should be relatively simple compared to media:.
  2993. * @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).
  2994. */
  2995. function get_enclosures()
  2996. {
  2997. if (!isset($this->data['enclosures']))
  2998. {
  2999. $this->data['enclosures'] = array();
  3000. // Elements
  3001. $captions_parent = null;
  3002. $categories_parent = null;
  3003. $copyrights_parent = null;
  3004. $credits_parent = null;
  3005. $description_parent = null;
  3006. $duration_parent = null;
  3007. $hashes_parent = null;
  3008. $keywords_parent = null;
  3009. $player_parent = null;
  3010. $ratings_parent = null;
  3011. $restrictions_parent = null;
  3012. $thumbnails_parent = null;
  3013. $title_parent = null;
  3014. // Let's do the channel and item-level ones first, and just re-use them if we need to.
  3015. $parent = $this->get_feed();
  3016. // CAPTIONS
  3017. if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  3018. {
  3019. foreach ($captions as $caption)
  3020. {
  3021. $caption_type = null;
  3022. $caption_lang = null;
  3023. $caption_startTime = null;
  3024. $caption_endTime = null;
  3025. $caption_text = null;
  3026. if (isset($caption['attribs']['']['type']))
  3027. {
  3028. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3029. }
  3030. if (isset($caption['attribs']['']['lang']))
  3031. {
  3032. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3033. }
  3034. if (isset($caption['attribs']['']['start']))
  3035. {
  3036. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3037. }
  3038. if (isset($caption['attribs']['']['end']))
  3039. {
  3040. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3041. }
  3042. if (isset($caption['data']))
  3043. {
  3044. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3045. }
  3046. $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3047. }
  3048. }
  3049. elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  3050. {
  3051. foreach ($captions as $caption)
  3052. {
  3053. $caption_type = null;
  3054. $caption_lang = null;
  3055. $caption_startTime = null;
  3056. $caption_endTime = null;
  3057. $caption_text = null;
  3058. if (isset($caption['attribs']['']['type']))
  3059. {
  3060. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3061. }
  3062. if (isset($caption['attribs']['']['lang']))
  3063. {
  3064. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3065. }
  3066. if (isset($caption['attribs']['']['start']))
  3067. {
  3068. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3069. }
  3070. if (isset($caption['attribs']['']['end']))
  3071. {
  3072. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3073. }
  3074. if (isset($caption['data']))
  3075. {
  3076. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3077. }
  3078. $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3079. }
  3080. }
  3081. if (is_array($captions_parent))
  3082. {
  3083. $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
  3084. }
  3085. // CATEGORIES
  3086. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  3087. {
  3088. $term = null;
  3089. $scheme = null;
  3090. $label = null;
  3091. if (isset($category['data']))
  3092. {
  3093. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3094. }
  3095. if (isset($category['attribs']['']['scheme']))
  3096. {
  3097. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3098. }
  3099. else
  3100. {
  3101. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3102. }
  3103. if (isset($category['attribs']['']['label']))
  3104. {
  3105. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3106. }
  3107. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3108. }
  3109. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  3110. {
  3111. $term = null;
  3112. $scheme = null;
  3113. $label = null;
  3114. if (isset($category['data']))
  3115. {
  3116. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3117. }
  3118. if (isset($category['attribs']['']['scheme']))
  3119. {
  3120. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3121. }
  3122. else
  3123. {
  3124. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3125. }
  3126. if (isset($category['attribs']['']['label']))
  3127. {
  3128. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3129. }
  3130. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3131. }
  3132. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
  3133. {
  3134. $term = null;
  3135. $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
  3136. $label = null;
  3137. if (isset($category['attribs']['']['text']))
  3138. {
  3139. $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  3140. }
  3141. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3142. if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
  3143. {
  3144. foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
  3145. {
  3146. if (isset($subcategory['attribs']['']['text']))
  3147. {
  3148. $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  3149. }
  3150. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3151. }
  3152. }
  3153. }
  3154. if (is_array($categories_parent))
  3155. {
  3156. $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
  3157. }
  3158. // COPYRIGHT
  3159. if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  3160. {
  3161. $copyright_url = null;
  3162. $copyright_label = null;
  3163. if (isset($copyright[0]['attribs']['']['url']))
  3164. {
  3165. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3166. }
  3167. if (isset($copyright[0]['data']))
  3168. {
  3169. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3170. }
  3171. $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  3172. }
  3173. elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  3174. {
  3175. $copyright_url = null;
  3176. $copyright_label = null;
  3177. if (isset($copyright[0]['attribs']['']['url']))
  3178. {
  3179. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3180. }
  3181. if (isset($copyright[0]['data']))
  3182. {
  3183. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3184. }
  3185. $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  3186. }
  3187. // CREDITS
  3188. if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  3189. {
  3190. foreach ($credits as $credit)
  3191. {
  3192. $credit_role = null;
  3193. $credit_scheme = null;
  3194. $credit_name = null;
  3195. if (isset($credit['attribs']['']['role']))
  3196. {
  3197. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3198. }
  3199. if (isset($credit['attribs']['']['scheme']))
  3200. {
  3201. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3202. }
  3203. else
  3204. {
  3205. $credit_scheme = 'urn:ebu';
  3206. }
  3207. if (isset($credit['data']))
  3208. {
  3209. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3210. }
  3211. $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3212. }
  3213. }
  3214. elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  3215. {
  3216. foreach ($credits as $credit)
  3217. {
  3218. $credit_role = null;
  3219. $credit_scheme = null;
  3220. $credit_name = null;
  3221. if (isset($credit['attribs']['']['role']))
  3222. {
  3223. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3224. }
  3225. if (isset($credit['attribs']['']['scheme']))
  3226. {
  3227. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3228. }
  3229. else
  3230. {
  3231. $credit_scheme = 'urn:ebu';
  3232. }
  3233. if (isset($credit['data']))
  3234. {
  3235. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3236. }
  3237. $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3238. }
  3239. }
  3240. if (is_array($credits_parent))
  3241. {
  3242. $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
  3243. }
  3244. // DESCRIPTION
  3245. if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  3246. {
  3247. if (isset($description_parent[0]['data']))
  3248. {
  3249. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3250. }
  3251. }
  3252. elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  3253. {
  3254. if (isset($description_parent[0]['data']))
  3255. {
  3256. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3257. }
  3258. }
  3259. // DURATION
  3260. if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
  3261. {
  3262. $seconds = null;
  3263. $minutes = null;
  3264. $hours = null;
  3265. if (isset($duration_parent[0]['data']))
  3266. {
  3267. $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3268. if (sizeof($temp) > 0)
  3269. {
  3270. (int) $seconds = array_pop($temp);
  3271. }
  3272. if (sizeof($temp) > 0)
  3273. {
  3274. (int) $minutes = array_pop($temp);
  3275. $seconds += $minutes * 60;
  3276. }
  3277. if (sizeof($temp) > 0)
  3278. {
  3279. (int) $hours = array_pop($temp);
  3280. $seconds += $hours * 3600;
  3281. }
  3282. unset($temp);
  3283. $duration_parent = $seconds;
  3284. }
  3285. }
  3286. // HASHES
  3287. if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  3288. {
  3289. foreach ($hashes_iterator as $hash)
  3290. {
  3291. $value = null;
  3292. $algo = null;
  3293. if (isset($hash['data']))
  3294. {
  3295. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3296. }
  3297. if (isset($hash['attribs']['']['algo']))
  3298. {
  3299. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3300. }
  3301. else
  3302. {
  3303. $algo = 'md5';
  3304. }
  3305. $hashes_parent[] = $algo.':'.$value;
  3306. }
  3307. }
  3308. elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  3309. {
  3310. foreach ($hashes_iterator as $hash)
  3311. {
  3312. $value = null;
  3313. $algo = null;
  3314. if (isset($hash['data']))
  3315. {
  3316. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3317. }
  3318. if (isset($hash['attribs']['']['algo']))
  3319. {
  3320. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3321. }
  3322. else
  3323. {
  3324. $algo = 'md5';
  3325. }
  3326. $hashes_parent[] = $algo.':'.$value;
  3327. }
  3328. }
  3329. if (is_array($hashes_parent))
  3330. {
  3331. $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
  3332. }
  3333. // KEYWORDS
  3334. if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  3335. {
  3336. if (isset($keywords[0]['data']))
  3337. {
  3338. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3339. foreach ($temp as $word)
  3340. {
  3341. $keywords_parent[] = trim($word);
  3342. }
  3343. }
  3344. unset($temp);
  3345. }
  3346. elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  3347. {
  3348. if (isset($keywords[0]['data']))
  3349. {
  3350. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3351. foreach ($temp as $word)
  3352. {
  3353. $keywords_parent[] = trim($word);
  3354. }
  3355. }
  3356. unset($temp);
  3357. }
  3358. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  3359. {
  3360. if (isset($keywords[0]['data']))
  3361. {
  3362. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3363. foreach ($temp as $word)
  3364. {
  3365. $keywords_parent[] = trim($word);
  3366. }
  3367. }
  3368. unset($temp);
  3369. }
  3370. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  3371. {
  3372. if (isset($keywords[0]['data']))
  3373. {
  3374. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3375. foreach ($temp as $word)
  3376. {
  3377. $keywords_parent[] = trim($word);
  3378. }
  3379. }
  3380. unset($temp);
  3381. }
  3382. if (is_array($keywords_parent))
  3383. {
  3384. $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
  3385. }
  3386. // PLAYER
  3387. if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  3388. {
  3389. if (isset($player_parent[0]['attribs']['']['url']))
  3390. {
  3391. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3392. }
  3393. }
  3394. elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  3395. {
  3396. if (isset($player_parent[0]['attribs']['']['url']))
  3397. {
  3398. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3399. }
  3400. }
  3401. // RATINGS
  3402. if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  3403. {
  3404. foreach ($ratings as $rating)
  3405. {
  3406. $rating_scheme = null;
  3407. $rating_value = null;
  3408. if (isset($rating['attribs']['']['scheme']))
  3409. {
  3410. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3411. }
  3412. else
  3413. {
  3414. $rating_scheme = 'urn:simple';
  3415. }
  3416. if (isset($rating['data']))
  3417. {
  3418. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3419. }
  3420. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3421. }
  3422. }
  3423. elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  3424. {
  3425. foreach ($ratings as $rating)
  3426. {
  3427. $rating_scheme = 'urn:itunes';
  3428. $rating_value = null;
  3429. if (isset($rating['data']))
  3430. {
  3431. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3432. }
  3433. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3434. }
  3435. }
  3436. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  3437. {
  3438. foreach ($ratings as $rating)
  3439. {
  3440. $rating_scheme = null;
  3441. $rating_value = null;
  3442. if (isset($rating['attribs']['']['scheme']))
  3443. {
  3444. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3445. }
  3446. else
  3447. {
  3448. $rating_scheme = 'urn:simple';
  3449. }
  3450. if (isset($rating['data']))
  3451. {
  3452. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3453. }
  3454. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3455. }
  3456. }
  3457. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  3458. {
  3459. foreach ($ratings as $rating)
  3460. {
  3461. $rating_scheme = 'urn:itunes';
  3462. $rating_value = null;
  3463. if (isset($rating['data']))
  3464. {
  3465. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3466. }
  3467. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3468. }
  3469. }
  3470. if (is_array($ratings_parent))
  3471. {
  3472. $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
  3473. }
  3474. // RESTRICTIONS
  3475. if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  3476. {
  3477. foreach ($restrictions as $restriction)
  3478. {
  3479. $restriction_relationship = null;
  3480. $restriction_type = null;
  3481. $restriction_value = null;
  3482. if (isset($restriction['attribs']['']['relationship']))
  3483. {
  3484. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  3485. }
  3486. if (isset($restriction['attribs']['']['type']))
  3487. {
  3488. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3489. }
  3490. if (isset($restriction['data']))
  3491. {
  3492. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3493. }
  3494. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3495. }
  3496. }
  3497. elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  3498. {
  3499. foreach ($restrictions as $restriction)
  3500. {
  3501. $restriction_relationship = 'allow';
  3502. $restriction_type = null;
  3503. $restriction_value = 'itunes';
  3504. if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
  3505. {
  3506. $restriction_relationship = 'deny';
  3507. }
  3508. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3509. }
  3510. }
  3511. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  3512. {
  3513. foreach ($restrictions as $restriction)
  3514. {
  3515. $restriction_relationship = null;
  3516. $restriction_type = null;
  3517. $restriction_value = null;
  3518. if (isset($restriction['attribs']['']['relationship']))
  3519. {
  3520. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  3521. }
  3522. if (isset($restriction['attribs']['']['type']))
  3523. {
  3524. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3525. }
  3526. if (isset($restriction['data']))
  3527. {
  3528. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3529. }
  3530. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3531. }
  3532. }
  3533. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  3534. {
  3535. foreach ($restrictions as $restriction)
  3536. {
  3537. $restriction_relationship = 'allow';
  3538. $restriction_type = null;
  3539. $restriction_value = 'itunes';
  3540. if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
  3541. {
  3542. $restriction_relationship = 'deny';
  3543. }
  3544. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3545. }
  3546. }
  3547. if (is_array($restrictions_parent))
  3548. {
  3549. $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
  3550. }
  3551. // THUMBNAILS
  3552. if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  3553. {
  3554. foreach ($thumbnails as $thumbnail)
  3555. {
  3556. if (isset($thumbnail['attribs']['']['url']))
  3557. {
  3558. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3559. }
  3560. }
  3561. }
  3562. elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  3563. {
  3564. foreach ($thumbnails as $thumbnail)
  3565. {
  3566. if (isset($thumbnail['attribs']['']['url']))
  3567. {
  3568. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3569. }
  3570. }
  3571. }
  3572. // TITLES
  3573. if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  3574. {
  3575. if (isset($title_parent[0]['data']))
  3576. {
  3577. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3578. }
  3579. }
  3580. elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  3581. {
  3582. if (isset($title_parent[0]['data']))
  3583. {
  3584. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3585. }
  3586. }
  3587. // Clear the memory
  3588. unset($parent);
  3589. // If we have media:group tags, loop through them.
  3590. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
  3591. {
  3592. // If we have media:content tags, loop through them.
  3593. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  3594. {
  3595. if (isset($content['attribs']['']['url']))
  3596. {
  3597. // Attributes
  3598. $bitrate = null;
  3599. $channels = null;
  3600. $duration = null;
  3601. $expression = null;
  3602. $framerate = null;
  3603. $height = null;
  3604. $javascript = null;
  3605. $lang = null;
  3606. $length = null;
  3607. $medium = null;
  3608. $samplingrate = null;
  3609. $type = null;
  3610. $url = null;
  3611. $width = null;
  3612. // Elements
  3613. $captions = null;
  3614. $categories = null;
  3615. $copyrights = null;
  3616. $credits = null;
  3617. $description = null;
  3618. $hashes = null;
  3619. $keywords = null;
  3620. $player = null;
  3621. $ratings = null;
  3622. $restrictions = null;
  3623. $thumbnails = null;
  3624. $title = null;
  3625. // Start checking the attributes of media:content
  3626. if (isset($content['attribs']['']['bitrate']))
  3627. {
  3628. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  3629. }
  3630. if (isset($content['attribs']['']['channels']))
  3631. {
  3632. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  3633. }
  3634. if (isset($content['attribs']['']['duration']))
  3635. {
  3636. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  3637. }
  3638. else
  3639. {
  3640. $duration = $duration_parent;
  3641. }
  3642. if (isset($content['attribs']['']['expression']))
  3643. {
  3644. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  3645. }
  3646. if (isset($content['attribs']['']['framerate']))
  3647. {
  3648. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  3649. }
  3650. if (isset($content['attribs']['']['height']))
  3651. {
  3652. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  3653. }
  3654. if (isset($content['attribs']['']['lang']))
  3655. {
  3656. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3657. }
  3658. if (isset($content['attribs']['']['fileSize']))
  3659. {
  3660. $length = ceil($content['attribs']['']['fileSize']);
  3661. }
  3662. if (isset($content['attribs']['']['medium']))
  3663. {
  3664. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  3665. }
  3666. if (isset($content['attribs']['']['samplingrate']))
  3667. {
  3668. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  3669. }
  3670. if (isset($content['attribs']['']['type']))
  3671. {
  3672. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3673. }
  3674. if (isset($content['attribs']['']['width']))
  3675. {
  3676. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  3677. }
  3678. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3679. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  3680. // CAPTIONS
  3681. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  3682. {
  3683. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  3684. {
  3685. $caption_type = null;
  3686. $caption_lang = null;
  3687. $caption_startTime = null;
  3688. $caption_endTime = null;
  3689. $caption_text = null;
  3690. if (isset($caption['attribs']['']['type']))
  3691. {
  3692. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3693. }
  3694. if (isset($caption['attribs']['']['lang']))
  3695. {
  3696. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3697. }
  3698. if (isset($caption['attribs']['']['start']))
  3699. {
  3700. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3701. }
  3702. if (isset($caption['attribs']['']['end']))
  3703. {
  3704. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3705. }
  3706. if (isset($caption['data']))
  3707. {
  3708. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3709. }
  3710. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3711. }
  3712. if (is_array($captions))
  3713. {
  3714. $captions = array_values(SimplePie_Misc::array_unique($captions));
  3715. }
  3716. }
  3717. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  3718. {
  3719. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  3720. {
  3721. $caption_type = null;
  3722. $caption_lang = null;
  3723. $caption_startTime = null;
  3724. $caption_endTime = null;
  3725. $caption_text = null;
  3726. if (isset($caption['attribs']['']['type']))
  3727. {
  3728. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3729. }
  3730. if (isset($caption['attribs']['']['lang']))
  3731. {
  3732. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3733. }
  3734. if (isset($caption['attribs']['']['start']))
  3735. {
  3736. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3737. }
  3738. if (isset($caption['attribs']['']['end']))
  3739. {
  3740. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3741. }
  3742. if (isset($caption['data']))
  3743. {
  3744. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3745. }
  3746. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3747. }
  3748. if (is_array($captions))
  3749. {
  3750. $captions = array_values(SimplePie_Misc::array_unique($captions));
  3751. }
  3752. }
  3753. else
  3754. {
  3755. $captions = $captions_parent;
  3756. }
  3757. // CATEGORIES
  3758. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  3759. {
  3760. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  3761. {
  3762. $term = null;
  3763. $scheme = null;
  3764. $label = null;
  3765. if (isset($category['data']))
  3766. {
  3767. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3768. }
  3769. if (isset($category['attribs']['']['scheme']))
  3770. {
  3771. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3772. }
  3773. else
  3774. {
  3775. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3776. }
  3777. if (isset($category['attribs']['']['label']))
  3778. {
  3779. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3780. }
  3781. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  3782. }
  3783. }
  3784. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  3785. {
  3786. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  3787. {
  3788. $term = null;
  3789. $scheme = null;
  3790. $label = null;
  3791. if (isset($category['data']))
  3792. {
  3793. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3794. }
  3795. if (isset($category['attribs']['']['scheme']))
  3796. {
  3797. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3798. }
  3799. else
  3800. {
  3801. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3802. }
  3803. if (isset($category['attribs']['']['label']))
  3804. {
  3805. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3806. }
  3807. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  3808. }
  3809. }
  3810. if (is_array($categories) && is_array($categories_parent))
  3811. {
  3812. $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
  3813. }
  3814. elseif (is_array($categories))
  3815. {
  3816. $categories = array_values(SimplePie_Misc::array_unique($categories));
  3817. }
  3818. elseif (is_array($categories_parent))
  3819. {
  3820. $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
  3821. }
  3822. // COPYRIGHTS
  3823. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  3824. {
  3825. $copyright_url = null;
  3826. $copyright_label = null;
  3827. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  3828. {
  3829. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3830. }
  3831. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  3832. {
  3833. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3834. }
  3835. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  3836. }
  3837. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  3838. {
  3839. $copyright_url = null;
  3840. $copyright_label = null;
  3841. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  3842. {
  3843. $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3844. }
  3845. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  3846. {
  3847. $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3848. }
  3849. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  3850. }
  3851. else
  3852. {
  3853. $copyrights = $copyrights_parent;
  3854. }
  3855. // CREDITS
  3856. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  3857. {
  3858. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  3859. {
  3860. $credit_role = null;
  3861. $credit_scheme = null;
  3862. $credit_name = null;
  3863. if (isset($credit['attribs']['']['role']))
  3864. {
  3865. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3866. }
  3867. if (isset($credit['attribs']['']['scheme']))
  3868. {
  3869. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3870. }
  3871. else
  3872. {
  3873. $credit_scheme = 'urn:ebu';
  3874. }
  3875. if (isset($credit['data']))
  3876. {
  3877. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3878. }
  3879. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3880. }
  3881. if (is_array($credits))
  3882. {
  3883. $credits = array_values(SimplePie_Misc::array_unique($credits));
  3884. }
  3885. }
  3886. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  3887. {
  3888. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  3889. {
  3890. $credit_role = null;
  3891. $credit_scheme = null;
  3892. $credit_name = null;
  3893. if (isset($credit['attribs']['']['role']))
  3894. {
  3895. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3896. }
  3897. if (isset($credit['attribs']['']['scheme']))
  3898. {
  3899. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3900. }
  3901. else
  3902. {
  3903. $credit_scheme = 'urn:ebu';
  3904. }
  3905. if (isset($credit['data']))
  3906. {
  3907. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3908. }
  3909. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3910. }
  3911. if (is_array($credits))
  3912. {
  3913. $credits = array_values(SimplePie_Misc::array_unique($credits));
  3914. }
  3915. }
  3916. else
  3917. {
  3918. $credits = $credits_parent;
  3919. }
  3920. // DESCRIPTION
  3921. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  3922. {
  3923. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3924. }
  3925. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  3926. {
  3927. $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3928. }
  3929. else
  3930. {
  3931. $description = $description_parent;
  3932. }
  3933. // HASHES
  3934. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  3935. {
  3936. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  3937. {
  3938. $value = null;
  3939. $algo = null;
  3940. if (isset($hash['data']))
  3941. {
  3942. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3943. }
  3944. if (isset($hash['attribs']['']['algo']))
  3945. {
  3946. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3947. }
  3948. else
  3949. {
  3950. $algo = 'md5';
  3951. }
  3952. $hashes[] = $algo.':'.$value;
  3953. }
  3954. if (is_array($hashes))
  3955. {
  3956. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  3957. }
  3958. }
  3959. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  3960. {
  3961. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  3962. {
  3963. $value = null;
  3964. $algo = null;
  3965. if (isset($hash['data']))
  3966. {
  3967. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3968. }
  3969. if (isset($hash['attribs']['']['algo']))
  3970. {
  3971. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3972. }
  3973. else
  3974. {
  3975. $algo = 'md5';
  3976. }
  3977. $hashes[] = $algo.':'.$value;
  3978. }
  3979. if (is_array($hashes))
  3980. {
  3981. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  3982. }
  3983. }
  3984. else
  3985. {
  3986. $hashes = $hashes_parent;
  3987. }
  3988. // KEYWORDS
  3989. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  3990. {
  3991. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  3992. {
  3993. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3994. foreach ($temp as $word)
  3995. {
  3996. $keywords[] = trim($word);
  3997. }
  3998. unset($temp);
  3999. }
  4000. if (is_array($keywords))
  4001. {
  4002. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4003. }
  4004. }
  4005. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4006. {
  4007. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4008. {
  4009. $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4010. foreach ($temp as $word)
  4011. {
  4012. $keywords[] = trim($word);
  4013. }
  4014. unset($temp);
  4015. }
  4016. if (is_array($keywords))
  4017. {
  4018. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4019. }
  4020. }
  4021. else
  4022. {
  4023. $keywords = $keywords_parent;
  4024. }
  4025. // PLAYER
  4026. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4027. {
  4028. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4029. }
  4030. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4031. {
  4032. $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4033. }
  4034. else
  4035. {
  4036. $player = $player_parent;
  4037. }
  4038. // RATINGS
  4039. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4040. {
  4041. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4042. {
  4043. $rating_scheme = null;
  4044. $rating_value = null;
  4045. if (isset($rating['attribs']['']['scheme']))
  4046. {
  4047. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4048. }
  4049. else
  4050. {
  4051. $rating_scheme = 'urn:simple';
  4052. }
  4053. if (isset($rating['data']))
  4054. {
  4055. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4056. }
  4057. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4058. }
  4059. if (is_array($ratings))
  4060. {
  4061. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4062. }
  4063. }
  4064. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4065. {
  4066. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4067. {
  4068. $rating_scheme = null;
  4069. $rating_value = null;
  4070. if (isset($rating['attribs']['']['scheme']))
  4071. {
  4072. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4073. }
  4074. else
  4075. {
  4076. $rating_scheme = 'urn:simple';
  4077. }
  4078. if (isset($rating['data']))
  4079. {
  4080. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4081. }
  4082. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4083. }
  4084. if (is_array($ratings))
  4085. {
  4086. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4087. }
  4088. }
  4089. else
  4090. {
  4091. $ratings = $ratings_parent;
  4092. }
  4093. // RESTRICTIONS
  4094. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4095. {
  4096. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4097. {
  4098. $restriction_relationship = null;
  4099. $restriction_type = null;
  4100. $restriction_value = null;
  4101. if (isset($restriction['attribs']['']['relationship']))
  4102. {
  4103. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4104. }
  4105. if (isset($restriction['attribs']['']['type']))
  4106. {
  4107. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4108. }
  4109. if (isset($restriction['data']))
  4110. {
  4111. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4112. }
  4113. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4114. }
  4115. if (is_array($restrictions))
  4116. {
  4117. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4118. }
  4119. }
  4120. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4121. {
  4122. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4123. {
  4124. $restriction_relationship = null;
  4125. $restriction_type = null;
  4126. $restriction_value = null;
  4127. if (isset($restriction['attribs']['']['relationship']))
  4128. {
  4129. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4130. }
  4131. if (isset($restriction['attribs']['']['type']))
  4132. {
  4133. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4134. }
  4135. if (isset($restriction['data']))
  4136. {
  4137. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4138. }
  4139. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4140. }
  4141. if (is_array($restrictions))
  4142. {
  4143. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4144. }
  4145. }
  4146. else
  4147. {
  4148. $restrictions = $restrictions_parent;
  4149. }
  4150. // THUMBNAILS
  4151. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4152. {
  4153. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4154. {
  4155. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4156. }
  4157. if (is_array($thumbnails))
  4158. {
  4159. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4160. }
  4161. }
  4162. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4163. {
  4164. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4165. {
  4166. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4167. }
  4168. if (is_array($thumbnails))
  4169. {
  4170. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4171. }
  4172. }
  4173. else
  4174. {
  4175. $thumbnails = $thumbnails_parent;
  4176. }
  4177. // TITLES
  4178. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4179. {
  4180. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4181. }
  4182. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4183. {
  4184. $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4185. }
  4186. else
  4187. {
  4188. $title = $title_parent;
  4189. }
  4190. $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);
  4191. }
  4192. }
  4193. }
  4194. // If we have standalone media:content tags, loop through them.
  4195. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
  4196. {
  4197. foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  4198. {
  4199. if (isset($content['attribs']['']['url']))
  4200. {
  4201. // Attributes
  4202. $bitrate = null;
  4203. $channels = null;
  4204. $duration = null;
  4205. $expression = null;
  4206. $framerate = null;
  4207. $height = null;
  4208. $javascript = null;
  4209. $lang = null;
  4210. $length = null;
  4211. $medium = null;
  4212. $samplingrate = null;
  4213. $type = null;
  4214. $url = null;
  4215. $width = null;
  4216. // Elements
  4217. $captions = null;
  4218. $categories = null;
  4219. $copyrights = null;
  4220. $credits = null;
  4221. $description = null;
  4222. $hashes = null;
  4223. $keywords = null;
  4224. $player = null;
  4225. $ratings = null;
  4226. $restrictions = null;
  4227. $thumbnails = null;
  4228. $title = null;
  4229. // Start checking the attributes of media:content
  4230. if (isset($content['attribs']['']['bitrate']))
  4231. {
  4232. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4233. }
  4234. if (isset($content['attribs']['']['channels']))
  4235. {
  4236. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  4237. }
  4238. if (isset($content['attribs']['']['duration']))
  4239. {
  4240. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  4241. }
  4242. else
  4243. {
  4244. $duration = $duration_parent;
  4245. }
  4246. if (isset($content['attribs']['']['expression']))
  4247. {
  4248. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  4249. }
  4250. if (isset($content['attribs']['']['framerate']))
  4251. {
  4252. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4253. }
  4254. if (isset($content['attribs']['']['height']))
  4255. {
  4256. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  4257. }
  4258. if (isset($content['attribs']['']['lang']))
  4259. {
  4260. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4261. }
  4262. if (isset($content['attribs']['']['fileSize']))
  4263. {
  4264. $length = ceil($content['attribs']['']['fileSize']);
  4265. }
  4266. if (isset($content['attribs']['']['medium']))
  4267. {
  4268. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  4269. }
  4270. if (isset($content['attribs']['']['samplingrate']))
  4271. {
  4272. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4273. }
  4274. if (isset($content['attribs']['']['type']))
  4275. {
  4276. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4277. }
  4278. if (isset($content['attribs']['']['width']))
  4279. {
  4280. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  4281. }
  4282. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4283. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  4284. // CAPTIONS
  4285. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4286. {
  4287. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4288. {
  4289. $caption_type = null;
  4290. $caption_lang = null;
  4291. $caption_startTime = null;
  4292. $caption_endTime = null;
  4293. $caption_text = null;
  4294. if (isset($caption['attribs']['']['type']))
  4295. {
  4296. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4297. }
  4298. if (isset($caption['attribs']['']['lang']))
  4299. {
  4300. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4301. }
  4302. if (isset($caption['attribs']['']['start']))
  4303. {
  4304. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4305. }
  4306. if (isset($caption['attribs']['']['end']))
  4307. {
  4308. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4309. }
  4310. if (isset($caption['data']))
  4311. {
  4312. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4313. }
  4314. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4315. }
  4316. if (is_array($captions))
  4317. {
  4318. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4319. }
  4320. }
  4321. else
  4322. {
  4323. $captions = $captions_parent;
  4324. }
  4325. // CATEGORIES
  4326. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4327. {
  4328. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4329. {
  4330. $term = null;
  4331. $scheme = null;
  4332. $label = null;
  4333. if (isset($category['data']))
  4334. {
  4335. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4336. }
  4337. if (isset($category['attribs']['']['scheme']))
  4338. {
  4339. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4340. }
  4341. else
  4342. {
  4343. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4344. }
  4345. if (isset($category['attribs']['']['label']))
  4346. {
  4347. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4348. }
  4349. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4350. }
  4351. }
  4352. if (is_array($categories) && is_array($categories_parent))
  4353. {
  4354. $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
  4355. }
  4356. elseif (is_array($categories))
  4357. {
  4358. $categories = array_values(SimplePie_Misc::array_unique($categories));
  4359. }
  4360. elseif (is_array($categories_parent))
  4361. {
  4362. $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
  4363. }
  4364. else
  4365. {
  4366. $categories = null;
  4367. }
  4368. // COPYRIGHTS
  4369. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4370. {
  4371. $copyright_url = null;
  4372. $copyright_label = null;
  4373. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4374. {
  4375. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4376. }
  4377. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4378. {
  4379. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4380. }
  4381. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4382. }
  4383. else
  4384. {
  4385. $copyrights = $copyrights_parent;
  4386. }
  4387. // CREDITS
  4388. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4389. {
  4390. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4391. {
  4392. $credit_role = null;
  4393. $credit_scheme = null;
  4394. $credit_name = null;
  4395. if (isset($credit['attribs']['']['role']))
  4396. {
  4397. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4398. }
  4399. if (isset($credit['attribs']['']['scheme']))
  4400. {
  4401. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4402. }
  4403. else
  4404. {
  4405. $credit_scheme = 'urn:ebu';
  4406. }
  4407. if (isset($credit['data']))
  4408. {
  4409. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4410. }
  4411. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4412. }
  4413. if (is_array($credits))
  4414. {
  4415. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4416. }
  4417. }
  4418. else
  4419. {
  4420. $credits = $credits_parent;
  4421. }
  4422. // DESCRIPTION
  4423. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4424. {
  4425. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4426. }
  4427. else
  4428. {
  4429. $description = $description_parent;
  4430. }
  4431. // HASHES
  4432. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4433. {
  4434. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4435. {
  4436. $value = null;
  4437. $algo = null;
  4438. if (isset($hash['data']))
  4439. {
  4440. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4441. }
  4442. if (isset($hash['attribs']['']['algo']))
  4443. {
  4444. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4445. }
  4446. else
  4447. {
  4448. $algo = 'md5';
  4449. }
  4450. $hashes[] = $algo.':'.$value;
  4451. }
  4452. if (is_array($hashes))
  4453. {
  4454. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4455. }
  4456. }
  4457. else
  4458. {
  4459. $hashes = $hashes_parent;
  4460. }
  4461. // KEYWORDS
  4462. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4463. {
  4464. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4465. {
  4466. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4467. foreach ($temp as $word)
  4468. {
  4469. $keywords[] = trim($word);
  4470. }
  4471. unset($temp);
  4472. }
  4473. if (is_array($keywords))
  4474. {
  4475. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4476. }
  4477. }
  4478. else
  4479. {
  4480. $keywords = $keywords_parent;
  4481. }
  4482. // PLAYER
  4483. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4484. {
  4485. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4486. }
  4487. else
  4488. {
  4489. $player = $player_parent;
  4490. }
  4491. // RATINGS
  4492. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4493. {
  4494. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4495. {
  4496. $rating_scheme = null;
  4497. $rating_value = null;
  4498. if (isset($rating['attribs']['']['scheme']))
  4499. {
  4500. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4501. }
  4502. else
  4503. {
  4504. $rating_scheme = 'urn:simple';
  4505. }
  4506. if (isset($rating['data']))
  4507. {
  4508. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4509. }
  4510. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4511. }
  4512. if (is_array($ratings))
  4513. {
  4514. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4515. }
  4516. }
  4517. else
  4518. {
  4519. $ratings = $ratings_parent;
  4520. }
  4521. // RESTRICTIONS
  4522. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4523. {
  4524. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4525. {
  4526. $restriction_relationship = null;
  4527. $restriction_type = null;
  4528. $restriction_value = null;
  4529. if (isset($restriction['attribs']['']['relationship']))
  4530. {
  4531. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4532. }
  4533. if (isset($restriction['attribs']['']['type']))
  4534. {
  4535. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4536. }
  4537. if (isset($restriction['data']))
  4538. {
  4539. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4540. }
  4541. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4542. }
  4543. if (is_array($restrictions))
  4544. {
  4545. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4546. }
  4547. }
  4548. else
  4549. {
  4550. $restrictions = $restrictions_parent;
  4551. }
  4552. // THUMBNAILS
  4553. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4554. {
  4555. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4556. {
  4557. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4558. }
  4559. if (is_array($thumbnails))
  4560. {
  4561. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4562. }
  4563. }
  4564. else
  4565. {
  4566. $thumbnails = $thumbnails_parent;
  4567. }
  4568. // TITLES
  4569. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4570. {
  4571. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4572. }
  4573. else
  4574. {
  4575. $title = $title_parent;
  4576. }
  4577. $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);
  4578. }
  4579. }
  4580. }
  4581. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  4582. {
  4583. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
  4584. {
  4585. // Attributes
  4586. $bitrate = null;
  4587. $channels = null;
  4588. $duration = null;
  4589. $expression = null;
  4590. $framerate = null;
  4591. $height = null;
  4592. $javascript = null;
  4593. $lang = null;
  4594. $length = null;
  4595. $medium = null;
  4596. $samplingrate = null;
  4597. $type = null;
  4598. $url = null;
  4599. $width = null;
  4600. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  4601. if (isset($link['attribs']['']['type']))
  4602. {
  4603. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4604. }
  4605. if (isset($link['attribs']['']['length']))
  4606. {
  4607. $length = ceil($link['attribs']['']['length']);
  4608. }
  4609. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  4610. $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);
  4611. }
  4612. }
  4613. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  4614. {
  4615. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
  4616. {
  4617. // Attributes
  4618. $bitrate = null;
  4619. $channels = null;
  4620. $duration = null;
  4621. $expression = null;
  4622. $framerate = null;
  4623. $height = null;
  4624. $javascript = null;
  4625. $lang = null;
  4626. $length = null;
  4627. $medium = null;
  4628. $samplingrate = null;
  4629. $type = null;
  4630. $url = null;
  4631. $width = null;
  4632. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  4633. if (isset($link['attribs']['']['type']))
  4634. {
  4635. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4636. }
  4637. if (isset($link['attribs']['']['length']))
  4638. {
  4639. $length = ceil($link['attribs']['']['length']);
  4640. }
  4641. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  4642. $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);
  4643. }
  4644. }
  4645. if ($enclosure = $this->get_item_tags('', 'enclosure'))
  4646. {
  4647. if (isset($enclosure[0]['attribs']['']['url']))
  4648. {
  4649. // Attributes
  4650. $bitrate = null;
  4651. $channels = null;
  4652. $duration = null;
  4653. $expression = null;
  4654. $framerate = null;
  4655. $height = null;
  4656. $javascript = null;
  4657. $lang = null;
  4658. $length = null;
  4659. $medium = null;
  4660. $samplingrate = null;
  4661. $type = null;
  4662. $url = null;
  4663. $width = null;
  4664. $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
  4665. if (isset($enclosure[0]['attribs']['']['type']))
  4666. {
  4667. $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4668. }
  4669. if (isset($enclosure[0]['attribs']['']['length']))
  4670. {
  4671. $length = ceil($enclosure[0]['attribs']['']['length']);
  4672. }
  4673. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  4674. $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);
  4675. }
  4676. }
  4677. $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
  4678. }
  4679. if (!empty($this->data['enclosures']))
  4680. {
  4681. return $this->data['enclosures'];
  4682. }
  4683. else
  4684. {
  4685. return null;
  4686. }
  4687. }
  4688. function get_latitude()
  4689. {
  4690. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  4691. {
  4692. return (float) $return[0]['data'];
  4693. }
  4694. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  4695. {
  4696. return (float) $match[1];
  4697. }
  4698. else
  4699. {
  4700. return null;
  4701. }
  4702. }
  4703. function get_longitude()
  4704. {
  4705. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  4706. {
  4707. return (float) $return[0]['data'];
  4708. }
  4709. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  4710. {
  4711. return (float) $return[0]['data'];
  4712. }
  4713. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  4714. {
  4715. return (float) $match[2];
  4716. }
  4717. else
  4718. {
  4719. return null;
  4720. }
  4721. }
  4722. /**
  4723. * Creates the add_to_* methods' return data
  4724. *
  4725. * @access private
  4726. * @param string $item_url String to prefix to the item permalink
  4727. * @param string $title_url String to prefix to the item title
  4728. * (and suffix to the item permalink)
  4729. * @return mixed URL if feed exists, false otherwise
  4730. */
  4731. function add_to_service($item_url, $title_url = null)
  4732. {
  4733. if ($this->get_permalink() !== null)
  4734. {
  4735. $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
  4736. if ($title_url !== null && $this->get_title() !== null)
  4737. {
  4738. $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
  4739. }
  4740. return $return;
  4741. }
  4742. else
  4743. {
  4744. return null;
  4745. }
  4746. }
  4747. function add_to_blinklist()
  4748. {
  4749. return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
  4750. }
  4751. function add_to_blogmarks()
  4752. {
  4753. return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
  4754. }
  4755. function add_to_delicious()
  4756. {
  4757. return $this->add_to_service('http://del.icio.us/post/?v=3&url=', '&title=');
  4758. }
  4759. function add_to_digg()
  4760. {
  4761. return $this->add_to_service('http://digg.com/submit?phase=2&URL=');
  4762. }
  4763. function add_to_furl()
  4764. {
  4765. return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
  4766. }
  4767. function add_to_magnolia()
  4768. {
  4769. return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
  4770. }
  4771. function add_to_myweb20()
  4772. {
  4773. return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
  4774. }
  4775. function add_to_newsvine()
  4776. {
  4777. return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
  4778. }
  4779. function add_to_reddit()
  4780. {
  4781. return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
  4782. }
  4783. function add_to_segnalo()
  4784. {
  4785. return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
  4786. }
  4787. function add_to_simpy()
  4788. {
  4789. return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
  4790. }
  4791. function add_to_spurl()
  4792. {
  4793. return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
  4794. }
  4795. function add_to_wists()
  4796. {
  4797. return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
  4798. }
  4799. function search_technorati()
  4800. {
  4801. return $this->add_to_service('http://www.technorati.com/search/');
  4802. }
  4803. }
  4804. class SimplePie_Author
  4805. {
  4806. var $name;
  4807. var $link;
  4808. var $email;
  4809. // Constructor, used to input the data
  4810. function SimplePie_Author($name = null, $link = null, $email = null)
  4811. {
  4812. $this->name = $name;
  4813. $this->link = $link;
  4814. $this->email = $email;
  4815. }
  4816. function __toString()
  4817. {
  4818. // There is no $this->data here
  4819. return md5(serialize($this));
  4820. }
  4821. function get_name()
  4822. {
  4823. if ($this->name !== null)
  4824. {
  4825. return $this->name;
  4826. }
  4827. else
  4828. {
  4829. return null;
  4830. }
  4831. }
  4832. function get_link()
  4833. {
  4834. if ($this->link !== null)
  4835. {
  4836. return $this->link;
  4837. }
  4838. else
  4839. {
  4840. return null;
  4841. }
  4842. }
  4843. function get_email()
  4844. {
  4845. if ($this->email !== null)
  4846. {
  4847. return $this->email;
  4848. }
  4849. else
  4850. {
  4851. return null;
  4852. }
  4853. }
  4854. }
  4855. class SimplePie_Category
  4856. {
  4857. var $term;
  4858. var $scheme;
  4859. var $label;
  4860. // Constructor, used to input the data
  4861. function SimplePie_Category($term = null, $scheme = null, $label = null)
  4862. {
  4863. $this->term = $term;
  4864. $this->scheme = $scheme;
  4865. $this->label = $label;
  4866. }
  4867. function __toString()
  4868. {
  4869. // There is no $this->data here
  4870. return md5(serialize($this));
  4871. }
  4872. function get_term()
  4873. {
  4874. if ($this->term !== null)
  4875. {
  4876. return $this->term;
  4877. }
  4878. else
  4879. {
  4880. return null;
  4881. }
  4882. }
  4883. function get_scheme()
  4884. {
  4885. if ($this->scheme !== null)
  4886. {
  4887. return $this->scheme;
  4888. }
  4889. else
  4890. {
  4891. return null;
  4892. }
  4893. }
  4894. function get_label()
  4895. {
  4896. if ($this->label !== null)
  4897. {
  4898. return $this->label;
  4899. }
  4900. else
  4901. {
  4902. return $this->get_term();
  4903. }
  4904. }
  4905. }
  4906. class SimplePie_Enclosure
  4907. {
  4908. var $bitrate;
  4909. var $captions;
  4910. var $categories;
  4911. var $channels;
  4912. var $copyright;
  4913. var $credits;
  4914. var $description;
  4915. var $duration;
  4916. var $expression;
  4917. var $framerate;
  4918. var $handler;
  4919. var $hashes;
  4920. var $height;
  4921. var $javascript;
  4922. var $keywords;
  4923. var $lang;
  4924. var $length;
  4925. var $link;
  4926. var $medium;
  4927. var $player;
  4928. var $ratings;
  4929. var $restrictions;
  4930. var $samplingrate;
  4931. var $thumbnails;
  4932. var $title;
  4933. var $type;
  4934. var $width;
  4935. // Constructor, used to input the data
  4936. 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)
  4937. {
  4938. $this->bitrate = $bitrate;
  4939. $this->captions = $captions;
  4940. $this->categories = $categories;
  4941. $this->channels = $channels;
  4942. $this->copyright = $copyright;
  4943. $this->credits = $credits;
  4944. $this->description = $description;
  4945. $this->duration = $duration;
  4946. $this->expression = $expression;
  4947. $this->framerate = $framerate;
  4948. $this->hashes = $hashes;
  4949. $this->height = $height;
  4950. $this->javascript = $javascript;
  4951. $this->keywords = $keywords;
  4952. $this->lang = $lang;
  4953. $this->length = $length;
  4954. $this->link = $link;
  4955. $this->medium = $medium;
  4956. $this->player = $player;
  4957. $this->ratings = $ratings;
  4958. $this->restrictions = $restrictions;
  4959. $this->samplingrate = $samplingrate;
  4960. $this->thumbnails = $thumbnails;
  4961. $this->title = $title;
  4962. $this->type = $type;
  4963. $this->width = $width;
  4964. if (class_exists('idna_convert'))
  4965. {
  4966. $idn =& new idna_convert;
  4967. $parsed = SimplePie_Misc::parse_url($link);
  4968. $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  4969. }
  4970. $this->handler = $this->get_handler(); // Needs to load last
  4971. }
  4972. function __toString()
  4973. {
  4974. // There is no $this->data here
  4975. return md5(serialize($this));
  4976. }
  4977. function get_bitrate()
  4978. {
  4979. if ($this->bitrate !== null)
  4980. {
  4981. return $this->bitrate;
  4982. }
  4983. else
  4984. {
  4985. return null;
  4986. }
  4987. }
  4988. function get_caption($key = 0)
  4989. {
  4990. $captions = $this->get_captions();
  4991. if (isset($captions[$key]))
  4992. {
  4993. return $captions[$key];
  4994. }
  4995. else
  4996. {
  4997. return null;
  4998. }
  4999. }
  5000. function get_captions()
  5001. {
  5002. if ($this->captions !== null)
  5003. {
  5004. return $this->captions;
  5005. }
  5006. else
  5007. {
  5008. return null;
  5009. }
  5010. }
  5011. function get_category($key = 0)
  5012. {
  5013. $categories = $this->get_categories();
  5014. if (isset($categories[$key]))
  5015. {
  5016. return $categories[$key];
  5017. }
  5018. else
  5019. {
  5020. return null;
  5021. }
  5022. }
  5023. function get_categories()
  5024. {
  5025. if ($this->categories !== null)
  5026. {
  5027. return $this->categories;
  5028. }
  5029. else
  5030. {
  5031. return null;
  5032. }
  5033. }
  5034. function get_channels()
  5035. {
  5036. if ($this->channels !== null)
  5037. {
  5038. return $this->channels;
  5039. }
  5040. else
  5041. {
  5042. return null;
  5043. }
  5044. }
  5045. function get_copyright()
  5046. {
  5047. if ($this->copyright !== null)
  5048. {
  5049. return $this->copyright;
  5050. }
  5051. else
  5052. {
  5053. return null;
  5054. }
  5055. }
  5056. function get_credit($key = 0)
  5057. {
  5058. $credits = $this->get_credits();
  5059. if (isset($credits[$key]))
  5060. {
  5061. return $credits[$key];
  5062. }
  5063. else
  5064. {
  5065. return null;
  5066. }
  5067. }
  5068. function get_credits()
  5069. {
  5070. if ($this->credits !== null)
  5071. {
  5072. return $this->credits;
  5073. }
  5074. else
  5075. {
  5076. return null;
  5077. }
  5078. }
  5079. function get_description()
  5080. {
  5081. if ($this->description !== null)
  5082. {
  5083. return $this->description;
  5084. }
  5085. else
  5086. {
  5087. return null;
  5088. }
  5089. }
  5090. function get_duration($convert = false)
  5091. {
  5092. if ($this->duration !== null)
  5093. {
  5094. if ($convert)
  5095. {
  5096. $time = SimplePie_Misc::time_hms($this->duration);
  5097. return $time;
  5098. }
  5099. else
  5100. {
  5101. return $this->duration;
  5102. }
  5103. }
  5104. else
  5105. {
  5106. return null;
  5107. }
  5108. }
  5109. function get_expression()
  5110. {
  5111. if ($this->expression !== null)
  5112. {
  5113. return $this->expression;
  5114. }
  5115. else
  5116. {
  5117. return 'full';
  5118. }
  5119. }
  5120. function get_extension()
  5121. {
  5122. if ($this->link !== null)
  5123. {
  5124. $url = SimplePie_Misc::parse_url($this->link);
  5125. if ($url['path'] !== '')
  5126. {
  5127. return pathinfo($url['path'], PATHINFO_EXTENSION);
  5128. }
  5129. }
  5130. return null;
  5131. }
  5132. function get_framerate()
  5133. {
  5134. if ($this->framerate !== null)
  5135. {
  5136. return $this->framerate;
  5137. }
  5138. else
  5139. {
  5140. return null;
  5141. }
  5142. }
  5143. function get_handler()
  5144. {
  5145. return $this->get_real_type(true);
  5146. }
  5147. function get_hash($key = 0)
  5148. {
  5149. $hashes = $this->get_hashes();
  5150. if (isset($hashes[$key]))
  5151. {
  5152. return $hashes[$key];
  5153. }
  5154. else
  5155. {
  5156. return null;
  5157. }
  5158. }
  5159. function get_hashes()
  5160. {
  5161. if ($this->hashes !== null)
  5162. {
  5163. return $this->hashes;
  5164. }
  5165. else
  5166. {
  5167. return null;
  5168. }
  5169. }
  5170. function get_height()
  5171. {
  5172. if ($this->height !== null)
  5173. {
  5174. return $this->height;
  5175. }
  5176. else
  5177. {
  5178. return null;
  5179. }
  5180. }
  5181. function get_language()
  5182. {
  5183. if ($this->lang !== null)
  5184. {
  5185. return $this->lang;
  5186. }
  5187. else
  5188. {
  5189. return null;
  5190. }
  5191. }
  5192. function get_keyword($key = 0)
  5193. {
  5194. $keywords = $this->get_keywords();
  5195. if (isset($keywords[$key]))
  5196. {
  5197. return $keywords[$key];
  5198. }
  5199. else
  5200. {
  5201. return null;
  5202. }
  5203. }
  5204. function get_keywords()
  5205. {
  5206. if ($this->keywords !== null)
  5207. {
  5208. return $this->keywords;
  5209. }
  5210. else
  5211. {
  5212. return null;
  5213. }
  5214. }
  5215. function get_length()
  5216. {
  5217. if ($this->length !== null)
  5218. {
  5219. return $this->length;
  5220. }
  5221. else
  5222. {
  5223. return null;
  5224. }
  5225. }
  5226. function get_link()
  5227. {
  5228. if ($this->link !== null)
  5229. {
  5230. return urldecode($this->link);
  5231. }
  5232. else
  5233. {
  5234. return null;
  5235. }
  5236. }
  5237. function get_medium()
  5238. {
  5239. if ($this->medium !== null)
  5240. {
  5241. return $this->medium;
  5242. }
  5243. else
  5244. {
  5245. return null;
  5246. }
  5247. }
  5248. function get_player()
  5249. {
  5250. if ($this->player !== null)
  5251. {
  5252. return $this->player;
  5253. }
  5254. else
  5255. {
  5256. return null;
  5257. }
  5258. }
  5259. function get_rating($key = 0)
  5260. {
  5261. $ratings = $this->get_ratings();
  5262. if (isset($ratings[$key]))
  5263. {
  5264. return $ratings[$key];
  5265. }
  5266. else
  5267. {
  5268. return null;
  5269. }
  5270. }
  5271. function get_ratings()
  5272. {
  5273. if ($this->ratings !== null)
  5274. {
  5275. return $this->ratings;
  5276. }
  5277. else
  5278. {
  5279. return null;
  5280. }
  5281. }
  5282. function get_restriction($key = 0)
  5283. {
  5284. $restrictions = $this->get_restrictions();
  5285. if (isset($restrictions[$key]))
  5286. {
  5287. return $restrictions[$key];
  5288. }
  5289. else
  5290. {
  5291. return null;
  5292. }
  5293. }
  5294. function get_restrictions()
  5295. {
  5296. if ($this->restrictions !== null)
  5297. {
  5298. return $this->restrictions;
  5299. }
  5300. else
  5301. {
  5302. return null;
  5303. }
  5304. }
  5305. function get_sampling_rate()
  5306. {
  5307. if ($this->samplingrate !== null)
  5308. {
  5309. return $this->samplingrate;
  5310. }
  5311. else
  5312. {
  5313. return null;
  5314. }
  5315. }
  5316. function get_size()
  5317. {
  5318. $length = $this->get_length();
  5319. if ($length !== null)
  5320. {
  5321. return round($length/1048576, 2);
  5322. }
  5323. else
  5324. {
  5325. return null;
  5326. }
  5327. }
  5328. function get_thumbnail($key = 0)
  5329. {
  5330. $thumbnails = $this->get_thumbnails();
  5331. if (isset($thumbnails[$key]))
  5332. {
  5333. return $thumbnails[$key];
  5334. }
  5335. else
  5336. {
  5337. return null;
  5338. }
  5339. }
  5340. function get_thumbnails()
  5341. {
  5342. if ($this->thumbnails !== null)
  5343. {
  5344. return $this->thumbnails;
  5345. }
  5346. else
  5347. {
  5348. return null;
  5349. }
  5350. }
  5351. function get_title()
  5352. {
  5353. if ($this->title !== null)
  5354. {
  5355. return $this->title;
  5356. }
  5357. else
  5358. {
  5359. return null;
  5360. }
  5361. }
  5362. function get_type()
  5363. {
  5364. if ($this->type !== null)
  5365. {
  5366. return $this->type;
  5367. }
  5368. else
  5369. {
  5370. return null;
  5371. }
  5372. }
  5373. function get_width()
  5374. {
  5375. if ($this->width !== null)
  5376. {
  5377. return $this->width;
  5378. }
  5379. else
  5380. {
  5381. return null;
  5382. }
  5383. }
  5384. function native_embed($options='')
  5385. {
  5386. return $this->embed($options, true);
  5387. }
  5388. /**
  5389. * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
  5390. */
  5391. function embed($options = '', $native = false)
  5392. {
  5393. // Set up defaults
  5394. $audio = '';
  5395. $video = '';
  5396. $alt = '';
  5397. $altclass = '';
  5398. $loop = 'false';
  5399. $width = 'auto';
  5400. $height = 'auto';
  5401. $bgcolor = '#ffffff';
  5402. $mediaplayer = '';
  5403. $widescreen = false;
  5404. $handler = $this->get_handler();
  5405. $type = $this->get_real_type();
  5406. // Process options and reassign values as necessary
  5407. if (is_array($options))
  5408. {
  5409. extract($options);
  5410. }
  5411. else
  5412. {
  5413. $options = explode(',', $options);
  5414. foreach($options as $option)
  5415. {
  5416. $opt = explode(':', $option, 2);
  5417. if (isset($opt[0], $opt[1]))
  5418. {
  5419. $opt[0] = trim($opt[0]);
  5420. $opt[1] = trim($opt[1]);
  5421. switch ($opt[0])
  5422. {
  5423. case 'audio':
  5424. $audio = $opt[1];
  5425. break;
  5426. case 'video':
  5427. $video = $opt[1];
  5428. break;
  5429. case 'alt':
  5430. $alt = $opt[1];
  5431. break;
  5432. case 'altclass':
  5433. $altclass = $opt[1];
  5434. break;
  5435. case 'loop':
  5436. $loop = $opt[1];
  5437. break;
  5438. case 'width':
  5439. $width = $opt[1];
  5440. break;
  5441. case 'height':
  5442. $height = $opt[1];
  5443. break;
  5444. case 'bgcolor':
  5445. $bgcolor = $opt[1];
  5446. break;
  5447. case 'mediaplayer':
  5448. $mediaplayer = $opt[1];
  5449. break;
  5450. case 'widescreen':
  5451. $widescreen = $opt[1];
  5452. break;
  5453. }
  5454. }
  5455. }
  5456. }
  5457. $mime = explode('/', $type, 2);
  5458. $mime = $mime[0];
  5459. // Process values for 'auto'
  5460. if ($width == 'auto')
  5461. {
  5462. if ($mime == 'video')
  5463. {
  5464. if ($height == 'auto')
  5465. {
  5466. $width = 480;
  5467. }
  5468. elseif ($widescreen)
  5469. {
  5470. $width = round((intval($height)/9)*16);
  5471. }
  5472. else
  5473. {
  5474. $width = round((intval($height)/3)*4);
  5475. }
  5476. }
  5477. else
  5478. {
  5479. $width = '100%';
  5480. }
  5481. }
  5482. if ($height == 'auto')
  5483. {
  5484. if ($mime == 'audio')
  5485. {
  5486. $height = 0;
  5487. }
  5488. elseif ($mime == 'video')
  5489. {
  5490. if ($width == 'auto')
  5491. {
  5492. if ($widescreen)
  5493. {
  5494. $height = 270;
  5495. }
  5496. else
  5497. {
  5498. $height = 360;
  5499. }
  5500. }
  5501. elseif ($widescreen)
  5502. {
  5503. $height = round((intval($width)/16)*9);
  5504. }
  5505. else
  5506. {
  5507. $height = round((intval($width)/4)*3);
  5508. }
  5509. }
  5510. else
  5511. {
  5512. $height = 376;
  5513. }
  5514. }
  5515. elseif ($mime == 'audio')
  5516. {
  5517. $height = 0;
  5518. }
  5519. // Set proper placeholder value
  5520. if ($mime == 'audio')
  5521. {
  5522. $placeholder = $audio;
  5523. }
  5524. elseif ($mime == 'video')
  5525. {
  5526. $placeholder = $video;
  5527. }
  5528. $embed = '';
  5529. // Make sure the JS library is included
  5530. if (!$native)
  5531. {
  5532. static $javascript_outputted = null;
  5533. if (!$javascript_outputted && $this->javascript)
  5534. {
  5535. $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
  5536. $javascript_outputted = true;
  5537. }
  5538. }
  5539. // Odeo Feed MP3's
  5540. if ($handler == 'odeo')
  5541. {
  5542. if ($native)
  5543. {
  5544. $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>';
  5545. }
  5546. else
  5547. {
  5548. $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
  5549. }
  5550. }
  5551. // Flash
  5552. elseif ($handler == 'flash')
  5553. {
  5554. if ($native)
  5555. {
  5556. $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>";
  5557. }
  5558. else
  5559. {
  5560. $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
  5561. }
  5562. }
  5563. // Flash Media Player file types.
  5564. // Preferred handler for MP3 file types.
  5565. elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
  5566. {
  5567. $height += 20;
  5568. if ($native)
  5569. {
  5570. $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>";
  5571. }
  5572. else
  5573. {
  5574. $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
  5575. }
  5576. }
  5577. // QuickTime 7 file types. Need to test with QuickTime 6.
  5578. // Only handle MP3's if the Flash Media Player is not present.
  5579. elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
  5580. {
  5581. $height += 16;
  5582. if ($native)
  5583. {
  5584. if ($placeholder != ""){
  5585. $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>";
  5586. }
  5587. else {
  5588. $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>";
  5589. }
  5590. }
  5591. else
  5592. {
  5593. $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
  5594. }
  5595. }
  5596. // Windows Media
  5597. elseif ($handler == 'wmedia')
  5598. {
  5599. $height += 45;
  5600. if ($native)
  5601. {
  5602. $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>";
  5603. }
  5604. else
  5605. {
  5606. $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
  5607. }
  5608. }
  5609. // Everything else
  5610. else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
  5611. return $embed;
  5612. }
  5613. function get_real_type($find_handler = false)
  5614. {
  5615. // If it's Odeo, let's get it out of the way.
  5616. if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
  5617. {
  5618. return 'odeo';
  5619. }
  5620. // Mime-types by handler.
  5621. $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
  5622. $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
  5623. $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
  5624. $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
  5625. $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
  5626. if ($this->get_type() !== null)
  5627. {
  5628. $type = strtolower($this->type);
  5629. }
  5630. else
  5631. {
  5632. $type = null;
  5633. }
  5634. // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
  5635. if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
  5636. {
  5637. switch (strtolower($this->get_extension()))
  5638. {
  5639. // Audio mime-types
  5640. case 'aac':
  5641. case 'adts':
  5642. $type = 'audio/acc';
  5643. break;
  5644. case 'aif':
  5645. case 'aifc':
  5646. case 'aiff':
  5647. case 'cdda':
  5648. $type = 'audio/aiff';
  5649. break;
  5650. case 'bwf':
  5651. $type = 'audio/wav';
  5652. break;
  5653. case 'kar':
  5654. case 'mid':
  5655. case 'midi':
  5656. case 'smf':
  5657. $type = 'audio/midi';
  5658. break;
  5659. case 'm4a':
  5660. $type = 'audio/x-m4a';
  5661. break;
  5662. case 'mp3':
  5663. case 'swa':
  5664. $type = 'audio/mp3';
  5665. break;
  5666. case 'wav':
  5667. $type = 'audio/wav';
  5668. break;
  5669. case 'wax':
  5670. $type = 'audio/x-ms-wax';
  5671. break;
  5672. case 'wma':
  5673. $type = 'audio/x-ms-wma';
  5674. break;
  5675. // Video mime-types
  5676. case '3gp':
  5677. case '3gpp':
  5678. $type = 'video/3gpp';
  5679. break;
  5680. case '3g2':
  5681. case '3gp2':
  5682. $type = 'video/3gpp2';
  5683. break;
  5684. case 'asf':
  5685. $type = 'video/x-ms-asf';
  5686. break;
  5687. case 'flv':
  5688. $type = 'video/x-flv';
  5689. break;
  5690. case 'm1a':
  5691. case 'm1s':
  5692. case 'm1v':
  5693. case 'm15':
  5694. case 'm75':
  5695. case 'mp2':
  5696. case 'mpa':
  5697. case 'mpeg':
  5698. case 'mpg':
  5699. case 'mpm':
  5700. case 'mpv':
  5701. $type = 'video/mpeg';
  5702. break;
  5703. case 'm4v':
  5704. $type = 'video/x-m4v';
  5705. break;
  5706. case 'mov':
  5707. case 'qt':
  5708. $type = 'video/quicktime';
  5709. break;
  5710. case 'mp4':
  5711. case 'mpg4':
  5712. $type = 'video/mp4';
  5713. break;
  5714. case 'sdv':
  5715. $type = 'video/sd-video';
  5716. break;
  5717. case 'wm':
  5718. $type = 'video/x-ms-wm';
  5719. break;
  5720. case 'wmv':
  5721. $type = 'video/x-ms-wmv';
  5722. break;
  5723. case 'wvx':
  5724. $type = 'video/x-ms-wvx';
  5725. break;
  5726. // Flash mime-types
  5727. case 'spl':
  5728. $type = 'application/futuresplash';
  5729. break;
  5730. case 'swf':
  5731. $type = 'application/x-shockwave-flash';
  5732. break;
  5733. }
  5734. }
  5735. if ($find_handler)
  5736. {
  5737. if (in_array($type, $types_flash))
  5738. {
  5739. return 'flash';
  5740. }
  5741. elseif (in_array($type, $types_fmedia))
  5742. {
  5743. return 'fmedia';
  5744. }
  5745. elseif (in_array($type, $types_quicktime))
  5746. {
  5747. return 'quicktime';
  5748. }
  5749. elseif (in_array($type, $types_wmedia))
  5750. {
  5751. return 'wmedia';
  5752. }
  5753. elseif (in_array($type, $types_mp3))
  5754. {
  5755. return 'mp3';
  5756. }
  5757. else
  5758. {
  5759. return null;
  5760. }
  5761. }
  5762. else
  5763. {
  5764. return $type;
  5765. }
  5766. }
  5767. }
  5768. class SimplePie_Caption
  5769. {
  5770. var $type;
  5771. var $lang;
  5772. var $startTime;
  5773. var $endTime;
  5774. var $text;
  5775. // Constructor, used to input the data
  5776. function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
  5777. {
  5778. $this->type = $type;
  5779. $this->lang = $lang;
  5780. $this->startTime = $startTime;
  5781. $this->endTime = $endTime;
  5782. $this->text = $text;
  5783. }
  5784. function __toString()
  5785. {
  5786. // There is no $this->data here
  5787. return md5(serialize($this));
  5788. }
  5789. function get_endtime()
  5790. {
  5791. if ($this->endTime !== null)
  5792. {
  5793. return $this->endTime;
  5794. }
  5795. else
  5796. {
  5797. return null;
  5798. }
  5799. }
  5800. function get_language()
  5801. {
  5802. if ($this->language !== null)
  5803. {
  5804. return $this->language;
  5805. }
  5806. else
  5807. {
  5808. return null;
  5809. }
  5810. }
  5811. function get_starttime()
  5812. {
  5813. if ($this->startTime !== null)
  5814. {
  5815. return $this->startTime;
  5816. }
  5817. else
  5818. {
  5819. return null;
  5820. }
  5821. }
  5822. function get_text()
  5823. {
  5824. if ($this->text !== null)
  5825. {
  5826. return $this->text;
  5827. }
  5828. else
  5829. {
  5830. return null;
  5831. }
  5832. }
  5833. function get_type()
  5834. {
  5835. if ($this->type !== null)
  5836. {
  5837. return $this->type;
  5838. }
  5839. else
  5840. {
  5841. return null;
  5842. }
  5843. }
  5844. }
  5845. class SimplePie_Credit
  5846. {
  5847. var $role;
  5848. var $scheme;
  5849. var $name;
  5850. // Constructor, used to input the data
  5851. function SimplePie_Credit($role = null, $scheme = null, $name = null)
  5852. {
  5853. $this->role = $role;
  5854. $this->scheme = $scheme;
  5855. $this->name = $name;
  5856. }
  5857. function __toString()
  5858. {
  5859. // There is no $this->data here
  5860. return md5(serialize($this));
  5861. }
  5862. function get_role()
  5863. {
  5864. if ($this->role !== null)
  5865. {
  5866. return $this->role;
  5867. }
  5868. else
  5869. {
  5870. return null;
  5871. }
  5872. }
  5873. function get_scheme()
  5874. {
  5875. if ($this->scheme !== null)
  5876. {
  5877. return $this->scheme;
  5878. }
  5879. else
  5880. {
  5881. return null;
  5882. }
  5883. }
  5884. function get_name()
  5885. {
  5886. if ($this->name !== null)
  5887. {
  5888. return $this->name;
  5889. }
  5890. else
  5891. {
  5892. return null;
  5893. }
  5894. }
  5895. }
  5896. class SimplePie_Copyright
  5897. {
  5898. var $url;
  5899. var $label;
  5900. // Constructor, used to input the data
  5901. function SimplePie_Copyright($url = null, $label = null)
  5902. {
  5903. $this->url = $url;
  5904. $this->label = $label;
  5905. }
  5906. function __toString()
  5907. {
  5908. // There is no $this->data here
  5909. return md5(serialize($this));
  5910. }
  5911. function get_url()
  5912. {
  5913. if ($this->url !== null)
  5914. {
  5915. return $this->url;
  5916. }
  5917. else
  5918. {
  5919. return null;
  5920. }
  5921. }
  5922. function get_attribution()
  5923. {
  5924. if ($this->label !== null)
  5925. {
  5926. return $this->label;
  5927. }
  5928. else
  5929. {
  5930. return null;
  5931. }
  5932. }
  5933. }
  5934. class SimplePie_Rating
  5935. {
  5936. var $scheme;
  5937. var $value;
  5938. // Constructor, used to input the data
  5939. function SimplePie_Rating($scheme = null, $value = null)
  5940. {
  5941. $this->scheme = $scheme;
  5942. $this->value = $value;
  5943. }
  5944. function __toString()
  5945. {
  5946. // There is no $this->data here
  5947. return md5(serialize($this));
  5948. }
  5949. function get_scheme()
  5950. {
  5951. if ($this->scheme !== null)
  5952. {
  5953. return $this->scheme;
  5954. }
  5955. else
  5956. {
  5957. return null;
  5958. }
  5959. }
  5960. function get_value()
  5961. {
  5962. if ($this->value !== null)
  5963. {
  5964. return $this->value;
  5965. }
  5966. else
  5967. {
  5968. return null;
  5969. }
  5970. }
  5971. }
  5972. class SimplePie_Restriction
  5973. {
  5974. var $relationship;
  5975. var $type;
  5976. var $value;
  5977. // Constructor, used to input the data
  5978. function SimplePie_Restriction($relationship = null, $type = null, $value = null)
  5979. {
  5980. $this->relationship = $relationship;
  5981. $this->type = $type;
  5982. $this->value = $value;
  5983. }
  5984. function __toString()
  5985. {
  5986. // There is no $this->data here
  5987. return md5(serialize($this));
  5988. }
  5989. function get_relationship()
  5990. {
  5991. if ($this->relationship !== null)
  5992. {
  5993. return $this->relationship;
  5994. }
  5995. else
  5996. {
  5997. return null;
  5998. }
  5999. }
  6000. function get_type()
  6001. {
  6002. if ($this->type !== null)
  6003. {
  6004. return $this->type;
  6005. }
  6006. else
  6007. {
  6008. return null;
  6009. }
  6010. }
  6011. function get_value()
  6012. {
  6013. if ($this->value !== null)
  6014. {
  6015. return $this->value;
  6016. }
  6017. else
  6018. {
  6019. return null;
  6020. }
  6021. }
  6022. }
  6023. /**
  6024. * @todo Move to properly supporting RFC2616 (HTTP/1.1)
  6025. */
  6026. class SimplePie_File
  6027. {
  6028. var $url;
  6029. var $useragent;
  6030. var $success = true;
  6031. var $headers = array();
  6032. var $body;
  6033. var $status_code;
  6034. var $redirects = 0;
  6035. var $error;
  6036. var $method;
  6037. function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
  6038. {
  6039. if (class_exists('idna_convert'))
  6040. {
  6041. $idn =& new idna_convert;
  6042. $parsed = SimplePie_Misc::parse_url($url);
  6043. $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  6044. }
  6045. $this->url = $url;
  6046. $this->useragent = $useragent;
  6047. if (preg_match('/^http(s)?:\/\//i', $url))
  6048. {
  6049. if ($useragent === null)
  6050. {
  6051. $useragent = ini_get('user_agent');
  6052. $this->useragent = $useragent;
  6053. }
  6054. if (!is_array($headers))
  6055. {
  6056. $headers = array();
  6057. }
  6058. if (!$force_fsockopen && extension_loaded('curl'))
  6059. {
  6060. $this->method = 'curl';
  6061. $fp = curl_init();
  6062. $headers2 = array();
  6063. foreach ($headers as $key => $value)
  6064. {
  6065. $headers2[] = "$key: $value";
  6066. }
  6067. if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
  6068. {
  6069. curl_setopt($fp, CURLOPT_ENCODING, '');
  6070. }
  6071. curl_setopt($fp, CURLOPT_URL, $url);
  6072. curl_setopt($fp, CURLOPT_HEADER, 1);
  6073. curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
  6074. curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
  6075. curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
  6076. curl_setopt($fp, CURLOPT_REFERER, $url);
  6077. curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
  6078. curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
  6079. if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
  6080. {
  6081. curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
  6082. curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
  6083. }
  6084. $this->headers = curl_exec($fp);
  6085. if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
  6086. {
  6087. curl_setopt($fp, CURLOPT_ENCODING, 'none');
  6088. $this->headers = curl_exec($fp);
  6089. }
  6090. if (curl_errno($fp))
  6091. {
  6092. $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
  6093. $this->success = false;
  6094. }
  6095. else
  6096. {
  6097. $info = curl_getinfo($fp);
  6098. curl_close($fp);
  6099. $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
  6100. $this->headers = array_pop($this->headers);
  6101. $parser =& new SimplePie_HTTP_Parser($this->headers);
  6102. if ($parser->parse())
  6103. {
  6104. $this->headers = $parser->headers;
  6105. $this->body = $parser->body;
  6106. $this->status_code = $parser->status_code;
  6107. if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  6108. {
  6109. $this->redirects++;
  6110. if (isset($this->headers['content-location']))
  6111. {
  6112. $location = SimplePie_Misc::absolutize_url($this->headers['location'], SimplePie_Misc::absolutize_url($this->headers['content-location'], $url));
  6113. }
  6114. else
  6115. {
  6116. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  6117. }
  6118. return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  6119. }
  6120. }
  6121. }
  6122. }
  6123. else
  6124. {
  6125. $this->method = 'fsockopen';
  6126. $url_parts = parse_url($url);
  6127. if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
  6128. {
  6129. $url_parts['host'] = "ssl://$url_parts[host]";
  6130. $url_parts['port'] = 443;
  6131. }
  6132. if (!isset($url_parts['port']))
  6133. {
  6134. $url_parts['port'] = 80;
  6135. }
  6136. $fp = fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
  6137. if (!$fp)
  6138. {
  6139. $this->error = 'fsockopen error: ' . $errstr;
  6140. $this->success = false;
  6141. }
  6142. else
  6143. {
  6144. if (function_exists('stream_set_timeout'))
  6145. {
  6146. stream_set_timeout($fp, $timeout);
  6147. }
  6148. else
  6149. {
  6150. socket_set_timeout($fp, $timeout);
  6151. }
  6152. if (isset($url_parts['path']))
  6153. {
  6154. if (isset($url_parts['query']))
  6155. {
  6156. $get = "$url_parts[path]?$url_parts[query]";
  6157. }
  6158. else
  6159. {
  6160. $get = $url_parts['path'];
  6161. }
  6162. }
  6163. else
  6164. {
  6165. $get = '/';
  6166. }
  6167. $out = "GET $get HTTP/1.0\r\n";
  6168. $out .= "Host: $url_parts[host]\r\n";
  6169. $out .= "User-Agent: $useragent\r\n";
  6170. if (function_exists('gzinflate'))
  6171. {
  6172. $out .= "Accept-Encoding: gzip,deflate\r\n";
  6173. }
  6174. if (isset($url_parts['user']) && isset($url_parts['pass']))
  6175. {
  6176. $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
  6177. }
  6178. foreach ($headers as $key => $value)
  6179. {
  6180. $out .= "$key: $value\r\n";
  6181. }
  6182. $out .= "Connection: Close\r\n\r\n";
  6183. fwrite($fp, $out);
  6184. if (function_exists('stream_get_meta_data'))
  6185. {
  6186. $info = stream_get_meta_data($fp);
  6187. }
  6188. else
  6189. {
  6190. $info = socket_get_status($fp);
  6191. }
  6192. $this->headers = '';
  6193. while (!$info['eof'] && !$info['timed_out'])
  6194. {
  6195. $this->headers .= fread($fp, 1160);
  6196. if (function_exists('stream_get_meta_data'))
  6197. {
  6198. $info = stream_get_meta_data($fp);
  6199. }
  6200. else
  6201. {
  6202. $info = socket_get_status($fp);
  6203. }
  6204. }
  6205. if (!$info['timed_out'])
  6206. {
  6207. $parser =& new SimplePie_HTTP_Parser($this->headers);
  6208. if ($parser->parse())
  6209. {
  6210. $this->headers = $parser->headers;
  6211. $this->body = $parser->body;
  6212. $this->status_code = $parser->status_code;
  6213. if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  6214. {
  6215. $this->redirects++;
  6216. if (isset($this->headers['content-location']))
  6217. {
  6218. $location = SimplePie_Misc::absolutize_url($this->headers['location'], SimplePie_Misc::absolutize_url($this->headers['content-location'], $url));
  6219. }
  6220. else
  6221. {
  6222. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  6223. }
  6224. return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  6225. }
  6226. if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
  6227. {
  6228. if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
  6229. {
  6230. $this->body = substr($this->body, 10);
  6231. }
  6232. $this->body = gzinflate($this->body);
  6233. }
  6234. }
  6235. }
  6236. else
  6237. {
  6238. $this->error = 'fsocket timed out';
  6239. $this->success = false;
  6240. }
  6241. fclose($fp);
  6242. }
  6243. }
  6244. }
  6245. elseif (function_exists('file_get_contents'))
  6246. {
  6247. $this->method = 'file_get_contents';
  6248. if (!$this->body = file_get_contents($url))
  6249. {
  6250. $this->error = 'file_get_contents could not read the file';
  6251. $this->success = false;
  6252. }
  6253. }
  6254. else
  6255. {
  6256. $this->method = 'fopen';
  6257. if (($fp = fopen($url, 'rb')) === false)
  6258. {
  6259. $this->error = 'failed to open stream: No such file or directory';
  6260. $this->success = false;
  6261. }
  6262. else
  6263. {
  6264. $this->body = '';
  6265. while (!feof($fp))
  6266. {
  6267. $this->body .= fread($fp, 8192);
  6268. }
  6269. fclose($fp);
  6270. }
  6271. }
  6272. }
  6273. }
  6274. /**
  6275. * HTTP Response Parser
  6276. *
  6277. * @package SimplePie
  6278. * @todo Support HTTP Requests
  6279. */
  6280. class SimplePie_HTTP_Parser
  6281. {
  6282. /**
  6283. * HTTP Version
  6284. *
  6285. * @access public
  6286. * @var string
  6287. */
  6288. var $http_version = '';
  6289. /**
  6290. * Status code
  6291. *
  6292. * @access public
  6293. * @var string
  6294. */
  6295. var $status_code = '';
  6296. /**
  6297. * Reason phrase
  6298. *
  6299. * @access public
  6300. * @var string
  6301. */
  6302. var $reason = '';
  6303. /**
  6304. * Key/value pairs of the headers
  6305. *
  6306. * @access public
  6307. * @var array
  6308. */
  6309. var $headers = array();
  6310. /**
  6311. * Body of the response
  6312. *
  6313. * @access public
  6314. * @var string
  6315. */
  6316. var $body = '';
  6317. /**
  6318. * Current state of the state machine
  6319. *
  6320. * @access private
  6321. * @var string
  6322. */
  6323. var $state = 'start';
  6324. /**
  6325. * Input data
  6326. *
  6327. * @access private
  6328. * @var string
  6329. */
  6330. var $data = '';
  6331. /**
  6332. * Input data length (to avoid calling strlen() everytime this is needed)
  6333. *
  6334. * @access private
  6335. * @var int
  6336. */
  6337. var $data_length = 0;
  6338. /**
  6339. * Current position of the pointer
  6340. *
  6341. * @access private
  6342. * @var int
  6343. */
  6344. var $position = 0;
  6345. /**
  6346. * Name of the hedaer currently being parsed
  6347. *
  6348. * @access private
  6349. * @var string
  6350. */
  6351. var $name = '';
  6352. /**
  6353. * Value of the hedaer currently being parsed
  6354. *
  6355. * @access private
  6356. * @var string
  6357. */
  6358. var $value = '';
  6359. /**
  6360. * Create an instance of the class with the input data
  6361. *
  6362. * @access public
  6363. * @param string $data Input data
  6364. */
  6365. function SimplePie_HTTP_Parser($data)
  6366. {
  6367. $this->data = $data;
  6368. $this->data_length = strlen($this->data);
  6369. }
  6370. /**
  6371. * Parse the input data
  6372. *
  6373. * @access public
  6374. * @return bool true on success, false on failure
  6375. */
  6376. function parse()
  6377. {
  6378. while ($this->state && $this->state != 'emit' && $this->has_data())
  6379. {
  6380. $state = $this->state;
  6381. $this->$state();
  6382. }
  6383. $this->data = '';
  6384. if ($this->state == 'emit')
  6385. {
  6386. return true;
  6387. }
  6388. else
  6389. {
  6390. $this->http_version = '';
  6391. $this->status_code = '';
  6392. $this->headers = array();
  6393. $this->body = '';
  6394. return false;
  6395. }
  6396. }
  6397. /**
  6398. * Check whether there is data beyond the pointer
  6399. *
  6400. * @access private
  6401. * @return bool true if there is further data, false if not
  6402. */
  6403. function has_data()
  6404. {
  6405. return (bool) ($this->position < $this->data_length);
  6406. }
  6407. /**
  6408. * See if the next character is LWS
  6409. *
  6410. * @access private
  6411. * @return bool true if the next character is LWS, false if not
  6412. */
  6413. function is_linear_whitespace()
  6414. {
  6415. return (bool) (strspn($this->data, "\x09\x20", $this->position, 1)
  6416. || (substr($this->data, $this->position, 2) == "\r\n" && strspn($this->data, "\x09\x20", $this->position + 2, 1))
  6417. || (strspn($this->data, "\r\n", $this->position, 1) && strspn($this->data, "\x09\x20", $this->position + 1, 1)));
  6418. }
  6419. /**
  6420. * The starting state of the state machine, see if the data is a response or request
  6421. *
  6422. * @access private
  6423. */
  6424. function start()
  6425. {
  6426. $this->state = 'http_version_response';
  6427. }
  6428. /**
  6429. * Parse an HTTP-version string
  6430. *
  6431. * @access private
  6432. */
  6433. function http_version()
  6434. {
  6435. if (preg_match('/^HTTP\/([0-9]+\.[0-9]+)/i', substr($this->data, $this->position, strcspn($this->data, "\r\n", $this->position)), $match))
  6436. {
  6437. $this->position += strlen($match[0]);
  6438. $this->http_version = $match[1];
  6439. return true;
  6440. }
  6441. else
  6442. {
  6443. return false;
  6444. }
  6445. }
  6446. /**
  6447. * Parse LWS, replacing consecutive characters with a single space
  6448. *
  6449. * @access private
  6450. */
  6451. function linear_whitespace()
  6452. {
  6453. do
  6454. {
  6455. if (substr($this->data, $this->position, 2) == "\r\n")
  6456. {
  6457. $this->position += 2;
  6458. }
  6459. elseif (strspn($this->data, "\r\n", $this->position, 1))
  6460. {
  6461. $this->position++;
  6462. }
  6463. $this->position += strspn($this->data, "\x09\x20", $this->position);
  6464. } while ($this->is_linear_whitespace());
  6465. $this->value .= "\x20";
  6466. }
  6467. /**
  6468. * Parse an HTTP-version string within a response
  6469. *
  6470. * @access private
  6471. */
  6472. function http_version_response()
  6473. {
  6474. if ($this->http_version() && $this->data[$this->position] == "\x20")
  6475. {
  6476. $this->state = 'status_code';
  6477. $this->position++;
  6478. }
  6479. else
  6480. {
  6481. $this->state = false;
  6482. }
  6483. }
  6484. /**
  6485. * Parse a status code
  6486. *
  6487. * @access private
  6488. */
  6489. function status_code()
  6490. {
  6491. if (strspn($this->data, '1234567890', $this->position, 3) == 3)
  6492. {
  6493. $this->status_code = substr($this->data, $this->position, 3);
  6494. $this->state = 'reason_phrase';
  6495. $this->position += 3;
  6496. }
  6497. else
  6498. {
  6499. $this->state = false;
  6500. }
  6501. }
  6502. /**
  6503. * Skip over the reason phrase (it has no normative value, and you can send absolutely anything here)
  6504. *
  6505. * @access private
  6506. */
  6507. function reason_phrase()
  6508. {
  6509. $len = strcspn($this->data, "\r\n", $this->position);
  6510. $this->reason = substr($this->data, $this->position, $len);
  6511. $this->position += $len;
  6512. if ($this->has_data())
  6513. {
  6514. if (substr($this->data, $this->position, 2) == "\r\n")
  6515. {
  6516. $this->position += 2;
  6517. }
  6518. elseif (strspn($this->data, "\r\n", $this->position, 1))
  6519. {
  6520. $this->position++;
  6521. }
  6522. $this->state = 'name';
  6523. }
  6524. }
  6525. /**
  6526. * Parse a header name
  6527. *
  6528. * @access private
  6529. */
  6530. function name()
  6531. {
  6532. $len = strcspn($this->data, ':', $this->position);
  6533. $this->name = substr($this->data, $this->position, $len);
  6534. $this->position += $len;
  6535. if ($this->has_data() && $this->data[$this->position] == ':')
  6536. {
  6537. $this->state = 'value_next';
  6538. $this->position++;
  6539. }
  6540. else
  6541. {
  6542. $this->state = false;
  6543. }
  6544. }
  6545. /**
  6546. * See what state to move the state machine to while within non-quoted header values
  6547. *
  6548. * @access private
  6549. */
  6550. function value_next()
  6551. {
  6552. if ($this->is_linear_whitespace())
  6553. {
  6554. $this->state = 'value_linear_whitespace';
  6555. }
  6556. elseif ($this->data[$this->position] == '"')
  6557. {
  6558. $this->state = 'value_quote_next';
  6559. $this->position++;
  6560. }
  6561. elseif (substr($this->data, $this->position, 2) == "\r\n")
  6562. {
  6563. $this->state = 'end_crlf';
  6564. $this->position += 2;
  6565. }
  6566. elseif (strspn($this->data, "\r\n", $this->position, 1))
  6567. {
  6568. $this->state = 'end_crlf';
  6569. $this->position++;
  6570. }
  6571. else
  6572. {
  6573. $this->state = 'value_no_quote';
  6574. }
  6575. }
  6576. /**
  6577. * Parse a header value while outside quotes
  6578. *
  6579. * @access private
  6580. */
  6581. function value_no_quote()
  6582. {
  6583. $len = strcspn($this->data, "\x09\x20\r\n\"", $this->position);
  6584. $this->value .= substr($this->data, $this->position, $len);
  6585. $this->state = 'value_next';
  6586. $this->position += $len;
  6587. }
  6588. /**
  6589. * Parse LWS outside quotes
  6590. *
  6591. * @access private
  6592. */
  6593. function value_linear_whitespace()
  6594. {
  6595. $this->linear_whitespace();
  6596. $this->state = 'value_next';
  6597. }
  6598. /**
  6599. * See what state to move the state machine to while within quoted header values
  6600. *
  6601. * @access private
  6602. */
  6603. function value_quote_next()
  6604. {
  6605. if ($this->is_linear_whitespace())
  6606. {
  6607. $this->state = 'value_linear_whitespace_quote';
  6608. }
  6609. else
  6610. {
  6611. switch ($this->data[$this->position])
  6612. {
  6613. case '"':
  6614. $this->state = 'value_next';
  6615. $this->position++;
  6616. break;
  6617. case '\\':
  6618. $this->state = 'value_quote_char';
  6619. $this->position++;
  6620. break;
  6621. default:
  6622. $this->state = 'value_quote';
  6623. break;
  6624. }
  6625. }
  6626. }
  6627. /**
  6628. * Parse a header value while within quotes
  6629. *
  6630. * @access private
  6631. */
  6632. function value_quote()
  6633. {
  6634. $len = strcspn($this->data, "\x09\x20\r\n\"\\", $this->position);
  6635. $this->value .= substr($this->data, $this->position, $len);
  6636. $this->position += $len;
  6637. $this->state = 'value_quote_next';
  6638. }
  6639. /**
  6640. * Parse an escaped character within quotes
  6641. *
  6642. * @access private
  6643. */
  6644. function value_quote_char()
  6645. {
  6646. $this->value .= $this->data[$this->position];
  6647. $this->state = 'value_quote_next';
  6648. $this->position++;
  6649. }
  6650. /**
  6651. * Parse LWS within quotes
  6652. *
  6653. * @access private
  6654. */
  6655. function value_linear_whitespace_quote()
  6656. {
  6657. $this->linear_whitespace();
  6658. $this->state = 'value_quote_next';
  6659. }
  6660. /**
  6661. * Parse a CRLF, and see whether we have a further header, or whether we are followed by the body
  6662. *
  6663. * @access private
  6664. */
  6665. function end_crlf()
  6666. {
  6667. $this->name = strtolower($this->name);
  6668. $this->value = trim($this->value, "\x20");
  6669. if (isset($this->headers[$this->name]))
  6670. {
  6671. $this->headers[$this->name] .= ', ' . $this->value;
  6672. }
  6673. else
  6674. {
  6675. $this->headers[$this->name] = $this->value;
  6676. }
  6677. if (substr($this->data, $this->position, 2) == "\r\n")
  6678. {
  6679. $this->body = substr($this->data, $this->position + 2);
  6680. $this->state = 'emit';
  6681. }
  6682. elseif (strspn($this->data, "\r\n", $this->position, 1))
  6683. {
  6684. $this->body = substr($this->data, $this->position + 1);
  6685. $this->state = 'emit';
  6686. }
  6687. else
  6688. {
  6689. $this->name = '';
  6690. $this->value = '';
  6691. $this->state = 'name';
  6692. }
  6693. }
  6694. }
  6695. class SimplePie_Cache
  6696. {
  6697. var $location;
  6698. var $filename;
  6699. var $extension;
  6700. var $name;
  6701. function SimplePie_Cache($location, $filename, $extension)
  6702. {
  6703. $this->location = $location;
  6704. $this->filename = rawurlencode($filename);
  6705. $this->extension = rawurlencode($extension);
  6706. $this->name = "$location/$this->filename.$this->extension";
  6707. }
  6708. function save($data)
  6709. {
  6710. if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
  6711. {
  6712. if (function_exists('file_put_contents'))
  6713. {
  6714. return (bool) file_put_contents($this->name, serialize($data));
  6715. }
  6716. else
  6717. {
  6718. $fp = fopen($this->name, 'wb');
  6719. if ($fp)
  6720. {
  6721. fwrite($fp, serialize($data));
  6722. fclose($fp);
  6723. return true;
  6724. }
  6725. }
  6726. }
  6727. return false;
  6728. }
  6729. function load()
  6730. {
  6731. if (file_exists($this->name) && is_readable($this->name))
  6732. {
  6733. if (function_exists('file_get_contents'))
  6734. {
  6735. return unserialize(file_get_contents($this->name));
  6736. }
  6737. elseif (($fp = fopen($this->name, 'rb')) !== false)
  6738. {
  6739. $data = '';
  6740. while (!feof($fp))
  6741. {
  6742. $data .= fread($fp, 8192);
  6743. }
  6744. fclose($fp);
  6745. return unserialize($data);
  6746. }
  6747. }
  6748. return false;
  6749. }
  6750. function mtime()
  6751. {
  6752. if (file_exists($this->name))
  6753. {
  6754. return filemtime($this->name);
  6755. }
  6756. return false;
  6757. }
  6758. function touch()
  6759. {
  6760. if (file_exists($this->name))
  6761. {
  6762. return touch($this->name);
  6763. }
  6764. return false;
  6765. }
  6766. function unlink()
  6767. {
  6768. if (file_exists($this->name))
  6769. {
  6770. return unlink($this->name);
  6771. }
  6772. return false;
  6773. }
  6774. }
  6775. class SimplePie_Misc
  6776. {
  6777. function time_hms($seconds)
  6778. {
  6779. $time = '';
  6780. $hours = floor($seconds / 3600);
  6781. $remainder = $seconds % 3600;
  6782. if ($hours > 0)
  6783. {
  6784. $time .= $hours.':';
  6785. }
  6786. $minutes = floor($remainder / 60);
  6787. $seconds = $remainder % 60;
  6788. if ($minutes < 10 && $hours > 0)
  6789. {
  6790. $minutes = '0' . $minutes;
  6791. }
  6792. if ($seconds < 10)
  6793. {
  6794. $seconds = '0' . $seconds;
  6795. }
  6796. $time .= $minutes.':';
  6797. $time .= $seconds;
  6798. return $time;
  6799. }
  6800. function absolutize_url($relative, $base)
  6801. {
  6802. if ($relative !== '')
  6803. {
  6804. $relative = SimplePie_Misc::parse_url($relative);
  6805. if ($relative['scheme'] !== '')
  6806. {
  6807. $target = $relative;
  6808. }
  6809. elseif ($base !== '')
  6810. {
  6811. $base = SimplePie_Misc::parse_url($base);
  6812. $target = SimplePie_Misc::parse_url('');
  6813. if ($relative['authority'] !== '')
  6814. {
  6815. $target = $relative;
  6816. $target['scheme'] = $base['scheme'];
  6817. }
  6818. else
  6819. {
  6820. $target['scheme'] = $base['scheme'];
  6821. $target['authority'] = $base['authority'];
  6822. if ($relative['path'] !== '')
  6823. {
  6824. if (strpos($relative['path'], '/') === 0)
  6825. {
  6826. $target['path'] = $relative['path'];
  6827. }
  6828. elseif (($target['path'] = dirname("$base[path].")) == '/')
  6829. {
  6830. $target['path'] .= $relative['path'];
  6831. }
  6832. else
  6833. {
  6834. $target['path'] .= '/' . $relative['path'];
  6835. }
  6836. if ($relative['query'] !== '')
  6837. {
  6838. $target['query'] = $relative['query'];
  6839. }
  6840. }
  6841. else
  6842. {
  6843. if ($base['path'] !== '')
  6844. {
  6845. $target['path'] = $base['path'];
  6846. }
  6847. else
  6848. {
  6849. $target['path'] = '/';
  6850. }
  6851. if ($relative['query'] !== '')
  6852. {
  6853. $target['query'] = $relative['query'];
  6854. }
  6855. elseif ($base['query'] !== '')
  6856. {
  6857. $target['query'] = $base['query'];
  6858. }
  6859. }
  6860. }
  6861. if ($relative['fragment'] !== '')
  6862. {
  6863. $target['fragment'] = $relative['fragment'];
  6864. }
  6865. }
  6866. else
  6867. {
  6868. // No base URL, just return the relative URL
  6869. $target = $relative;
  6870. }
  6871. $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
  6872. }
  6873. else
  6874. {
  6875. $return = $base;
  6876. }
  6877. $return = SimplePie_Misc::normalize_url($return);
  6878. return $return;
  6879. }
  6880. function remove_dot_segments($input)
  6881. {
  6882. $output = '';
  6883. while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
  6884. {
  6885. // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
  6886. if (strpos($input, '../') === 0)
  6887. {
  6888. $input = substr($input, 3);
  6889. }
  6890. elseif (strpos($input, './') === 0)
  6891. {
  6892. $input = substr($input, 2);
  6893. }
  6894. // 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,
  6895. elseif (strpos($input, '/./') === 0)
  6896. {
  6897. $input = substr_replace($input, '/', 0, 3);
  6898. }
  6899. elseif ($input == '/.')
  6900. {
  6901. $input = '/';
  6902. }
  6903. // 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,
  6904. elseif (strpos($input, '/../') === 0)
  6905. {
  6906. $input = substr_replace($input, '/', 0, 4);
  6907. $output = substr_replace($output, '', strrpos($output, '/'));
  6908. }
  6909. elseif ($input == '/..')
  6910. {
  6911. $input = '/';
  6912. $output = substr_replace($output, '', strrpos($output, '/'));
  6913. }
  6914. // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
  6915. elseif ($input == '.' || $input == '..')
  6916. {
  6917. $input = '';
  6918. }
  6919. // 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
  6920. elseif (($pos = strpos($input, '/', 1)) !== false)
  6921. {
  6922. $output .= substr($input, 0, $pos);
  6923. $input = substr_replace($input, '', 0, $pos);
  6924. }
  6925. else
  6926. {
  6927. $output .= $input;
  6928. $input = '';
  6929. }
  6930. }
  6931. return $output . $input;
  6932. }
  6933. function get_element($realname, $string)
  6934. {
  6935. $return = array();
  6936. $name = preg_quote($realname, '/');
  6937. if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
  6938. {
  6939. for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
  6940. {
  6941. $return[$i]['tag'] = $realname;
  6942. $return[$i]['full'] = $matches[$i][0][0];
  6943. $return[$i]['offset'] = $matches[$i][0][1];
  6944. if (strlen($matches[$i][3][0]) <= 2)
  6945. {
  6946. $return[$i]['self_closing'] = true;
  6947. }
  6948. else
  6949. {
  6950. $return[$i]['self_closing'] = false;
  6951. $return[$i]['content'] = $matches[$i][4][0];
  6952. }
  6953. $return[$i]['attribs'] = array();
  6954. if (isset($matches[$i][2][0]) && preg_match_all('/((?:[^\s:]+:)?[^\s:]+)(?:\s*=\s*(?:"([^"]*)"|\'([^\']*)\'|([a-z0-9\-._:]*)))?\s/U', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
  6955. {
  6956. for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
  6957. {
  6958. if (count($attribs[$j]) == 2)
  6959. {
  6960. $attribs[$j][2] = $attribs[$j][1];
  6961. }
  6962. $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
  6963. }
  6964. }
  6965. }
  6966. }
  6967. return $return;
  6968. }
  6969. function element_implode($element)
  6970. {
  6971. $full = "<$element[tag]";
  6972. foreach ($element['attribs'] as $key => $value)
  6973. {
  6974. $key = strtolower($key);
  6975. $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
  6976. }
  6977. if ($element['self_closing'])
  6978. {
  6979. $full .= ' />';
  6980. }
  6981. else
  6982. {
  6983. $full .= ">$element[content]</$element[tag]>";
  6984. }
  6985. return $full;
  6986. }
  6987. function error($message, $level, $file, $line)
  6988. {
  6989. switch ($level)
  6990. {
  6991. case E_USER_ERROR:
  6992. $note = 'PHP Error';
  6993. break;
  6994. case E_USER_WARNING:
  6995. $note = 'PHP Warning';
  6996. break;
  6997. case E_USER_NOTICE:
  6998. $note = 'PHP Notice';
  6999. break;
  7000. default:
  7001. $note = 'Unknown Error';
  7002. break;
  7003. }
  7004. error_log("$note: $message in $file on line $line", 0);
  7005. return $message;
  7006. }
  7007. /**
  7008. * If a file has been cached, retrieve and display it.
  7009. *
  7010. * This is most useful for caching images (get_favicon(), etc.),
  7011. * however it works for all cached files. This WILL NOT display ANY
  7012. * file/image/page/whatever, but rather only display what has already
  7013. * been cached by SimplePie.
  7014. *
  7015. * @access public
  7016. * @see SimplePie::get_favicon()
  7017. * @param str $identifier_url URL that is used to identify the content.
  7018. * This may or may not be the actual URL of the live content.
  7019. * @param str $cache_location Location of SimplePie's cache. Defaults
  7020. * to './cache'.
  7021. * @param str $cache_extension The file extension that the file was
  7022. * cached with. Defaults to 'spc'.
  7023. * @param str $cache_class Name of the cache-handling class being used
  7024. * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
  7025. * as-is unless you've overloaded the class.
  7026. * @param str $cache_name_function Function that converts the filename
  7027. * for saving. Defaults to 'md5'.
  7028. */
  7029. function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
  7030. {
  7031. $cache =& new $cache_class($cache_location, call_user_func($cache_name_function, $identifier_url), $cache_extension);
  7032. if ($file = $cache->load())
  7033. {
  7034. header('Content-type:' . $file['headers']['content-type']);
  7035. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  7036. echo $file['body'];
  7037. exit;
  7038. }
  7039. die('Cached file for ' . $identifier_url . ' cannot be found.');
  7040. }
  7041. function fix_protocol($url, $http = 1)
  7042. {
  7043. $url = SimplePie_Misc::normalize_url($url);
  7044. $parsed = SimplePie_Misc::parse_url($url);
  7045. if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
  7046. {
  7047. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
  7048. }
  7049. if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
  7050. {
  7051. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
  7052. }
  7053. if ($http == 2 && $parsed['scheme'] !== '')
  7054. {
  7055. return "feed:$url";
  7056. }
  7057. elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
  7058. {
  7059. return substr_replace($url, 'podcast', 0, 4);
  7060. }
  7061. elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
  7062. {
  7063. return substr_replace($url, 'itpc', 0, 4);
  7064. }
  7065. else
  7066. {
  7067. return $url;
  7068. }
  7069. }
  7070. function parse_url($url)
  7071. {
  7072. static $cache = array();
  7073. if (isset($cache[$url]))
  7074. {
  7075. return $cache[$url];
  7076. }
  7077. elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
  7078. {
  7079. for ($i = count($match); $i <= 9; $i++)
  7080. {
  7081. $match[$i] = '';
  7082. }
  7083. return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
  7084. }
  7085. else
  7086. {
  7087. return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
  7088. }
  7089. }
  7090. function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
  7091. {
  7092. $return = '';
  7093. if ($scheme !== '')
  7094. {
  7095. $return .= "$scheme:";
  7096. }
  7097. if ($authority !== '')
  7098. {
  7099. $return .= "//$authority";
  7100. }
  7101. if ($path !== '')
  7102. {
  7103. $return .= $path;
  7104. }
  7105. if ($query !== '')
  7106. {
  7107. $return .= "?$query";
  7108. }
  7109. if ($fragment !== '')
  7110. {
  7111. $return .= "#$fragment";
  7112. }
  7113. return $return;
  7114. }
  7115. function normalize_url($url)
  7116. {
  7117. $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
  7118. $url = SimplePie_Misc::parse_url($url);
  7119. $url['scheme'] = strtolower($url['scheme']);
  7120. if ($url['authority'] !== '')
  7121. {
  7122. $url['authority'] = strtolower($url['authority']);
  7123. $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
  7124. }
  7125. return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
  7126. }
  7127. function percent_encoding_normalization($match)
  7128. {
  7129. $integer = hexdec($match[1]);
  7130. if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
  7131. {
  7132. return chr($integer);
  7133. }
  7134. else
  7135. {
  7136. return strtoupper($match[0]);
  7137. }
  7138. }
  7139. /**
  7140. * Remove bad UTF-8 bytes
  7141. *
  7142. * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
  7143. * FAQ: Multilingual Forms (modified to include full ASCII range)
  7144. *
  7145. * @author Geoffrey Sneddon
  7146. * @see http://www.w3.org/International/questions/qa-forms-utf-8
  7147. * @param string $str String to remove bad UTF-8 bytes from
  7148. * @return string UTF-8 string
  7149. */
  7150. function utf8_bad_replace($str)
  7151. {
  7152. if (function_exists('iconv'))
  7153. {
  7154. return iconv('UTF-8', 'UTF-8//IGNORE', $str);
  7155. }
  7156. elseif (function_exists('mb_convert_encoding'))
  7157. {
  7158. return mb_convert_encoding($str, 'UTF-8', 'UTF-8');
  7159. }
  7160. 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))
  7161. {
  7162. return implode("\xEF\xBF\xBD", $matches[0]);
  7163. }
  7164. elseif ($str !== '')
  7165. {
  7166. return "\xEF\xBF\xBD";
  7167. }
  7168. else
  7169. {
  7170. return '';
  7171. }
  7172. }
  7173. function change_encoding($data, $input, $output)
  7174. {
  7175. $input = SimplePie_Misc::encoding($input);
  7176. $output = SimplePie_Misc::encoding($output);
  7177. if (function_exists('iconv') && ($return = @iconv($input, "$output//IGNORE", $data)))
  7178. {
  7179. return $return;
  7180. }
  7181. elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
  7182. {
  7183. return $return;
  7184. }
  7185. elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
  7186. {
  7187. return $return;
  7188. }
  7189. elseif ($input == 'ISO-8859-1' && $output == 'UTF-8')
  7190. {
  7191. return utf8_encode($data);
  7192. }
  7193. elseif ($input == 'UTF-8' && $output == 'ISO-8859-1')
  7194. {
  7195. return utf8_decode($data);
  7196. }
  7197. return $data;
  7198. }
  7199. function encoding($encoding)
  7200. {
  7201. // Character sets are case-insensitive (though we'll return them in the form given in their registration)
  7202. switch (strtoupper($encoding))
  7203. {
  7204. case 'ANSI_X3.4-1968':
  7205. case 'ISO-IR-6':
  7206. case 'ANSI_X3.4-1986':
  7207. case 'ISO_646.IRV:1991':
  7208. case 'ASCII':
  7209. case 'ISO646-US':
  7210. case 'US-ASCII':
  7211. case 'US':
  7212. case 'IBM367':
  7213. case 'CP367':
  7214. case 'CSASCII':
  7215. return 'US-ASCII';
  7216. case 'ISO_8859-1:1987':
  7217. case 'ISO-IR-100':
  7218. case 'ISO_8859-1':
  7219. case 'ISO-8859-1':
  7220. case 'LATIN1':
  7221. case 'L1':
  7222. case 'IBM819':
  7223. case 'CP819':
  7224. case 'CSISOLATIN1':
  7225. return 'ISO-8859-1';
  7226. case 'ISO_8859-2:1987':
  7227. case 'ISO-IR-101':
  7228. case 'ISO_8859-2':
  7229. case 'ISO-8859-2':
  7230. case 'LATIN2':
  7231. case 'L2':
  7232. case 'CSISOLATIN2':
  7233. return 'ISO-8859-2';
  7234. case 'ISO_8859-3:1988':
  7235. case 'ISO-IR-109':
  7236. case 'ISO_8859-3':
  7237. case 'ISO-8859-3':
  7238. case 'LATIN3':
  7239. case 'L3':
  7240. case 'CSISOLATIN3':
  7241. return 'ISO-8859-3';
  7242. case 'ISO_8859-4:1988':
  7243. case 'ISO-IR-110':
  7244. case 'ISO_8859-4':
  7245. case 'ISO-8859-4':
  7246. case 'LATIN4':
  7247. case 'L4':
  7248. case 'CSISOLATIN4':
  7249. return 'ISO-8859-4';
  7250. case 'ISO_8859-5:1988':
  7251. case 'ISO-IR-144':
  7252. case 'ISO_8859-5':
  7253. case 'ISO-8859-5':
  7254. case 'CYRILLIC':
  7255. case 'CSISOLATINCYRILLIC':
  7256. return 'ISO-8859-5';
  7257. case 'ISO_8859-6:1987':
  7258. case 'ISO-IR-127':
  7259. case 'ISO_8859-6':
  7260. case 'ISO-8859-6':
  7261. case 'ECMA-114':
  7262. case 'ASMO-708':
  7263. case 'ARABIC':
  7264. case 'CSISOLATINARABIC':
  7265. return 'ISO-8859-6';
  7266. case 'ISO_8859-7:1987':
  7267. case 'ISO-IR-126':
  7268. case 'ISO_8859-7':
  7269. case 'ISO-8859-7':
  7270. case 'ELOT_928':
  7271. case 'ECMA-118':
  7272. case 'GREEK':
  7273. case 'GREEK8':
  7274. case 'CSISOLATINGREEK':
  7275. return 'ISO-8859-7';
  7276. case 'ISO_8859-8:1988':
  7277. case 'ISO-IR-138':
  7278. case 'ISO_8859-8':
  7279. case 'ISO-8859-8':
  7280. case 'HEBREW':
  7281. case 'CSISOLATINHEBREW':
  7282. return 'ISO-8859-8';
  7283. case 'ISO_8859-9:1989':
  7284. case 'ISO-IR-148':
  7285. case 'ISO_8859-9':
  7286. case 'ISO-8859-9':
  7287. case 'LATIN5':
  7288. case 'L5':
  7289. case 'CSISOLATIN5':
  7290. return 'ISO-8859-9';
  7291. case 'ISO-8859-10':
  7292. case 'ISO-IR-157':
  7293. case 'L6':
  7294. case 'ISO_8859-10:1992':
  7295. case 'CSISOLATIN6':
  7296. case 'LATIN6':
  7297. return 'ISO-8859-10';
  7298. case 'ISO_6937-2-ADD':
  7299. case 'ISO-IR-142':
  7300. case 'CSISOTEXTCOMM':
  7301. return 'ISO_6937-2-add';
  7302. case 'JIS_X0201':
  7303. case 'X0201':
  7304. case 'CSHALFWIDTHKATAKANA':
  7305. return 'JIS_X0201';
  7306. case 'JIS_ENCODING':
  7307. case 'CSJISENCODING':
  7308. return 'JIS_Encoding';
  7309. case 'SHIFT_JIS':
  7310. case 'MS_KANJI':
  7311. case 'CSSHIFTJIS':
  7312. return 'Shift_JIS';
  7313. case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
  7314. case 'CSEUCPKDFMTJAPANESE':
  7315. case 'EUC-JP':
  7316. return 'EUC-JP';
  7317. case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
  7318. case 'CSEUCFIXWIDJAPANESE':
  7319. return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
  7320. case 'BS_4730':
  7321. case 'ISO-IR-4':
  7322. case 'ISO646-GB':
  7323. case 'GB':
  7324. case 'UK':
  7325. case 'CSISO4UNITEDKINGDOM':
  7326. return 'BS_4730';
  7327. case 'SEN_850200_C':
  7328. case 'ISO-IR-11':
  7329. case 'ISO646-SE2':
  7330. case 'SE2':
  7331. case 'CSISO11SWEDISHFORNAMES':
  7332. return 'SEN_850200_C';
  7333. case 'IT':
  7334. case 'ISO-IR-15':
  7335. case 'ISO646-IT':
  7336. case 'CSISO15ITALIAN':
  7337. return 'IT';
  7338. case 'ES':
  7339. case 'ISO-IR-17':
  7340. case 'ISO646-ES':
  7341. case 'CSISO17SPANISH':
  7342. return 'ES';
  7343. case 'DIN_66003':
  7344. case 'ISO-IR-21':
  7345. case 'DE':
  7346. case 'ISO646-DE':
  7347. case 'CSISO21GERMAN':
  7348. return 'DIN_66003';
  7349. case 'NS_4551-1':
  7350. case 'ISO-IR-60':
  7351. case 'ISO646-NO':
  7352. case 'NO':
  7353. case 'CSISO60DANISHNORWEGIAN':
  7354. case 'CSISO60NORWEGIAN1':
  7355. return 'NS_4551-1';
  7356. case 'NF_Z_62-010':
  7357. case 'ISO-IR-69':
  7358. case 'ISO646-FR':
  7359. case 'FR':
  7360. case 'CSISO69FRENCH':
  7361. return 'NF_Z_62-010';
  7362. case 'ISO-10646-UTF-1':
  7363. case 'CSISO10646UTF1':
  7364. return 'ISO-10646-UTF-1';
  7365. case 'ISO_646.BASIC:1983':
  7366. case 'REF':
  7367. case 'CSISO646BASIC1983':
  7368. return 'ISO_646.basic:1983';
  7369. case 'INVARIANT':
  7370. case 'CSINVARIANT':
  7371. return 'INVARIANT';
  7372. case 'ISO_646.IRV:1983':
  7373. case 'ISO-IR-2':
  7374. case 'IRV':
  7375. case 'CSISO2INTLREFVERSION':
  7376. return 'ISO_646.irv:1983';
  7377. case 'NATS-SEFI':
  7378. case 'ISO-IR-8-1':
  7379. case 'CSNATSSEFI':
  7380. return 'NATS-SEFI';
  7381. case 'NATS-SEFI-ADD':
  7382. case 'ISO-IR-8-2':
  7383. case 'CSNATSSEFIADD':
  7384. return 'NATS-SEFI-ADD';
  7385. case 'NATS-DANO':
  7386. case 'ISO-IR-9-1':
  7387. case 'CSNATSDANO':
  7388. return 'NATS-DANO';
  7389. case 'NATS-DANO-ADD':
  7390. case 'ISO-IR-9-2':
  7391. case 'CSNATSDANOADD':
  7392. return 'NATS-DANO-ADD';
  7393. case 'SEN_850200_B':
  7394. case 'ISO-IR-10':
  7395. case 'FI':
  7396. case 'ISO646-FI':
  7397. case 'ISO646-SE':
  7398. case 'SE':
  7399. case 'CSISO10SWEDISH':
  7400. return 'SEN_850200_B';
  7401. case 'KS_C_5601-1987':
  7402. case 'ISO-IR-149':
  7403. case 'KS_C_5601-1989':
  7404. case 'KSC_5601':
  7405. case 'KOREAN':
  7406. case 'CSKSC56011987':
  7407. return 'KS_C_5601-1987';
  7408. case 'ISO-2022-KR':
  7409. case 'CSISO2022KR':
  7410. return 'ISO-2022-KR';
  7411. case 'EUC-KR':
  7412. case 'CSEUCKR':
  7413. return 'EUC-KR';
  7414. case 'ISO-2022-JP':
  7415. case 'CSISO2022JP':
  7416. return 'ISO-2022-JP';
  7417. case 'ISO-2022-JP-2':
  7418. case 'CSISO2022JP2':
  7419. return 'ISO-2022-JP-2';
  7420. case 'JIS_C6220-1969-JP':
  7421. case 'JIS_C6220-1969':
  7422. case 'ISO-IR-13':
  7423. case 'KATAKANA':
  7424. case 'X0201-7':
  7425. case 'CSISO13JISC6220JP':
  7426. return 'JIS_C6220-1969-jp';
  7427. case 'JIS_C6220-1969-RO':
  7428. case 'ISO-IR-14':
  7429. case 'JP':
  7430. case 'ISO646-JP':
  7431. case 'CSISO14JISC6220RO':
  7432. return 'JIS_C6220-1969-ro';
  7433. case 'PT':
  7434. case 'ISO-IR-16':
  7435. case 'ISO646-PT':
  7436. case 'CSISO16PORTUGUESE':
  7437. return 'PT';
  7438. case 'GREEK7-OLD':
  7439. case 'ISO-IR-18':
  7440. case 'CSISO18GREEK7OLD':
  7441. return 'greek7-old';
  7442. case 'LATIN-GREEK':
  7443. case 'ISO-IR-19':
  7444. case 'CSISO19LATINGREEK':
  7445. return 'latin-greek';
  7446. case 'NF_Z_62-010_(1973)':
  7447. case 'ISO-IR-25':
  7448. case 'ISO646-FR1':
  7449. case 'CSISO25FRENCH':
  7450. return 'NF_Z_62-010_(1973)';
  7451. case 'LATIN-GREEK-1':
  7452. case 'ISO-IR-27':
  7453. case 'CSISO27LATINGREEK1':
  7454. return 'Latin-greek-1';
  7455. case 'ISO_5427':
  7456. case 'ISO-IR-37':
  7457. case 'CSISO5427CYRILLIC':
  7458. return 'ISO_5427';
  7459. case 'JIS_C6226-1978':
  7460. case 'ISO-IR-42':
  7461. case 'CSISO42JISC62261978':
  7462. return 'JIS_C6226-1978';
  7463. case 'BS_VIEWDATA':
  7464. case 'ISO-IR-47':
  7465. case 'CSISO47BSVIEWDATA':
  7466. return 'BS_viewdata';
  7467. case 'INIS':
  7468. case 'ISO-IR-49':
  7469. case 'CSISO49INIS':
  7470. return 'INIS';
  7471. case 'INIS-8':
  7472. case 'ISO-IR-50':
  7473. case 'CSISO50INIS8':
  7474. return 'INIS-8';
  7475. case 'INIS-CYRILLIC':
  7476. case 'ISO-IR-51':
  7477. case 'CSISO51INISCYRILLIC':
  7478. return 'INIS-cyrillic';
  7479. case 'ISO_5427:1981':
  7480. case 'ISO-IR-54':
  7481. case 'ISO5427CYRILLIC1981':
  7482. return 'ISO_5427:1981';
  7483. case 'ISO_5428:1980':
  7484. case 'ISO-IR-55':
  7485. case 'CSISO5428GREEK':
  7486. return 'ISO_5428:1980';
  7487. case 'GB_1988-80':
  7488. case 'ISO-IR-57':
  7489. case 'CN':
  7490. case 'ISO646-CN':
  7491. case 'CSISO57GB1988':
  7492. return 'GB_1988-80';
  7493. case 'GB_2312-80':
  7494. case 'ISO-IR-58':
  7495. case 'CHINESE':
  7496. case 'CSISO58GB231280':
  7497. return 'GB_2312-80';
  7498. case 'NS_4551-2':
  7499. case 'ISO646-NO2':
  7500. case 'ISO-IR-61':
  7501. case 'NO2':
  7502. case 'CSISO61NORWEGIAN2':
  7503. return 'NS_4551-2';
  7504. case 'VIDEOTEX-SUPPL':
  7505. case 'ISO-IR-70':
  7506. case 'CSISO70VIDEOTEXSUPP1':
  7507. return 'videotex-suppl';
  7508. case 'PT2':
  7509. case 'ISO-IR-84':
  7510. case 'ISO646-PT2':
  7511. case 'CSISO84PORTUGUESE2':
  7512. return 'PT2';
  7513. case 'ES2':
  7514. case 'ISO-IR-85':
  7515. case 'ISO646-ES2':
  7516. case 'CSISO85SPANISH2':
  7517. return 'ES2';
  7518. case 'MSZ_7795.3':
  7519. case 'ISO-IR-86':
  7520. case 'ISO646-HU':
  7521. case 'HU':
  7522. case 'CSISO86HUNGARIAN':
  7523. return 'MSZ_7795.3';
  7524. case 'JIS_C6226-1983':
  7525. case 'ISO-IR-87':
  7526. case 'X0208':
  7527. case 'JIS_X0208-1983':
  7528. case 'CSISO87JISX0208':
  7529. return 'JIS_C6226-1983';
  7530. case 'GREEK7':
  7531. case 'ISO-IR-88':
  7532. case 'CSISO88GREEK7':
  7533. return 'greek7';
  7534. case 'ASMO_449':
  7535. case 'ISO_9036':
  7536. case 'ARABIC7':
  7537. case 'ISO-IR-89':
  7538. case 'CSISO89ASMO449':
  7539. return 'ASMO_449';
  7540. case 'ISO-IR-90':
  7541. case 'CSISO90':
  7542. return 'iso-ir-90';
  7543. case 'JIS_C6229-1984-A':
  7544. case 'ISO-IR-91':
  7545. case 'JP-OCR-A':
  7546. case 'CSISO91JISC62291984A':
  7547. return 'JIS_C6229-1984-a';
  7548. case 'JIS_C6229-1984-B':
  7549. case 'ISO-IR-92':
  7550. case 'ISO646-JP-OCR-B':
  7551. case 'JP-OCR-B':
  7552. case 'CSISO92JISC62991984B':
  7553. return 'JIS_C6229-1984-b';
  7554. case 'JIS_C6229-1984-B-ADD':
  7555. case 'ISO-IR-93':
  7556. case 'JP-OCR-B-ADD':
  7557. case 'CSISO93JIS62291984BADD':
  7558. return 'JIS_C6229-1984-b-add';
  7559. case 'JIS_C6229-1984-HAND':
  7560. case 'ISO-IR-94':
  7561. case 'JP-OCR-HAND':
  7562. case 'CSISO94JIS62291984HAND':
  7563. return 'JIS_C6229-1984-hand';
  7564. case 'JIS_C6229-1984-HAND-ADD':
  7565. case 'ISO-IR-95':
  7566. case 'JP-OCR-HAND-ADD':
  7567. case 'CSISO95JIS62291984HANDADD':
  7568. return 'JIS_C6229-1984-hand-add';
  7569. case 'JIS_C6229-1984-KANA':
  7570. case 'ISO-IR-96':
  7571. case 'CSISO96JISC62291984KANA':
  7572. return 'JIS_C6229-1984-kana';
  7573. case 'ISO_2033-1983':
  7574. case 'ISO-IR-98':
  7575. case 'E13B':
  7576. case 'CSISO2033':
  7577. return 'ISO_2033-1983';
  7578. case 'ANSI_X3.110-1983':
  7579. case 'ISO-IR-99':
  7580. case 'CSA_T500-1983':
  7581. case 'NAPLPS':
  7582. case 'CSISO99NAPLPS':
  7583. return 'ANSI_X3.110-1983';
  7584. case 'T.61-7BIT':
  7585. case 'ISO-IR-102':
  7586. case 'CSISO102T617BIT':
  7587. return 'T.61-7bit';
  7588. case 'T.61-8BIT':
  7589. case 'T.61':
  7590. case 'ISO-IR-103':
  7591. case 'CSISO103T618BIT':
  7592. return 'T.61-8bit';
  7593. case 'ECMA-CYRILLIC':
  7594. case 'ISO-IR-111':
  7595. case 'KOI8-E':
  7596. case 'CSISO111ECMACYRILLIC':
  7597. return 'ECMA-cyrillic';
  7598. case 'CSA_Z243.4-1985-1':
  7599. case 'ISO-IR-121':
  7600. case 'ISO646-CA':
  7601. case 'CSA7-1':
  7602. case 'CA':
  7603. case 'CSISO121CANADIAN1':
  7604. return 'CSA_Z243.4-1985-1';
  7605. case 'CSA_Z243.4-1985-2':
  7606. case 'ISO-IR-122':
  7607. case 'ISO646-CA2':
  7608. case 'CSA7-2':
  7609. case 'CSISO122CANADIAN2':
  7610. return 'CSA_Z243.4-1985-2';
  7611. case 'CSA_Z243.4-1985-GR':
  7612. case 'ISO-IR-123':
  7613. case 'CSISO123CSAZ24341985GR':
  7614. return 'CSA_Z243.4-1985-gr';
  7615. case 'ISO_8859-6-E':
  7616. case 'CSISO88596E':
  7617. case 'ISO-8859-6-E':
  7618. return 'ISO-8859-6-E';
  7619. case 'ISO_8859-6-I':
  7620. case 'CSISO88596I':
  7621. case 'ISO-8859-6-I':
  7622. return 'ISO-8859-6-I';
  7623. case 'T.101-G2':
  7624. case 'ISO-IR-128':
  7625. case 'CSISO128T101G2':
  7626. return 'T.101-G2';
  7627. case 'ISO_8859-8-E':
  7628. case 'CSISO88598E':
  7629. case 'ISO-8859-8-E':
  7630. return 'ISO-8859-8-E';
  7631. case 'ISO_8859-8-I':
  7632. case 'CSISO88598I':
  7633. case 'ISO-8859-8-I':
  7634. return 'ISO-8859-8-I';
  7635. case 'CSN_369103':
  7636. case 'ISO-IR-139':
  7637. case 'CSISO139CSN369103':
  7638. return 'CSN_369103';
  7639. case 'JUS_I.B1.002':
  7640. case 'ISO-IR-141':
  7641. case 'ISO646-YU':
  7642. case 'JS':
  7643. case 'YU':
  7644. case 'CSISO141JUSIB1002':
  7645. return 'JUS_I.B1.002';
  7646. case 'IEC_P27-1':
  7647. case 'ISO-IR-143':
  7648. case 'CSISO143IECP271':
  7649. return 'IEC_P27-1';
  7650. case 'JUS_I.B1.003-SERB':
  7651. case 'ISO-IR-146':
  7652. case 'SERBIAN':
  7653. case 'CSISO146SERBIAN':
  7654. return 'JUS_I.B1.003-serb';
  7655. case 'JUS_I.B1.003-MAC':
  7656. case 'MACEDONIAN':
  7657. case 'ISO-IR-147':
  7658. case 'CSISO147MACEDONIAN':
  7659. return 'JUS_I.B1.003-mac';
  7660. case 'GREEK-CCITT':
  7661. case 'ISO-IR-150':
  7662. case 'CSISO150':
  7663. case 'CSISO150GREEKCCITT':
  7664. return 'greek-ccitt';
  7665. case 'NC_NC00-10:81':
  7666. case 'CUBA':
  7667. case 'ISO-IR-151':
  7668. case 'ISO646-CU':
  7669. case 'CSISO151CUBA':
  7670. return 'NC_NC00-10:81';
  7671. case 'ISO_6937-2-25':
  7672. case 'ISO-IR-152':
  7673. case 'CSISO6937ADD':
  7674. return 'ISO_6937-2-25';
  7675. case 'GOST_19768-74':
  7676. case 'ST_SEV_358-88':
  7677. case 'ISO-IR-153':
  7678. case 'CSISO153GOST1976874':
  7679. return 'GOST_19768-74';
  7680. case 'ISO_8859-SUPP':
  7681. case 'ISO-IR-154':
  7682. case 'LATIN1-2-5':
  7683. case 'CSISO8859SUPP':
  7684. return 'ISO_8859-supp';
  7685. case 'ISO_10367-BOX':
  7686. case 'ISO-IR-155':
  7687. case 'CSISO10367BOX':
  7688. return 'ISO_10367-box';
  7689. case 'LATIN-LAP':
  7690. case 'LAP':
  7691. case 'ISO-IR-158':
  7692. case 'CSISO158LAP':
  7693. return 'latin-lap';
  7694. case 'JIS_X0212-1990':
  7695. case 'X0212':
  7696. case 'ISO-IR-159':
  7697. case 'CSISO159JISX02121990':
  7698. return 'JIS_X0212-1990';
  7699. case 'DS_2089':
  7700. case 'DS2089':
  7701. case 'ISO646-DK':
  7702. case 'DK':
  7703. case 'CSISO646DANISH':
  7704. return 'DS_2089';
  7705. case 'US-DK':
  7706. case 'CSUSDK':
  7707. return 'us-dk';
  7708. case 'DK-US':
  7709. case 'CSDKUS':
  7710. return 'dk-us';
  7711. case 'KSC5636':
  7712. case 'ISO646-KR':
  7713. case 'CSKSC5636':
  7714. return 'KSC5636';
  7715. case 'UNICODE-1-1-UTF-7':
  7716. case 'CSUNICODE11UTF7':
  7717. return 'UNICODE-1-1-UTF-7';
  7718. case 'ISO-2022-CN':
  7719. return 'ISO-2022-CN';
  7720. case 'ISO-2022-CN-EXT':
  7721. return 'ISO-2022-CN-EXT';
  7722. case 'UTF-8':
  7723. return 'UTF-8';
  7724. case 'ISO-8859-13':
  7725. return 'ISO-8859-13';
  7726. case 'ISO-8859-14':
  7727. case 'ISO-IR-199':
  7728. case 'ISO_8859-14:1998':
  7729. case 'ISO_8859-14':
  7730. case 'LATIN8':
  7731. case 'ISO-CELTIC':
  7732. case 'L8':
  7733. return 'ISO-8859-14';
  7734. case 'ISO-8859-15':
  7735. case 'ISO_8859-15':
  7736. case 'LATIN-9':
  7737. return 'ISO-8859-15';
  7738. case 'ISO-8859-16':
  7739. case 'ISO-IR-226':
  7740. case 'ISO_8859-16:2001':
  7741. case 'ISO_8859-16':
  7742. case 'LATIN10':
  7743. case 'L10':
  7744. return 'ISO-8859-16';
  7745. case 'GBK':
  7746. case 'CP936':
  7747. case 'MS936':
  7748. case 'WINDOWS-936':
  7749. return 'GBK';
  7750. case 'GB18030':
  7751. return 'GB18030';
  7752. case 'OSD_EBCDIC_DF04_15':
  7753. return 'OSD_EBCDIC_DF04_15';
  7754. case 'OSD_EBCDIC_DF03_IRV':
  7755. return 'OSD_EBCDIC_DF03_IRV';
  7756. case 'OSD_EBCDIC_DF04_1':
  7757. return 'OSD_EBCDIC_DF04_1';
  7758. case 'ISO-11548-1':
  7759. case 'ISO_11548-1':
  7760. case 'ISO_TR_11548-1':
  7761. case 'CSISO115481':
  7762. return 'ISO-11548-1';
  7763. case 'KZ-1048':
  7764. case 'STRK1048-2002':
  7765. case 'RK1048':
  7766. case 'CSKZ1048':
  7767. return 'KZ-1048';
  7768. case 'ISO-10646-UCS-2':
  7769. case 'CSUNICODE':
  7770. return 'ISO-10646-UCS-2';
  7771. case 'ISO-10646-UCS-4':
  7772. case 'CSUCS4':
  7773. return 'ISO-10646-UCS-4';
  7774. case 'ISO-10646-UCS-BASIC':
  7775. case 'CSUNICODEASCII':
  7776. return 'ISO-10646-UCS-Basic';
  7777. case 'ISO-10646-UNICODE-LATIN1':
  7778. case 'CSUNICODELATIN1':
  7779. case 'ISO-10646':
  7780. return 'ISO-10646-Unicode-Latin1';
  7781. case 'ISO-10646-J-1':
  7782. return 'ISO-10646-J-1';
  7783. case 'ISO-UNICODE-IBM-1261':
  7784. case 'CSUNICODEIBM1261':
  7785. return 'ISO-Unicode-IBM-1261';
  7786. case 'ISO-UNICODE-IBM-1268':
  7787. case 'CSUNICODEIBM1268':
  7788. return 'ISO-Unicode-IBM-1268';
  7789. case 'ISO-UNICODE-IBM-1276':
  7790. case 'CSUNICODEIBM1276':
  7791. return 'ISO-Unicode-IBM-1276';
  7792. case 'ISO-UNICODE-IBM-1264':
  7793. case 'CSUNICODEIBM1264':
  7794. return 'ISO-Unicode-IBM-1264';
  7795. case 'ISO-UNICODE-IBM-1265':
  7796. case 'CSUNICODEIBM1265':
  7797. return 'ISO-Unicode-IBM-1265';
  7798. case 'UNICODE-1-1':
  7799. case 'CSUNICODE11':
  7800. return 'UNICODE-1-1';
  7801. case 'SCSU':
  7802. return 'SCSU';
  7803. case 'UTF-7':
  7804. return 'UTF-7';
  7805. case 'UTF-16BE':
  7806. return 'UTF-16BE';
  7807. case 'UTF-16LE':
  7808. return 'UTF-16LE';
  7809. case 'UTF-16':
  7810. return 'UTF-16';
  7811. case 'CESU-8':
  7812. case 'CSCESU-8':
  7813. return 'CESU-8';
  7814. case 'UTF-32':
  7815. return 'UTF-32';
  7816. case 'UTF-32BE':
  7817. return 'UTF-32BE';
  7818. case 'UTF-32LE':
  7819. return 'UTF-32LE';
  7820. case 'BOCU-1':
  7821. case 'CSBOCU-1':
  7822. return 'BOCU-1';
  7823. case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
  7824. case 'CSWINDOWS30LATIN1':
  7825. return 'ISO-8859-1-Windows-3.0-Latin-1';
  7826. case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
  7827. case 'CSWINDOWS31LATIN1':
  7828. return 'ISO-8859-1-Windows-3.1-Latin-1';
  7829. case 'ISO-8859-2-WINDOWS-LATIN-2':
  7830. case 'CSWINDOWS31LATIN2':
  7831. return 'ISO-8859-2-Windows-Latin-2';
  7832. case 'ISO-8859-9-WINDOWS-LATIN-5':
  7833. case 'CSWINDOWS31LATIN5':
  7834. return 'ISO-8859-9-Windows-Latin-5';
  7835. case 'HP-ROMAN8':
  7836. case 'ROMAN8':
  7837. case 'R8':
  7838. case 'CSHPROMAN8':
  7839. return 'hp-roman8';
  7840. case 'ADOBE-STANDARD-ENCODING':
  7841. case 'CSADOBESTANDARDENCODING':
  7842. return 'Adobe-Standard-Encoding';
  7843. case 'VENTURA-US':
  7844. case 'CSVENTURAUS':
  7845. return 'Ventura-US';
  7846. case 'VENTURA-INTERNATIONAL':
  7847. case 'CSVENTURAINTERNATIONAL':
  7848. return 'Ventura-International';
  7849. case 'DEC-MCS':
  7850. case 'DEC':
  7851. case 'CSDECMCS':
  7852. return 'DEC-MCS';
  7853. case 'IBM850':
  7854. case 'CP850':
  7855. case '850':
  7856. case 'CSPC850MULTILINGUAL':
  7857. return 'IBM850';
  7858. case 'PC8-DANISH-NORWEGIAN':
  7859. case 'CSPC8DANISHNORWEGIAN':
  7860. return 'PC8-Danish-Norwegian';
  7861. case 'IBM862':
  7862. case 'CP862':
  7863. case '862':
  7864. case 'CSPC862LATINHEBREW':
  7865. return 'IBM862';
  7866. case 'PC8-TURKISH':
  7867. case 'CSPC8TURKISH':
  7868. return 'PC8-Turkish';
  7869. case 'IBM-SYMBOLS':
  7870. case 'CSIBMSYMBOLS':
  7871. return 'IBM-Symbols';
  7872. case 'IBM-THAI':
  7873. case 'CSIBMTHAI':
  7874. return 'IBM-Thai';
  7875. case 'HP-LEGAL':
  7876. case 'CSHPLEGAL':
  7877. return 'HP-Legal';
  7878. case 'HP-PI-FONT':
  7879. case 'CSHPPIFONT':
  7880. return 'HP-Pi-font';
  7881. case 'HP-MATH8':
  7882. case 'CSHPMATH8':
  7883. return 'HP-Math8';
  7884. case 'ADOBE-SYMBOL-ENCODING':
  7885. case 'CSHPPSMATH':
  7886. return 'Adobe-Symbol-Encoding';
  7887. case 'HP-DESKTOP':
  7888. case 'CSHPDESKTOP':
  7889. return 'HP-DeskTop';
  7890. case 'VENTURA-MATH':
  7891. case 'CSVENTURAMATH':
  7892. return 'Ventura-Math';
  7893. case 'MICROSOFT-PUBLISHING':
  7894. case 'CSMICROSOFTPUBLISHING':
  7895. return 'Microsoft-Publishing';
  7896. case 'WINDOWS-31J':
  7897. case 'CSWINDOWS31J':
  7898. return 'Windows-31J';
  7899. case 'GB2312':
  7900. case 'CSGB2312':
  7901. return 'GB2312';
  7902. case 'BIG5':
  7903. case 'CSBIG5':
  7904. return 'Big5';
  7905. case 'MACINTOSH':
  7906. case 'MAC':
  7907. case 'CSMACINTOSH':
  7908. return 'macintosh';
  7909. case 'IBM037':
  7910. case 'CP037':
  7911. case 'EBCDIC-CP-US':
  7912. case 'EBCDIC-CP-CA':
  7913. case 'EBCDIC-CP-WT':
  7914. case 'EBCDIC-CP-NL':
  7915. case 'CSIBM037':
  7916. return 'IBM037';
  7917. case 'IBM038':
  7918. case 'EBCDIC-INT':
  7919. case 'CP038':
  7920. case 'CSIBM038':
  7921. return 'IBM038';
  7922. case 'IBM273':
  7923. case 'CP273':
  7924. case 'CSIBM273':
  7925. return 'IBM273';
  7926. case 'IBM274':
  7927. case 'EBCDIC-BE':
  7928. case 'CP274':
  7929. case 'CSIBM274':
  7930. return 'IBM274';
  7931. case 'IBM275':
  7932. case 'EBCDIC-BR':
  7933. case 'CP275':
  7934. case 'CSIBM275':
  7935. return 'IBM275';
  7936. case 'IBM277':
  7937. case 'EBCDIC-CP-DK':
  7938. case 'EBCDIC-CP-NO':
  7939. case 'CSIBM277':
  7940. return 'IBM277';
  7941. case 'IBM278':
  7942. case 'CP278':
  7943. case 'EBCDIC-CP-FI':
  7944. case 'EBCDIC-CP-SE':
  7945. case 'CSIBM278':
  7946. return 'IBM278';
  7947. case 'IBM280':
  7948. case 'CP280':
  7949. case 'EBCDIC-CP-IT':
  7950. case 'CSIBM280':
  7951. return 'IBM280';
  7952. case 'IBM281':
  7953. case 'EBCDIC-JP-E':
  7954. case 'CP281':
  7955. case 'CSIBM281':
  7956. return 'IBM281';
  7957. case 'IBM284':
  7958. case 'CP284':
  7959. case 'EBCDIC-CP-ES':
  7960. case 'CSIBM284':
  7961. return 'IBM284';
  7962. case 'IBM285':
  7963. case 'CP285':
  7964. case 'EBCDIC-CP-GB':
  7965. case 'CSIBM285':
  7966. return 'IBM285';
  7967. case 'IBM290':
  7968. case 'CP290':
  7969. case 'EBCDIC-JP-KANA':
  7970. case 'CSIBM290':
  7971. return 'IBM290';
  7972. case 'IBM297':
  7973. case 'CP297':
  7974. case 'EBCDIC-CP-FR':
  7975. case 'CSIBM297':
  7976. return 'IBM297';
  7977. case 'IBM420':
  7978. case 'CP420':
  7979. case 'EBCDIC-CP-AR1':
  7980. case 'CSIBM420':
  7981. return 'IBM420';
  7982. case 'IBM423':
  7983. case 'CP423':
  7984. case 'EBCDIC-CP-GR':
  7985. case 'CSIBM423':
  7986. return 'IBM423';
  7987. case 'IBM424':
  7988. case 'CP424':
  7989. case 'EBCDIC-CP-HE':
  7990. case 'CSIBM424':
  7991. return 'IBM424';
  7992. case 'IBM437':
  7993. case 'CP437':
  7994. case '437':
  7995. case 'CSPC8CODEPAGE437':
  7996. return 'IBM437';
  7997. case 'IBM500':
  7998. case 'CP500':
  7999. case 'EBCDIC-CP-BE':
  8000. case 'EBCDIC-CP-CH':
  8001. case 'CSIBM500':
  8002. return 'IBM500';
  8003. case 'IBM851':
  8004. case 'CP851':
  8005. case '851':
  8006. case 'CSIBM851':
  8007. return 'IBM851';
  8008. case 'IBM852':
  8009. case 'CP852':
  8010. case '852':
  8011. case 'CSPCP852':
  8012. return 'IBM852';
  8013. case 'IBM855':
  8014. case 'CP855':
  8015. case '855':
  8016. case 'CSIBM855':
  8017. return 'IBM855';
  8018. case 'IBM857':
  8019. case 'CP857':
  8020. case '857':
  8021. case 'CSIBM857':
  8022. return 'IBM857';
  8023. case 'IBM860':
  8024. case 'CP860':
  8025. case '860':
  8026. case 'CSIBM860':
  8027. return 'IBM860';
  8028. case 'IBM861':
  8029. case 'CP861':
  8030. case '861':
  8031. case 'CP-IS':
  8032. case 'CSIBM861':
  8033. return 'IBM861';
  8034. case 'IBM863':
  8035. case 'CP863':
  8036. case '863':
  8037. case 'CSIBM863':
  8038. return 'IBM863';
  8039. case 'IBM864':
  8040. case 'CP864':
  8041. case 'CSIBM864':
  8042. return 'IBM864';
  8043. case 'IBM865':
  8044. case 'CP865':
  8045. case '865':
  8046. case 'CSIBM865':
  8047. return 'IBM865';
  8048. case 'IBM868':
  8049. case 'CP868':
  8050. case 'CP-AR':
  8051. case 'CSIBM868':
  8052. return 'IBM868';
  8053. case 'IBM869':
  8054. case 'CP869':
  8055. case '869':
  8056. case 'CP-GR':
  8057. case 'CSIBM869':
  8058. return 'IBM869';
  8059. case 'IBM870':
  8060. case 'CP870':
  8061. case 'EBCDIC-CP-ROECE':
  8062. case 'EBCDIC-CP-YU':
  8063. case 'CSIBM870':
  8064. return 'IBM870';
  8065. case 'IBM871':
  8066. case 'CP871':
  8067. case 'EBCDIC-CP-IS':
  8068. case 'CSIBM871':
  8069. return 'IBM871';
  8070. case 'IBM880':
  8071. case 'CP880':
  8072. case 'EBCDIC-CYRILLIC':
  8073. case 'CSIBM880':
  8074. return 'IBM880';
  8075. case 'IBM891':
  8076. case 'CP891':
  8077. case 'CSIBM891':
  8078. return 'IBM891';
  8079. case 'IBM903':
  8080. case 'CP903':
  8081. case 'CSIBM903':
  8082. return 'IBM903';
  8083. case 'IBM904':
  8084. case 'CP904':
  8085. case '904':
  8086. case 'CSIBBM904':
  8087. return 'IBM904';
  8088. case 'IBM905':
  8089. case 'CP905':
  8090. case 'EBCDIC-CP-TR':
  8091. case 'CSIBM905':
  8092. return 'IBM905';
  8093. case 'IBM918':
  8094. case 'CP918':
  8095. case 'EBCDIC-CP-AR2':
  8096. case 'CSIBM918':
  8097. return 'IBM918';
  8098. case 'IBM1026':
  8099. case 'CP1026':
  8100. case 'CSIBM1026':
  8101. return 'IBM1026';
  8102. case 'EBCDIC-AT-DE':
  8103. case 'CSIBMEBCDICATDE':
  8104. return 'EBCDIC-AT-DE';
  8105. case 'EBCDIC-AT-DE-A':
  8106. case 'CSEBCDICATDEA':
  8107. return 'EBCDIC-AT-DE-A';
  8108. case 'EBCDIC-CA-FR':
  8109. case 'CSEBCDICCAFR':
  8110. return 'EBCDIC-CA-FR';
  8111. case 'EBCDIC-DK-NO':
  8112. case 'CSEBCDICDKNO':
  8113. return 'EBCDIC-DK-NO';
  8114. case 'EBCDIC-DK-NO-A':
  8115. case 'CSEBCDICDKNOA':
  8116. return 'EBCDIC-DK-NO-A';
  8117. case 'EBCDIC-FI-SE':
  8118. case 'CSEBCDICFISE':
  8119. return 'EBCDIC-FI-SE';
  8120. case 'EBCDIC-FI-SE-A':
  8121. case 'CSEBCDICFISEA':
  8122. return 'EBCDIC-FI-SE-A';
  8123. case 'EBCDIC-FR':
  8124. case 'CSEBCDICFR':
  8125. return 'EBCDIC-FR';
  8126. case 'EBCDIC-IT':
  8127. case 'CSEBCDICIT':
  8128. return 'EBCDIC-IT';
  8129. case 'EBCDIC-PT':
  8130. case 'CSEBCDICPT':
  8131. return 'EBCDIC-PT';
  8132. case 'EBCDIC-ES':
  8133. case 'CSEBCDICES':
  8134. return 'EBCDIC-ES';
  8135. case 'EBCDIC-ES-A':
  8136. case 'CSEBCDICESA':
  8137. return 'EBCDIC-ES-A';
  8138. case 'EBCDIC-ES-S':
  8139. case 'CSEBCDICESS':
  8140. return 'EBCDIC-ES-S';
  8141. case 'EBCDIC-UK':
  8142. case 'CSEBCDICUK':
  8143. return 'EBCDIC-UK';
  8144. case 'EBCDIC-US':
  8145. case 'CSEBCDICUS':
  8146. return 'EBCDIC-US';
  8147. case 'UNKNOWN-8BIT':
  8148. case 'CSUNKNOWN8BIT':
  8149. return 'UNKNOWN-8BIT';
  8150. case 'MNEMONIC':
  8151. case 'CSMNEMONIC':
  8152. return 'MNEMONIC';
  8153. case 'MNEM':
  8154. case 'CSMNEM':
  8155. return 'MNEM';
  8156. case 'VISCII':
  8157. case 'CSVISCII':
  8158. return 'VISCII';
  8159. case 'VIQR':
  8160. case 'CSVIQR':
  8161. return 'VIQR';
  8162. case 'KOI8-R':
  8163. case 'CSKOI8R':
  8164. return 'KOI8-R';
  8165. case 'HZ-GB-2312':
  8166. return 'HZ-GB-2312';
  8167. case 'IBM866':
  8168. case 'CP866':
  8169. case '866':
  8170. case 'CSIBM866':
  8171. return 'IBM866';
  8172. case 'IBM775':
  8173. case 'CP775':
  8174. case 'CSPC775BALTIC':
  8175. return 'IBM775';
  8176. case 'KOI8-U':
  8177. return 'KOI8-U';
  8178. case 'IBM00858':
  8179. case 'CCSID00858':
  8180. case 'CP00858':
  8181. case 'PC-MULTILINGUAL-850+EURO':
  8182. return 'IBM00858';
  8183. case 'IBM00924':
  8184. case 'CCSID00924':
  8185. case 'CP00924':
  8186. case 'EBCDIC-LATIN9--EURO':
  8187. return 'IBM00924';
  8188. case 'IBM01140':
  8189. case 'CCSID01140':
  8190. case 'CP01140':
  8191. case 'EBCDIC-US-37+EURO':
  8192. return 'IBM01140';
  8193. case 'IBM01141':
  8194. case 'CCSID01141':
  8195. case 'CP01141':
  8196. case 'EBCDIC-DE-273+EURO':
  8197. return 'IBM01141';
  8198. case 'IBM01142':
  8199. case 'CCSID01142':
  8200. case 'CP01142':
  8201. case 'EBCDIC-DK-277+EURO':
  8202. case 'EBCDIC-NO-277+EURO':
  8203. return 'IBM01142';
  8204. case 'IBM01143':
  8205. case 'CCSID01143':
  8206. case 'CP01143':
  8207. case 'EBCDIC-FI-278+EURO':
  8208. case 'EBCDIC-SE-278+EURO':
  8209. return 'IBM01143';
  8210. case 'IBM01144':
  8211. case 'CCSID01144':
  8212. case 'CP01144':
  8213. case 'EBCDIC-IT-280+EURO':
  8214. return 'IBM01144';
  8215. case 'IBM01145':
  8216. case 'CCSID01145':
  8217. case 'CP01145':
  8218. case 'EBCDIC-ES-284+EURO':
  8219. return 'IBM01145';
  8220. case 'IBM01146':
  8221. case 'CCSID01146':
  8222. case 'CP01146':
  8223. case 'EBCDIC-GB-285+EURO':
  8224. return 'IBM01146';
  8225. case 'IBM01147':
  8226. case 'CCSID01147':
  8227. case 'CP01147':
  8228. case 'EBCDIC-FR-297+EURO':
  8229. return 'IBM01147';
  8230. case 'IBM01148':
  8231. case 'CCSID01148':
  8232. case 'CP01148':
  8233. case 'EBCDIC-INTERNATIONAL-500+EURO':
  8234. return 'IBM01148';
  8235. case 'IBM01149':
  8236. case 'CCSID01149':
  8237. case 'CP01149':
  8238. case 'EBCDIC-IS-871+EURO':
  8239. return 'IBM01149';
  8240. case 'BIG5-HKSCS':
  8241. return 'Big5-HKSCS';
  8242. case 'IBM1047':
  8243. case 'IBM-1047':
  8244. return 'IBM1047';
  8245. case 'PTCP154':
  8246. case 'CSPTCP154':
  8247. case 'PT154':
  8248. case 'CP154':
  8249. case 'CYRILLIC-ASIAN':
  8250. return 'PTCP154';
  8251. case 'AMIGA-1251':
  8252. case 'AMI1251':
  8253. case 'AMIGA1251':
  8254. case 'AMI-1251':
  8255. return 'Amiga-1251';
  8256. case 'KOI7-SWITCHED':
  8257. return 'KOI7-switched';
  8258. case 'BRF':
  8259. case 'CSBRF':
  8260. return 'BRF';
  8261. case 'TSCII':
  8262. case 'CSTSCII':
  8263. return 'TSCII';
  8264. case 'WINDOWS-1250':
  8265. return 'windows-1250';
  8266. case 'WINDOWS-1251':
  8267. return 'windows-1251';
  8268. case 'WINDOWS-1252':
  8269. return 'windows-1252';
  8270. case 'WINDOWS-1253':
  8271. return 'windows-1253';
  8272. case 'WINDOWS-1254':
  8273. return 'windows-1254';
  8274. case 'WINDOWS-1255':
  8275. return 'windows-1255';
  8276. case 'WINDOWS-1256':
  8277. return 'windows-1256';
  8278. case 'WINDOWS-1257':
  8279. return 'windows-1257';
  8280. case 'WINDOWS-1258':
  8281. return 'windows-1258';
  8282. default:
  8283. return (string) $encoding;
  8284. }
  8285. }
  8286. function get_curl_version()
  8287. {
  8288. if (is_array($curl = curl_version()))
  8289. {
  8290. $curl = $curl['version'];
  8291. }
  8292. elseif (substr($curl, 0, 5) == 'curl/')
  8293. {
  8294. $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
  8295. }
  8296. elseif (substr($curl, 0, 8) == 'libcurl/')
  8297. {
  8298. $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
  8299. }
  8300. else
  8301. {
  8302. $curl = 0;
  8303. }
  8304. return $curl;
  8305. }
  8306. function is_subclass_of($class1, $class2)
  8307. {
  8308. if (func_num_args() != 2)
  8309. {
  8310. trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
  8311. }
  8312. elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
  8313. {
  8314. return is_subclass_of($class1, $class2);
  8315. }
  8316. elseif (is_string($class1) && is_string($class2))
  8317. {
  8318. if (class_exists($class1))
  8319. {
  8320. if (class_exists($class2))
  8321. {
  8322. $class2 = strtolower($class2);
  8323. while ($class1 = strtolower(get_parent_class($class1)))
  8324. {
  8325. if ($class1 == $class2)
  8326. {
  8327. return true;
  8328. }
  8329. }
  8330. }
  8331. }
  8332. else
  8333. {
  8334. trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
  8335. }
  8336. }
  8337. return false;
  8338. }
  8339. /**
  8340. * Strip HTML comments
  8341. *
  8342. * @access public
  8343. * @param string $data Data to strip comments from
  8344. * @return string Comment stripped string
  8345. */
  8346. function strip_comments($data)
  8347. {
  8348. $output = '';
  8349. while (($start = strpos($data, '<!--')) !== false)
  8350. {
  8351. $output .= substr($data, 0, $start);
  8352. if (($end = strpos($data, '-->', $start)) !== false)
  8353. {
  8354. $data = substr_replace($data, '', 0, $end + 3);
  8355. }
  8356. else
  8357. {
  8358. $data = '';
  8359. }
  8360. }
  8361. return $output . $data;
  8362. }
  8363. function parse_date($dt, $rfc822_tz = true)
  8364. {
  8365. static $cache = array();
  8366. if (!isset($cache[$dt][$rfc822_tz]))
  8367. {
  8368. $dt = SimplePie_Misc::uncomment_rfc822($dt);
  8369. /*
  8370. Capturing subpatterns:
  8371. 1: RFC 822 date
  8372. 2: RFC 822 day
  8373. 3: RFC 822 month
  8374. 4: RFC 822 year
  8375. 5: ISO 8601 date
  8376. 6: ISO 8601 century
  8377. 7: ISO 8601 year
  8378. 8: ISO 8601 month
  8379. 9: ISO 8601 day
  8380. 10: ISO 8601 ordinal day
  8381. 11: ISO 8601 month
  8382. 12: ISO 8601 day
  8383. 13: ISO 8601 week
  8384. 14: ISO 8601 day of week
  8385. 15: Time
  8386. 16: Hour
  8387. 17: Hour Decimal
  8388. 18: Minute
  8389. 19: Minute Decimal
  8390. 20: Second
  8391. 21: Second Decimal
  8392. 22: Timezone
  8393. 23: Diff Âą
  8394. 24: Hour
  8395. 25: Hour Decimal
  8396. 26: Minute
  8397. 27: Minute Decimal
  8398. 28: Alphabetic Timezone
  8399. */
  8400. if (preg_match('/^(?:(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)[,\s]+)?(([0-9]{1,2})\s*(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s*([0-9]{4}|[0-9]{2}))|(([0-9]{2})(?:([0-9]{2})(?:(?:-|\s)*(?:([0-9]{2})([0-9]{2})|([0-9]{3})|([0-9]{2})(?:(?:-|\s)*([0-9]{2}))?|W([0-9]{2})(?:(?:-|\s)*([0-9]))?))?)?))((?:T|\s)+([0-9]{2})(?:(?:,|\.)([0-9]*)|(?:\:|\s)*([0-9]{2})(?:(?:,|\.)([0-9]*)|(?:\:|\s)*([0-9]{2})(?:(?:,|\.)([0-9]*))?)?)?(?:\s)*((?:(\+|-)([0-9]{2})(?:(?:,|\.)([0-9]*)|(?:\:|\s)*(?:([0-9]{2})(?:(?:,|\.)([0-9]*))?))?)|(UTC|GMT|EST|CST|MST|PST|EDT|CDT|MDT|PDT|UT|[A-IK-Z]))?)?$/i', $dt, $match))
  8401. {
  8402. // Fill all matches
  8403. for ($i = count($match); $i <= 28; $i++)
  8404. {
  8405. $match[$i] = '';
  8406. }
  8407. // Set blank vars
  8408. $year = 1970;
  8409. $month = 1;
  8410. $day = 1;
  8411. $hour = 0;
  8412. $minute = 0;
  8413. $second = 0;
  8414. $timezone = false;
  8415. // RFC 822
  8416. if ($match[1] !== '')
  8417. {
  8418. if (strlen($match[4]) == 2)
  8419. {
  8420. $year = ($match[4] < 70) ? "20$match[4]" : "19$match[4]";
  8421. }
  8422. else
  8423. {
  8424. $year = $match[4];
  8425. }
  8426. switch (strtolower($match[3]))
  8427. {
  8428. case 'jan':
  8429. $month = 1;
  8430. break;
  8431. case 'feb':
  8432. $month = 2;
  8433. break;
  8434. case 'mar':
  8435. $month = 3;
  8436. break;
  8437. case 'apr':
  8438. $month = 4;
  8439. break;
  8440. case 'may':
  8441. $month = 5;
  8442. break;
  8443. case 'jun':
  8444. $month = 6;
  8445. break;
  8446. case 'jul':
  8447. $month = 7;
  8448. break;
  8449. case 'aug':
  8450. $month = 8;
  8451. break;
  8452. case 'sep':
  8453. $month = 9;
  8454. break;
  8455. case 'oct':
  8456. $month = 10;
  8457. break;
  8458. case 'nov':
  8459. $month = 11;
  8460. break;
  8461. case 'dec':
  8462. $month = 12;
  8463. break;
  8464. }
  8465. $day = $match[2];
  8466. }
  8467. // ISO 8601
  8468. else
  8469. {
  8470. // Year
  8471. if ($match[7] !== '')
  8472. {
  8473. $year = "$match[6]$match[7]";
  8474. // Two Digit Month/Day
  8475. if ($match[11] !== '')
  8476. {
  8477. $month = $match[11];
  8478. if ($match[12] !== '')
  8479. {
  8480. $day = $match[12];
  8481. }
  8482. }
  8483. // Four Digit Month/Day
  8484. elseif ($match[8] !== '')
  8485. {
  8486. $month = $match[8];
  8487. $day = $match[9];
  8488. }
  8489. // Ordinal Day
  8490. elseif ($match[10] !== '')
  8491. {
  8492. $day = $match[10];
  8493. }
  8494. // Week Date
  8495. elseif ($match[13] !== '')
  8496. {
  8497. // Week Day
  8498. if ($match[14] !== '')
  8499. {
  8500. $day = $match[14];
  8501. }
  8502. $first_day_of_year = date('w', mktime(0, 0, 0, 1, 1, $year));
  8503. if ($first_day_of_year == 0)
  8504. {
  8505. $first_day_of_year = 7;
  8506. }
  8507. $day = 7 * ($match[13] - 1) + $day - ($first_day_of_year - 1);
  8508. }
  8509. }
  8510. else
  8511. {
  8512. $year = "$match[6]00";
  8513. }
  8514. }
  8515. // Time
  8516. if ($match[15] !== '')
  8517. {
  8518. $time = 0;
  8519. $time += ($match[16] + ('.' . $match[17])) * 3600;
  8520. $time += ($match[18] + ('.' . $match[19])) * 60;
  8521. $time += $match[20] + ('.' . $match[21]);
  8522. $hour = floor($time / 3600);
  8523. $time -= $hour * 3600;
  8524. $minute = floor($time / 60);
  8525. $time -= $minute * 60;
  8526. $second = round($time);
  8527. // Timezone
  8528. if ($match[22] !== '')
  8529. {
  8530. // Alphabetic Timezone
  8531. if ($match[28] !== '')
  8532. {
  8533. // Military
  8534. if (strlen($match[28]) == 1)
  8535. {
  8536. if ($match[28] == 'Z' || $match[28] == 'z' || !$rfc822_tz)
  8537. {
  8538. $timezone = 0;
  8539. }
  8540. else
  8541. {
  8542. $timezone = ord(strtoupper($match[28]));
  8543. if ($timezone > 74)
  8544. {
  8545. $timezone--;
  8546. }
  8547. if ($timezone <= 76)
  8548. {
  8549. $timezone = -($timezone - 64);
  8550. }
  8551. else
  8552. {
  8553. $timezone -= 76;
  8554. }
  8555. $timezone *= 3600;
  8556. }
  8557. }
  8558. // Code
  8559. else
  8560. {
  8561. switch (strtoupper($match[28]))
  8562. {
  8563. case 'UT':
  8564. case 'UTC':
  8565. case 'GMT':
  8566. $timezone = 0;
  8567. break;
  8568. case 'EST':
  8569. $timezone = -18000;
  8570. break;
  8571. case 'CST':
  8572. $timezone = -21600;
  8573. break;
  8574. case 'MST':
  8575. $timezone = -25200;
  8576. break;
  8577. case 'PST':
  8578. $timezone = -28800;
  8579. break;
  8580. case 'EDT':
  8581. $timezone = -14400;
  8582. break;
  8583. case 'CDT':
  8584. $timezone = -18000;
  8585. break;
  8586. case 'MDT':
  8587. $timezone = -21600;
  8588. break;
  8589. case 'PDT':
  8590. $timezone = -25200;
  8591. break;
  8592. }
  8593. }
  8594. }
  8595. // Timezone difference from UTC
  8596. else
  8597. {
  8598. $timezone = 0;
  8599. $timezone += ($match[24] + ('.' . $match[25])) * 3600;
  8600. $timezone += ($match[26] + ('.' . $match[27])) * 60;
  8601. $timezone = (int) round($timezone);
  8602. if ($match[23] == '-')
  8603. {
  8604. $timezone = -$timezone;
  8605. }
  8606. }
  8607. }
  8608. }
  8609. if ($timezone === false)
  8610. {
  8611. $cache[$dt][$rfc822_tz] = mktime($hour, $minute, $second, $month, $day, $year);
  8612. }
  8613. else
  8614. {
  8615. $cache[$dt][$rfc822_tz] = gmmktime($hour, $minute, $second, $month, $day, $year) - $timezone;
  8616. }
  8617. }
  8618. elseif (($time = strtotime($dt)) > 0)
  8619. {
  8620. $cache[$dt][$rfc822_tz] = $time;
  8621. }
  8622. else
  8623. {
  8624. $cache[$dt][$rfc822_tz] = false;
  8625. }
  8626. }
  8627. return $cache[$dt][$rfc822_tz];
  8628. }
  8629. /**
  8630. * Decode HTML entities
  8631. *
  8632. * @static
  8633. * @access public
  8634. * @param string $data Input data
  8635. * @return string Output data
  8636. */
  8637. function entities_decode($data)
  8638. {
  8639. $decoder = new SimplePie_Decode_HTML_Entities($data);
  8640. return $decoder->parse();
  8641. }
  8642. /**
  8643. * Remove RFC822 comments
  8644. *
  8645. * @author Tomas V.V.Cox <cox@idecnet.com>
  8646. * @author Pierre-Alain Joye <pajoye@php.net>
  8647. * @author Amir Mohammad Saied <amir@php.net>
  8648. * @copyright 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox,Amir Mohammad Saied
  8649. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  8650. * @version CVS: $Id: Validate.php,v 1.104 2006/11/17 16:32:06 amir Exp $
  8651. * @link http://pear.php.net/package/Validate
  8652. * @access public
  8653. * @param string $data Data to strip comments from
  8654. * @return string Comment stripped string
  8655. */
  8656. function uncomment_rfc822($data)
  8657. {
  8658. if ((version_compare(PHP_VERSION, '4.4.6', '>=') && version_compare(PHP_VERSION, '5', '<')) || version_compare(PHP_VERSION, '5.2.2', '>='))
  8659. {
  8660. return $data;
  8661. }
  8662. else
  8663. {
  8664. return preg_replace('/((?:(?:\\\\"|[^("])*(?:"(?:[^"\\\\\r]|\\\\.)*"\s*)?)*)((?<!\\\\)\((?:(?2)|.)*?(?<!\\\\)\))/', '$1', $data);
  8665. }
  8666. }
  8667. function parse_mime($mime)
  8668. {
  8669. if (($pos = strpos($mime, ';')) === false)
  8670. {
  8671. return trim($mime);
  8672. }
  8673. else
  8674. {
  8675. return trim(substr($mime, 0, $pos));
  8676. }
  8677. }
  8678. function htmlspecialchars_decode($string, $quote_style)
  8679. {
  8680. if (function_exists('htmlspecialchars_decode'))
  8681. {
  8682. return htmlspecialchars_decode($string, $quote_style);
  8683. }
  8684. else
  8685. {
  8686. return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
  8687. }
  8688. }
  8689. function atom_03_construct_type($attribs)
  8690. {
  8691. if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
  8692. {
  8693. $mode = SIMPLEPIE_CONSTRUCT_BASE64;
  8694. }
  8695. else
  8696. {
  8697. $mode = SIMPLEPIE_CONSTRUCT_NONE;
  8698. }
  8699. if (isset($attribs['']['type']))
  8700. {
  8701. switch (strtolower(trim($attribs['']['type'])))
  8702. {
  8703. case 'text':
  8704. case 'text/plain':
  8705. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  8706. case 'html':
  8707. case 'text/html':
  8708. return SIMPLEPIE_CONSTRUCT_HTML | $mode;
  8709. case 'xhtml':
  8710. case 'application/xhtml+xml':
  8711. return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
  8712. default:
  8713. return SIMPLEPIE_CONSTRUCT_NONE | $mode;
  8714. }
  8715. }
  8716. else
  8717. {
  8718. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  8719. }
  8720. }
  8721. function atom_10_construct_type($attribs)
  8722. {
  8723. if (isset($attribs['']['type']))
  8724. {
  8725. switch (strtolower(trim($attribs['']['type'])))
  8726. {
  8727. case 'text':
  8728. return SIMPLEPIE_CONSTRUCT_TEXT;
  8729. case 'html':
  8730. return SIMPLEPIE_CONSTRUCT_HTML;
  8731. case 'xhtml':
  8732. return SIMPLEPIE_CONSTRUCT_XHTML;
  8733. default:
  8734. return SIMPLEPIE_CONSTRUCT_NONE;
  8735. }
  8736. }
  8737. return SIMPLEPIE_CONSTRUCT_TEXT;
  8738. }
  8739. function atom_10_content_construct_type($attribs)
  8740. {
  8741. if (isset($attribs['']['type']))
  8742. {
  8743. $type = strtolower(trim($attribs['']['type']));
  8744. switch ($type)
  8745. {
  8746. case 'text':
  8747. return SIMPLEPIE_CONSTRUCT_TEXT;
  8748. case 'html':
  8749. return SIMPLEPIE_CONSTRUCT_HTML;
  8750. case 'xhtml':
  8751. return SIMPLEPIE_CONSTRUCT_XHTML;
  8752. }
  8753. if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
  8754. {
  8755. return SIMPLEPIE_CONSTRUCT_NONE;
  8756. }
  8757. else
  8758. {
  8759. return SIMPLEPIE_CONSTRUCT_BASE64;
  8760. }
  8761. }
  8762. else
  8763. {
  8764. return SIMPLEPIE_CONSTRUCT_TEXT;
  8765. }
  8766. }
  8767. function is_isegment_nz_nc($string)
  8768. {
  8769. 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);
  8770. }
  8771. function space_seperated_tokens($string)
  8772. {
  8773. $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
  8774. $string_length = strlen($string);
  8775. $position = strspn($string, $space_characters);
  8776. $tokens = array();
  8777. while ($position < $string_length)
  8778. {
  8779. $len = strcspn($string, $space_characters, $position);
  8780. $tokens[] = substr($string, $position, $len);
  8781. $position += $len;
  8782. $position += strspn($string, $space_characters, $position);
  8783. }
  8784. return $tokens;
  8785. }
  8786. function array_unique($array)
  8787. {
  8788. if (version_compare(PHP_VERSION, '5.2', '>='))
  8789. {
  8790. return array_unique($array);
  8791. }
  8792. else
  8793. {
  8794. $array = (array) $array;
  8795. $new_array = array();
  8796. $new_array_strings = array();
  8797. foreach ($array as $key => $value)
  8798. {
  8799. if (is_object($value))
  8800. {
  8801. if (method_exists($value, '__toString'))
  8802. {
  8803. $cmp = $value->__toString();
  8804. }
  8805. else
  8806. {
  8807. trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
  8808. }
  8809. }
  8810. elseif (is_array($value))
  8811. {
  8812. $cmp = (string) reset($value);
  8813. }
  8814. else
  8815. {
  8816. $cmp = (string) $value;
  8817. }
  8818. if (!in_array($cmp, $new_array_strings))
  8819. {
  8820. $new_array[$key] = $value;
  8821. $new_array_strings[] = $cmp;
  8822. }
  8823. }
  8824. return $new_array;
  8825. }
  8826. }
  8827. /**
  8828. * Converts a unicode codepoint to a UTF-8 character
  8829. *
  8830. * @static
  8831. * @access public
  8832. * @param int $codepoint Unicode codepoint
  8833. * @return string UTF-8 character
  8834. */
  8835. function codepoint_to_utf8($codepoint)
  8836. {
  8837. static $cache = array();
  8838. $codepoint = (int) $codepoint;
  8839. if (isset($cache[$codepoint]))
  8840. {
  8841. return $cache[$codepoint];
  8842. }
  8843. elseif ($codepoint < 0)
  8844. {
  8845. return $cache[$codepoint] = false;
  8846. }
  8847. else if ($codepoint <= 0x7f)
  8848. {
  8849. return $cache[$codepoint] = chr($codepoint);
  8850. }
  8851. else if ($codepoint <= 0x7ff)
  8852. {
  8853. return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
  8854. }
  8855. else if ($codepoint <= 0xffff)
  8856. {
  8857. return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  8858. }
  8859. else if ($codepoint <= 0x10ffff)
  8860. {
  8861. return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  8862. }
  8863. else
  8864. {
  8865. // U+FFFD REPLACEMENT CHARACTER
  8866. return $cache[$codepoint] = "\xEF\xBF\xBD";
  8867. }
  8868. }
  8869. /**
  8870. * Re-implementation of PHP 4.2.0's is_a()
  8871. *
  8872. * @static
  8873. * @access public
  8874. * @param object $object The tested object
  8875. * @param string $class_name The class name
  8876. * @return bool Returns true if the object is of this class or has this class as one of its parents, false otherwise
  8877. */
  8878. function is_a($object, $class_name)
  8879. {
  8880. if (function_exists('is_a'))
  8881. {
  8882. return is_a($object, $class_name);
  8883. }
  8884. elseif (!is_object($object))
  8885. {
  8886. return false;
  8887. }
  8888. elseif (get_class($object) == strtolower($class_name))
  8889. {
  8890. return true;
  8891. }
  8892. else
  8893. {
  8894. return is_subclass_of($object, $class_name);
  8895. }
  8896. }
  8897. /**
  8898. * Re-implementation of PHP 5's stripos()
  8899. *
  8900. * Returns the numeric position of the first occurrence of needle in the
  8901. * haystack string.
  8902. *
  8903. * @static
  8904. * @access string
  8905. * @param object $haystack
  8906. * @param string $needle Note that the needle may be a string of one or more
  8907. * characters. If needle is not a string, it is converted to an integer
  8908. * and applied as the ordinal value of a character.
  8909. * @param int $offset The optional offset parameter allows you to specify which
  8910. * character in haystack to start searching. The position returned is still
  8911. * relative to the beginning of haystack.
  8912. * @return bool If needle is not found, stripos() will return boolean false.
  8913. */
  8914. function stripos($haystack, $needle, $offset = 0)
  8915. {
  8916. if (function_exists('stripos'))
  8917. {
  8918. return stripos($haystack, $needle, $offset);
  8919. }
  8920. else
  8921. {
  8922. if (is_string($needle))
  8923. {
  8924. $needle = strtolower($needle);
  8925. }
  8926. elseif (is_int($needle) || is_bool($needle) || is_double($needle))
  8927. {
  8928. $needle = strtolower(chr($needle));
  8929. }
  8930. else
  8931. {
  8932. trigger_error('needle is not a string or an integer', E_USER_WARNING);
  8933. return false;
  8934. }
  8935. return strpos(strtolower($haystack), $needle, $offset);
  8936. }
  8937. }
  8938. }
  8939. /**
  8940. * Decode HTML Entities
  8941. *
  8942. * This implements HTML5 as of revision 967 (2007-06-28)
  8943. *
  8944. * @package SimplePie
  8945. */
  8946. class SimplePie_Decode_HTML_Entities
  8947. {
  8948. /**
  8949. * Data to be parsed
  8950. *
  8951. * @access private
  8952. * @var string
  8953. */
  8954. var $data = '';
  8955. /**
  8956. * Currently consumed bytes
  8957. *
  8958. * @access private
  8959. * @var string
  8960. */
  8961. var $consumed = '';
  8962. /**
  8963. * Position of the current byte being parsed
  8964. *
  8965. * @access private
  8966. * @var int
  8967. */
  8968. var $position = 0;
  8969. /**
  8970. * Create an instance of the class with the input data
  8971. *
  8972. * @access public
  8973. * @param string $data Input data
  8974. */
  8975. function SimplePie_Decode_HTML_Entities($data)
  8976. {
  8977. $this->data = $data;
  8978. }
  8979. /**
  8980. * Parse the input data
  8981. *
  8982. * @access public
  8983. * @return string Output data
  8984. */
  8985. function parse()
  8986. {
  8987. while (($this->position = strpos($this->data, '&', $this->position)) !== false)
  8988. {
  8989. $this->consume();
  8990. $this->entity();
  8991. $this->consumed = '';
  8992. }
  8993. return $this->data;
  8994. }
  8995. /**
  8996. * Consume the next byte
  8997. *
  8998. * @access private
  8999. * @return mixed The next byte, or false, if there is no more data
  9000. */
  9001. function consume()
  9002. {
  9003. if (isset($this->data[$this->position]))
  9004. {
  9005. $this->consumed .= $this->data[$this->position];
  9006. return $this->data[$this->position++];
  9007. }
  9008. else
  9009. {
  9010. $this->consumed = false;
  9011. return false;
  9012. }
  9013. }
  9014. /**
  9015. * Consume a range of characters
  9016. *
  9017. * @access private
  9018. * @param string $chars Characters to consume
  9019. * @return mixed A series of characters that match the range, or false
  9020. */
  9021. function consume_range($chars)
  9022. {
  9023. if ($len = strspn($this->data, $chars, $this->position))
  9024. {
  9025. $data = substr($this->data, $this->position, $len);
  9026. $this->consumed .= $data;
  9027. $this->position += $len;
  9028. return $data;
  9029. }
  9030. else
  9031. {
  9032. $this->consumed = false;
  9033. return false;
  9034. }
  9035. }
  9036. /**
  9037. * Unconsume one byte
  9038. *
  9039. * @access private
  9040. */
  9041. function unconsume()
  9042. {
  9043. $this->consumed = substr($this->consumed, 0, -1);
  9044. $this->position--;
  9045. }
  9046. /**
  9047. * Decode an entity
  9048. *
  9049. * @access private
  9050. */
  9051. function entity()
  9052. {
  9053. switch ($this->consume())
  9054. {
  9055. case "\x09":
  9056. case "\x0A":
  9057. case "\x0B":
  9058. case "\x0B":
  9059. case "\x0C":
  9060. case "\x20":
  9061. case "\x3C":
  9062. case "\x26":
  9063. case false:
  9064. break;
  9065. case "\x23":
  9066. switch ($this->consume())
  9067. {
  9068. case "\x78":
  9069. case "\x58":
  9070. $range = '0123456789ABCDEFabcdef';
  9071. $hex = true;
  9072. break;
  9073. default:
  9074. $range = '0123456789';
  9075. $hex = false;
  9076. $this->unconsume();
  9077. break;
  9078. }
  9079. if ($codepoint = $this->consume_range($range))
  9080. {
  9081. 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");
  9082. if ($hex)
  9083. {
  9084. $codepoint = hexdec($codepoint);
  9085. }
  9086. else
  9087. {
  9088. $codepoint = intval($codepoint);
  9089. }
  9090. if (isset($windows_1252_specials[$codepoint]))
  9091. {
  9092. $replacement = $windows_1252_specials[$codepoint];
  9093. }
  9094. else
  9095. {
  9096. $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
  9097. }
  9098. if ($this->consume() != ';')
  9099. {
  9100. $this->unconsume();
  9101. }
  9102. $consumed_length = strlen($this->consumed);
  9103. $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
  9104. $this->position += strlen($replacement) - $consumed_length;
  9105. }
  9106. break;
  9107. default:
  9108. 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");
  9109. for ($i = 0, $match = null; $i < 9 && $this->consume(); $i++)
  9110. {
  9111. $consumed = substr($this->consumed, 1);
  9112. if (isset($entities[$consumed]))
  9113. {
  9114. $match = $consumed;
  9115. }
  9116. }
  9117. if ($match !== null)
  9118. {
  9119. $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
  9120. $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
  9121. }
  9122. break;
  9123. }
  9124. }
  9125. }
  9126. class SimplePie_Locator
  9127. {
  9128. var $useragent;
  9129. var $timeout;
  9130. var $file;
  9131. var $local = array();
  9132. var $elsewhere = array();
  9133. var $file_class = 'SimplePie_File';
  9134. var $cached_entities = array();
  9135. var $http_base;
  9136. var $base;
  9137. var $base_location = 0;
  9138. var $checked_feeds = 0;
  9139. var $max_checked_feeds = 10;
  9140. function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10)
  9141. {
  9142. $this->file =& $file;
  9143. $this->file_class = $file_class;
  9144. $this->useragent = $useragent;
  9145. $this->timeout = $timeout;
  9146. $this->max_checked_feeds = $max_checked_feeds;
  9147. }
  9148. function find($type = SIMPLEPIE_LOCATOR_ALL)
  9149. {
  9150. if ($this->is_feed($this->file))
  9151. {
  9152. return $this->file;
  9153. }
  9154. if ($type & ~SIMPLEPIE_LOCATOR_NONE)
  9155. {
  9156. $this->get_base();
  9157. }
  9158. if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
  9159. {
  9160. return $working;
  9161. }
  9162. if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
  9163. {
  9164. if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
  9165. {
  9166. return $working;
  9167. }
  9168. if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
  9169. {
  9170. return $working;
  9171. }
  9172. if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
  9173. {
  9174. return $working;
  9175. }
  9176. if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
  9177. {
  9178. return $working;
  9179. }
  9180. }
  9181. return null;
  9182. }
  9183. function is_feed(&$file)
  9184. {
  9185. $body = SimplePie_Misc::strip_comments($file->body);
  9186. if (preg_match('/<([^\s:]+:)?(rss|RDF|feed)' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/i', $body))
  9187. {
  9188. return true;
  9189. }
  9190. return false;
  9191. }
  9192. function get_base()
  9193. {
  9194. if (isset($this->file->headers['content-location']))
  9195. {
  9196. $this->http_base = SimplePie_Misc::absolutize_url(trim($this->file->headers['content-location']), $this->file->url);
  9197. }
  9198. else
  9199. {
  9200. $this->http_base = $this->file->url;
  9201. }
  9202. $this->base = $this->http_base;
  9203. $elements = SimplePie_Misc::get_element('base', $this->file->body);
  9204. foreach ($elements as $element)
  9205. {
  9206. if ($element['attribs']['href']['data'] !== '')
  9207. {
  9208. $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
  9209. $this->base_location = $element['offset'];
  9210. break;
  9211. }
  9212. }
  9213. }
  9214. function autodiscovery()
  9215. {
  9216. $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));
  9217. $done = array();
  9218. foreach ($links as $link)
  9219. {
  9220. if ($this->checked_feeds == $this->max_checked_feeds)
  9221. {
  9222. break;
  9223. }
  9224. if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
  9225. {
  9226. $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
  9227. if ($this->base_location < $link['offset'])
  9228. {
  9229. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
  9230. }
  9231. else
  9232. {
  9233. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
  9234. }
  9235. 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'))))
  9236. {
  9237. $this->checked_feeds++;
  9238. $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
  9239. if ($this->is_feed($feed))
  9240. {
  9241. return $feed;
  9242. }
  9243. }
  9244. $done[] = $href;
  9245. }
  9246. }
  9247. return null;
  9248. }
  9249. function get_links()
  9250. {
  9251. $links = SimplePie_Misc::get_element('a', $this->file->body);
  9252. foreach ($links as $link)
  9253. {
  9254. if (isset($link['attribs']['href']['data']))
  9255. {
  9256. $href = trim($link['attribs']['href']['data']);
  9257. $parsed = SimplePie_Misc::parse_url($href);
  9258. if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
  9259. {
  9260. if ($this->base_location < $link['offset'])
  9261. {
  9262. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
  9263. }
  9264. else
  9265. {
  9266. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
  9267. }
  9268. $current = SimplePie_Misc::parse_url($this->file->url);
  9269. if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
  9270. {
  9271. $this->local[] = $href;
  9272. }
  9273. else
  9274. {
  9275. $this->elsewhere[] = $href;
  9276. }
  9277. }
  9278. }
  9279. }
  9280. $this->local = array_unique($this->local);
  9281. $this->elsewhere = array_unique($this->elsewhere);
  9282. if (!empty($this->local) || !empty($this->elsewhere))
  9283. {
  9284. return true;
  9285. }
  9286. return null;
  9287. }
  9288. function extension(&$array)
  9289. {
  9290. foreach ($array as $key => $value)
  9291. {
  9292. if ($this->checked_feeds == $this->max_checked_feeds)
  9293. {
  9294. break;
  9295. }
  9296. if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
  9297. {
  9298. $this->checked_feeds++;
  9299. $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
  9300. if ($this->is_feed($feed))
  9301. {
  9302. return $feed;
  9303. }
  9304. else
  9305. {
  9306. unset($array[$key]);
  9307. }
  9308. }
  9309. }
  9310. return null;
  9311. }
  9312. function body(&$array)
  9313. {
  9314. foreach ($array as $key => $value)
  9315. {
  9316. if ($this->checked_feeds == $this->max_checked_feeds)
  9317. {
  9318. break;
  9319. }
  9320. if (preg_match('/(rss|rdf|atom|xml)/i', $value))
  9321. {
  9322. $this->checked_feeds++;
  9323. $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
  9324. if ($this->is_feed($feed))
  9325. {
  9326. return $feed;
  9327. }
  9328. else
  9329. {
  9330. unset($array[$key]);
  9331. }
  9332. }
  9333. }
  9334. return null;
  9335. }
  9336. }
  9337. class SimplePie_Parser
  9338. {
  9339. var $xml;
  9340. var $error_code;
  9341. var $error_string;
  9342. var $current_line;
  9343. var $current_column;
  9344. var $current_byte;
  9345. var $separator = ' ';
  9346. var $feed = false;
  9347. var $namespace = array('');
  9348. var $element = array('');
  9349. var $xml_base = array('');
  9350. var $xml_base_explicit = array(false);
  9351. var $xml_lang = array('');
  9352. var $data = array();
  9353. var $datas = array(array());
  9354. var $current_xhtml_construct = -1;
  9355. var $encoding;
  9356. function pre_process(&$data, $encoding)
  9357. {
  9358. // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
  9359. if (strtoupper($encoding) == 'US-ASCII')
  9360. {
  9361. $this->encoding = 'UTF-8';
  9362. }
  9363. else
  9364. {
  9365. $this->encoding = $encoding;
  9366. }
  9367. // Strip BOM:
  9368. // UTF-32 Big Endian BOM
  9369. if (strpos($data, "\x0\x0\xFE\xFF") === 0)
  9370. {
  9371. $data = substr($data, 4);
  9372. }
  9373. // UTF-32 Little Endian BOM
  9374. elseif (strpos($data, "\xFF\xFE\x0\x0") === 0)
  9375. {
  9376. $data = substr($data, 4);
  9377. }
  9378. // UTF-16 Big Endian BOM
  9379. elseif (strpos($data, "\xFE\xFF") === 0)
  9380. {
  9381. $data = substr($data, 2);
  9382. }
  9383. // UTF-16 Little Endian BOM
  9384. elseif (strpos($data, "\xFF\xFE") === 0)
  9385. {
  9386. $data = substr($data, 2);
  9387. }
  9388. // UTF-8 BOM
  9389. elseif (strpos($data, "\xEF\xBB\xBF") === 0)
  9390. {
  9391. $data = substr($data, 3);
  9392. }
  9393. // Make sure the XML prolog is sane and has the correct encoding
  9394. $data = preg_replace("/^<\?xml[\x20\x9\xD\xA]+version([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"1.0\"|'1.0'|\"1.1\"|'1.1')([\x20\x9\xD\xA]+encoding([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"[A-Za-z][A-Za-z0-9._\-]*\"|'[A-Za-z][A-Za-z0-9._\-]*'))?([\x20\x9\xD\xA]+standalone([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"(yes|no)\"|'(yes|no)'))?([\x20\x9\xD\xA]+)?\?>/", '', $data);
  9395. $data = "<?xml version='1.0' encoding='$encoding'?>\n" . $data;
  9396. }
  9397. function parse(&$data)
  9398. {
  9399. $return = true;
  9400. // Create the parser
  9401. $this->xml = xml_parser_create_ns($this->encoding, $this->separator);
  9402. xml_parser_set_option($this->xml, XML_OPTION_SKIP_WHITE, 1);
  9403. xml_parser_set_option($this->xml, XML_OPTION_CASE_FOLDING, 0);
  9404. xml_set_object($this->xml, $this);
  9405. xml_set_character_data_handler($this->xml, 'cdata');
  9406. xml_set_element_handler($this->xml, 'tag_open', 'tag_close');
  9407. // Parse!
  9408. if (!xml_parse($this->xml, $data, true))
  9409. {
  9410. $this->data = null;
  9411. $this->error_code = xml_get_error_code($this->xml);
  9412. $this->error_string = xml_error_string($this->error_code);
  9413. $return = false;
  9414. }
  9415. $this->current_line = xml_get_current_line_number($this->xml);
  9416. $this->current_column = xml_get_current_column_number($this->xml);
  9417. $this->current_byte = xml_get_current_byte_index($this->xml);
  9418. xml_parser_free($this->xml);
  9419. return $return;
  9420. }
  9421. function get_error_code()
  9422. {
  9423. return $this->error_code;
  9424. }
  9425. function get_error_string()
  9426. {
  9427. return $this->error_string;
  9428. }
  9429. function get_current_line()
  9430. {
  9431. return $this->current_line;
  9432. }
  9433. function get_current_column()
  9434. {
  9435. return $this->current_column;
  9436. }
  9437. function get_current_byte()
  9438. {
  9439. return $this->current_byte;
  9440. }
  9441. function get_data()
  9442. {
  9443. return $this->data;
  9444. }
  9445. function tag_open($parser, $tag, $attributes)
  9446. {
  9447. if ($this->feed === 0)
  9448. {
  9449. return;
  9450. }
  9451. elseif ($this->feed == false)
  9452. {
  9453. if (in_array($tag, array(
  9454. SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
  9455. SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
  9456. 'rss',
  9457. SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
  9458. )))
  9459. {
  9460. $this->feed = 1;
  9461. }
  9462. }
  9463. else
  9464. {
  9465. $this->feed++;
  9466. }
  9467. list($this->namespace[], $this->element[]) = $this->split_ns($tag);
  9468. $attribs = array();
  9469. foreach ($attributes as $name => $value)
  9470. {
  9471. list($attrib_namespace, $attribute) = $this->split_ns($name);
  9472. $attribs[$attrib_namespace][$attribute] = $value;
  9473. }
  9474. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
  9475. {
  9476. $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
  9477. $this->xml_base_explicit[] = true;
  9478. }
  9479. else
  9480. {
  9481. $this->xml_base[] = end($this->xml_base);
  9482. $this->xml_base_explicit[] = end($this->xml_base_explicit);
  9483. }
  9484. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
  9485. {
  9486. $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
  9487. }
  9488. else
  9489. {
  9490. $this->xml_lang[] = end($this->xml_lang);
  9491. }
  9492. if ($this->current_xhtml_construct >= 0)
  9493. {
  9494. $this->current_xhtml_construct++;
  9495. if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
  9496. {
  9497. $this->data['data'] .= '<' . end($this->element);
  9498. if (isset($attribs['']))
  9499. {
  9500. foreach ($attribs[''] as $name => $value)
  9501. {
  9502. $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
  9503. }
  9504. }
  9505. $this->data['data'] .= '>';
  9506. }
  9507. }
  9508. else
  9509. {
  9510. $this->datas[] =& $this->data;
  9511. $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
  9512. $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));
  9513. 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')
  9514. || (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'))
  9515. {
  9516. $this->current_xhtml_construct = 0;
  9517. }
  9518. }
  9519. }
  9520. function cdata($parser, $cdata)
  9521. {
  9522. if ($this->current_xhtml_construct >= 0)
  9523. {
  9524. $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
  9525. }
  9526. elseif ($this->feed > 1)
  9527. {
  9528. $this->data['data'] .= $cdata;
  9529. }
  9530. }
  9531. function tag_close($parser, $tag)
  9532. {
  9533. if (!$this->feed)
  9534. {
  9535. return;
  9536. }
  9537. if ($this->current_xhtml_construct >= 0)
  9538. {
  9539. $this->current_xhtml_construct--;
  9540. 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')))
  9541. {
  9542. $this->data['data'] .= '</' . end($this->element) . '>';
  9543. }
  9544. }
  9545. if ($this->current_xhtml_construct == -1)
  9546. {
  9547. $this->data =& $this->datas[$this->feed];
  9548. array_pop($this->datas);
  9549. }
  9550. array_pop($this->element);
  9551. array_pop($this->namespace);
  9552. array_pop($this->xml_base);
  9553. array_pop($this->xml_base_explicit);
  9554. array_pop($this->xml_lang);
  9555. $this->feed--;
  9556. }
  9557. function split_ns($string)
  9558. {
  9559. static $cache = array();
  9560. if (!isset($cache[$string]))
  9561. {
  9562. if ($pos = strpos($string, $this->separator))
  9563. {
  9564. static $separator_length;
  9565. if (!$separator_length)
  9566. {
  9567. $separator_length = strlen($this->separator);
  9568. }
  9569. $cache[$string] = array(substr($string, 0, $pos), substr($string, $pos + $separator_length));
  9570. }
  9571. else
  9572. {
  9573. $cache[$string] = array('', $string);
  9574. }
  9575. }
  9576. return $cache[$string];
  9577. }
  9578. }
  9579. /**
  9580. * @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 shortern a string while preserving HTML tags
  9581. */
  9582. class SimplePie_Sanitize
  9583. {
  9584. // Private vars
  9585. var $base;
  9586. // Options
  9587. var $remove_div = true;
  9588. var $image_handler = '';
  9589. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  9590. var $encode_instead_of_strip = false;
  9591. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  9592. var $strip_comments = false;
  9593. var $output_encoding = 'UTF-8';
  9594. var $enable_cache = true;
  9595. var $cache_location = './cache';
  9596. var $cache_name_function = 'md5';
  9597. var $cache_class = 'SimplePie_Cache';
  9598. var $file_class = 'SimplePie_File';
  9599. var $timeout = 10;
  9600. var $useragent = '';
  9601. var $force_fsockopen = false;
  9602. var $replace_url_attributes = array(
  9603. 'a' => 'href',
  9604. 'area' => 'href',
  9605. 'blockquote' => 'cite',
  9606. 'del' => 'cite',
  9607. 'form' => 'action',
  9608. 'img' => array('longdesc', 'src'),
  9609. 'input' => 'src',
  9610. 'ins' => 'cite',
  9611. 'q' => 'cite'
  9612. );
  9613. function remove_div($enable = true)
  9614. {
  9615. $this->remove_div = (bool) $enable;
  9616. }
  9617. function set_image_handler($page = false)
  9618. {
  9619. if ($page)
  9620. {
  9621. $this->image_handler = (string) $page;
  9622. }
  9623. else
  9624. {
  9625. $this->image_handler = false;
  9626. }
  9627. }
  9628. function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
  9629. {
  9630. if (isset($enable_cache))
  9631. {
  9632. $this->enable_cache = (bool) $enable_cache;
  9633. }
  9634. if ($cache_location)
  9635. {
  9636. $this->cache_location = (string) $cache_location;
  9637. }
  9638. if ($cache_name_function)
  9639. {
  9640. $this->cache_name_function = (string) $cache_name_function;
  9641. }
  9642. if ($cache_class)
  9643. {
  9644. $this->cache_class = (string) $cache_class;
  9645. }
  9646. }
  9647. function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
  9648. {
  9649. if ($file_class)
  9650. {
  9651. $this->file_class = (string) $file_class;
  9652. }
  9653. if ($timeout)
  9654. {
  9655. $this->timeout = (string) $timeout;
  9656. }
  9657. if ($useragent)
  9658. {
  9659. $this->useragent = (string) $useragent;
  9660. }
  9661. if ($force_fsockopen)
  9662. {
  9663. $this->force_fsockopen = (string) $force_fsockopen;
  9664. }
  9665. }
  9666. function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
  9667. {
  9668. if ($tags)
  9669. {
  9670. if (is_array($tags))
  9671. {
  9672. $this->strip_htmltags = $tags;
  9673. }
  9674. else
  9675. {
  9676. $this->strip_htmltags = explode(',', $tags);
  9677. }
  9678. }
  9679. else
  9680. {
  9681. $this->strip_htmltags = false;
  9682. }
  9683. }
  9684. function encode_instead_of_strip($encode = false)
  9685. {
  9686. $this->encode_instead_of_strip = (bool) $encode;
  9687. }
  9688. function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
  9689. {
  9690. if ($attribs)
  9691. {
  9692. if (is_array($attribs))
  9693. {
  9694. $this->strip_attributes = $attribs;
  9695. }
  9696. else
  9697. {
  9698. $this->strip_attributes = explode(',', $attribs);
  9699. }
  9700. }
  9701. else
  9702. {
  9703. $this->strip_attributes = false;
  9704. }
  9705. }
  9706. function strip_comments($strip = false)
  9707. {
  9708. $this->strip_comments = (bool) $strip;
  9709. }
  9710. function set_output_encoding($encoding = 'UTF-8')
  9711. {
  9712. $this->output_encoding = (string) $encoding;
  9713. }
  9714. /**
  9715. * Set element/attribute key/value pairs of HTML attributes
  9716. * containing URLs that need to be resolved relative to the feed
  9717. *
  9718. * @access public
  9719. * @since 1.0
  9720. * @param array $element_attribute Element/attribute key/value pairs
  9721. */
  9722. 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'))
  9723. {
  9724. $this->replace_url_attributes = (array) $element_attribute;
  9725. }
  9726. function sanitize($data, $type, $base = '')
  9727. {
  9728. $data = trim($data);
  9729. if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
  9730. {
  9731. if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
  9732. {
  9733. if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/(\w+)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
  9734. {
  9735. $type |= SIMPLEPIE_CONSTRUCT_HTML;
  9736. }
  9737. else
  9738. {
  9739. $type |= SIMPLEPIE_CONSTRUCT_TEXT;
  9740. }
  9741. }
  9742. if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
  9743. {
  9744. $data = base64_decode($data);
  9745. }
  9746. if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
  9747. {
  9748. if ($this->remove_div)
  9749. {
  9750. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
  9751. $data = preg_replace('/<\/div>$/', '', $data);
  9752. }
  9753. else
  9754. {
  9755. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
  9756. }
  9757. }
  9758. if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
  9759. {
  9760. // Strip comments
  9761. if ($this->strip_comments)
  9762. {
  9763. $data = SimplePie_Misc::strip_comments($data);
  9764. }
  9765. // Strip out HTML tags and attributes that might cause various security problems.
  9766. // Based on recommendations by Mark Pilgrim at:
  9767. // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
  9768. if ($this->strip_htmltags)
  9769. {
  9770. foreach ($this->strip_htmltags as $tag)
  9771. {
  9772. $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
  9773. while (preg_match($pcre, $data))
  9774. {
  9775. $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
  9776. }
  9777. }
  9778. }
  9779. if ($this->strip_attributes)
  9780. {
  9781. foreach ($this->strip_attributes as $attrib)
  9782. {
  9783. $data = preg_replace('/ '. trim($attrib) .'=("|&quot;)(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|\'|&apos;|<|>|\+|{|})*("|&quot;)/i', '', $data);
  9784. $data = preg_replace('/ '. trim($attrib) .'=(\'|&apos;)(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|"|&quot;|<|>|\+|{|})*(\'|&apos;)/i', '', $data);
  9785. $data = preg_replace('/ '. trim($attrib) .'=(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|\+|{|})*/i', '', $data);
  9786. }
  9787. }
  9788. // Replace relative URLs
  9789. $this->base = $base;
  9790. foreach ($this->replace_url_attributes as $element => $attributes)
  9791. {
  9792. $data = $this->replace_urls($data, $element, $attributes);
  9793. }
  9794. // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
  9795. if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
  9796. {
  9797. $images = SimplePie_Misc::get_element('img', $data);
  9798. foreach ($images as $img)
  9799. {
  9800. if (isset($img['attribs']['src']['data']))
  9801. {
  9802. $image_url = $img['attribs']['src']['data'];
  9803. $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $image_url), 'spi');
  9804. if ($cache->load())
  9805. {
  9806. $img['attribs']['src']['data'] = $this->image_handler . rawurlencode($img['attribs']['src']['data']);
  9807. $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
  9808. }
  9809. else
  9810. {
  9811. $file =& new $this->file_class($image_url, $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
  9812. $headers = $file->headers;
  9813. if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
  9814. {
  9815. if (!$cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  9816. {
  9817. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  9818. }
  9819. $img['attribs']['src']['data'] = $this->image_handler . rawurlencode($img['attribs']['src']['data']);
  9820. $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
  9821. }
  9822. }
  9823. }
  9824. }
  9825. }
  9826. // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
  9827. $data = trim($data);
  9828. }
  9829. if ($type & SIMPLEPIE_CONSTRUCT_IRI)
  9830. {
  9831. $data = SimplePie_Misc::absolutize_url($data, $base);
  9832. }
  9833. if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
  9834. {
  9835. $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
  9836. }
  9837. if ($this->output_encoding != 'UTF-8')
  9838. {
  9839. $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
  9840. }
  9841. }
  9842. return $data;
  9843. }
  9844. function replace_urls($data, $tag, $attributes)
  9845. {
  9846. if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
  9847. {
  9848. $elements = SimplePie_Misc::get_element($tag, $data);
  9849. foreach ($elements as $element)
  9850. {
  9851. if (is_array($attributes))
  9852. {
  9853. foreach ($attributes as $attribute)
  9854. {
  9855. if (isset($element['attribs'][$attribute]['data']))
  9856. {
  9857. $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
  9858. $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
  9859. }
  9860. }
  9861. }
  9862. elseif (isset($element['attribs'][$attributes]['data']))
  9863. {
  9864. $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
  9865. $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
  9866. }
  9867. }
  9868. }
  9869. return $data;
  9870. }
  9871. function do_strip_htmltags($match)
  9872. {
  9873. if ($this->encode_instead_of_strip)
  9874. {
  9875. if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  9876. {
  9877. $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
  9878. $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
  9879. return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
  9880. }
  9881. else
  9882. {
  9883. return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
  9884. }
  9885. }
  9886. elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  9887. {
  9888. return $match[4];
  9889. }
  9890. else
  9891. {
  9892. return '';
  9893. }
  9894. }
  9895. }
  9896. ?>