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

/plugins/feed/simplepie.inc.php

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