PageRenderTime 58ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 2ms

/sites/all/modules/activitystream/activitystream_feed/simplepie.inc

https://github.com/jiva-technology/smcuk
PHP | 13269 lines | 11493 code | 585 blank | 1191 comment | 874 complexity | bbb6c1c21dce3ccfd35747c34f9f4c8d MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * SimplePie
  4. *
  5. * A PHP-Based RSS and Atom Feed Framework.
  6. * Takes the hard work out of managing a complete RSS/Atom solution.
  7. *
  8. * Copyright (c) 2004-2007, Ryan Parman and Geoffrey Sneddon
  9. * All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without modification, are
  12. * permitted provided that the following conditions are met:
  13. *
  14. * * Redistributions of source code must retain the above copyright notice, this list of
  15. * conditions and the following disclaimer.
  16. *
  17. * * Redistributions in binary form must reproduce the above copyright notice, this list
  18. * of conditions and the following disclaimer in the documentation and/or other materials
  19. * provided with the distribution.
  20. *
  21. * * Neither the name of the SimplePie Team nor the names of its contributors may be used
  22. * to endorse or promote products derived from this software without specific prior
  23. * written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  26. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  27. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
  28. * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  30. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  32. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. *
  35. * @package SimplePie
  36. * @version 1.1
  37. * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
  38. * @author Ryan Parman
  39. * @author Geoffrey Sneddon
  40. * @link http://simplepie.org/ SimplePie
  41. * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
  42. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  43. * @todo phpDoc comments
  44. */
  45. /**
  46. * SimplePie Name
  47. */
  48. define('SIMPLEPIE_NAME', 'SimplePie');
  49. /**
  50. * SimplePie Version
  51. */
  52. define('SIMPLEPIE_VERSION', '1.1');
  53. /**
  54. * SimplePie Build
  55. */
  56. define('SIMPLEPIE_BUILD', 20080102221556);
  57. /**
  58. * SimplePie Website URL
  59. */
  60. define('SIMPLEPIE_URL', 'http://simplepie.org');
  61. /**
  62. * SimplePie Useragent
  63. * @see SimplePie::set_useragent()
  64. */
  65. define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
  66. /**
  67. * SimplePie Linkback
  68. */
  69. define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
  70. /**
  71. * No Autodiscovery
  72. * @see SimplePie::set_autodiscovery_level()
  73. */
  74. define('SIMPLEPIE_LOCATOR_NONE', 0);
  75. /**
  76. * Feed Link Element Autodiscovery
  77. * @see SimplePie::set_autodiscovery_level()
  78. */
  79. define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
  80. /**
  81. * Local Feed Extension Autodiscovery
  82. * @see SimplePie::set_autodiscovery_level()
  83. */
  84. define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
  85. /**
  86. * Local Feed Body Autodiscovery
  87. * @see SimplePie::set_autodiscovery_level()
  88. */
  89. define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
  90. /**
  91. * Remote Feed Extension Autodiscovery
  92. * @see SimplePie::set_autodiscovery_level()
  93. */
  94. define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
  95. /**
  96. * Remote Feed Body Autodiscovery
  97. * @see SimplePie::set_autodiscovery_level()
  98. */
  99. define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
  100. /**
  101. * All Feed Autodiscovery
  102. * @see SimplePie::set_autodiscovery_level()
  103. */
  104. define('SIMPLEPIE_LOCATOR_ALL', 31);
  105. /**
  106. * No known feed type
  107. */
  108. define('SIMPLEPIE_TYPE_NONE', 0);
  109. /**
  110. * RSS 0.90
  111. */
  112. define('SIMPLEPIE_TYPE_RSS_090', 1);
  113. /**
  114. * RSS 0.91 (Netscape)
  115. */
  116. define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
  117. /**
  118. * RSS 0.91 (Userland)
  119. */
  120. define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
  121. /**
  122. * RSS 0.91 (both Netscape and Userland)
  123. */
  124. define('SIMPLEPIE_TYPE_RSS_091', 6);
  125. /**
  126. * RSS 0.92
  127. */
  128. define('SIMPLEPIE_TYPE_RSS_092', 8);
  129. /**
  130. * RSS 0.93
  131. */
  132. define('SIMPLEPIE_TYPE_RSS_093', 16);
  133. /**
  134. * RSS 0.94
  135. */
  136. define('SIMPLEPIE_TYPE_RSS_094', 32);
  137. /**
  138. * RSS 1.0
  139. */
  140. define('SIMPLEPIE_TYPE_RSS_10', 64);
  141. /**
  142. * RSS 2.0
  143. */
  144. define('SIMPLEPIE_TYPE_RSS_20', 128);
  145. /**
  146. * RDF-based RSS
  147. */
  148. define('SIMPLEPIE_TYPE_RSS_RDF', 65);
  149. /**
  150. * Non-RDF-based RSS (truly intended as syndication format)
  151. */
  152. define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
  153. /**
  154. * All RSS
  155. */
  156. define('SIMPLEPIE_TYPE_RSS_ALL', 255);
  157. /**
  158. * Atom 0.3
  159. */
  160. define('SIMPLEPIE_TYPE_ATOM_03', 256);
  161. /**
  162. * Atom 1.0
  163. */
  164. define('SIMPLEPIE_TYPE_ATOM_10', 512);
  165. /**
  166. * All Atom
  167. */
  168. define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
  169. /**
  170. * All feed types
  171. */
  172. define('SIMPLEPIE_TYPE_ALL', 1023);
  173. /**
  174. * No construct
  175. */
  176. define('SIMPLEPIE_CONSTRUCT_NONE', 0);
  177. /**
  178. * Text construct
  179. */
  180. define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
  181. /**
  182. * HTML construct
  183. */
  184. define('SIMPLEPIE_CONSTRUCT_HTML', 2);
  185. /**
  186. * XHTML construct
  187. */
  188. define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
  189. /**
  190. * base64-encoded construct
  191. */
  192. define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
  193. /**
  194. * IRI construct
  195. */
  196. define('SIMPLEPIE_CONSTRUCT_IRI', 16);
  197. /**
  198. * A construct that might be HTML
  199. */
  200. define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
  201. /**
  202. * All constructs
  203. */
  204. define('SIMPLEPIE_CONSTRUCT_ALL', 63);
  205. /**
  206. * PCRE for HTML attributes
  207. */
  208. define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
  209. /**
  210. * PCRE for XML attributes
  211. */
  212. define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
  213. /**
  214. * XML Namespace
  215. */
  216. define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
  217. /**
  218. * Atom 1.0 Namespace
  219. */
  220. define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
  221. /**
  222. * Atom 0.3 Namespace
  223. */
  224. define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
  225. /**
  226. * RDF Namespace
  227. */
  228. define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
  229. /**
  230. * RSS 0.90 Namespace
  231. */
  232. define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
  233. /**
  234. * RSS 1.0 Namespace
  235. */
  236. define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
  237. /**
  238. * RSS 1.0 Content Module Namespace
  239. */
  240. define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
  241. /**
  242. * DC 1.0 Namespace
  243. */
  244. define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
  245. /**
  246. * DC 1.1 Namespace
  247. */
  248. define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
  249. /**
  250. * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
  251. */
  252. define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
  253. /**
  254. * GeoRSS Namespace
  255. */
  256. define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
  257. /**
  258. * Media RSS Namespace
  259. */
  260. define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
  261. /**
  262. * iTunes RSS Namespace
  263. */
  264. define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
  265. /**
  266. * XHTML Namespace
  267. */
  268. define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
  269. /**
  270. * IANA Link Relations Registry
  271. */
  272. define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
  273. /**
  274. * Whether we're running on PHP5
  275. */
  276. define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
  277. /**
  278. * No file source
  279. */
  280. define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
  281. /**
  282. * Remote file source
  283. */
  284. define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
  285. /**
  286. * Local file source
  287. */
  288. define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
  289. /**
  290. * fsockopen() file source
  291. */
  292. define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
  293. /**
  294. * cURL file source
  295. */
  296. define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
  297. /**
  298. * file_get_contents() file source
  299. */
  300. define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
  301. /**
  302. * SimplePie
  303. *
  304. * @package SimplePie
  305. * @version "Razzleberry"
  306. * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
  307. * @author Ryan Parman
  308. * @author Geoffrey Sneddon
  309. * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
  310. */
  311. class SimplePie
  312. {
  313. /**
  314. * @var array Raw data
  315. * @access private
  316. */
  317. var $data = array();
  318. /**
  319. * @var mixed Error string
  320. * @access private
  321. */
  322. var $error;
  323. /**
  324. * @var object Instance of SimplePie_Sanitize (or other class)
  325. * @see SimplePie::set_sanitize_class()
  326. * @access private
  327. */
  328. var $sanitize;
  329. /**
  330. * @var string SimplePie Useragent
  331. * @see SimplePie::set_useragent()
  332. * @access private
  333. */
  334. var $useragent = SIMPLEPIE_USERAGENT;
  335. /**
  336. * @var string Feed URL
  337. * @see SimplePie::set_feed_url()
  338. * @access private
  339. */
  340. var $feed_url;
  341. /**
  342. * @var object Instance of SimplePie_File to use as a feed
  343. * @see SimplePie::set_file()
  344. * @access private
  345. */
  346. var $file;
  347. /**
  348. * @var string Raw feed data
  349. * @see SimplePie::set_raw_data()
  350. * @access private
  351. */
  352. var $raw_data;
  353. /**
  354. * @var int Timeout for fetching remote files
  355. * @see SimplePie::set_timeout()
  356. * @access private
  357. */
  358. var $timeout = 10;
  359. /**
  360. * @var bool Forces fsockopen() to be used for remote files instead
  361. * of cURL, even if a new enough version is installed
  362. * @see SimplePie::force_fsockopen()
  363. * @access private
  364. */
  365. var $force_fsockopen = false;
  366. /**
  367. * @var bool Force the given data/URL to be treated as a feed no matter what
  368. * it appears like
  369. * @see SimplePie::force_feed()
  370. * @access private
  371. */
  372. var $force_feed = false;
  373. /**
  374. * @var bool Enable/Disable XML dump
  375. * @see SimplePie::enable_xml_dump()
  376. * @access private
  377. */
  378. var $xml_dump = false;
  379. /**
  380. * @var bool Enable/Disable Caching
  381. * @see SimplePie::enable_cache()
  382. * @access private
  383. */
  384. var $cache = true;
  385. /**
  386. * @var int Cache duration (in seconds)
  387. * @see SimplePie::set_cache_duration()
  388. * @access private
  389. */
  390. var $cache_duration = 3600;
  391. /**
  392. * @var int Auto-discovery cache duration (in seconds)
  393. * @see SimplePie::set_autodiscovery_cache_duration()
  394. * @access private
  395. */
  396. var $autodiscovery_cache_duration = 604800; // 7 Days.
  397. /**
  398. * @var string Cache location (relative to executing script)
  399. * @see SimplePie::set_cache_location()
  400. * @access private
  401. */
  402. var $cache_location = './cache';
  403. /**
  404. * @var string Function that creates the cache filename
  405. * @see SimplePie::set_cache_name_function()
  406. * @access private
  407. */
  408. var $cache_name_function = 'md5';
  409. /**
  410. * @var bool Reorder feed by date descending
  411. * @see SimplePie::enable_order_by_date()
  412. * @access private
  413. */
  414. var $order_by_date = true;
  415. /**
  416. * @var mixed Force input encoding to be set to the follow value
  417. * (false, or anything type-cast to false, disables this feature)
  418. * @see SimplePie::set_input_encoding()
  419. * @access private
  420. */
  421. var $input_encoding = false;
  422. /**
  423. * @var int Feed Autodiscovery Level
  424. * @see SimplePie::set_autodiscovery_level()
  425. * @access private
  426. */
  427. var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
  428. /**
  429. * @var string Class used for caching feeds
  430. * @see SimplePie::set_cache_class()
  431. * @access private
  432. */
  433. var $cache_class = 'SimplePie_Cache';
  434. /**
  435. * @var string Class used for locating feeds
  436. * @see SimplePie::set_locator_class()
  437. * @access private
  438. */
  439. var $locator_class = 'SimplePie_Locator';
  440. /**
  441. * @var string Class used for parsing feeds
  442. * @see SimplePie::set_parser_class()
  443. * @access private
  444. */
  445. var $parser_class = 'SimplePie_Parser';
  446. /**
  447. * @var string Class used for fetching feeds
  448. * @see SimplePie::set_file_class()
  449. * @access private
  450. */
  451. var $file_class = 'SimplePie_File';
  452. /**
  453. * @var string Class used for items
  454. * @see SimplePie::set_item_class()
  455. * @access private
  456. */
  457. var $item_class = 'SimplePie_Item';
  458. /**
  459. * @var string Class used for authors
  460. * @see SimplePie::set_author_class()
  461. * @access private
  462. */
  463. var $author_class = 'SimplePie_Author';
  464. /**
  465. * @var string Class used for categories
  466. * @see SimplePie::set_category_class()
  467. * @access private
  468. */
  469. var $category_class = 'SimplePie_Category';
  470. /**
  471. * @var string Class used for enclosures
  472. * @see SimplePie::set_enclosures_class()
  473. * @access private
  474. */
  475. var $enclosure_class = 'SimplePie_Enclosure';
  476. /**
  477. * @var string Class used for Media RSS <media:text> captions
  478. * @see SimplePie::set_caption_class()
  479. * @access private
  480. */
  481. var $caption_class = 'SimplePie_Caption';
  482. /**
  483. * @var string Class used for Media RSS <media:copyright>
  484. * @see SimplePie::set_copyright_class()
  485. * @access private
  486. */
  487. var $copyright_class = 'SimplePie_Copyright';
  488. /**
  489. * @var string Class used for Media RSS <media:credit>
  490. * @see SimplePie::set_credit_class()
  491. * @access private
  492. */
  493. var $credit_class = 'SimplePie_Credit';
  494. /**
  495. * @var string Class used for Media RSS <media:rating>
  496. * @see SimplePie::set_rating_class()
  497. * @access private
  498. */
  499. var $rating_class = 'SimplePie_Rating';
  500. /**
  501. * @var string Class used for Media RSS <media:restriction>
  502. * @see SimplePie::set_restriction_class()
  503. * @access private
  504. */
  505. var $restriction_class = 'SimplePie_Restriction';
  506. /**
  507. * @var string Class used for content-type sniffing
  508. * @see SimplePie::set_content_type_sniffer_class()
  509. * @access private
  510. */
  511. var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
  512. /**
  513. * @var string Class used for item sources.
  514. * @see SimplePie::set_source_class()
  515. * @access private
  516. */
  517. var $source_class = 'SimplePie_Source';
  518. /**
  519. * @var mixed Set javascript query string parameter (false, or
  520. * anything type-cast to false, disables this feature)
  521. * @see SimplePie::set_javascript()
  522. * @access private
  523. */
  524. var $javascript = 'js';
  525. /**
  526. * @var int Maximum number of feeds to check with autodiscovery
  527. * @see SimplePie::set_max_checked_feeds()
  528. * @access private
  529. */
  530. var $max_checked_feeds = 10;
  531. /**
  532. * @var string Web-accessible path to the handler_favicon.php file.
  533. * @see SimplePie::set_favicon_handler()
  534. * @access private
  535. */
  536. var $favicon_handler = '';
  537. /**
  538. * @var string Web-accessible path to the handler_image.php file.
  539. * @see SimplePie::set_image_handler()
  540. * @access private
  541. */
  542. var $image_handler = '';
  543. /**
  544. * @var array Stores the URLs when multiple feeds are being initialized.
  545. * @see SimplePie::set_feed_url()
  546. * @access private
  547. */
  548. var $multifeed_url = array();
  549. /**
  550. * @var array Stores SimplePie objects when multiple feeds initialized.
  551. * @access private
  552. */
  553. var $multifeed_objects = array();
  554. /**
  555. * @var array Stores the get_object_vars() array for use with multifeeds.
  556. * @see SimplePie::set_feed_url()
  557. * @access private
  558. */
  559. var $config_settings = null;
  560. /**
  561. * @var integer Stores the number of items to return per-feed with multifeeds.
  562. * @see SimplePie::set_item_limit()
  563. * @access private
  564. */
  565. var $item_limit = 0;
  566. /**
  567. * @var array Stores the default attributes to be stripped by strip_attributes().
  568. * @see SimplePie::strip_attributes()
  569. * @access private
  570. */
  571. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  572. /**
  573. * @var array Stores the default tags to be stripped by strip_htmltags().
  574. * @see SimplePie::strip_htmltags()
  575. * @access private
  576. */
  577. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  578. /**
  579. * The SimplePie class contains feed level data and options
  580. *
  581. * There are two ways that you can create a new SimplePie object. The first
  582. * is by passing a feed URL as a parameter to the SimplePie constructor
  583. * (as well as optionally setting the cache location and cache expiry). This
  584. * will initialise the whole feed with all of the default settings, and you
  585. * can begin accessing methods and properties immediately.
  586. *
  587. * The second way is to create the SimplePie object with no parameters
  588. * at all. This will enable you to set configuration options. After setting
  589. * them, you must initialise the feed using $feed->init(). At that point the
  590. * object's methods and properties will be available to you. This format is
  591. * what is used throughout this documentation.
  592. *
  593. * @access public
  594. * @since 1.0 Preview Release
  595. * @param string $feed_url This is the URL you want to parse.
  596. * @param string $cache_location This is where you want the cache to be stored.
  597. * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
  598. */
  599. function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
  600. {
  601. // Other objects, instances created here so we can set options on them
  602. $this->sanitize =& new SimplePie_Sanitize;
  603. // Set options if they're passed to the constructor
  604. if ($cache_location !== null)
  605. {
  606. $this->set_cache_location($cache_location);
  607. }
  608. if ($cache_duration !== null)
  609. {
  610. $this->set_cache_duration($cache_duration);
  611. }
  612. // Only init the script if we're passed a feed URL
  613. if ($feed_url !== null)
  614. {
  615. $this->set_feed_url($feed_url);
  616. $this->init();
  617. }
  618. }
  619. /**
  620. * Used for converting object to a string
  621. */
  622. function __toString()
  623. {
  624. return md5(serialize($this->data));
  625. }
  626. /**
  627. * Remove items that link back to this before destroying this object
  628. */
  629. function __destruct()
  630. {
  631. if (!empty($this->data['items']))
  632. {
  633. foreach ($this->data['items'] as $item)
  634. {
  635. $item->__destruct();
  636. }
  637. unset($this->data['items']);
  638. }
  639. if (!empty($this->data['ordered_items']))
  640. {
  641. foreach ($this->data['ordered_items'] as $item)
  642. {
  643. $item->__destruct();
  644. }
  645. unset($this->data['ordered_items']);
  646. }
  647. }
  648. /**
  649. * Force the given data/URL to be treated as a feed no matter what it
  650. * appears like
  651. *
  652. * @access public
  653. * @since 1.1
  654. * @param bool $enable Force the given data/URL to be treated as a feed
  655. */
  656. function force_feed($enable = false)
  657. {
  658. $this->force_feed = (bool) $enable;
  659. }
  660. /**
  661. * This is the URL of the feed you want to parse.
  662. *
  663. * This allows you to enter the URL of the feed you want to parse, or the
  664. * website you want to try to use auto-discovery on. This takes priority
  665. * over any set raw data.
  666. *
  667. * You can set multiple feeds to mash together by passing an array instead
  668. * of a string for the $url. Remember that with each additional feed comes
  669. * additional processing and resources.
  670. *
  671. * @access public
  672. * @since 1.0 Preview Release
  673. * @param mixed $url This is the URL (or array of URLs) that you want to parse.
  674. * @see SimplePie::set_raw_data()
  675. */
  676. function set_feed_url($url)
  677. {
  678. if (is_array($url))
  679. {
  680. $this->multifeed_url = array();
  681. foreach ($url as $value)
  682. {
  683. $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
  684. }
  685. }
  686. else
  687. {
  688. $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
  689. }
  690. }
  691. /**
  692. * Provides an instance of SimplePie_File to use as a feed
  693. *
  694. * @access public
  695. * @param object &$file Instance of SimplePie_File (or subclass)
  696. * @return bool True on success, false on failure
  697. */
  698. function set_file(&$file)
  699. {
  700. if (is_a($file, 'SimplePie_File'))
  701. {
  702. $this->feed_url = $file->url;
  703. $this->file =& $file;
  704. return true;
  705. }
  706. return false;
  707. }
  708. /**
  709. * Allows you to use a string of RSS/Atom data instead of a remote feed.
  710. *
  711. * If you have a feed available as a string in PHP, you can tell SimplePie
  712. * to parse that data string instead of a remote feed. Any set feed URL
  713. * takes precedence.
  714. *
  715. * @access public
  716. * @since 1.0 Beta 3
  717. * @param string $data RSS or Atom data as a string.
  718. * @see SimplePie::set_feed_url()
  719. */
  720. function set_raw_data($data)
  721. {
  722. $this->raw_data = trim($data);
  723. }
  724. /**
  725. * Allows you to override the default timeout for fetching remote feeds.
  726. *
  727. * This allows you to change the maximum time the feed's server to respond
  728. * and send the feed back.
  729. *
  730. * @access public
  731. * @since 1.0 Beta 3
  732. * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
  733. */
  734. function set_timeout($timeout = 10)
  735. {
  736. $this->timeout = (int) $timeout;
  737. }
  738. /**
  739. * Forces SimplePie to use fsockopen() instead of the preferred cURL
  740. * functions.
  741. *
  742. * @access public
  743. * @since 1.0 Beta 3
  744. * @param bool $enable Force fsockopen() to be used
  745. */
  746. function force_fsockopen($enable = false)
  747. {
  748. $this->force_fsockopen = (bool) $enable;
  749. }
  750. /**
  751. * Outputs the raw XML content of the feed, after it has gone through
  752. * SimplePie's filters.
  753. *
  754. * Used only for debugging, this function will output the XML content as
  755. * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
  756. * before trying to parse it. Many parts of the feed are re-written in
  757. * memory, and in the end, you have a parsable feed. XML dump shows you the
  758. * actual XML that SimplePie tries to parse, which may or may not be very
  759. * different from the original feed.
  760. *
  761. * @access public
  762. * @since 1.0 Preview Release
  763. * @param bool $enable Enable XML dump
  764. */
  765. function enable_xml_dump($enable = false)
  766. {
  767. $this->xml_dump = (bool) $enable;
  768. }
  769. /**
  770. * Enables/disables caching in SimplePie.
  771. *
  772. * This option allows you to disable caching all-together in SimplePie.
  773. * However, disabling the cache can lead to longer load times.
  774. *
  775. * @access public
  776. * @since 1.0 Preview Release
  777. * @param bool $enable Enable caching
  778. */
  779. function enable_cache($enable = true)
  780. {
  781. $this->cache = (bool) $enable;
  782. }
  783. /**
  784. * Set the length of time (in seconds) that the contents of a feed
  785. * will be cached.
  786. *
  787. * @access public
  788. * @param int $seconds The feed content cache duration.
  789. */
  790. function set_cache_duration($seconds = 3600)
  791. {
  792. $this->cache_duration = (int) $seconds;
  793. }
  794. /**
  795. * Set the length of time (in seconds) that the autodiscovered feed
  796. * URL will be cached.
  797. *
  798. * @access public
  799. * @param int $seconds The autodiscovered feed URL cache duration.
  800. */
  801. function set_autodiscovery_cache_duration($seconds = 604800)
  802. {
  803. $this->autodiscovery_cache_duration = (int) $seconds;
  804. }
  805. /**
  806. * Set the file system location where the cached files should be stored.
  807. *
  808. * @access public
  809. * @param string $location The file system location.
  810. */
  811. function set_cache_location($location = './cache')
  812. {
  813. $this->cache_location = (string) $location;
  814. }
  815. /**
  816. * Determines whether feed items should be sorted into reverse chronological order.
  817. *
  818. * @access public
  819. * @param bool $enable Sort as reverse chronological order.
  820. */
  821. function enable_order_by_date($enable = true)
  822. {
  823. $this->order_by_date = (bool) $enable;
  824. }
  825. /**
  826. * Allows you to override the character encoding reported by the feed.
  827. *
  828. * @access public
  829. * @param string $encoding Character encoding.
  830. */
  831. function set_input_encoding($encoding = false)
  832. {
  833. if ($encoding)
  834. {
  835. $this->input_encoding = (string) $encoding;
  836. }
  837. else
  838. {
  839. $this->input_encoding = false;
  840. }
  841. }
  842. /**
  843. * Set how much feed autodiscovery to do
  844. *
  845. * @access public
  846. * @see SIMPLEPIE_LOCATOR_NONE
  847. * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
  848. * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
  849. * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
  850. * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
  851. * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
  852. * @see SIMPLEPIE_LOCATOR_ALL
  853. * @param int $level Feed Autodiscovery Level (level can be a
  854. * combination of the above constants, see bitwise OR operator)
  855. */
  856. function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
  857. {
  858. $this->autodiscovery = (int) $level;
  859. }
  860. /**
  861. * Allows you to change which class SimplePie uses for caching.
  862. * Useful when you are overloading or extending SimplePie's default classes.
  863. *
  864. * @access public
  865. * @param string $class Name of custom class.
  866. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  867. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  868. */
  869. function set_cache_class($class = 'SimplePie_Cache')
  870. {
  871. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
  872. {
  873. $this->cache_class = $class;
  874. return true;
  875. }
  876. return false;
  877. }
  878. /**
  879. * Allows you to change which class SimplePie uses for auto-discovery.
  880. * Useful when you are overloading or extending SimplePie's default classes.
  881. *
  882. * @access public
  883. * @param string $class Name of custom class.
  884. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  885. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  886. */
  887. function set_locator_class($class = 'SimplePie_Locator')
  888. {
  889. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
  890. {
  891. $this->locator_class = $class;
  892. return true;
  893. }
  894. return false;
  895. }
  896. /**
  897. * Allows you to change which class SimplePie uses for XML parsing.
  898. * Useful when you are overloading or extending SimplePie's default classes.
  899. *
  900. * @access public
  901. * @param string $class Name of custom class.
  902. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  903. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  904. */
  905. function set_parser_class($class = 'SimplePie_Parser')
  906. {
  907. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
  908. {
  909. $this->parser_class = $class;
  910. return true;
  911. }
  912. return false;
  913. }
  914. /**
  915. * Allows you to change which class SimplePie uses for remote file fetching.
  916. * Useful when you are overloading or extending SimplePie's default classes.
  917. *
  918. * @access public
  919. * @param string $class Name of custom class.
  920. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  921. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  922. */
  923. function set_file_class($class = 'SimplePie_File')
  924. {
  925. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
  926. {
  927. $this->file_class = $class;
  928. return true;
  929. }
  930. return false;
  931. }
  932. /**
  933. * Allows you to change which class SimplePie uses for data sanitization.
  934. * Useful when you are overloading or extending SimplePie's default classes.
  935. *
  936. * @access public
  937. * @param string $class Name of custom class.
  938. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  939. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  940. */
  941. function set_sanitize_class($class = 'SimplePie_Sanitize')
  942. {
  943. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
  944. {
  945. $this->sanitize =& new $class;
  946. return true;
  947. }
  948. return false;
  949. }
  950. /**
  951. * Allows you to change which class SimplePie uses for handling feed items.
  952. * Useful when you are overloading or extending SimplePie's default classes.
  953. *
  954. * @access public
  955. * @param string $class Name of custom class.
  956. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  957. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  958. */
  959. function set_item_class($class = 'SimplePie_Item')
  960. {
  961. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
  962. {
  963. $this->item_class = $class;
  964. return true;
  965. }
  966. return false;
  967. }
  968. /**
  969. * Allows you to change which class SimplePie uses for handling author data.
  970. * Useful when you are overloading or extending SimplePie's default classes.
  971. *
  972. * @access public
  973. * @param string $class Name of custom class.
  974. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  975. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  976. */
  977. function set_author_class($class = 'SimplePie_Author')
  978. {
  979. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
  980. {
  981. $this->author_class = $class;
  982. return true;
  983. }
  984. return false;
  985. }
  986. /**
  987. * Allows you to change which class SimplePie uses for handling category data.
  988. * Useful when you are overloading or extending SimplePie's default classes.
  989. *
  990. * @access public
  991. * @param string $class Name of custom class.
  992. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  993. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  994. */
  995. function set_category_class($class = 'SimplePie_Category')
  996. {
  997. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
  998. {
  999. $this->category_class = $class;
  1000. return true;
  1001. }
  1002. return false;
  1003. }
  1004. /**
  1005. * Allows you to change which class SimplePie uses for feed enclosures.
  1006. * Useful when you are overloading or extending SimplePie's default classes.
  1007. *
  1008. * @access public
  1009. * @param string $class Name of custom class.
  1010. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1011. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1012. */
  1013. function set_enclosure_class($class = 'SimplePie_Enclosure')
  1014. {
  1015. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
  1016. {
  1017. $this->enclosure_class = $class;
  1018. return true;
  1019. }
  1020. return false;
  1021. }
  1022. /**
  1023. * Allows you to change which class SimplePie uses for <media:text> captions
  1024. * Useful when you are overloading or extending SimplePie's default classes.
  1025. *
  1026. * @access public
  1027. * @param string $class Name of custom class.
  1028. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1029. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1030. */
  1031. function set_caption_class($class = 'SimplePie_Caption')
  1032. {
  1033. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
  1034. {
  1035. $this->caption_class = $class;
  1036. return true;
  1037. }
  1038. return false;
  1039. }
  1040. /**
  1041. * Allows you to change which class SimplePie uses for <media:copyright>
  1042. * Useful when you are overloading or extending SimplePie's default classes.
  1043. *
  1044. * @access public
  1045. * @param string $class Name of custom class.
  1046. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1047. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1048. */
  1049. function set_copyright_class($class = 'SimplePie_Copyright')
  1050. {
  1051. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
  1052. {
  1053. $this->copyright_class = $class;
  1054. return true;
  1055. }
  1056. return false;
  1057. }
  1058. /**
  1059. * Allows you to change which class SimplePie uses for <media:credit>
  1060. * Useful when you are overloading or extending SimplePie's default classes.
  1061. *
  1062. * @access public
  1063. * @param string $class Name of custom class.
  1064. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1065. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1066. */
  1067. function set_credit_class($class = 'SimplePie_Credit')
  1068. {
  1069. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
  1070. {
  1071. $this->credit_class = $class;
  1072. return true;
  1073. }
  1074. return false;
  1075. }
  1076. /**
  1077. * Allows you to change which class SimplePie uses for <media:rating>
  1078. * Useful when you are overloading or extending SimplePie's default classes.
  1079. *
  1080. * @access public
  1081. * @param string $class Name of custom class.
  1082. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1083. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1084. */
  1085. function set_rating_class($class = 'SimplePie_Rating')
  1086. {
  1087. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
  1088. {
  1089. $this->rating_class = $class;
  1090. return true;
  1091. }
  1092. return false;
  1093. }
  1094. /**
  1095. * Allows you to change which class SimplePie uses for <media:restriction>
  1096. * Useful when you are overloading or extending SimplePie's default classes.
  1097. *
  1098. * @access public
  1099. * @param string $class Name of custom class.
  1100. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1101. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1102. */
  1103. function set_restriction_class($class = 'SimplePie_Restriction')
  1104. {
  1105. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
  1106. {
  1107. $this->restriction_class = $class;
  1108. return true;
  1109. }
  1110. return false;
  1111. }
  1112. /**
  1113. * Allows you to change which class SimplePie uses for content-type sniffing.
  1114. * Useful when you are overloading or extending SimplePie's default classes.
  1115. *
  1116. * @access public
  1117. * @param string $class Name of custom class.
  1118. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1119. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1120. */
  1121. function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
  1122. {
  1123. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
  1124. {
  1125. $this->content_type_sniffer_class = $class;
  1126. return true;
  1127. }
  1128. return false;
  1129. }
  1130. /**
  1131. * Allows you to change which class SimplePie uses item sources.
  1132. * Useful when you are overloading or extending SimplePie's default classes.
  1133. *
  1134. * @access public
  1135. * @param string $class Name of custom class.
  1136. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1137. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1138. */
  1139. function set_source_class($class = 'SimplePie_Source')
  1140. {
  1141. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
  1142. {
  1143. $this->source_class = $class;
  1144. return true;
  1145. }
  1146. return false;
  1147. }
  1148. /**
  1149. * Allows you to override the default user agent string.
  1150. *
  1151. * @access public
  1152. * @param string $ua New user agent string.
  1153. */
  1154. function set_useragent($ua = SIMPLEPIE_USERAGENT)
  1155. {
  1156. $this->useragent = (string) $ua;
  1157. }
  1158. /**
  1159. * Set callback function to create cache filename with
  1160. *
  1161. * @access public
  1162. * @param mixed $function Callback function
  1163. */
  1164. function set_cache_name_function($function = 'md5')
  1165. {
  1166. if (is_callable($function))
  1167. {
  1168. $this->cache_name_function = $function;
  1169. }
  1170. }
  1171. /**
  1172. * Set javascript query string parameter
  1173. *
  1174. * @access public
  1175. * @param mixed $get Javascript query string parameter
  1176. */
  1177. function set_javascript($get = 'js')
  1178. {
  1179. if ($get)
  1180. {
  1181. $this->javascript = (string) $get;
  1182. }
  1183. else
  1184. {
  1185. $this->javascript = false;
  1186. }
  1187. }
  1188. /**
  1189. * Set options to make SP as fast as possible. Forgoes a
  1190. * substantial amount of data sanitization in favor of speed.
  1191. *
  1192. * @access public
  1193. * @param bool $set Whether to set them or not
  1194. */
  1195. function set_stupidly_fast($set = false)
  1196. {
  1197. if ($set)
  1198. {
  1199. $this->enable_order_by_date(false);
  1200. $this->remove_div(false);
  1201. $this->strip_comments(false);
  1202. $this->strip_htmltags(false);
  1203. $this->strip_attributes(false);
  1204. $this->set_image_handler(false);
  1205. }
  1206. }
  1207. /**
  1208. * Set maximum number of feeds to check with autodiscovery
  1209. *
  1210. * @access public
  1211. * @param int $max Maximum number of feeds to check
  1212. */
  1213. function set_max_checked_feeds($max = 10)
  1214. {
  1215. $this->max_checked_feeds = (int) $max;
  1216. }
  1217. function remove_div($enable = true)
  1218. {
  1219. $this->sanitize->remove_div($enable);
  1220. }
  1221. function strip_htmltags($tags = '', $encode = null)
  1222. {
  1223. if ($tags === '')
  1224. {
  1225. $tags = $this->strip_htmltags;
  1226. }
  1227. $this->sanitize->strip_htmltags($tags);
  1228. if ($encode !== null)
  1229. {
  1230. $this->sanitize->encode_instead_of_strip($tags);
  1231. }
  1232. }
  1233. function encode_instead_of_strip($enable = true)
  1234. {
  1235. $this->sanitize->encode_instead_of_strip($enable);
  1236. }
  1237. function strip_attributes($attribs = '')
  1238. {
  1239. if ($attribs === '')
  1240. {
  1241. $attribs = $this->strip_attributes;
  1242. }
  1243. $this->sanitize->strip_attributes($attribs);
  1244. }
  1245. function set_output_encoding($encoding = 'UTF-8')
  1246. {
  1247. $this->sanitize->set_output_encoding($encoding);
  1248. }
  1249. function strip_comments($strip = false)
  1250. {
  1251. $this->sanitize->strip_comments($strip);
  1252. }
  1253. /**
  1254. * Set element/attribute key/value pairs of HTML attributes
  1255. * containing URLs that need to be resolved relative to the feed
  1256. *
  1257. * @access public
  1258. * @since 1.0
  1259. * @param array $element_attribute Element/attribute key/value pairs
  1260. */
  1261. function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
  1262. {
  1263. $this->sanitize->set_url_replacements($element_attribute);
  1264. }
  1265. /**
  1266. * Set the handler to enable the display of cached favicons.
  1267. *
  1268. * @access public
  1269. * @param str $page Web-accessible path to the handler_favicon.php file.
  1270. * @param str $qs The query string that the value should be passed to.
  1271. */
  1272. function set_favicon_handler($page = false, $qs = 'i')
  1273. {
  1274. if ($page != false)
  1275. {
  1276. $this->favicon_handler = $page . '?' . $qs . '=';
  1277. }
  1278. else
  1279. {
  1280. $this->favicon_handler = '';
  1281. }
  1282. }
  1283. /**
  1284. * Set the handler to enable the display of cached images.
  1285. *
  1286. * @access public
  1287. * @param str $page Web-accessible path to the handler_image.php file.
  1288. * @param str $qs The query string that the value should be passed to.
  1289. */
  1290. function set_image_handler($page = false, $qs = 'i')
  1291. {
  1292. if ($page != false)
  1293. {
  1294. $this->sanitize->set_image_handler($page . '?' . $qs . '=');
  1295. }
  1296. else
  1297. {
  1298. $this->image_handler = '';
  1299. }
  1300. }
  1301. /**
  1302. * Set the limit for items returned per-feed with multifeeds.
  1303. *
  1304. * @access public
  1305. * @param integer $limit The maximum number of items to return.
  1306. */
  1307. function set_item_limit($limit = 0)
  1308. {
  1309. $this->item_limit = (int) $limit;
  1310. }
  1311. function init()
  1312. {
  1313. if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
  1314. {
  1315. return false;
  1316. }
  1317. if (isset($_GET[$this->javascript]))
  1318. {
  1319. if (function_exists('ob_gzhandler'))
  1320. {
  1321. ob_start('ob_gzhandler');
  1322. }
  1323. header('Content-type: text/javascript; charset: UTF-8');
  1324. header('Cache-Control: must-revalidate');
  1325. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  1326. ?>
  1327. function embed_odeo(link) {
  1328. 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>');
  1329. }
  1330. function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
  1331. if (placeholder != '') {
  1332. 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>');
  1333. }
  1334. else {
  1335. 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>');
  1336. }
  1337. }
  1338. function embed_flash(bgcolor, width, height, link, loop, type) {
  1339. 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>');
  1340. }
  1341. function embed_flv(width, height, link, placeholder, loop, player) {
  1342. 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>');
  1343. }
  1344. function embed_wmedia(width, height, link) {
  1345. document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
  1346. }
  1347. <?php
  1348. exit;
  1349. }
  1350. // Pass whatever was set with config options over to the sanitizer.
  1351. $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
  1352. $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
  1353. if ($this->feed_url !== null || $this->raw_data !== null)
  1354. {
  1355. $this->data = array();
  1356. $this->multifeed_objects = array();
  1357. $cache = false;
  1358. if ($this->feed_url !== null)
  1359. {
  1360. $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
  1361. // Decide whether to enable caching
  1362. if ($this->cache && $parsed_feed_url['scheme'] !== '')
  1363. {
  1364. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
  1365. }
  1366. // If it's enabled and we don't want an XML dump, use the cache
  1367. if ($cache && !$this->xml_dump)
  1368. {
  1369. // Load the Cache
  1370. $this->data = $cache->load();
  1371. if (!empty($this->data))
  1372. {
  1373. // If the cache is for an outdated build of SimplePie
  1374. if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
  1375. {
  1376. $cache->unlink();
  1377. $this->data = array();
  1378. }
  1379. // If we've hit a collision just rerun it with caching disabled
  1380. elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
  1381. {
  1382. $cache = false;
  1383. $this->data = array();
  1384. }
  1385. // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
  1386. elseif (isset($this->data['feed_url']))
  1387. {
  1388. // If the autodiscovery cache is still valid use it.
  1389. if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
  1390. {
  1391. // Do not need to do feed autodiscovery yet.
  1392. if ($this->data['feed_url'] == $this->data['url'])
  1393. {
  1394. $cache->unlink();
  1395. $this->data = array();
  1396. }
  1397. else
  1398. {
  1399. $this->set_feed_url($this->data['feed_url']);
  1400. return $this->init();
  1401. }
  1402. }
  1403. }
  1404. // Check if the cache has been updated
  1405. elseif ($cache->mtime() + $this->cache_duration < time())
  1406. {
  1407. // If we have last-modified and/or etag set
  1408. if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
  1409. {
  1410. $headers = array();
  1411. if (isset($this->data['headers']['last-modified']))
  1412. {
  1413. $headers['if-modified-since'] = $this->data['headers']['last-modified'];
  1414. }
  1415. if (isset($this->data['headers']['etag']))
  1416. {
  1417. $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
  1418. }
  1419. $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
  1420. if ($file->success)
  1421. {
  1422. if ($file->status_code == 304)
  1423. {
  1424. $cache->touch();
  1425. return true;
  1426. }
  1427. else
  1428. {
  1429. $headers = $file->headers;
  1430. }
  1431. }
  1432. else
  1433. {
  1434. unset($file);
  1435. }
  1436. }
  1437. }
  1438. // If the cache is still valid, just return true
  1439. else
  1440. {
  1441. return true;
  1442. }
  1443. }
  1444. // If the cache is empty, delete it
  1445. else
  1446. {
  1447. $cache->unlink();
  1448. $this->data = array();
  1449. }
  1450. }
  1451. // 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.
  1452. if (!isset($file))
  1453. {
  1454. if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
  1455. {
  1456. $file =& $this->file;
  1457. }
  1458. else
  1459. {
  1460. $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
  1461. }
  1462. }
  1463. // If the file connection has an error, set SimplePie::error to that and quit
  1464. if (!$file->success)
  1465. {
  1466. $this->error = $file->error;
  1467. if (!empty($this->data))
  1468. {
  1469. return true;
  1470. }
  1471. else
  1472. {
  1473. return false;
  1474. }
  1475. }
  1476. if (!$this->force_feed)
  1477. {
  1478. // Check if the supplied URL is a feed, if it isn't, look for it.
  1479. $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
  1480. if (!$locate->is_feed($file))
  1481. {
  1482. // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
  1483. unset($file);
  1484. if ($file = $locate->find($this->autodiscovery))
  1485. {
  1486. if ($cache)
  1487. {
  1488. $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
  1489. if (!$cache->save($this))
  1490. {
  1491. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1492. }
  1493. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
  1494. }
  1495. $this->feed_url = $file->url;
  1496. }
  1497. else
  1498. {
  1499. $this->error = "A feed could not be found at $this->feed_url";
  1500. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1501. return false;
  1502. }
  1503. }
  1504. $locate = null;
  1505. }
  1506. $headers = $file->headers;
  1507. $data = $file->body;
  1508. $sniffer = new $this->content_type_sniffer_class($file);
  1509. $sniffed = $sniffer->get_type();
  1510. }
  1511. else
  1512. {
  1513. $data = $this->raw_data;
  1514. }
  1515. // Set up array of possible encodings
  1516. $encodings = array();
  1517. // First check to see if input has been overridden.
  1518. if ($this->input_encoding !== false)
  1519. {
  1520. $encodings[] = $this->input_encoding;
  1521. }
  1522. $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
  1523. $text_types = array('text/xml', 'text/xml-external-parsed-entity');
  1524. // RFC 3023 (only applies to sniffed content)
  1525. if (isset($sniffed))
  1526. {
  1527. if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
  1528. {
  1529. if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  1530. {
  1531. $encodings[] = strtoupper($charset[1]);
  1532. }
  1533. $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
  1534. $encodings[] = 'UTF-8';
  1535. }
  1536. elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
  1537. {
  1538. if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  1539. {
  1540. $encodings[] = $charset[1];
  1541. }
  1542. $encodings[] = 'US-ASCII';
  1543. }
  1544. // Text MIME-type default
  1545. elseif (substr($sniffed, 0, 5) === 'text/')
  1546. {
  1547. $encodings[] = 'US-ASCII';
  1548. }
  1549. }
  1550. // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
  1551. $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
  1552. $encodings[] = 'UTF-8';
  1553. $encodings[] = 'ISO-8859-1';
  1554. // There's no point in trying an encoding twice
  1555. $encodings = array_unique($encodings);
  1556. // If we want the XML, just output that with the most likely encoding and quit
  1557. if ($this->xml_dump)
  1558. {
  1559. header('Content-type: text/xml; charset=' . $encodings[0]);
  1560. echo $data;
  1561. exit;
  1562. }
  1563. // Loop through each possible encoding, till we return something, or run out of possibilities
  1564. foreach ($encodings as $encoding)
  1565. {
  1566. // Change the encoding to UTF-8 (as we always use UTF-8 internally)
  1567. $utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8');
  1568. // Create new parser
  1569. $parser =& new $this->parser_class();
  1570. // If it's parsed fine
  1571. if ($parser->parse($utf8_data, 'UTF-8'))
  1572. {
  1573. $this->data = $parser->get_data();
  1574. if (isset($this->data['child']))
  1575. {
  1576. if (isset($headers))
  1577. {
  1578. $this->data['headers'] = $headers;
  1579. }
  1580. $this->data['build'] = SIMPLEPIE_BUILD;
  1581. // Cache the file if caching is enabled
  1582. if ($cache && !$cache->save($this))
  1583. {
  1584. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1585. }
  1586. return true;
  1587. }
  1588. else
  1589. {
  1590. $this->error = "A feed could not be found at $this->feed_url";
  1591. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1592. return false;
  1593. }
  1594. }
  1595. }
  1596. // We have an error, just set SimplePie::error to it and quit
  1597. $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
  1598. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1599. return false;
  1600. }
  1601. elseif (!empty($this->multifeed_url))
  1602. {
  1603. $i = 0;
  1604. $success = 0;
  1605. $this->multifeed_objects = array();
  1606. foreach ($this->multifeed_url as $url)
  1607. {
  1608. if (SIMPLEPIE_PHP5)
  1609. {
  1610. // This keyword needs to defy coding standards for PHP4 compatibility
  1611. $this->multifeed_objects[$i] = clone($this);
  1612. }
  1613. else
  1614. {
  1615. $this->multifeed_objects[$i] = $this;
  1616. }
  1617. $this->multifeed_objects[$i]->set_feed_url($url);
  1618. $success |= $this->multifeed_objects[$i]->init();
  1619. $i++;
  1620. }
  1621. return (bool) $success;
  1622. }
  1623. else
  1624. {
  1625. return false;
  1626. }
  1627. }
  1628. /**
  1629. * Return the error message for the occured error
  1630. *
  1631. * @access public
  1632. * @return string Error message
  1633. */
  1634. function error()
  1635. {
  1636. return $this->error;
  1637. }
  1638. function get_encoding()
  1639. {
  1640. return $this->sanitize->output_encoding;
  1641. }
  1642. function handle_content_type($mime = 'text/html')
  1643. {
  1644. if (!headers_sent())
  1645. {
  1646. $header = "Content-type: $mime;";
  1647. if ($this->get_encoding())
  1648. {
  1649. $header .= ' charset=' . $this->get_encoding();
  1650. }
  1651. else
  1652. {
  1653. $header .= ' charset=UTF-8';
  1654. }
  1655. header($header);
  1656. }
  1657. }
  1658. function get_type()
  1659. {
  1660. if (!isset($this->data['type']))
  1661. {
  1662. $this->data['type'] = SIMPLEPIE_TYPE_ALL;
  1663. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
  1664. {
  1665. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
  1666. }
  1667. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
  1668. {
  1669. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
  1670. }
  1671. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
  1672. {
  1673. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
  1674. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
  1675. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
  1676. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
  1677. {
  1678. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
  1679. }
  1680. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
  1681. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
  1682. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
  1683. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
  1684. {
  1685. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
  1686. }
  1687. }
  1688. elseif (isset($this->data['child']['']['rss']))
  1689. {
  1690. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
  1691. if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
  1692. {
  1693. switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
  1694. {
  1695. case '0.91':
  1696. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
  1697. if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
  1698. {
  1699. switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
  1700. {
  1701. case '0':
  1702. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
  1703. break;
  1704. case '24':
  1705. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
  1706. break;
  1707. }
  1708. }
  1709. break;
  1710. case '0.92':
  1711. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
  1712. break;
  1713. case '0.93':
  1714. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
  1715. break;
  1716. case '0.94':
  1717. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
  1718. break;
  1719. case '2.0':
  1720. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
  1721. break;
  1722. }
  1723. }
  1724. }
  1725. else
  1726. {
  1727. $this->data['type'] = SIMPLEPIE_TYPE_NONE;
  1728. }
  1729. }
  1730. return $this->data['type'];
  1731. }
  1732. /**
  1733. * Returns the URL for the favicon of the feed's website.
  1734. *
  1735. * @todo Cache atom:icon
  1736. * @access public
  1737. * @since 1.0
  1738. */
  1739. function get_favicon()
  1740. {
  1741. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  1742. {
  1743. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1744. }
  1745. elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
  1746. {
  1747. $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
  1748. if ($this->cache && $this->favicon_handler)
  1749. {
  1750. $favicon_filename = call_user_func($this->cache_name_function, $favicon);
  1751. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
  1752. if ($cache->load())
  1753. {
  1754. return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
  1755. }
  1756. else
  1757. {
  1758. $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
  1759. if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
  1760. {
  1761. $sniffer = new $this->content_type_sniffer_class($file);
  1762. if (substr($sniffer->get_type(), 0, 6) === 'image/')
  1763. {
  1764. if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  1765. {
  1766. return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
  1767. }
  1768. else
  1769. {
  1770. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1771. return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
  1772. }
  1773. }
  1774. }
  1775. }
  1776. }
  1777. else
  1778. {
  1779. return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
  1780. }
  1781. }
  1782. return false;
  1783. }
  1784. /**
  1785. * @todo If we have a perm redirect we should return the new URL
  1786. * @todo When we make the above change, let's support <itunes:new-feed-url> as well
  1787. * @todo Also, |atom:link|@rel=self
  1788. */
  1789. function subscribe_url()
  1790. {
  1791. if ($this->feed_url !== null)
  1792. {
  1793. return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
  1794. }
  1795. else
  1796. {
  1797. return null;
  1798. }
  1799. }
  1800. function subscribe_feed()
  1801. {
  1802. if ($this->feed_url !== null)
  1803. {
  1804. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
  1805. }
  1806. else
  1807. {
  1808. return null;
  1809. }
  1810. }
  1811. function subscribe_outlook()
  1812. {
  1813. if ($this->feed_url !== null)
  1814. {
  1815. return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
  1816. }
  1817. else
  1818. {
  1819. return null;
  1820. }
  1821. }
  1822. function subscribe_podcast()
  1823. {
  1824. if ($this->feed_url !== null)
  1825. {
  1826. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
  1827. }
  1828. else
  1829. {
  1830. return null;
  1831. }
  1832. }
  1833. function subscribe_itunes()
  1834. {
  1835. if ($this->feed_url !== null)
  1836. {
  1837. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
  1838. }
  1839. else
  1840. {
  1841. return null;
  1842. }
  1843. }
  1844. /**
  1845. * Creates the subscribe_* methods' return data
  1846. *
  1847. * @access private
  1848. * @param string $feed_url String to prefix to the feed URL
  1849. * @param string $site_url String to prefix to the site URL (and
  1850. * suffix to the feed URL)
  1851. * @return mixed URL if feed exists, false otherwise
  1852. */
  1853. function subscribe_service($feed_url, $site_url = null)
  1854. {
  1855. if ($this->subscribe_url())
  1856. {
  1857. $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
  1858. if ($site_url !== null && $this->get_link() !== null)
  1859. {
  1860. $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
  1861. }
  1862. return $return;
  1863. }
  1864. else
  1865. {
  1866. return null;
  1867. }
  1868. }
  1869. function subscribe_aol()
  1870. {
  1871. return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
  1872. }
  1873. function subscribe_bloglines()
  1874. {
  1875. return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
  1876. }
  1877. function subscribe_eskobo()
  1878. {
  1879. return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
  1880. }
  1881. function subscribe_feedfeeds()
  1882. {
  1883. return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
  1884. }
  1885. function subscribe_feedster()
  1886. {
  1887. return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
  1888. }
  1889. function subscribe_google()
  1890. {
  1891. return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
  1892. }
  1893. function subscribe_gritwire()
  1894. {
  1895. return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
  1896. }
  1897. function subscribe_msn()
  1898. {
  1899. return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
  1900. }
  1901. function subscribe_netvibes()
  1902. {
  1903. return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
  1904. }
  1905. function subscribe_newsburst()
  1906. {
  1907. return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
  1908. }
  1909. function subscribe_newsgator()
  1910. {
  1911. return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
  1912. }
  1913. function subscribe_odeo()
  1914. {
  1915. return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
  1916. }
  1917. function subscribe_podnova()
  1918. {
  1919. return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
  1920. }
  1921. function subscribe_rojo()
  1922. {
  1923. return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
  1924. }
  1925. function subscribe_yahoo()
  1926. {
  1927. return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
  1928. }
  1929. function get_feed_tags($namespace, $tag)
  1930. {
  1931. $type = $this->get_type();
  1932. if ($type & SIMPLEPIE_TYPE_ATOM_10)
  1933. {
  1934. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
  1935. {
  1936. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
  1937. }
  1938. }
  1939. if ($type & SIMPLEPIE_TYPE_ATOM_03)
  1940. {
  1941. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
  1942. {
  1943. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
  1944. }
  1945. }
  1946. if ($type & SIMPLEPIE_TYPE_RSS_RDF)
  1947. {
  1948. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
  1949. {
  1950. return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
  1951. }
  1952. }
  1953. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  1954. {
  1955. if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
  1956. {
  1957. return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
  1958. }
  1959. }
  1960. return null;
  1961. }
  1962. function get_channel_tags($namespace, $tag)
  1963. {
  1964. $type = $this->get_type();
  1965. if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
  1966. {
  1967. if ($return = $this->get_feed_tags($namespace, $tag))
  1968. {
  1969. return $return;
  1970. }
  1971. }
  1972. if ($type & SIMPLEPIE_TYPE_RSS_10)
  1973. {
  1974. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
  1975. {
  1976. if (isset($channel[0]['child'][$namespace][$tag]))
  1977. {
  1978. return $channel[0]['child'][$namespace][$tag];
  1979. }
  1980. }
  1981. }
  1982. if ($type & SIMPLEPIE_TYPE_RSS_090)
  1983. {
  1984. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
  1985. {
  1986. if (isset($channel[0]['child'][$namespace][$tag]))
  1987. {
  1988. return $channel[0]['child'][$namespace][$tag];
  1989. }
  1990. }
  1991. }
  1992. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  1993. {
  1994. if ($channel = $this->get_feed_tags('', 'channel'))
  1995. {
  1996. if (isset($channel[0]['child'][$namespace][$tag]))
  1997. {
  1998. return $channel[0]['child'][$namespace][$tag];
  1999. }
  2000. }
  2001. }
  2002. return null;
  2003. }
  2004. function get_image_tags($namespace, $tag)
  2005. {
  2006. $type = $this->get_type();
  2007. if ($type & SIMPLEPIE_TYPE_RSS_10)
  2008. {
  2009. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
  2010. {
  2011. if (isset($image[0]['child'][$namespace][$tag]))
  2012. {
  2013. return $image[0]['child'][$namespace][$tag];
  2014. }
  2015. }
  2016. }
  2017. if ($type & SIMPLEPIE_TYPE_RSS_090)
  2018. {
  2019. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
  2020. {
  2021. if (isset($image[0]['child'][$namespace][$tag]))
  2022. {
  2023. return $image[0]['child'][$namespace][$tag];
  2024. }
  2025. }
  2026. }
  2027. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  2028. {
  2029. if ($image = $this->get_channel_tags('', 'image'))
  2030. {
  2031. if (isset($image[0]['child'][$namespace][$tag]))
  2032. {
  2033. return $image[0]['child'][$namespace][$tag];
  2034. }
  2035. }
  2036. }
  2037. return null;
  2038. }
  2039. function get_base($element = array())
  2040. {
  2041. if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
  2042. {
  2043. return $element['xml_base'];
  2044. }
  2045. elseif ($this->get_link() !== null)
  2046. {
  2047. return $this->get_link();
  2048. }
  2049. else
  2050. {
  2051. return $this->subscribe_url();
  2052. }
  2053. }
  2054. function sanitize($data, $type, $base = '')
  2055. {
  2056. return $this->sanitize->sanitize($data, $type, $base);
  2057. }
  2058. function get_title()
  2059. {
  2060. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  2061. {
  2062. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2063. }
  2064. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  2065. {
  2066. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2067. }
  2068. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2069. {
  2070. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2071. }
  2072. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2073. {
  2074. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2075. }
  2076. elseif ($return = $this->get_channel_tags('', 'title'))
  2077. {
  2078. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2079. }
  2080. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2081. {
  2082. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2083. }
  2084. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2085. {
  2086. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2087. }
  2088. else
  2089. {
  2090. return null;
  2091. }
  2092. }
  2093. function get_category($key = 0)
  2094. {
  2095. $categories = $this->get_categories();
  2096. if (isset($categories[$key]))
  2097. {
  2098. return $categories[$key];
  2099. }
  2100. else
  2101. {
  2102. return null;
  2103. }
  2104. }
  2105. function get_categories()
  2106. {
  2107. $categories = array();
  2108. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  2109. {
  2110. $term = null;
  2111. $scheme = null;
  2112. $label = null;
  2113. if (isset($category['attribs']['']['term']))
  2114. {
  2115. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  2116. }
  2117. if (isset($category['attribs']['']['scheme']))
  2118. {
  2119. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  2120. }
  2121. if (isset($category['attribs']['']['label']))
  2122. {
  2123. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  2124. }
  2125. $categories[] =& new $this->category_class($term, $scheme, $label);
  2126. }
  2127. foreach ((array) $this->get_channel_tags('', 'category') as $category)
  2128. {
  2129. $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2130. }
  2131. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  2132. {
  2133. $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2134. }
  2135. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  2136. {
  2137. $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2138. }
  2139. if (!empty($categories))
  2140. {
  2141. return SimplePie_Misc::array_unique($categories);
  2142. }
  2143. else
  2144. {
  2145. return null;
  2146. }
  2147. }
  2148. function get_author($key = 0)
  2149. {
  2150. $authors = $this->get_authors();
  2151. if (isset($authors[$key]))
  2152. {
  2153. return $authors[$key];
  2154. }
  2155. else
  2156. {
  2157. return null;
  2158. }
  2159. }
  2160. function get_authors()
  2161. {
  2162. $authors = array();
  2163. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  2164. {
  2165. $name = null;
  2166. $uri = null;
  2167. $email = null;
  2168. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  2169. {
  2170. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2171. }
  2172. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  2173. {
  2174. $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]));
  2175. }
  2176. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  2177. {
  2178. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2179. }
  2180. if ($name !== null || $email !== null || $uri !== null)
  2181. {
  2182. $authors[] =& new $this->author_class($name, $uri, $email);
  2183. }
  2184. }
  2185. if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  2186. {
  2187. $name = null;
  2188. $url = null;
  2189. $email = null;
  2190. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  2191. {
  2192. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2193. }
  2194. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  2195. {
  2196. $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
  2197. }
  2198. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  2199. {
  2200. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2201. }
  2202. if ($name !== null || $email !== null || $url !== null)
  2203. {
  2204. $authors[] =& new $this->author_class($name, $url, $email);
  2205. }
  2206. }
  2207. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  2208. {
  2209. $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2210. }
  2211. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  2212. {
  2213. $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2214. }
  2215. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  2216. {
  2217. $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2218. }
  2219. if (!empty($authors))
  2220. {
  2221. return SimplePie_Misc::array_unique($authors);
  2222. }
  2223. else
  2224. {
  2225. return null;
  2226. }
  2227. }
  2228. function get_contributor($key = 0)
  2229. {
  2230. $contributors = $this->get_contributors();
  2231. if (isset($contributors[$key]))
  2232. {
  2233. return $contributors[$key];
  2234. }
  2235. else
  2236. {
  2237. return null;
  2238. }
  2239. }
  2240. function get_contributors()
  2241. {
  2242. $contributors = array();
  2243. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  2244. {
  2245. $name = null;
  2246. $uri = null;
  2247. $email = null;
  2248. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  2249. {
  2250. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2251. }
  2252. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  2253. {
  2254. $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
  2255. }
  2256. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  2257. {
  2258. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2259. }
  2260. if ($name !== null || $email !== null || $uri !== null)
  2261. {
  2262. $contributors[] =& new $this->author_class($name, $uri, $email);
  2263. }
  2264. }
  2265. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  2266. {
  2267. $name = null;
  2268. $url = null;
  2269. $email = null;
  2270. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  2271. {
  2272. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2273. }
  2274. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  2275. {
  2276. $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
  2277. }
  2278. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  2279. {
  2280. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2281. }
  2282. if ($name !== null || $email !== null || $url !== null)
  2283. {
  2284. $contributors[] =& new $this->author_class($name, $url, $email);
  2285. }
  2286. }
  2287. if (!empty($contributors))
  2288. {
  2289. return SimplePie_Misc::array_unique($contributors);
  2290. }
  2291. else
  2292. {
  2293. return null;
  2294. }
  2295. }
  2296. function get_link($key = 0, $rel = 'alternate')
  2297. {
  2298. $links = $this->get_links($rel);
  2299. if (isset($links[$key]))
  2300. {
  2301. return $links[$key];
  2302. }
  2303. else
  2304. {
  2305. return null;
  2306. }
  2307. }
  2308. /**
  2309. * Added for parity between the parent-level and the item/entry-level.
  2310. */
  2311. function get_permalink()
  2312. {
  2313. return $this->get_link(0);
  2314. }
  2315. function get_links($rel = 'alternate')
  2316. {
  2317. if (!isset($this->data['links']))
  2318. {
  2319. $this->data['links'] = array();
  2320. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  2321. {
  2322. foreach ($links as $link)
  2323. {
  2324. if (isset($link['attribs']['']['href']))
  2325. {
  2326. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2327. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2328. }
  2329. }
  2330. }
  2331. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  2332. {
  2333. foreach ($links as $link)
  2334. {
  2335. if (isset($link['attribs']['']['href']))
  2336. {
  2337. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2338. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2339. }
  2340. }
  2341. }
  2342. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2343. {
  2344. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2345. }
  2346. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2347. {
  2348. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2349. }
  2350. if ($links = $this->get_channel_tags('', 'link'))
  2351. {
  2352. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2353. }
  2354. $keys = array_keys($this->data['links']);
  2355. foreach ($keys as $key)
  2356. {
  2357. if (SimplePie_Misc::is_isegment_nz_nc($key))
  2358. {
  2359. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  2360. {
  2361. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  2362. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  2363. }
  2364. else
  2365. {
  2366. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  2367. }
  2368. }
  2369. elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  2370. {
  2371. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  2372. }
  2373. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  2374. }
  2375. }
  2376. if (isset($this->data['links'][$rel]))
  2377. {
  2378. return $this->data['links'][$rel];
  2379. }
  2380. else
  2381. {
  2382. return null;
  2383. }
  2384. }
  2385. function get_description()
  2386. {
  2387. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  2388. {
  2389. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2390. }
  2391. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  2392. {
  2393. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2394. }
  2395. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  2396. {
  2397. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2398. }
  2399. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  2400. {
  2401. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2402. }
  2403. elseif ($return = $this->get_channel_tags('', 'description'))
  2404. {
  2405. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2406. }
  2407. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  2408. {
  2409. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2410. }
  2411. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  2412. {
  2413. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2414. }
  2415. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  2416. {
  2417. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2418. }
  2419. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  2420. {
  2421. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2422. }
  2423. else
  2424. {
  2425. return null;
  2426. }
  2427. }
  2428. function get_copyright()
  2429. {
  2430. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  2431. {
  2432. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2433. }
  2434. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
  2435. {
  2436. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2437. }
  2438. elseif ($return = $this->get_channel_tags('', 'copyright'))
  2439. {
  2440. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2441. }
  2442. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  2443. {
  2444. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2445. }
  2446. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  2447. {
  2448. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2449. }
  2450. else
  2451. {
  2452. return null;
  2453. }
  2454. }
  2455. function get_language()
  2456. {
  2457. if ($return = $this->get_channel_tags('', 'language'))
  2458. {
  2459. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2460. }
  2461. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  2462. {
  2463. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2464. }
  2465. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  2466. {
  2467. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2468. }
  2469. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
  2470. {
  2471. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2472. }
  2473. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
  2474. {
  2475. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2476. }
  2477. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
  2478. {
  2479. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2480. }
  2481. elseif (isset($this->data['headers']['content-language']))
  2482. {
  2483. return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
  2484. }
  2485. else
  2486. {
  2487. return null;
  2488. }
  2489. }
  2490. function get_latitude()
  2491. {
  2492. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  2493. {
  2494. return (float) $return[0]['data'];
  2495. }
  2496. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  2497. {
  2498. return (float) $match[1];
  2499. }
  2500. else
  2501. {
  2502. return null;
  2503. }
  2504. }
  2505. function get_longitude()
  2506. {
  2507. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  2508. {
  2509. return (float) $return[0]['data'];
  2510. }
  2511. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  2512. {
  2513. return (float) $return[0]['data'];
  2514. }
  2515. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  2516. {
  2517. return (float) $match[2];
  2518. }
  2519. else
  2520. {
  2521. return null;
  2522. }
  2523. }
  2524. function get_image_title()
  2525. {
  2526. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2527. {
  2528. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2529. }
  2530. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2531. {
  2532. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2533. }
  2534. elseif ($return = $this->get_image_tags('', 'title'))
  2535. {
  2536. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2537. }
  2538. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2539. {
  2540. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2541. }
  2542. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2543. {
  2544. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2545. }
  2546. else
  2547. {
  2548. return null;
  2549. }
  2550. }
  2551. function get_image_url()
  2552. {
  2553. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  2554. {
  2555. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  2556. }
  2557. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  2558. {
  2559. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2560. }
  2561. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  2562. {
  2563. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2564. }
  2565. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
  2566. {
  2567. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2568. }
  2569. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
  2570. {
  2571. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2572. }
  2573. elseif ($return = $this->get_image_tags('', 'url'))
  2574. {
  2575. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2576. }
  2577. else
  2578. {
  2579. return null;
  2580. }
  2581. }
  2582. function get_image_link()
  2583. {
  2584. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2585. {
  2586. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2587. }
  2588. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2589. {
  2590. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2591. }
  2592. elseif ($return = $this->get_image_tags('', 'link'))
  2593. {
  2594. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2595. }
  2596. else
  2597. {
  2598. return null;
  2599. }
  2600. }
  2601. function get_image_width()
  2602. {
  2603. if ($return = $this->get_image_tags('', 'width'))
  2604. {
  2605. return round($return[0]['data']);
  2606. }
  2607. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
  2608. {
  2609. return 88.0;
  2610. }
  2611. else
  2612. {
  2613. return null;
  2614. }
  2615. }
  2616. function get_image_height()
  2617. {
  2618. if ($return = $this->get_image_tags('', 'height'))
  2619. {
  2620. return round($return[0]['data']);
  2621. }
  2622. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
  2623. {
  2624. return 31.0;
  2625. }
  2626. else
  2627. {
  2628. return null;
  2629. }
  2630. }
  2631. function get_item_quantity($max = 0)
  2632. {
  2633. $qty = count($this->get_items());
  2634. if ($max == 0)
  2635. {
  2636. return $qty;
  2637. }
  2638. else
  2639. {
  2640. return ($qty > $max) ? $max : $qty;
  2641. }
  2642. }
  2643. function get_item($key = 0)
  2644. {
  2645. $items = $this->get_items();
  2646. if (isset($items[$key]))
  2647. {
  2648. return $items[$key];
  2649. }
  2650. else
  2651. {
  2652. return null;
  2653. }
  2654. }
  2655. function get_items($start = 0, $end = 0)
  2656. {
  2657. if (!empty($this->multifeed_objects))
  2658. {
  2659. return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
  2660. }
  2661. elseif (!isset($this->data['items']))
  2662. {
  2663. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
  2664. {
  2665. $keys = array_keys($items);
  2666. foreach ($keys as $key)
  2667. {
  2668. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2669. }
  2670. }
  2671. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
  2672. {
  2673. $keys = array_keys($items);
  2674. foreach ($keys as $key)
  2675. {
  2676. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2677. }
  2678. }
  2679. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
  2680. {
  2681. $keys = array_keys($items);
  2682. foreach ($keys as $key)
  2683. {
  2684. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2685. }
  2686. }
  2687. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
  2688. {
  2689. $keys = array_keys($items);
  2690. foreach ($keys as $key)
  2691. {
  2692. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2693. }
  2694. }
  2695. if ($items = $this->get_channel_tags('', 'item'))
  2696. {
  2697. $keys = array_keys($items);
  2698. foreach ($keys as $key)
  2699. {
  2700. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2701. }
  2702. }
  2703. }
  2704. if (!empty($this->data['items']))
  2705. {
  2706. // If we want to order it by date, check if all items have a date, and then sort it
  2707. if ($this->order_by_date)
  2708. {
  2709. if (!isset($this->data['ordered_items']))
  2710. {
  2711. $do_sort = true;
  2712. foreach ($this->data['items'] as $item)
  2713. {
  2714. if (!$item->get_date('U'))
  2715. {
  2716. $do_sort = false;
  2717. break;
  2718. }
  2719. }
  2720. $item = null;
  2721. $this->data['ordered_items'] = $this->data['items'];
  2722. if ($do_sort)
  2723. {
  2724. usort($this->data['ordered_items'], array(&$this, 'sort_items'));
  2725. }
  2726. }
  2727. $items = $this->data['ordered_items'];
  2728. }
  2729. else
  2730. {
  2731. $items = $this->data['items'];
  2732. }
  2733. // Slice the data as desired
  2734. if ($end == 0)
  2735. {
  2736. return array_slice($items, $start);
  2737. }
  2738. else
  2739. {
  2740. return array_slice($items, $start, $end);
  2741. }
  2742. }
  2743. else
  2744. {
  2745. return array();
  2746. }
  2747. }
  2748. function sort_items($a, $b)
  2749. {
  2750. return $a->get_date('U') <= $b->get_date('U');
  2751. }
  2752. function merge_items($urls, $start = 0, $end = 0, $limit = 0)
  2753. {
  2754. if (is_array($urls) && sizeof($urls) > 0)
  2755. {
  2756. $items = array();
  2757. foreach ($urls as $arg)
  2758. {
  2759. if (is_a($arg, 'SimplePie'))
  2760. {
  2761. $items = array_merge($items, $arg->get_items(0, $limit));
  2762. }
  2763. else
  2764. {
  2765. trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
  2766. }
  2767. }
  2768. $do_sort = true;
  2769. foreach ($items as $item)
  2770. {
  2771. if (!$item->get_date('U'))
  2772. {
  2773. $do_sort = false;
  2774. break;
  2775. }
  2776. }
  2777. $item = null;
  2778. if ($do_sort)
  2779. {
  2780. usort($items, array('SimplePie', 'sort_items'));
  2781. }
  2782. if ($end == 0)
  2783. {
  2784. return array_slice($items, $start);
  2785. }
  2786. else
  2787. {
  2788. return array_slice($items, $start, $end);
  2789. }
  2790. }
  2791. else
  2792. {
  2793. trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
  2794. return array();
  2795. }
  2796. }
  2797. }
  2798. class SimplePie_Item
  2799. {
  2800. var $feed;
  2801. var $data = array();
  2802. function SimplePie_Item($feed, $data)
  2803. {
  2804. $this->feed = $feed;
  2805. $this->data = $data;
  2806. }
  2807. function __toString()
  2808. {
  2809. return md5(serialize($this->data));
  2810. }
  2811. /**
  2812. * Remove items that link back to this before destroying this object
  2813. */
  2814. function __destruct()
  2815. {
  2816. unset($this->feed);
  2817. }
  2818. function get_item_tags($namespace, $tag)
  2819. {
  2820. if (isset($this->data['child'][$namespace][$tag]))
  2821. {
  2822. return $this->data['child'][$namespace][$tag];
  2823. }
  2824. else
  2825. {
  2826. return null;
  2827. }
  2828. }
  2829. function get_base($element = array())
  2830. {
  2831. return $this->feed->get_base($element);
  2832. }
  2833. function sanitize($data, $type, $base = '')
  2834. {
  2835. return $this->feed->sanitize($data, $type, $base);
  2836. }
  2837. function get_feed()
  2838. {
  2839. return $this->feed;
  2840. }
  2841. function get_id($hash = false)
  2842. {
  2843. if (!$hash)
  2844. {
  2845. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
  2846. {
  2847. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2848. }
  2849. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
  2850. {
  2851. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2852. }
  2853. elseif ($return = $this->get_item_tags('', 'guid'))
  2854. {
  2855. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2856. }
  2857. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
  2858. {
  2859. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2860. }
  2861. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
  2862. {
  2863. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2864. }
  2865. elseif (($return = $this->get_permalink()) !== null)
  2866. {
  2867. return $return;
  2868. }
  2869. elseif (($return = $this->get_title()) !== null)
  2870. {
  2871. return $return;
  2872. }
  2873. }
  2874. if ($this->get_permalink() !== null || $this->get_title() !== null)
  2875. {
  2876. return md5($this->get_permalink() . $this->get_title());
  2877. }
  2878. else
  2879. {
  2880. return md5(serialize($this->data));
  2881. }
  2882. }
  2883. function get_title()
  2884. {
  2885. if (!isset($this->data['title']))
  2886. {
  2887. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  2888. {
  2889. $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2890. }
  2891. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  2892. {
  2893. $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2894. }
  2895. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2896. {
  2897. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2898. }
  2899. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2900. {
  2901. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2902. }
  2903. elseif ($return = $this->get_item_tags('', 'title'))
  2904. {
  2905. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2906. }
  2907. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2908. {
  2909. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2910. }
  2911. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2912. {
  2913. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2914. }
  2915. else
  2916. {
  2917. $this->data['title'] = null;
  2918. }
  2919. }
  2920. return $this->data['title'];
  2921. }
  2922. function get_description($description_only = false)
  2923. {
  2924. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
  2925. {
  2926. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2927. }
  2928. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
  2929. {
  2930. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2931. }
  2932. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  2933. {
  2934. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2935. }
  2936. elseif ($return = $this->get_item_tags('', 'description'))
  2937. {
  2938. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2939. }
  2940. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  2941. {
  2942. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2943. }
  2944. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  2945. {
  2946. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2947. }
  2948. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  2949. {
  2950. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2951. }
  2952. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  2953. {
  2954. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2955. }
  2956. elseif (!$description_only)
  2957. {
  2958. return $this->get_content(true);
  2959. }
  2960. else
  2961. {
  2962. return null;
  2963. }
  2964. }
  2965. function get_content($content_only = false)
  2966. {
  2967. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
  2968. {
  2969. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2970. }
  2971. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
  2972. {
  2973. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2974. }
  2975. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
  2976. {
  2977. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2978. }
  2979. elseif (!$content_only)
  2980. {
  2981. return $this->get_description(true);
  2982. }
  2983. else
  2984. {
  2985. return null;
  2986. }
  2987. }
  2988. function get_category($key = 0)
  2989. {
  2990. $categories = $this->get_categories();
  2991. if (isset($categories[$key]))
  2992. {
  2993. return $categories[$key];
  2994. }
  2995. else
  2996. {
  2997. return null;
  2998. }
  2999. }
  3000. function get_categories()
  3001. {
  3002. $categories = array();
  3003. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  3004. {
  3005. $term = null;
  3006. $scheme = null;
  3007. $label = null;
  3008. if (isset($category['attribs']['']['term']))
  3009. {
  3010. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  3011. }
  3012. if (isset($category['attribs']['']['scheme']))
  3013. {
  3014. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3015. }
  3016. if (isset($category['attribs']['']['label']))
  3017. {
  3018. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3019. }
  3020. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  3021. }
  3022. foreach ((array) $this->get_item_tags('', 'category') as $category)
  3023. {
  3024. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3025. }
  3026. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  3027. {
  3028. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3029. }
  3030. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  3031. {
  3032. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3033. }
  3034. if (!empty($categories))
  3035. {
  3036. return SimplePie_Misc::array_unique($categories);
  3037. }
  3038. else
  3039. {
  3040. return null;
  3041. }
  3042. }
  3043. function get_author($key = 0)
  3044. {
  3045. $authors = $this->get_authors();
  3046. if (isset($authors[$key]))
  3047. {
  3048. return $authors[$key];
  3049. }
  3050. else
  3051. {
  3052. return null;
  3053. }
  3054. }
  3055. function get_contributor($key = 0)
  3056. {
  3057. $contributors = $this->get_contributors();
  3058. if (isset($contributors[$key]))
  3059. {
  3060. return $contributors[$key];
  3061. }
  3062. else
  3063. {
  3064. return null;
  3065. }
  3066. }
  3067. function get_contributors()
  3068. {
  3069. $contributors = array();
  3070. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  3071. {
  3072. $name = null;
  3073. $uri = null;
  3074. $email = null;
  3075. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  3076. {
  3077. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3078. }
  3079. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  3080. {
  3081. $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
  3082. }
  3083. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  3084. {
  3085. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3086. }
  3087. if ($name !== null || $email !== null || $uri !== null)
  3088. {
  3089. $contributors[] =& new $this->feed->author_class($name, $uri, $email);
  3090. }
  3091. }
  3092. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  3093. {
  3094. $name = null;
  3095. $url = null;
  3096. $email = null;
  3097. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  3098. {
  3099. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3100. }
  3101. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  3102. {
  3103. $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
  3104. }
  3105. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  3106. {
  3107. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3108. }
  3109. if ($name !== null || $email !== null || $url !== null)
  3110. {
  3111. $contributors[] =& new $this->feed->author_class($name, $url, $email);
  3112. }
  3113. }
  3114. if (!empty($contributors))
  3115. {
  3116. return SimplePie_Misc::array_unique($contributors);
  3117. }
  3118. else
  3119. {
  3120. return null;
  3121. }
  3122. }
  3123. /**
  3124. * @todo Atom inheritance (item author, source author, feed author)
  3125. */
  3126. function get_authors()
  3127. {
  3128. $authors = array();
  3129. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  3130. {
  3131. $name = null;
  3132. $uri = null;
  3133. $email = null;
  3134. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  3135. {
  3136. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3137. }
  3138. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  3139. {
  3140. $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]));
  3141. }
  3142. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  3143. {
  3144. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3145. }
  3146. if ($name !== null || $email !== null || $uri !== null)
  3147. {
  3148. $authors[] =& new $this->feed->author_class($name, $uri, $email);
  3149. }
  3150. }
  3151. if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  3152. {
  3153. $name = null;
  3154. $url = null;
  3155. $email = null;
  3156. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  3157. {
  3158. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3159. }
  3160. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  3161. {
  3162. $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
  3163. }
  3164. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  3165. {
  3166. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3167. }
  3168. if ($name !== null || $email !== null || $url !== null)
  3169. {
  3170. $authors[] =& new $this->feed->author_class($name, $url, $email);
  3171. }
  3172. }
  3173. if ($author = $this->get_item_tags('', 'author'))
  3174. {
  3175. $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3176. }
  3177. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  3178. {
  3179. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3180. }
  3181. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  3182. {
  3183. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3184. }
  3185. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  3186. {
  3187. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3188. }
  3189. if (!empty($authors))
  3190. {
  3191. return SimplePie_Misc::array_unique($authors);
  3192. }
  3193. elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
  3194. {
  3195. return $authors;
  3196. }
  3197. elseif ($authors = $this->feed->get_authors())
  3198. {
  3199. return $authors;
  3200. }
  3201. else
  3202. {
  3203. return null;
  3204. }
  3205. }
  3206. function get_copyright()
  3207. {
  3208. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  3209. {
  3210. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  3211. }
  3212. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  3213. {
  3214. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3215. }
  3216. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  3217. {
  3218. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3219. }
  3220. else
  3221. {
  3222. return null;
  3223. }
  3224. }
  3225. function get_date($date_format = 'j F Y, g:i a')
  3226. {
  3227. if (!isset($this->data['date']))
  3228. {
  3229. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
  3230. {
  3231. $this->data['date']['raw'] = $return[0]['data'];
  3232. }
  3233. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
  3234. {
  3235. $this->data['date']['raw'] = $return[0]['data'];
  3236. }
  3237. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
  3238. {
  3239. $this->data['date']['raw'] = $return[0]['data'];
  3240. }
  3241. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
  3242. {
  3243. $this->data['date']['raw'] = $return[0]['data'];
  3244. }
  3245. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
  3246. {
  3247. $this->data['date']['raw'] = $return[0]['data'];
  3248. }
  3249. elseif ($return = $this->get_item_tags('', 'pubDate'))
  3250. {
  3251. $this->data['date']['raw'] = $return[0]['data'];
  3252. }
  3253. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
  3254. {
  3255. $this->data['date']['raw'] = $return[0]['data'];
  3256. }
  3257. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
  3258. {
  3259. $this->data['date']['raw'] = $return[0]['data'];
  3260. }
  3261. if (!empty($this->data['date']['raw']))
  3262. {
  3263. $parser = SimplePie_Parse_Date::get();
  3264. $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
  3265. }
  3266. else
  3267. {
  3268. $this->data['date'] = null;
  3269. }
  3270. }
  3271. if ($this->data['date'])
  3272. {
  3273. $date_format = (string) $date_format;
  3274. switch ($date_format)
  3275. {
  3276. case '':
  3277. return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
  3278. case 'U':
  3279. return $this->data['date']['parsed'];
  3280. default:
  3281. return date($date_format, $this->data['date']['parsed']);
  3282. }
  3283. }
  3284. else
  3285. {
  3286. return null;
  3287. }
  3288. }
  3289. function get_local_date($date_format = '%c')
  3290. {
  3291. if (!$date_format)
  3292. {
  3293. return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
  3294. }
  3295. elseif (($date = $this->get_date('U')) !== null)
  3296. {
  3297. return strftime($date_format, $date);
  3298. }
  3299. else
  3300. {
  3301. return null;
  3302. }
  3303. }
  3304. function get_permalink()
  3305. {
  3306. $link = $this->get_link();
  3307. $enclosure = $this->get_enclosure(0);
  3308. if ($link !== null)
  3309. {
  3310. return $link;
  3311. }
  3312. elseif ($enclosure !== null)
  3313. {
  3314. return $enclosure->get_link();
  3315. }
  3316. else
  3317. {
  3318. return null;
  3319. }
  3320. }
  3321. function get_link($key = 0, $rel = 'alternate')
  3322. {
  3323. $links = $this->get_links($rel);
  3324. if ($links[$key] !== null)
  3325. {
  3326. return $links[$key];
  3327. }
  3328. else
  3329. {
  3330. return null;
  3331. }
  3332. }
  3333. function get_links($rel = 'alternate')
  3334. {
  3335. if (!isset($this->data['links']))
  3336. {
  3337. $this->data['links'] = array();
  3338. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  3339. {
  3340. if (isset($link['attribs']['']['href']))
  3341. {
  3342. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  3343. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  3344. }
  3345. }
  3346. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  3347. {
  3348. if (isset($link['attribs']['']['href']))
  3349. {
  3350. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  3351. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  3352. }
  3353. }
  3354. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  3355. {
  3356. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3357. }
  3358. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  3359. {
  3360. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3361. }
  3362. if ($links = $this->get_item_tags('', 'link'))
  3363. {
  3364. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3365. }
  3366. if ($links = $this->get_item_tags('', 'guid'))
  3367. {
  3368. if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
  3369. {
  3370. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3371. }
  3372. }
  3373. $keys = array_keys($this->data['links']);
  3374. foreach ($keys as $key)
  3375. {
  3376. if (SimplePie_Misc::is_isegment_nz_nc($key))
  3377. {
  3378. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  3379. {
  3380. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  3381. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  3382. }
  3383. else
  3384. {
  3385. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  3386. }
  3387. }
  3388. elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  3389. {
  3390. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  3391. }
  3392. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  3393. }
  3394. }
  3395. if (isset($this->data['links'][$rel]))
  3396. {
  3397. return $this->data['links'][$rel];
  3398. }
  3399. else
  3400. {
  3401. return null;
  3402. }
  3403. }
  3404. /**
  3405. * @todo Add ability to prefer one type of content over another (in a media group).
  3406. */
  3407. function get_enclosure($key = 0, $prefer = null)
  3408. {
  3409. $enclosures = $this->get_enclosures();
  3410. if (isset($enclosures[$key]))
  3411. {
  3412. return $enclosures[$key];
  3413. }
  3414. else
  3415. {
  3416. return null;
  3417. }
  3418. }
  3419. /**
  3420. * Grabs all available enclosures (podcasts, etc.)
  3421. *
  3422. * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
  3423. *
  3424. * 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.
  3425. *
  3426. * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
  3427. * @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).
  3428. */
  3429. function get_enclosures()
  3430. {
  3431. if (!isset($this->data['enclosures']))
  3432. {
  3433. $this->data['enclosures'] = array();
  3434. // Elements
  3435. $captions_parent = null;
  3436. $categories_parent = null;
  3437. $copyrights_parent = null;
  3438. $credits_parent = null;
  3439. $description_parent = null;
  3440. $duration_parent = null;
  3441. $hashes_parent = null;
  3442. $keywords_parent = null;
  3443. $player_parent = null;
  3444. $ratings_parent = null;
  3445. $restrictions_parent = null;
  3446. $thumbnails_parent = null;
  3447. $title_parent = null;
  3448. // Let's do the channel and item-level ones first, and just re-use them if we need to.
  3449. $parent = $this->get_feed();
  3450. // CAPTIONS
  3451. if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  3452. {
  3453. foreach ($captions as $caption)
  3454. {
  3455. $caption_type = null;
  3456. $caption_lang = null;
  3457. $caption_startTime = null;
  3458. $caption_endTime = null;
  3459. $caption_text = null;
  3460. if (isset($caption['attribs']['']['type']))
  3461. {
  3462. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3463. }
  3464. if (isset($caption['attribs']['']['lang']))
  3465. {
  3466. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3467. }
  3468. if (isset($caption['attribs']['']['start']))
  3469. {
  3470. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3471. }
  3472. if (isset($caption['attribs']['']['end']))
  3473. {
  3474. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3475. }
  3476. if (isset($caption['data']))
  3477. {
  3478. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3479. }
  3480. $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3481. }
  3482. }
  3483. elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  3484. {
  3485. foreach ($captions as $caption)
  3486. {
  3487. $caption_type = null;
  3488. $caption_lang = null;
  3489. $caption_startTime = null;
  3490. $caption_endTime = null;
  3491. $caption_text = null;
  3492. if (isset($caption['attribs']['']['type']))
  3493. {
  3494. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3495. }
  3496. if (isset($caption['attribs']['']['lang']))
  3497. {
  3498. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3499. }
  3500. if (isset($caption['attribs']['']['start']))
  3501. {
  3502. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3503. }
  3504. if (isset($caption['attribs']['']['end']))
  3505. {
  3506. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3507. }
  3508. if (isset($caption['data']))
  3509. {
  3510. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3511. }
  3512. $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3513. }
  3514. }
  3515. if (is_array($captions_parent))
  3516. {
  3517. $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
  3518. }
  3519. // CATEGORIES
  3520. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  3521. {
  3522. $term = null;
  3523. $scheme = null;
  3524. $label = null;
  3525. if (isset($category['data']))
  3526. {
  3527. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3528. }
  3529. if (isset($category['attribs']['']['scheme']))
  3530. {
  3531. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3532. }
  3533. else
  3534. {
  3535. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3536. }
  3537. if (isset($category['attribs']['']['label']))
  3538. {
  3539. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3540. }
  3541. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3542. }
  3543. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  3544. {
  3545. $term = null;
  3546. $scheme = null;
  3547. $label = null;
  3548. if (isset($category['data']))
  3549. {
  3550. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3551. }
  3552. if (isset($category['attribs']['']['scheme']))
  3553. {
  3554. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3555. }
  3556. else
  3557. {
  3558. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3559. }
  3560. if (isset($category['attribs']['']['label']))
  3561. {
  3562. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3563. }
  3564. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3565. }
  3566. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
  3567. {
  3568. $term = null;
  3569. $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
  3570. $label = null;
  3571. if (isset($category['attribs']['']['text']))
  3572. {
  3573. $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  3574. }
  3575. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3576. if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
  3577. {
  3578. foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
  3579. {
  3580. if (isset($subcategory['attribs']['']['text']))
  3581. {
  3582. $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  3583. }
  3584. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3585. }
  3586. }
  3587. }
  3588. if (is_array($categories_parent))
  3589. {
  3590. $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
  3591. }
  3592. // COPYRIGHT
  3593. if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  3594. {
  3595. $copyright_url = null;
  3596. $copyright_label = null;
  3597. if (isset($copyright[0]['attribs']['']['url']))
  3598. {
  3599. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3600. }
  3601. if (isset($copyright[0]['data']))
  3602. {
  3603. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3604. }
  3605. $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  3606. }
  3607. elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  3608. {
  3609. $copyright_url = null;
  3610. $copyright_label = null;
  3611. if (isset($copyright[0]['attribs']['']['url']))
  3612. {
  3613. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3614. }
  3615. if (isset($copyright[0]['data']))
  3616. {
  3617. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3618. }
  3619. $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  3620. }
  3621. // CREDITS
  3622. if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  3623. {
  3624. foreach ($credits as $credit)
  3625. {
  3626. $credit_role = null;
  3627. $credit_scheme = null;
  3628. $credit_name = null;
  3629. if (isset($credit['attribs']['']['role']))
  3630. {
  3631. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3632. }
  3633. if (isset($credit['attribs']['']['scheme']))
  3634. {
  3635. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3636. }
  3637. else
  3638. {
  3639. $credit_scheme = 'urn:ebu';
  3640. }
  3641. if (isset($credit['data']))
  3642. {
  3643. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3644. }
  3645. $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3646. }
  3647. }
  3648. elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  3649. {
  3650. foreach ($credits as $credit)
  3651. {
  3652. $credit_role = null;
  3653. $credit_scheme = null;
  3654. $credit_name = null;
  3655. if (isset($credit['attribs']['']['role']))
  3656. {
  3657. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3658. }
  3659. if (isset($credit['attribs']['']['scheme']))
  3660. {
  3661. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3662. }
  3663. else
  3664. {
  3665. $credit_scheme = 'urn:ebu';
  3666. }
  3667. if (isset($credit['data']))
  3668. {
  3669. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3670. }
  3671. $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3672. }
  3673. }
  3674. if (is_array($credits_parent))
  3675. {
  3676. $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
  3677. }
  3678. // DESCRIPTION
  3679. if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  3680. {
  3681. if (isset($description_parent[0]['data']))
  3682. {
  3683. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3684. }
  3685. }
  3686. elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  3687. {
  3688. if (isset($description_parent[0]['data']))
  3689. {
  3690. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3691. }
  3692. }
  3693. // DURATION
  3694. if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
  3695. {
  3696. $seconds = null;
  3697. $minutes = null;
  3698. $hours = null;
  3699. if (isset($duration_parent[0]['data']))
  3700. {
  3701. $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3702. if (sizeof($temp) > 0)
  3703. {
  3704. (int) $seconds = array_pop($temp);
  3705. }
  3706. if (sizeof($temp) > 0)
  3707. {
  3708. (int) $minutes = array_pop($temp);
  3709. $seconds += $minutes * 60;
  3710. }
  3711. if (sizeof($temp) > 0)
  3712. {
  3713. (int) $hours = array_pop($temp);
  3714. $seconds += $hours * 3600;
  3715. }
  3716. unset($temp);
  3717. $duration_parent = $seconds;
  3718. }
  3719. }
  3720. // HASHES
  3721. if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  3722. {
  3723. foreach ($hashes_iterator as $hash)
  3724. {
  3725. $value = null;
  3726. $algo = null;
  3727. if (isset($hash['data']))
  3728. {
  3729. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3730. }
  3731. if (isset($hash['attribs']['']['algo']))
  3732. {
  3733. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3734. }
  3735. else
  3736. {
  3737. $algo = 'md5';
  3738. }
  3739. $hashes_parent[] = $algo.':'.$value;
  3740. }
  3741. }
  3742. elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  3743. {
  3744. foreach ($hashes_iterator as $hash)
  3745. {
  3746. $value = null;
  3747. $algo = null;
  3748. if (isset($hash['data']))
  3749. {
  3750. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3751. }
  3752. if (isset($hash['attribs']['']['algo']))
  3753. {
  3754. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3755. }
  3756. else
  3757. {
  3758. $algo = 'md5';
  3759. }
  3760. $hashes_parent[] = $algo.':'.$value;
  3761. }
  3762. }
  3763. if (is_array($hashes_parent))
  3764. {
  3765. $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
  3766. }
  3767. // KEYWORDS
  3768. if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  3769. {
  3770. if (isset($keywords[0]['data']))
  3771. {
  3772. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3773. foreach ($temp as $word)
  3774. {
  3775. $keywords_parent[] = trim($word);
  3776. }
  3777. }
  3778. unset($temp);
  3779. }
  3780. elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  3781. {
  3782. if (isset($keywords[0]['data']))
  3783. {
  3784. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3785. foreach ($temp as $word)
  3786. {
  3787. $keywords_parent[] = trim($word);
  3788. }
  3789. }
  3790. unset($temp);
  3791. }
  3792. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  3793. {
  3794. if (isset($keywords[0]['data']))
  3795. {
  3796. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3797. foreach ($temp as $word)
  3798. {
  3799. $keywords_parent[] = trim($word);
  3800. }
  3801. }
  3802. unset($temp);
  3803. }
  3804. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  3805. {
  3806. if (isset($keywords[0]['data']))
  3807. {
  3808. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3809. foreach ($temp as $word)
  3810. {
  3811. $keywords_parent[] = trim($word);
  3812. }
  3813. }
  3814. unset($temp);
  3815. }
  3816. if (is_array($keywords_parent))
  3817. {
  3818. $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
  3819. }
  3820. // PLAYER
  3821. if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  3822. {
  3823. if (isset($player_parent[0]['attribs']['']['url']))
  3824. {
  3825. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3826. }
  3827. }
  3828. elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  3829. {
  3830. if (isset($player_parent[0]['attribs']['']['url']))
  3831. {
  3832. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3833. }
  3834. }
  3835. // RATINGS
  3836. if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  3837. {
  3838. foreach ($ratings as $rating)
  3839. {
  3840. $rating_scheme = null;
  3841. $rating_value = null;
  3842. if (isset($rating['attribs']['']['scheme']))
  3843. {
  3844. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3845. }
  3846. else
  3847. {
  3848. $rating_scheme = 'urn:simple';
  3849. }
  3850. if (isset($rating['data']))
  3851. {
  3852. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3853. }
  3854. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3855. }
  3856. }
  3857. elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  3858. {
  3859. foreach ($ratings as $rating)
  3860. {
  3861. $rating_scheme = 'urn:itunes';
  3862. $rating_value = null;
  3863. if (isset($rating['data']))
  3864. {
  3865. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3866. }
  3867. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3868. }
  3869. }
  3870. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  3871. {
  3872. foreach ($ratings as $rating)
  3873. {
  3874. $rating_scheme = null;
  3875. $rating_value = null;
  3876. if (isset($rating['attribs']['']['scheme']))
  3877. {
  3878. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3879. }
  3880. else
  3881. {
  3882. $rating_scheme = 'urn:simple';
  3883. }
  3884. if (isset($rating['data']))
  3885. {
  3886. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3887. }
  3888. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3889. }
  3890. }
  3891. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  3892. {
  3893. foreach ($ratings as $rating)
  3894. {
  3895. $rating_scheme = 'urn:itunes';
  3896. $rating_value = null;
  3897. if (isset($rating['data']))
  3898. {
  3899. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3900. }
  3901. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3902. }
  3903. }
  3904. if (is_array($ratings_parent))
  3905. {
  3906. $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
  3907. }
  3908. // RESTRICTIONS
  3909. if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  3910. {
  3911. foreach ($restrictions as $restriction)
  3912. {
  3913. $restriction_relationship = null;
  3914. $restriction_type = null;
  3915. $restriction_value = null;
  3916. if (isset($restriction['attribs']['']['relationship']))
  3917. {
  3918. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  3919. }
  3920. if (isset($restriction['attribs']['']['type']))
  3921. {
  3922. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3923. }
  3924. if (isset($restriction['data']))
  3925. {
  3926. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3927. }
  3928. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3929. }
  3930. }
  3931. elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  3932. {
  3933. foreach ($restrictions as $restriction)
  3934. {
  3935. $restriction_relationship = 'allow';
  3936. $restriction_type = null;
  3937. $restriction_value = 'itunes';
  3938. if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
  3939. {
  3940. $restriction_relationship = 'deny';
  3941. }
  3942. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3943. }
  3944. }
  3945. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  3946. {
  3947. foreach ($restrictions as $restriction)
  3948. {
  3949. $restriction_relationship = null;
  3950. $restriction_type = null;
  3951. $restriction_value = null;
  3952. if (isset($restriction['attribs']['']['relationship']))
  3953. {
  3954. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  3955. }
  3956. if (isset($restriction['attribs']['']['type']))
  3957. {
  3958. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3959. }
  3960. if (isset($restriction['data']))
  3961. {
  3962. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3963. }
  3964. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3965. }
  3966. }
  3967. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  3968. {
  3969. foreach ($restrictions as $restriction)
  3970. {
  3971. $restriction_relationship = 'allow';
  3972. $restriction_type = null;
  3973. $restriction_value = 'itunes';
  3974. if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
  3975. {
  3976. $restriction_relationship = 'deny';
  3977. }
  3978. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3979. }
  3980. }
  3981. if (is_array($restrictions_parent))
  3982. {
  3983. $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
  3984. }
  3985. // THUMBNAILS
  3986. if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  3987. {
  3988. foreach ($thumbnails as $thumbnail)
  3989. {
  3990. if (isset($thumbnail['attribs']['']['url']))
  3991. {
  3992. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3993. }
  3994. }
  3995. }
  3996. elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  3997. {
  3998. foreach ($thumbnails as $thumbnail)
  3999. {
  4000. if (isset($thumbnail['attribs']['']['url']))
  4001. {
  4002. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4003. }
  4004. }
  4005. }
  4006. // TITLES
  4007. if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  4008. {
  4009. if (isset($title_parent[0]['data']))
  4010. {
  4011. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4012. }
  4013. }
  4014. elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  4015. {
  4016. if (isset($title_parent[0]['data']))
  4017. {
  4018. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4019. }
  4020. }
  4021. // Clear the memory
  4022. unset($parent);
  4023. // If we have media:group tags, loop through them.
  4024. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
  4025. {
  4026. // If we have media:content tags, loop through them.
  4027. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  4028. {
  4029. if (isset($content['attribs']['']['url']))
  4030. {
  4031. // Attributes
  4032. $bitrate = null;
  4033. $channels = null;
  4034. $duration = null;
  4035. $expression = null;
  4036. $framerate = null;
  4037. $height = null;
  4038. $javascript = null;
  4039. $lang = null;
  4040. $length = null;
  4041. $medium = null;
  4042. $samplingrate = null;
  4043. $type = null;
  4044. $url = null;
  4045. $width = null;
  4046. // Elements
  4047. $captions = null;
  4048. $categories = null;
  4049. $copyrights = null;
  4050. $credits = null;
  4051. $description = null;
  4052. $hashes = null;
  4053. $keywords = null;
  4054. $player = null;
  4055. $ratings = null;
  4056. $restrictions = null;
  4057. $thumbnails = null;
  4058. $title = null;
  4059. // Start checking the attributes of media:content
  4060. if (isset($content['attribs']['']['bitrate']))
  4061. {
  4062. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4063. }
  4064. if (isset($content['attribs']['']['channels']))
  4065. {
  4066. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  4067. }
  4068. if (isset($content['attribs']['']['duration']))
  4069. {
  4070. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  4071. }
  4072. else
  4073. {
  4074. $duration = $duration_parent;
  4075. }
  4076. if (isset($content['attribs']['']['expression']))
  4077. {
  4078. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  4079. }
  4080. if (isset($content['attribs']['']['framerate']))
  4081. {
  4082. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4083. }
  4084. if (isset($content['attribs']['']['height']))
  4085. {
  4086. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  4087. }
  4088. if (isset($content['attribs']['']['lang']))
  4089. {
  4090. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4091. }
  4092. if (isset($content['attribs']['']['fileSize']))
  4093. {
  4094. $length = ceil($content['attribs']['']['fileSize']);
  4095. }
  4096. if (isset($content['attribs']['']['medium']))
  4097. {
  4098. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  4099. }
  4100. if (isset($content['attribs']['']['samplingrate']))
  4101. {
  4102. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4103. }
  4104. if (isset($content['attribs']['']['type']))
  4105. {
  4106. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4107. }
  4108. if (isset($content['attribs']['']['width']))
  4109. {
  4110. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  4111. }
  4112. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4113. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  4114. // CAPTIONS
  4115. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4116. {
  4117. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4118. {
  4119. $caption_type = null;
  4120. $caption_lang = null;
  4121. $caption_startTime = null;
  4122. $caption_endTime = null;
  4123. $caption_text = null;
  4124. if (isset($caption['attribs']['']['type']))
  4125. {
  4126. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4127. }
  4128. if (isset($caption['attribs']['']['lang']))
  4129. {
  4130. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4131. }
  4132. if (isset($caption['attribs']['']['start']))
  4133. {
  4134. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4135. }
  4136. if (isset($caption['attribs']['']['end']))
  4137. {
  4138. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4139. }
  4140. if (isset($caption['data']))
  4141. {
  4142. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4143. }
  4144. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4145. }
  4146. if (is_array($captions))
  4147. {
  4148. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4149. }
  4150. }
  4151. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4152. {
  4153. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4154. {
  4155. $caption_type = null;
  4156. $caption_lang = null;
  4157. $caption_startTime = null;
  4158. $caption_endTime = null;
  4159. $caption_text = null;
  4160. if (isset($caption['attribs']['']['type']))
  4161. {
  4162. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4163. }
  4164. if (isset($caption['attribs']['']['lang']))
  4165. {
  4166. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4167. }
  4168. if (isset($caption['attribs']['']['start']))
  4169. {
  4170. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4171. }
  4172. if (isset($caption['attribs']['']['end']))
  4173. {
  4174. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4175. }
  4176. if (isset($caption['data']))
  4177. {
  4178. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4179. }
  4180. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4181. }
  4182. if (is_array($captions))
  4183. {
  4184. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4185. }
  4186. }
  4187. else
  4188. {
  4189. $captions = $captions_parent;
  4190. }
  4191. // CATEGORIES
  4192. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4193. {
  4194. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4195. {
  4196. $term = null;
  4197. $scheme = null;
  4198. $label = null;
  4199. if (isset($category['data']))
  4200. {
  4201. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4202. }
  4203. if (isset($category['attribs']['']['scheme']))
  4204. {
  4205. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4206. }
  4207. else
  4208. {
  4209. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4210. }
  4211. if (isset($category['attribs']['']['label']))
  4212. {
  4213. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4214. }
  4215. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4216. }
  4217. }
  4218. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4219. {
  4220. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4221. {
  4222. $term = null;
  4223. $scheme = null;
  4224. $label = null;
  4225. if (isset($category['data']))
  4226. {
  4227. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4228. }
  4229. if (isset($category['attribs']['']['scheme']))
  4230. {
  4231. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4232. }
  4233. else
  4234. {
  4235. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4236. }
  4237. if (isset($category['attribs']['']['label']))
  4238. {
  4239. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4240. }
  4241. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4242. }
  4243. }
  4244. if (is_array($categories) && is_array($categories_parent))
  4245. {
  4246. $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
  4247. }
  4248. elseif (is_array($categories))
  4249. {
  4250. $categories = array_values(SimplePie_Misc::array_unique($categories));
  4251. }
  4252. elseif (is_array($categories_parent))
  4253. {
  4254. $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
  4255. }
  4256. // COPYRIGHTS
  4257. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4258. {
  4259. $copyright_url = null;
  4260. $copyright_label = null;
  4261. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4262. {
  4263. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4264. }
  4265. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4266. {
  4267. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4268. }
  4269. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4270. }
  4271. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4272. {
  4273. $copyright_url = null;
  4274. $copyright_label = null;
  4275. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4276. {
  4277. $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4278. }
  4279. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4280. {
  4281. $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4282. }
  4283. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4284. }
  4285. else
  4286. {
  4287. $copyrights = $copyrights_parent;
  4288. }
  4289. // CREDITS
  4290. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4291. {
  4292. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4293. {
  4294. $credit_role = null;
  4295. $credit_scheme = null;
  4296. $credit_name = null;
  4297. if (isset($credit['attribs']['']['role']))
  4298. {
  4299. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4300. }
  4301. if (isset($credit['attribs']['']['scheme']))
  4302. {
  4303. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4304. }
  4305. else
  4306. {
  4307. $credit_scheme = 'urn:ebu';
  4308. }
  4309. if (isset($credit['data']))
  4310. {
  4311. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4312. }
  4313. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4314. }
  4315. if (is_array($credits))
  4316. {
  4317. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4318. }
  4319. }
  4320. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4321. {
  4322. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4323. {
  4324. $credit_role = null;
  4325. $credit_scheme = null;
  4326. $credit_name = null;
  4327. if (isset($credit['attribs']['']['role']))
  4328. {
  4329. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4330. }
  4331. if (isset($credit['attribs']['']['scheme']))
  4332. {
  4333. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4334. }
  4335. else
  4336. {
  4337. $credit_scheme = 'urn:ebu';
  4338. }
  4339. if (isset($credit['data']))
  4340. {
  4341. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4342. }
  4343. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4344. }
  4345. if (is_array($credits))
  4346. {
  4347. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4348. }
  4349. }
  4350. else
  4351. {
  4352. $credits = $credits_parent;
  4353. }
  4354. // DESCRIPTION
  4355. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4356. {
  4357. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4358. }
  4359. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4360. {
  4361. $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4362. }
  4363. else
  4364. {
  4365. $description = $description_parent;
  4366. }
  4367. // HASHES
  4368. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4369. {
  4370. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4371. {
  4372. $value = null;
  4373. $algo = null;
  4374. if (isset($hash['data']))
  4375. {
  4376. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4377. }
  4378. if (isset($hash['attribs']['']['algo']))
  4379. {
  4380. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4381. }
  4382. else
  4383. {
  4384. $algo = 'md5';
  4385. }
  4386. $hashes[] = $algo.':'.$value;
  4387. }
  4388. if (is_array($hashes))
  4389. {
  4390. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4391. }
  4392. }
  4393. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4394. {
  4395. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4396. {
  4397. $value = null;
  4398. $algo = null;
  4399. if (isset($hash['data']))
  4400. {
  4401. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4402. }
  4403. if (isset($hash['attribs']['']['algo']))
  4404. {
  4405. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4406. }
  4407. else
  4408. {
  4409. $algo = 'md5';
  4410. }
  4411. $hashes[] = $algo.':'.$value;
  4412. }
  4413. if (is_array($hashes))
  4414. {
  4415. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4416. }
  4417. }
  4418. else
  4419. {
  4420. $hashes = $hashes_parent;
  4421. }
  4422. // KEYWORDS
  4423. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4424. {
  4425. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4426. {
  4427. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4428. foreach ($temp as $word)
  4429. {
  4430. $keywords[] = trim($word);
  4431. }
  4432. unset($temp);
  4433. }
  4434. if (is_array($keywords))
  4435. {
  4436. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4437. }
  4438. }
  4439. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4440. {
  4441. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4442. {
  4443. $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4444. foreach ($temp as $word)
  4445. {
  4446. $keywords[] = trim($word);
  4447. }
  4448. unset($temp);
  4449. }
  4450. if (is_array($keywords))
  4451. {
  4452. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4453. }
  4454. }
  4455. else
  4456. {
  4457. $keywords = $keywords_parent;
  4458. }
  4459. // PLAYER
  4460. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4461. {
  4462. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4463. }
  4464. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4465. {
  4466. $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4467. }
  4468. else
  4469. {
  4470. $player = $player_parent;
  4471. }
  4472. // RATINGS
  4473. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4474. {
  4475. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4476. {
  4477. $rating_scheme = null;
  4478. $rating_value = null;
  4479. if (isset($rating['attribs']['']['scheme']))
  4480. {
  4481. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4482. }
  4483. else
  4484. {
  4485. $rating_scheme = 'urn:simple';
  4486. }
  4487. if (isset($rating['data']))
  4488. {
  4489. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4490. }
  4491. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4492. }
  4493. if (is_array($ratings))
  4494. {
  4495. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4496. }
  4497. }
  4498. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4499. {
  4500. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4501. {
  4502. $rating_scheme = null;
  4503. $rating_value = null;
  4504. if (isset($rating['attribs']['']['scheme']))
  4505. {
  4506. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4507. }
  4508. else
  4509. {
  4510. $rating_scheme = 'urn:simple';
  4511. }
  4512. if (isset($rating['data']))
  4513. {
  4514. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4515. }
  4516. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4517. }
  4518. if (is_array($ratings))
  4519. {
  4520. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4521. }
  4522. }
  4523. else
  4524. {
  4525. $ratings = $ratings_parent;
  4526. }
  4527. // RESTRICTIONS
  4528. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4529. {
  4530. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4531. {
  4532. $restriction_relationship = null;
  4533. $restriction_type = null;
  4534. $restriction_value = null;
  4535. if (isset($restriction['attribs']['']['relationship']))
  4536. {
  4537. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4538. }
  4539. if (isset($restriction['attribs']['']['type']))
  4540. {
  4541. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4542. }
  4543. if (isset($restriction['data']))
  4544. {
  4545. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4546. }
  4547. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4548. }
  4549. if (is_array($restrictions))
  4550. {
  4551. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4552. }
  4553. }
  4554. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4555. {
  4556. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4557. {
  4558. $restriction_relationship = null;
  4559. $restriction_type = null;
  4560. $restriction_value = null;
  4561. if (isset($restriction['attribs']['']['relationship']))
  4562. {
  4563. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4564. }
  4565. if (isset($restriction['attribs']['']['type']))
  4566. {
  4567. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4568. }
  4569. if (isset($restriction['data']))
  4570. {
  4571. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4572. }
  4573. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4574. }
  4575. if (is_array($restrictions))
  4576. {
  4577. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4578. }
  4579. }
  4580. else
  4581. {
  4582. $restrictions = $restrictions_parent;
  4583. }
  4584. // THUMBNAILS
  4585. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4586. {
  4587. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4588. {
  4589. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4590. }
  4591. if (is_array($thumbnails))
  4592. {
  4593. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4594. }
  4595. }
  4596. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4597. {
  4598. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4599. {
  4600. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4601. }
  4602. if (is_array($thumbnails))
  4603. {
  4604. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4605. }
  4606. }
  4607. else
  4608. {
  4609. $thumbnails = $thumbnails_parent;
  4610. }
  4611. // TITLES
  4612. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4613. {
  4614. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4615. }
  4616. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4617. {
  4618. $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4619. }
  4620. else
  4621. {
  4622. $title = $title_parent;
  4623. }
  4624. $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);
  4625. }
  4626. }
  4627. }
  4628. // If we have standalone media:content tags, loop through them.
  4629. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
  4630. {
  4631. foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  4632. {
  4633. if (isset($content['attribs']['']['url']))
  4634. {
  4635. // Attributes
  4636. $bitrate = null;
  4637. $channels = null;
  4638. $duration = null;
  4639. $expression = null;
  4640. $framerate = null;
  4641. $height = null;
  4642. $javascript = null;
  4643. $lang = null;
  4644. $length = null;
  4645. $medium = null;
  4646. $samplingrate = null;
  4647. $type = null;
  4648. $url = null;
  4649. $width = null;
  4650. // Elements
  4651. $captions = null;
  4652. $categories = null;
  4653. $copyrights = null;
  4654. $credits = null;
  4655. $description = null;
  4656. $hashes = null;
  4657. $keywords = null;
  4658. $player = null;
  4659. $ratings = null;
  4660. $restrictions = null;
  4661. $thumbnails = null;
  4662. $title = null;
  4663. // Start checking the attributes of media:content
  4664. if (isset($content['attribs']['']['bitrate']))
  4665. {
  4666. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4667. }
  4668. if (isset($content['attribs']['']['channels']))
  4669. {
  4670. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  4671. }
  4672. if (isset($content['attribs']['']['duration']))
  4673. {
  4674. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  4675. }
  4676. else
  4677. {
  4678. $duration = $duration_parent;
  4679. }
  4680. if (isset($content['attribs']['']['expression']))
  4681. {
  4682. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  4683. }
  4684. if (isset($content['attribs']['']['framerate']))
  4685. {
  4686. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4687. }
  4688. if (isset($content['attribs']['']['height']))
  4689. {
  4690. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  4691. }
  4692. if (isset($content['attribs']['']['lang']))
  4693. {
  4694. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4695. }
  4696. if (isset($content['attribs']['']['fileSize']))
  4697. {
  4698. $length = ceil($content['attribs']['']['fileSize']);
  4699. }
  4700. if (isset($content['attribs']['']['medium']))
  4701. {
  4702. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  4703. }
  4704. if (isset($content['attribs']['']['samplingrate']))
  4705. {
  4706. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4707. }
  4708. if (isset($content['attribs']['']['type']))
  4709. {
  4710. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4711. }
  4712. if (isset($content['attribs']['']['width']))
  4713. {
  4714. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  4715. }
  4716. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4717. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  4718. // CAPTIONS
  4719. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4720. {
  4721. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4722. {
  4723. $caption_type = null;
  4724. $caption_lang = null;
  4725. $caption_startTime = null;
  4726. $caption_endTime = null;
  4727. $caption_text = null;
  4728. if (isset($caption['attribs']['']['type']))
  4729. {
  4730. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4731. }
  4732. if (isset($caption['attribs']['']['lang']))
  4733. {
  4734. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4735. }
  4736. if (isset($caption['attribs']['']['start']))
  4737. {
  4738. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4739. }
  4740. if (isset($caption['attribs']['']['end']))
  4741. {
  4742. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4743. }
  4744. if (isset($caption['data']))
  4745. {
  4746. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4747. }
  4748. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4749. }
  4750. if (is_array($captions))
  4751. {
  4752. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4753. }
  4754. }
  4755. else
  4756. {
  4757. $captions = $captions_parent;
  4758. }
  4759. // CATEGORIES
  4760. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4761. {
  4762. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4763. {
  4764. $term = null;
  4765. $scheme = null;
  4766. $label = null;
  4767. if (isset($category['data']))
  4768. {
  4769. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4770. }
  4771. if (isset($category['attribs']['']['scheme']))
  4772. {
  4773. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4774. }
  4775. else
  4776. {
  4777. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4778. }
  4779. if (isset($category['attribs']['']['label']))
  4780. {
  4781. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4782. }
  4783. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4784. }
  4785. }
  4786. if (is_array($categories) && is_array($categories_parent))
  4787. {
  4788. $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
  4789. }
  4790. elseif (is_array($categories))
  4791. {
  4792. $categories = array_values(SimplePie_Misc::array_unique($categories));
  4793. }
  4794. elseif (is_array($categories_parent))
  4795. {
  4796. $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
  4797. }
  4798. else
  4799. {
  4800. $categories = null;
  4801. }
  4802. // COPYRIGHTS
  4803. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4804. {
  4805. $copyright_url = null;
  4806. $copyright_label = null;
  4807. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4808. {
  4809. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4810. }
  4811. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4812. {
  4813. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4814. }
  4815. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4816. }
  4817. else
  4818. {
  4819. $copyrights = $copyrights_parent;
  4820. }
  4821. // CREDITS
  4822. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4823. {
  4824. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4825. {
  4826. $credit_role = null;
  4827. $credit_scheme = null;
  4828. $credit_name = null;
  4829. if (isset($credit['attribs']['']['role']))
  4830. {
  4831. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4832. }
  4833. if (isset($credit['attribs']['']['scheme']))
  4834. {
  4835. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4836. }
  4837. else
  4838. {
  4839. $credit_scheme = 'urn:ebu';
  4840. }
  4841. if (isset($credit['data']))
  4842. {
  4843. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4844. }
  4845. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4846. }
  4847. if (is_array($credits))
  4848. {
  4849. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4850. }
  4851. }
  4852. else
  4853. {
  4854. $credits = $credits_parent;
  4855. }
  4856. // DESCRIPTION
  4857. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4858. {
  4859. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4860. }
  4861. else
  4862. {
  4863. $description = $description_parent;
  4864. }
  4865. // HASHES
  4866. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4867. {
  4868. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4869. {
  4870. $value = null;
  4871. $algo = null;
  4872. if (isset($hash['data']))
  4873. {
  4874. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4875. }
  4876. if (isset($hash['attribs']['']['algo']))
  4877. {
  4878. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4879. }
  4880. else
  4881. {
  4882. $algo = 'md5';
  4883. }
  4884. $hashes[] = $algo.':'.$value;
  4885. }
  4886. if (is_array($hashes))
  4887. {
  4888. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4889. }
  4890. }
  4891. else
  4892. {
  4893. $hashes = $hashes_parent;
  4894. }
  4895. // KEYWORDS
  4896. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4897. {
  4898. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4899. {
  4900. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4901. foreach ($temp as $word)
  4902. {
  4903. $keywords[] = trim($word);
  4904. }
  4905. unset($temp);
  4906. }
  4907. if (is_array($keywords))
  4908. {
  4909. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4910. }
  4911. }
  4912. else
  4913. {
  4914. $keywords = $keywords_parent;
  4915. }
  4916. // PLAYER
  4917. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4918. {
  4919. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4920. }
  4921. else
  4922. {
  4923. $player = $player_parent;
  4924. }
  4925. // RATINGS
  4926. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4927. {
  4928. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4929. {
  4930. $rating_scheme = null;
  4931. $rating_value = null;
  4932. if (isset($rating['attribs']['']['scheme']))
  4933. {
  4934. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4935. }
  4936. else
  4937. {
  4938. $rating_scheme = 'urn:simple';
  4939. }
  4940. if (isset($rating['data']))
  4941. {
  4942. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4943. }
  4944. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4945. }
  4946. if (is_array($ratings))
  4947. {
  4948. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4949. }
  4950. }
  4951. else
  4952. {
  4953. $ratings = $ratings_parent;
  4954. }
  4955. // RESTRICTIONS
  4956. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4957. {
  4958. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4959. {
  4960. $restriction_relationship = null;
  4961. $restriction_type = null;
  4962. $restriction_value = null;
  4963. if (isset($restriction['attribs']['']['relationship']))
  4964. {
  4965. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4966. }
  4967. if (isset($restriction['attribs']['']['type']))
  4968. {
  4969. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4970. }
  4971. if (isset($restriction['data']))
  4972. {
  4973. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4974. }
  4975. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4976. }
  4977. if (is_array($restrictions))
  4978. {
  4979. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4980. }
  4981. }
  4982. else
  4983. {
  4984. $restrictions = $restrictions_parent;
  4985. }
  4986. // THUMBNAILS
  4987. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4988. {
  4989. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4990. {
  4991. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4992. }
  4993. if (is_array($thumbnails))
  4994. {
  4995. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4996. }
  4997. }
  4998. else
  4999. {
  5000. $thumbnails = $thumbnails_parent;
  5001. }
  5002. // TITLES
  5003. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  5004. {
  5005. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5006. }
  5007. else
  5008. {
  5009. $title = $title_parent;
  5010. }
  5011. $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);
  5012. }
  5013. }
  5014. }
  5015. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  5016. {
  5017. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
  5018. {
  5019. // Attributes
  5020. $bitrate = null;
  5021. $channels = null;
  5022. $duration = null;
  5023. $expression = null;
  5024. $framerate = null;
  5025. $height = null;
  5026. $javascript = null;
  5027. $lang = null;
  5028. $length = null;
  5029. $medium = null;
  5030. $samplingrate = null;
  5031. $type = null;
  5032. $url = null;
  5033. $width = null;
  5034. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5035. if (isset($link['attribs']['']['type']))
  5036. {
  5037. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5038. }
  5039. if (isset($link['attribs']['']['length']))
  5040. {
  5041. $length = ceil($link['attribs']['']['length']);
  5042. }
  5043. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5044. $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);
  5045. }
  5046. }
  5047. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  5048. {
  5049. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
  5050. {
  5051. // Attributes
  5052. $bitrate = null;
  5053. $channels = null;
  5054. $duration = null;
  5055. $expression = null;
  5056. $framerate = null;
  5057. $height = null;
  5058. $javascript = null;
  5059. $lang = null;
  5060. $length = null;
  5061. $medium = null;
  5062. $samplingrate = null;
  5063. $type = null;
  5064. $url = null;
  5065. $width = null;
  5066. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5067. if (isset($link['attribs']['']['type']))
  5068. {
  5069. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5070. }
  5071. if (isset($link['attribs']['']['length']))
  5072. {
  5073. $length = ceil($link['attribs']['']['length']);
  5074. }
  5075. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5076. $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);
  5077. }
  5078. }
  5079. if ($enclosure = $this->get_item_tags('', 'enclosure'))
  5080. {
  5081. if (isset($enclosure[0]['attribs']['']['url']))
  5082. {
  5083. // Attributes
  5084. $bitrate = null;
  5085. $channels = null;
  5086. $duration = null;
  5087. $expression = null;
  5088. $framerate = null;
  5089. $height = null;
  5090. $javascript = null;
  5091. $lang = null;
  5092. $length = null;
  5093. $medium = null;
  5094. $samplingrate = null;
  5095. $type = null;
  5096. $url = null;
  5097. $width = null;
  5098. $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
  5099. if (isset($enclosure[0]['attribs']['']['type']))
  5100. {
  5101. $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5102. }
  5103. if (isset($enclosure[0]['attribs']['']['length']))
  5104. {
  5105. $length = ceil($enclosure[0]['attribs']['']['length']);
  5106. }
  5107. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5108. $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);
  5109. }
  5110. }
  5111. if (sizeof($this->data['enclosures']) == 0)
  5112. {
  5113. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5114. $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);
  5115. }
  5116. $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
  5117. }
  5118. if (!empty($this->data['enclosures']))
  5119. {
  5120. return $this->data['enclosures'];
  5121. }
  5122. else
  5123. {
  5124. return null;
  5125. }
  5126. }
  5127. function get_latitude()
  5128. {
  5129. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  5130. {
  5131. return (float) $return[0]['data'];
  5132. }
  5133. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5134. {
  5135. return (float) $match[1];
  5136. }
  5137. else
  5138. {
  5139. return null;
  5140. }
  5141. }
  5142. function get_longitude()
  5143. {
  5144. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  5145. {
  5146. return (float) $return[0]['data'];
  5147. }
  5148. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  5149. {
  5150. return (float) $return[0]['data'];
  5151. }
  5152. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5153. {
  5154. return (float) $match[2];
  5155. }
  5156. else
  5157. {
  5158. return null;
  5159. }
  5160. }
  5161. function get_source()
  5162. {
  5163. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
  5164. {
  5165. return new $this->feed->source_class($this, $return[0]);
  5166. }
  5167. else
  5168. {
  5169. return null;
  5170. }
  5171. }
  5172. /**
  5173. * Creates the add_to_* methods' return data
  5174. *
  5175. * @access private
  5176. * @param string $item_url String to prefix to the item permalink
  5177. * @param string $title_url String to prefix to the item title
  5178. * (and suffix to the item permalink)
  5179. * @return mixed URL if feed exists, false otherwise
  5180. */
  5181. function add_to_service($item_url, $title_url = null)
  5182. {
  5183. if ($this->get_permalink() !== null)
  5184. {
  5185. $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
  5186. if ($title_url !== null && $this->get_title() !== null)
  5187. {
  5188. $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
  5189. }
  5190. return $return;
  5191. }
  5192. else
  5193. {
  5194. return null;
  5195. }
  5196. }
  5197. function add_to_blinklist()
  5198. {
  5199. return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
  5200. }
  5201. function add_to_blogmarks()
  5202. {
  5203. return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
  5204. }
  5205. function add_to_delicious()
  5206. {
  5207. return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
  5208. }
  5209. function add_to_digg()
  5210. {
  5211. return $this->add_to_service('http://digg.com/submit?phase=2&URL=');
  5212. }
  5213. function add_to_furl()
  5214. {
  5215. return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
  5216. }
  5217. function add_to_magnolia()
  5218. {
  5219. return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
  5220. }
  5221. function add_to_myweb20()
  5222. {
  5223. return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
  5224. }
  5225. function add_to_newsvine()
  5226. {
  5227. return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
  5228. }
  5229. function add_to_reddit()
  5230. {
  5231. return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
  5232. }
  5233. function add_to_segnalo()
  5234. {
  5235. return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
  5236. }
  5237. function add_to_simpy()
  5238. {
  5239. return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
  5240. }
  5241. function add_to_spurl()
  5242. {
  5243. return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
  5244. }
  5245. function add_to_wists()
  5246. {
  5247. return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
  5248. }
  5249. function search_technorati()
  5250. {
  5251. return $this->add_to_service('http://www.technorati.com/search/');
  5252. }
  5253. }
  5254. class SimplePie_Source
  5255. {
  5256. var $item;
  5257. var $data = array();
  5258. function SimplePie_Source($item, $data)
  5259. {
  5260. $this->item = $item;
  5261. $this->data = $data;
  5262. }
  5263. function __toString()
  5264. {
  5265. return md5(serialize($this->data));
  5266. }
  5267. /**
  5268. * Remove items that link back to this before destroying this object
  5269. */
  5270. function __destruct()
  5271. {
  5272. unset($this->item);
  5273. }
  5274. function get_source_tags($namespace, $tag)
  5275. {
  5276. if (isset($this->data['child'][$namespace][$tag]))
  5277. {
  5278. return $this->data['child'][$namespace][$tag];
  5279. }
  5280. else
  5281. {
  5282. return null;
  5283. }
  5284. }
  5285. function get_base($element = array())
  5286. {
  5287. return $this->item->get_base($element);
  5288. }
  5289. function sanitize($data, $type, $base = '')
  5290. {
  5291. return $this->item->sanitize($data, $type, $base);
  5292. }
  5293. function get_item()
  5294. {
  5295. return $this->item;
  5296. }
  5297. function get_title()
  5298. {
  5299. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  5300. {
  5301. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5302. }
  5303. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  5304. {
  5305. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5306. }
  5307. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  5308. {
  5309. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5310. }
  5311. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  5312. {
  5313. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5314. }
  5315. elseif ($return = $this->get_source_tags('', 'title'))
  5316. {
  5317. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5318. }
  5319. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  5320. {
  5321. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5322. }
  5323. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  5324. {
  5325. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5326. }
  5327. else
  5328. {
  5329. return null;
  5330. }
  5331. }
  5332. function get_category($key = 0)
  5333. {
  5334. $categories = $this->get_categories();
  5335. if (isset($categories[$key]))
  5336. {
  5337. return $categories[$key];
  5338. }
  5339. else
  5340. {
  5341. return null;
  5342. }
  5343. }
  5344. function get_categories()
  5345. {
  5346. $categories = array();
  5347. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  5348. {
  5349. $term = null;
  5350. $scheme = null;
  5351. $label = null;
  5352. if (isset($category['attribs']['']['term']))
  5353. {
  5354. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  5355. }
  5356. if (isset($category['attribs']['']['scheme']))
  5357. {
  5358. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  5359. }
  5360. if (isset($category['attribs']['']['label']))
  5361. {
  5362. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  5363. }
  5364. $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
  5365. }
  5366. foreach ((array) $this->get_source_tags('', 'category') as $category)
  5367. {
  5368. $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5369. }
  5370. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  5371. {
  5372. $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5373. }
  5374. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  5375. {
  5376. $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5377. }
  5378. if (!empty($categories))
  5379. {
  5380. return SimplePie_Misc::array_unique($categories);
  5381. }
  5382. else
  5383. {
  5384. return null;
  5385. }
  5386. }
  5387. function get_author($key = 0)
  5388. {
  5389. $authors = $this->get_authors();
  5390. if (isset($authors[$key]))
  5391. {
  5392. return $authors[$key];
  5393. }
  5394. else
  5395. {
  5396. return null;
  5397. }
  5398. }
  5399. function get_authors()
  5400. {
  5401. $authors = array();
  5402. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  5403. {
  5404. $name = null;
  5405. $uri = null;
  5406. $email = null;
  5407. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  5408. {
  5409. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5410. }
  5411. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  5412. {
  5413. $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]));
  5414. }
  5415. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  5416. {
  5417. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5418. }
  5419. if ($name !== null || $email !== null || $uri !== null)
  5420. {
  5421. $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
  5422. }
  5423. }
  5424. if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  5425. {
  5426. $name = null;
  5427. $url = null;
  5428. $email = null;
  5429. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  5430. {
  5431. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5432. }
  5433. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  5434. {
  5435. $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
  5436. }
  5437. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  5438. {
  5439. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5440. }
  5441. if ($name !== null || $email !== null || $url !== null)
  5442. {
  5443. $authors[] =& new $this->item->feed->author_class($name, $url, $email);
  5444. }
  5445. }
  5446. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  5447. {
  5448. $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5449. }
  5450. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  5451. {
  5452. $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5453. }
  5454. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  5455. {
  5456. $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5457. }
  5458. if (!empty($authors))
  5459. {
  5460. return SimplePie_Misc::array_unique($authors);
  5461. }
  5462. else
  5463. {
  5464. return null;
  5465. }
  5466. }
  5467. function get_contributor($key = 0)
  5468. {
  5469. $contributors = $this->get_contributors();
  5470. if (isset($contributors[$key]))
  5471. {
  5472. return $contributors[$key];
  5473. }
  5474. else
  5475. {
  5476. return null;
  5477. }
  5478. }
  5479. function get_contributors()
  5480. {
  5481. $contributors = array();
  5482. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  5483. {
  5484. $name = null;
  5485. $uri = null;
  5486. $email = null;
  5487. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  5488. {
  5489. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5490. }
  5491. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  5492. {
  5493. $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
  5494. }
  5495. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  5496. {
  5497. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5498. }
  5499. if ($name !== null || $email !== null || $uri !== null)
  5500. {
  5501. $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
  5502. }
  5503. }
  5504. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  5505. {
  5506. $name = null;
  5507. $url = null;
  5508. $email = null;
  5509. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  5510. {
  5511. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5512. }
  5513. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  5514. {
  5515. $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
  5516. }
  5517. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  5518. {
  5519. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5520. }
  5521. if ($name !== null || $email !== null || $url !== null)
  5522. {
  5523. $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
  5524. }
  5525. }
  5526. if (!empty($contributors))
  5527. {
  5528. return SimplePie_Misc::array_unique($contributors);
  5529. }
  5530. else
  5531. {
  5532. return null;
  5533. }
  5534. }
  5535. function get_link($key = 0, $rel = 'alternate')
  5536. {
  5537. $links = $this->get_links($rel);
  5538. if (isset($links[$key]))
  5539. {
  5540. return $links[$key];
  5541. }
  5542. else
  5543. {
  5544. return null;
  5545. }
  5546. }
  5547. /**
  5548. * Added for parity between the parent-level and the item/entry-level.
  5549. */
  5550. function get_permalink()
  5551. {
  5552. return $this->get_link(0);
  5553. }
  5554. function get_links($rel = 'alternate')
  5555. {
  5556. if (!isset($this->data['links']))
  5557. {
  5558. $this->data['links'] = array();
  5559. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  5560. {
  5561. foreach ($links as $link)
  5562. {
  5563. if (isset($link['attribs']['']['href']))
  5564. {
  5565. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  5566. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5567. }
  5568. }
  5569. }
  5570. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  5571. {
  5572. foreach ($links as $link)
  5573. {
  5574. if (isset($link['attribs']['']['href']))
  5575. {
  5576. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  5577. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5578. }
  5579. }
  5580. }
  5581. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  5582. {
  5583. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5584. }
  5585. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  5586. {
  5587. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5588. }
  5589. if ($links = $this->get_source_tags('', 'link'))
  5590. {
  5591. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5592. }
  5593. $keys = array_keys($this->data['links']);
  5594. foreach ($keys as $key)
  5595. {
  5596. if (SimplePie_Misc::is_isegment_nz_nc($key))
  5597. {
  5598. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  5599. {
  5600. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  5601. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  5602. }
  5603. else
  5604. {
  5605. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  5606. }
  5607. }
  5608. elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  5609. {
  5610. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  5611. }
  5612. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  5613. }
  5614. }
  5615. if (isset($this->data['links'][$rel]))
  5616. {
  5617. return $this->data['links'][$rel];
  5618. }
  5619. else
  5620. {
  5621. return null;
  5622. }
  5623. }
  5624. function get_description()
  5625. {
  5626. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  5627. {
  5628. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5629. }
  5630. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  5631. {
  5632. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5633. }
  5634. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  5635. {
  5636. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5637. }
  5638. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  5639. {
  5640. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5641. }
  5642. elseif ($return = $this->get_source_tags('', 'description'))
  5643. {
  5644. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5645. }
  5646. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  5647. {
  5648. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5649. }
  5650. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  5651. {
  5652. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5653. }
  5654. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  5655. {
  5656. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5657. }
  5658. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  5659. {
  5660. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5661. }
  5662. else
  5663. {
  5664. return null;
  5665. }
  5666. }
  5667. function get_copyright()
  5668. {
  5669. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  5670. {
  5671. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5672. }
  5673. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
  5674. {
  5675. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5676. }
  5677. elseif ($return = $this->get_source_tags('', 'copyright'))
  5678. {
  5679. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5680. }
  5681. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  5682. {
  5683. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5684. }
  5685. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  5686. {
  5687. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5688. }
  5689. else
  5690. {
  5691. return null;
  5692. }
  5693. }
  5694. function get_language()
  5695. {
  5696. if ($return = $this->get_source_tags('', 'language'))
  5697. {
  5698. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5699. }
  5700. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  5701. {
  5702. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5703. }
  5704. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  5705. {
  5706. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5707. }
  5708. elseif (isset($this->data['xml_lang']))
  5709. {
  5710. return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  5711. }
  5712. else
  5713. {
  5714. return null;
  5715. }
  5716. }
  5717. function get_latitude()
  5718. {
  5719. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  5720. {
  5721. return (float) $return[0]['data'];
  5722. }
  5723. elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5724. {
  5725. return (float) $match[1];
  5726. }
  5727. else
  5728. {
  5729. return null;
  5730. }
  5731. }
  5732. function get_longitude()
  5733. {
  5734. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  5735. {
  5736. return (float) $return[0]['data'];
  5737. }
  5738. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  5739. {
  5740. return (float) $return[0]['data'];
  5741. }
  5742. elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5743. {
  5744. return (float) $match[2];
  5745. }
  5746. else
  5747. {
  5748. return null;
  5749. }
  5750. }
  5751. function get_image_url()
  5752. {
  5753. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  5754. {
  5755. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  5756. }
  5757. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  5758. {
  5759. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  5760. }
  5761. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  5762. {
  5763. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  5764. }
  5765. else
  5766. {
  5767. return null;
  5768. }
  5769. }
  5770. }
  5771. class SimplePie_Author
  5772. {
  5773. var $name;
  5774. var $link;
  5775. var $email;
  5776. // Constructor, used to input the data
  5777. function SimplePie_Author($name = null, $link = null, $email = null)
  5778. {
  5779. $this->name = $name;
  5780. $this->link = $link;
  5781. $this->email = $email;
  5782. }
  5783. function __toString()
  5784. {
  5785. // There is no $this->data here
  5786. return md5(serialize($this));
  5787. }
  5788. function get_name()
  5789. {
  5790. if ($this->name !== null)
  5791. {
  5792. return $this->name;
  5793. }
  5794. else
  5795. {
  5796. return null;
  5797. }
  5798. }
  5799. function get_link()
  5800. {
  5801. if ($this->link !== null)
  5802. {
  5803. return $this->link;
  5804. }
  5805. else
  5806. {
  5807. return null;
  5808. }
  5809. }
  5810. function get_email()
  5811. {
  5812. if ($this->email !== null)
  5813. {
  5814. return $this->email;
  5815. }
  5816. else
  5817. {
  5818. return null;
  5819. }
  5820. }
  5821. }
  5822. class SimplePie_Category
  5823. {
  5824. var $term;
  5825. var $scheme;
  5826. var $label;
  5827. // Constructor, used to input the data
  5828. function SimplePie_Category($term = null, $scheme = null, $label = null)
  5829. {
  5830. $this->term = $term;
  5831. $this->scheme = $scheme;
  5832. $this->label = $label;
  5833. }
  5834. function __toString()
  5835. {
  5836. // There is no $this->data here
  5837. return md5(serialize($this));
  5838. }
  5839. function get_term()
  5840. {
  5841. if ($this->term !== null)
  5842. {
  5843. return $this->term;
  5844. }
  5845. else
  5846. {
  5847. return null;
  5848. }
  5849. }
  5850. function get_scheme()
  5851. {
  5852. if ($this->scheme !== null)
  5853. {
  5854. return $this->scheme;
  5855. }
  5856. else
  5857. {
  5858. return null;
  5859. }
  5860. }
  5861. function get_label()
  5862. {
  5863. if ($this->label !== null)
  5864. {
  5865. return $this->label;
  5866. }
  5867. else
  5868. {
  5869. return $this->get_term();
  5870. }
  5871. }
  5872. }
  5873. class SimplePie_Enclosure
  5874. {
  5875. var $bitrate;
  5876. var $captions;
  5877. var $categories;
  5878. var $channels;
  5879. var $copyright;
  5880. var $credits;
  5881. var $description;
  5882. var $duration;
  5883. var $expression;
  5884. var $framerate;
  5885. var $handler;
  5886. var $hashes;
  5887. var $height;
  5888. var $javascript;
  5889. var $keywords;
  5890. var $lang;
  5891. var $length;
  5892. var $link;
  5893. var $medium;
  5894. var $player;
  5895. var $ratings;
  5896. var $restrictions;
  5897. var $samplingrate;
  5898. var $thumbnails;
  5899. var $title;
  5900. var $type;
  5901. var $width;
  5902. // Constructor, used to input the data
  5903. 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)
  5904. {
  5905. $this->bitrate = $bitrate;
  5906. $this->captions = $captions;
  5907. $this->categories = $categories;
  5908. $this->channels = $channels;
  5909. $this->copyright = $copyright;
  5910. $this->credits = $credits;
  5911. $this->description = $description;
  5912. $this->duration = $duration;
  5913. $this->expression = $expression;
  5914. $this->framerate = $framerate;
  5915. $this->hashes = $hashes;
  5916. $this->height = $height;
  5917. $this->javascript = $javascript;
  5918. $this->keywords = $keywords;
  5919. $this->lang = $lang;
  5920. $this->length = $length;
  5921. $this->link = $link;
  5922. $this->medium = $medium;
  5923. $this->player = $player;
  5924. $this->ratings = $ratings;
  5925. $this->restrictions = $restrictions;
  5926. $this->samplingrate = $samplingrate;
  5927. $this->thumbnails = $thumbnails;
  5928. $this->title = $title;
  5929. $this->type = $type;
  5930. $this->width = $width;
  5931. if (class_exists('idna_convert'))
  5932. {
  5933. $idn =& new idna_convert;
  5934. $parsed = SimplePie_Misc::parse_url($link);
  5935. $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  5936. }
  5937. $this->handler = $this->get_handler(); // Needs to load last
  5938. }
  5939. function __toString()
  5940. {
  5941. // There is no $this->data here
  5942. return md5(serialize($this));
  5943. }
  5944. function get_bitrate()
  5945. {
  5946. if ($this->bitrate !== null)
  5947. {
  5948. return $this->bitrate;
  5949. }
  5950. else
  5951. {
  5952. return null;
  5953. }
  5954. }
  5955. function get_caption($key = 0)
  5956. {
  5957. $captions = $this->get_captions();
  5958. if (isset($captions[$key]))
  5959. {
  5960. return $captions[$key];
  5961. }
  5962. else
  5963. {
  5964. return null;
  5965. }
  5966. }
  5967. function get_captions()
  5968. {
  5969. if ($this->captions !== null)
  5970. {
  5971. return $this->captions;
  5972. }
  5973. else
  5974. {
  5975. return null;
  5976. }
  5977. }
  5978. function get_category($key = 0)
  5979. {
  5980. $categories = $this->get_categories();
  5981. if (isset($categories[$key]))
  5982. {
  5983. return $categories[$key];
  5984. }
  5985. else
  5986. {
  5987. return null;
  5988. }
  5989. }
  5990. function get_categories()
  5991. {
  5992. if ($this->categories !== null)
  5993. {
  5994. return $this->categories;
  5995. }
  5996. else
  5997. {
  5998. return null;
  5999. }
  6000. }
  6001. function get_channels()
  6002. {
  6003. if ($this->channels !== null)
  6004. {
  6005. return $this->channels;
  6006. }
  6007. else
  6008. {
  6009. return null;
  6010. }
  6011. }
  6012. function get_copyright()
  6013. {
  6014. if ($this->copyright !== null)
  6015. {
  6016. return $this->copyright;
  6017. }
  6018. else
  6019. {
  6020. return null;
  6021. }
  6022. }
  6023. function get_credit($key = 0)
  6024. {
  6025. $credits = $this->get_credits();
  6026. if (isset($credits[$key]))
  6027. {
  6028. return $credits[$key];
  6029. }
  6030. else
  6031. {
  6032. return null;
  6033. }
  6034. }
  6035. function get_credits()
  6036. {
  6037. if ($this->credits !== null)
  6038. {
  6039. return $this->credits;
  6040. }
  6041. else
  6042. {
  6043. return null;
  6044. }
  6045. }
  6046. function get_description()
  6047. {
  6048. if ($this->description !== null)
  6049. {
  6050. return $this->description;
  6051. }
  6052. else
  6053. {
  6054. return null;
  6055. }
  6056. }
  6057. function get_duration($convert = false)
  6058. {
  6059. if ($this->duration !== null)
  6060. {
  6061. if ($convert)
  6062. {
  6063. $time = SimplePie_Misc::time_hms($this->duration);
  6064. return $time;
  6065. }
  6066. else
  6067. {
  6068. return $this->duration;
  6069. }
  6070. }
  6071. else
  6072. {
  6073. return null;
  6074. }
  6075. }
  6076. function get_expression()
  6077. {
  6078. if ($this->expression !== null)
  6079. {
  6080. return $this->expression;
  6081. }
  6082. else
  6083. {
  6084. return 'full';
  6085. }
  6086. }
  6087. function get_extension()
  6088. {
  6089. if ($this->link !== null)
  6090. {
  6091. $url = SimplePie_Misc::parse_url($this->link);
  6092. if ($url['path'] !== '')
  6093. {
  6094. return pathinfo($url['path'], PATHINFO_EXTENSION);
  6095. }
  6096. }
  6097. return null;
  6098. }
  6099. function get_framerate()
  6100. {
  6101. if ($this->framerate !== null)
  6102. {
  6103. return $this->framerate;
  6104. }
  6105. else
  6106. {
  6107. return null;
  6108. }
  6109. }
  6110. function get_handler()
  6111. {
  6112. return $this->get_real_type(true);
  6113. }
  6114. function get_hash($key = 0)
  6115. {
  6116. $hashes = $this->get_hashes();
  6117. if (isset($hashes[$key]))
  6118. {
  6119. return $hashes[$key];
  6120. }
  6121. else
  6122. {
  6123. return null;
  6124. }
  6125. }
  6126. function get_hashes()
  6127. {
  6128. if ($this->hashes !== null)
  6129. {
  6130. return $this->hashes;
  6131. }
  6132. else
  6133. {
  6134. return null;
  6135. }
  6136. }
  6137. function get_height()
  6138. {
  6139. if ($this->height !== null)
  6140. {
  6141. return $this->height;
  6142. }
  6143. else
  6144. {
  6145. return null;
  6146. }
  6147. }
  6148. function get_language()
  6149. {
  6150. if ($this->lang !== null)
  6151. {
  6152. return $this->lang;
  6153. }
  6154. else
  6155. {
  6156. return null;
  6157. }
  6158. }
  6159. function get_keyword($key = 0)
  6160. {
  6161. $keywords = $this->get_keywords();
  6162. if (isset($keywords[$key]))
  6163. {
  6164. return $keywords[$key];
  6165. }
  6166. else
  6167. {
  6168. return null;
  6169. }
  6170. }
  6171. function get_keywords()
  6172. {
  6173. if ($this->keywords !== null)
  6174. {
  6175. return $this->keywords;
  6176. }
  6177. else
  6178. {
  6179. return null;
  6180. }
  6181. }
  6182. function get_length()
  6183. {
  6184. if ($this->length !== null)
  6185. {
  6186. return $this->length;
  6187. }
  6188. else
  6189. {
  6190. return null;
  6191. }
  6192. }
  6193. function get_link()
  6194. {
  6195. if ($this->link !== null)
  6196. {
  6197. return urldecode($this->link);
  6198. }
  6199. else
  6200. {
  6201. return null;
  6202. }
  6203. }
  6204. function get_medium()
  6205. {
  6206. if ($this->medium !== null)
  6207. {
  6208. return $this->medium;
  6209. }
  6210. else
  6211. {
  6212. return null;
  6213. }
  6214. }
  6215. function get_player()
  6216. {
  6217. if ($this->player !== null)
  6218. {
  6219. return $this->player;
  6220. }
  6221. else
  6222. {
  6223. return null;
  6224. }
  6225. }
  6226. function get_rating($key = 0)
  6227. {
  6228. $ratings = $this->get_ratings();
  6229. if (isset($ratings[$key]))
  6230. {
  6231. return $ratings[$key];
  6232. }
  6233. else
  6234. {
  6235. return null;
  6236. }
  6237. }
  6238. function get_ratings()
  6239. {
  6240. if ($this->ratings !== null)
  6241. {
  6242. return $this->ratings;
  6243. }
  6244. else
  6245. {
  6246. return null;
  6247. }
  6248. }
  6249. function get_restriction($key = 0)
  6250. {
  6251. $restrictions = $this->get_restrictions();
  6252. if (isset($restrictions[$key]))
  6253. {
  6254. return $restrictions[$key];
  6255. }
  6256. else
  6257. {
  6258. return null;
  6259. }
  6260. }
  6261. function get_restrictions()
  6262. {
  6263. if ($this->restrictions !== null)
  6264. {
  6265. return $this->restrictions;
  6266. }
  6267. else
  6268. {
  6269. return null;
  6270. }
  6271. }
  6272. function get_sampling_rate()
  6273. {
  6274. if ($this->samplingrate !== null)
  6275. {
  6276. return $this->samplingrate;
  6277. }
  6278. else
  6279. {
  6280. return null;
  6281. }
  6282. }
  6283. function get_size()
  6284. {
  6285. $length = $this->get_length();
  6286. if ($length !== null)
  6287. {
  6288. return round($length/1048576, 2);
  6289. }
  6290. else
  6291. {
  6292. return null;
  6293. }
  6294. }
  6295. function get_thumbnail($key = 0)
  6296. {
  6297. $thumbnails = $this->get_thumbnails();
  6298. if (isset($thumbnails[$key]))
  6299. {
  6300. return $thumbnails[$key];
  6301. }
  6302. else
  6303. {
  6304. return null;
  6305. }
  6306. }
  6307. function get_thumbnails()
  6308. {
  6309. if ($this->thumbnails !== null)
  6310. {
  6311. return $this->thumbnails;
  6312. }
  6313. else
  6314. {
  6315. return null;
  6316. }
  6317. }
  6318. function get_title()
  6319. {
  6320. if ($this->title !== null)
  6321. {
  6322. return $this->title;
  6323. }
  6324. else
  6325. {
  6326. return null;
  6327. }
  6328. }
  6329. function get_type()
  6330. {
  6331. if ($this->type !== null)
  6332. {
  6333. return $this->type;
  6334. }
  6335. else
  6336. {
  6337. return null;
  6338. }
  6339. }
  6340. function get_width()
  6341. {
  6342. if ($this->width !== null)
  6343. {
  6344. return $this->width;
  6345. }
  6346. else
  6347. {
  6348. return null;
  6349. }
  6350. }
  6351. function native_embed($options='')
  6352. {
  6353. return $this->embed($options, true);
  6354. }
  6355. /**
  6356. * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
  6357. */
  6358. function embed($options = '', $native = false)
  6359. {
  6360. // Set up defaults
  6361. $audio = '';
  6362. $video = '';
  6363. $alt = '';
  6364. $altclass = '';
  6365. $loop = 'false';
  6366. $width = 'auto';
  6367. $height = 'auto';
  6368. $bgcolor = '#ffffff';
  6369. $mediaplayer = '';
  6370. $widescreen = false;
  6371. $handler = $this->get_handler();
  6372. $type = $this->get_real_type();
  6373. // Process options and reassign values as necessary
  6374. if (is_array($options))
  6375. {
  6376. extract($options);
  6377. }
  6378. else
  6379. {
  6380. $options = explode(',', $options);
  6381. foreach($options as $option)
  6382. {
  6383. $opt = explode(':', $option, 2);
  6384. if (isset($opt[0], $opt[1]))
  6385. {
  6386. $opt[0] = trim($opt[0]);
  6387. $opt[1] = trim($opt[1]);
  6388. switch ($opt[0])
  6389. {
  6390. case 'audio':
  6391. $audio = $opt[1];
  6392. break;
  6393. case 'video':
  6394. $video = $opt[1];
  6395. break;
  6396. case 'alt':
  6397. $alt = $opt[1];
  6398. break;
  6399. case 'altclass':
  6400. $altclass = $opt[1];
  6401. break;
  6402. case 'loop':
  6403. $loop = $opt[1];
  6404. break;
  6405. case 'width':
  6406. $width = $opt[1];
  6407. break;
  6408. case 'height':
  6409. $height = $opt[1];
  6410. break;
  6411. case 'bgcolor':
  6412. $bgcolor = $opt[1];
  6413. break;
  6414. case 'mediaplayer':
  6415. $mediaplayer = $opt[1];
  6416. break;
  6417. case 'widescreen':
  6418. $widescreen = $opt[1];
  6419. break;
  6420. }
  6421. }
  6422. }
  6423. }
  6424. $mime = explode('/', $type, 2);
  6425. $mime = $mime[0];
  6426. // Process values for 'auto'
  6427. if ($width == 'auto')
  6428. {
  6429. if ($mime == 'video')
  6430. {
  6431. if ($height == 'auto')
  6432. {
  6433. $width = 480;
  6434. }
  6435. elseif ($widescreen)
  6436. {
  6437. $width = round((intval($height)/9)*16);
  6438. }
  6439. else
  6440. {
  6441. $width = round((intval($height)/3)*4);
  6442. }
  6443. }
  6444. else
  6445. {
  6446. $width = '100%';
  6447. }
  6448. }
  6449. if ($height == 'auto')
  6450. {
  6451. if ($mime == 'audio')
  6452. {
  6453. $height = 0;
  6454. }
  6455. elseif ($mime == 'video')
  6456. {
  6457. if ($width == 'auto')
  6458. {
  6459. if ($widescreen)
  6460. {
  6461. $height = 270;
  6462. }
  6463. else
  6464. {
  6465. $height = 360;
  6466. }
  6467. }
  6468. elseif ($widescreen)
  6469. {
  6470. $height = round((intval($width)/16)*9);
  6471. }
  6472. else
  6473. {
  6474. $height = round((intval($width)/4)*3);
  6475. }
  6476. }
  6477. else
  6478. {
  6479. $height = 376;
  6480. }
  6481. }
  6482. elseif ($mime == 'audio')
  6483. {
  6484. $height = 0;
  6485. }
  6486. // Set proper placeholder value
  6487. if ($mime == 'audio')
  6488. {
  6489. $placeholder = $audio;
  6490. }
  6491. elseif ($mime == 'video')
  6492. {
  6493. $placeholder = $video;
  6494. }
  6495. $embed = '';
  6496. // Make sure the JS library is included
  6497. if (!$native)
  6498. {
  6499. static $javascript_outputted = null;
  6500. if (!$javascript_outputted && $this->javascript)
  6501. {
  6502. $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
  6503. $javascript_outputted = true;
  6504. }
  6505. }
  6506. // Odeo Feed MP3's
  6507. if ($handler == 'odeo')
  6508. {
  6509. if ($native)
  6510. {
  6511. $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>';
  6512. }
  6513. else
  6514. {
  6515. $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
  6516. }
  6517. }
  6518. // Flash
  6519. elseif ($handler == 'flash')
  6520. {
  6521. if ($native)
  6522. {
  6523. $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>";
  6524. }
  6525. else
  6526. {
  6527. $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
  6528. }
  6529. }
  6530. // Flash Media Player file types.
  6531. // Preferred handler for MP3 file types.
  6532. elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
  6533. {
  6534. $height += 20;
  6535. if ($native)
  6536. {
  6537. $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>";
  6538. }
  6539. else
  6540. {
  6541. $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
  6542. }
  6543. }
  6544. // QuickTime 7 file types. Need to test with QuickTime 6.
  6545. // Only handle MP3's if the Flash Media Player is not present.
  6546. elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
  6547. {
  6548. $height += 16;
  6549. if ($native)
  6550. {
  6551. if ($placeholder != ""){
  6552. $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>";
  6553. }
  6554. else {
  6555. $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>";
  6556. }
  6557. }
  6558. else
  6559. {
  6560. $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
  6561. }
  6562. }
  6563. // Windows Media
  6564. elseif ($handler == 'wmedia')
  6565. {
  6566. $height += 45;
  6567. if ($native)
  6568. {
  6569. $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>";
  6570. }
  6571. else
  6572. {
  6573. $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
  6574. }
  6575. }
  6576. // Everything else
  6577. else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
  6578. return $embed;
  6579. }
  6580. function get_real_type($find_handler = false)
  6581. {
  6582. // If it's Odeo, let's get it out of the way.
  6583. if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
  6584. {
  6585. return 'odeo';
  6586. }
  6587. // Mime-types by handler.
  6588. $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
  6589. $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
  6590. $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
  6591. $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
  6592. $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
  6593. if ($this->get_type() !== null)
  6594. {
  6595. $type = strtolower($this->type);
  6596. }
  6597. else
  6598. {
  6599. $type = null;
  6600. }
  6601. // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
  6602. if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
  6603. {
  6604. switch (strtolower($this->get_extension()))
  6605. {
  6606. // Audio mime-types
  6607. case 'aac':
  6608. case 'adts':
  6609. $type = 'audio/acc';
  6610. break;
  6611. case 'aif':
  6612. case 'aifc':
  6613. case 'aiff':
  6614. case 'cdda':
  6615. $type = 'audio/aiff';
  6616. break;
  6617. case 'bwf':
  6618. $type = 'audio/wav';
  6619. break;
  6620. case 'kar':
  6621. case 'mid':
  6622. case 'midi':
  6623. case 'smf':
  6624. $type = 'audio/midi';
  6625. break;
  6626. case 'm4a':
  6627. $type = 'audio/x-m4a';
  6628. break;
  6629. case 'mp3':
  6630. case 'swa':
  6631. $type = 'audio/mp3';
  6632. break;
  6633. case 'wav':
  6634. $type = 'audio/wav';
  6635. break;
  6636. case 'wax':
  6637. $type = 'audio/x-ms-wax';
  6638. break;
  6639. case 'wma':
  6640. $type = 'audio/x-ms-wma';
  6641. break;
  6642. // Video mime-types
  6643. case '3gp':
  6644. case '3gpp':
  6645. $type = 'video/3gpp';
  6646. break;
  6647. case '3g2':
  6648. case '3gp2':
  6649. $type = 'video/3gpp2';
  6650. break;
  6651. case 'asf':
  6652. $type = 'video/x-ms-asf';
  6653. break;
  6654. case 'flv':
  6655. $type = 'video/x-flv';
  6656. break;
  6657. case 'm1a':
  6658. case 'm1s':
  6659. case 'm1v':
  6660. case 'm15':
  6661. case 'm75':
  6662. case 'mp2':
  6663. case 'mpa':
  6664. case 'mpeg':
  6665. case 'mpg':
  6666. case 'mpm':
  6667. case 'mpv':
  6668. $type = 'video/mpeg';
  6669. break;
  6670. case 'm4v':
  6671. $type = 'video/x-m4v';
  6672. break;
  6673. case 'mov':
  6674. case 'qt':
  6675. $type = 'video/quicktime';
  6676. break;
  6677. case 'mp4':
  6678. case 'mpg4':
  6679. $type = 'video/mp4';
  6680. break;
  6681. case 'sdv':
  6682. $type = 'video/sd-video';
  6683. break;
  6684. case 'wm':
  6685. $type = 'video/x-ms-wm';
  6686. break;
  6687. case 'wmv':
  6688. $type = 'video/x-ms-wmv';
  6689. break;
  6690. case 'wvx':
  6691. $type = 'video/x-ms-wvx';
  6692. break;
  6693. // Flash mime-types
  6694. case 'spl':
  6695. $type = 'application/futuresplash';
  6696. break;
  6697. case 'swf':
  6698. $type = 'application/x-shockwave-flash';
  6699. break;
  6700. }
  6701. }
  6702. if ($find_handler)
  6703. {
  6704. if (in_array($type, $types_flash))
  6705. {
  6706. return 'flash';
  6707. }
  6708. elseif (in_array($type, $types_fmedia))
  6709. {
  6710. return 'fmedia';
  6711. }
  6712. elseif (in_array($type, $types_quicktime))
  6713. {
  6714. return 'quicktime';
  6715. }
  6716. elseif (in_array($type, $types_wmedia))
  6717. {
  6718. return 'wmedia';
  6719. }
  6720. elseif (in_array($type, $types_mp3))
  6721. {
  6722. return 'mp3';
  6723. }
  6724. else
  6725. {
  6726. return null;
  6727. }
  6728. }
  6729. else
  6730. {
  6731. return $type;
  6732. }
  6733. }
  6734. }
  6735. class SimplePie_Caption
  6736. {
  6737. var $type;
  6738. var $lang;
  6739. var $startTime;
  6740. var $endTime;
  6741. var $text;
  6742. // Constructor, used to input the data
  6743. function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
  6744. {
  6745. $this->type = $type;
  6746. $this->lang = $lang;
  6747. $this->startTime = $startTime;
  6748. $this->endTime = $endTime;
  6749. $this->text = $text;
  6750. }
  6751. function __toString()
  6752. {
  6753. // There is no $this->data here
  6754. return md5(serialize($this));
  6755. }
  6756. function get_endtime()
  6757. {
  6758. if ($this->endTime !== null)
  6759. {
  6760. return $this->endTime;
  6761. }
  6762. else
  6763. {
  6764. return null;
  6765. }
  6766. }
  6767. function get_language()
  6768. {
  6769. if ($this->lang !== null)
  6770. {
  6771. return $this->lang;
  6772. }
  6773. else
  6774. {
  6775. return null;
  6776. }
  6777. }
  6778. function get_starttime()
  6779. {
  6780. if ($this->startTime !== null)
  6781. {
  6782. return $this->startTime;
  6783. }
  6784. else
  6785. {
  6786. return null;
  6787. }
  6788. }
  6789. function get_text()
  6790. {
  6791. if ($this->text !== null)
  6792. {
  6793. return $this->text;
  6794. }
  6795. else
  6796. {
  6797. return null;
  6798. }
  6799. }
  6800. function get_type()
  6801. {
  6802. if ($this->type !== null)
  6803. {
  6804. return $this->type;
  6805. }
  6806. else
  6807. {
  6808. return null;
  6809. }
  6810. }
  6811. }
  6812. class SimplePie_Credit
  6813. {
  6814. var $role;
  6815. var $scheme;
  6816. var $name;
  6817. // Constructor, used to input the data
  6818. function SimplePie_Credit($role = null, $scheme = null, $name = null)
  6819. {
  6820. $this->role = $role;
  6821. $this->scheme = $scheme;
  6822. $this->name = $name;
  6823. }
  6824. function __toString()
  6825. {
  6826. // There is no $this->data here
  6827. return md5(serialize($this));
  6828. }
  6829. function get_role()
  6830. {
  6831. if ($this->role !== null)
  6832. {
  6833. return $this->role;
  6834. }
  6835. else
  6836. {
  6837. return null;
  6838. }
  6839. }
  6840. function get_scheme()
  6841. {
  6842. if ($this->scheme !== null)
  6843. {
  6844. return $this->scheme;
  6845. }
  6846. else
  6847. {
  6848. return null;
  6849. }
  6850. }
  6851. function get_name()
  6852. {
  6853. if ($this->name !== null)
  6854. {
  6855. return $this->name;
  6856. }
  6857. else
  6858. {
  6859. return null;
  6860. }
  6861. }
  6862. }
  6863. class SimplePie_Copyright
  6864. {
  6865. var $url;
  6866. var $label;
  6867. // Constructor, used to input the data
  6868. function SimplePie_Copyright($url = null, $label = null)
  6869. {
  6870. $this->url = $url;
  6871. $this->label = $label;
  6872. }
  6873. function __toString()
  6874. {
  6875. // There is no $this->data here
  6876. return md5(serialize($this));
  6877. }
  6878. function get_url()
  6879. {
  6880. if ($this->url !== null)
  6881. {
  6882. return $this->url;
  6883. }
  6884. else
  6885. {
  6886. return null;
  6887. }
  6888. }
  6889. function get_attribution()
  6890. {
  6891. if ($this->label !== null)
  6892. {
  6893. return $this->label;
  6894. }
  6895. else
  6896. {
  6897. return null;
  6898. }
  6899. }
  6900. }
  6901. class SimplePie_Rating
  6902. {
  6903. var $scheme;
  6904. var $value;
  6905. // Constructor, used to input the data
  6906. function SimplePie_Rating($scheme = null, $value = null)
  6907. {
  6908. $this->scheme = $scheme;
  6909. $this->value = $value;
  6910. }
  6911. function __toString()
  6912. {
  6913. // There is no $this->data here
  6914. return md5(serialize($this));
  6915. }
  6916. function get_scheme()
  6917. {
  6918. if ($this->scheme !== null)
  6919. {
  6920. return $this->scheme;
  6921. }
  6922. else
  6923. {
  6924. return null;
  6925. }
  6926. }
  6927. function get_value()
  6928. {
  6929. if ($this->value !== null)
  6930. {
  6931. return $this->value;
  6932. }
  6933. else
  6934. {
  6935. return null;
  6936. }
  6937. }
  6938. }
  6939. class SimplePie_Restriction
  6940. {
  6941. var $relationship;
  6942. var $type;
  6943. var $value;
  6944. // Constructor, used to input the data
  6945. function SimplePie_Restriction($relationship = null, $type = null, $value = null)
  6946. {
  6947. $this->relationship = $relationship;
  6948. $this->type = $type;
  6949. $this->value = $value;
  6950. }
  6951. function __toString()
  6952. {
  6953. // There is no $this->data here
  6954. return md5(serialize($this));
  6955. }
  6956. function get_relationship()
  6957. {
  6958. if ($this->relationship !== null)
  6959. {
  6960. return $this->relationship;
  6961. }
  6962. else
  6963. {
  6964. return null;
  6965. }
  6966. }
  6967. function get_type()
  6968. {
  6969. if ($this->type !== null)
  6970. {
  6971. return $this->type;
  6972. }
  6973. else
  6974. {
  6975. return null;
  6976. }
  6977. }
  6978. function get_value()
  6979. {
  6980. if ($this->value !== null)
  6981. {
  6982. return $this->value;
  6983. }
  6984. else
  6985. {
  6986. return null;
  6987. }
  6988. }
  6989. }
  6990. /**
  6991. * @todo Move to properly supporting RFC2616 (HTTP/1.1)
  6992. */
  6993. class SimplePie_File
  6994. {
  6995. var $url;
  6996. var $useragent;
  6997. var $success = true;
  6998. var $headers = array();
  6999. var $body;
  7000. var $status_code;
  7001. var $redirects = 0;
  7002. var $error;
  7003. var $method = SIMPLEPIE_FILE_SOURCE_NONE;
  7004. function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
  7005. {
  7006. if (class_exists('idna_convert'))
  7007. {
  7008. $idn =& new idna_convert;
  7009. $parsed = SimplePie_Misc::parse_url($url);
  7010. $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  7011. }
  7012. $this->url = $url;
  7013. $this->useragent = $useragent;
  7014. if (preg_match('/^http(s)?:\/\//i', $url))
  7015. {
  7016. if ($useragent === null)
  7017. {
  7018. $useragent = ini_get('user_agent');
  7019. $this->useragent = $useragent;
  7020. }
  7021. if (!is_array($headers))
  7022. {
  7023. $headers = array();
  7024. }
  7025. if (!$force_fsockopen && function_exists('curl_exec'))
  7026. {
  7027. $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
  7028. $fp = curl_init();
  7029. $headers2 = array();
  7030. foreach ($headers as $key => $value)
  7031. {
  7032. $headers2[] = "$key: $value";
  7033. }
  7034. if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
  7035. {
  7036. curl_setopt($fp, CURLOPT_ENCODING, '');
  7037. }
  7038. curl_setopt($fp, CURLOPT_URL, $url);
  7039. curl_setopt($fp, CURLOPT_HEADER, 1);
  7040. curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
  7041. curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
  7042. curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
  7043. curl_setopt($fp, CURLOPT_REFERER, $url);
  7044. curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
  7045. curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
  7046. if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
  7047. {
  7048. curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
  7049. curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
  7050. }
  7051. $this->headers = curl_exec($fp);
  7052. if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
  7053. {
  7054. curl_setopt($fp, CURLOPT_ENCODING, 'none');
  7055. $this->headers = curl_exec($fp);
  7056. }
  7057. if (curl_errno($fp))
  7058. {
  7059. $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
  7060. $this->success = false;
  7061. }
  7062. else
  7063. {
  7064. $info = curl_getinfo($fp);
  7065. curl_close($fp);
  7066. $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
  7067. $this->headers = array_pop($this->headers);
  7068. $parser =& new SimplePie_HTTP_Parser($this->headers);
  7069. if ($parser->parse())
  7070. {
  7071. $this->headers = $parser->headers;
  7072. $this->body = $parser->body;
  7073. $this->status_code = $parser->status_code;
  7074. if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  7075. {
  7076. $this->redirects++;
  7077. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  7078. return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  7079. }
  7080. }
  7081. }
  7082. }
  7083. else
  7084. {
  7085. $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
  7086. $url_parts = parse_url($url);
  7087. if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
  7088. {
  7089. $url_parts['host'] = "ssl://$url_parts[host]";
  7090. $url_parts['port'] = 443;
  7091. }
  7092. if (!isset($url_parts['port']))
  7093. {
  7094. $url_parts['port'] = 80;
  7095. }
  7096. $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
  7097. if (!$fp)
  7098. {
  7099. $this->error = 'fsockopen error: ' . $errstr;
  7100. $this->success = false;
  7101. }
  7102. else
  7103. {
  7104. stream_set_timeout($fp, $timeout);
  7105. if (isset($url_parts['path']))
  7106. {
  7107. if (isset($url_parts['query']))
  7108. {
  7109. $get = "$url_parts[path]?$url_parts[query]";
  7110. }
  7111. else
  7112. {
  7113. $get = $url_parts['path'];
  7114. }
  7115. }
  7116. else
  7117. {
  7118. $get = '/';
  7119. }
  7120. $out = "GET $get HTTP/1.0\r\n";
  7121. $out .= "Host: $url_parts[host]\r\n";
  7122. $out .= "User-Agent: $useragent\r\n";
  7123. if (function_exists('gzinflate'))
  7124. {
  7125. $out .= "Accept-Encoding: gzip,deflate\r\n";
  7126. }
  7127. if (isset($url_parts['user']) && isset($url_parts['pass']))
  7128. {
  7129. $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
  7130. }
  7131. foreach ($headers as $key => $value)
  7132. {
  7133. $out .= "$key: $value\r\n";
  7134. }
  7135. $out .= "Connection: Close\r\n\r\n";
  7136. fwrite($fp, $out);
  7137. $info = stream_get_meta_data($fp);
  7138. $this->headers = '';
  7139. while (!$info['eof'] && !$info['timed_out'])
  7140. {
  7141. $this->headers .= fread($fp, 1160);
  7142. $info = stream_get_meta_data($fp);
  7143. }
  7144. if (!$info['timed_out'])
  7145. {
  7146. $parser =& new SimplePie_HTTP_Parser($this->headers);
  7147. if ($parser->parse())
  7148. {
  7149. $this->headers = $parser->headers;
  7150. $this->body = $parser->body;
  7151. $this->status_code = $parser->status_code;
  7152. if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  7153. {
  7154. $this->redirects++;
  7155. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  7156. return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  7157. }
  7158. if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
  7159. {
  7160. if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
  7161. {
  7162. $this->body = substr($this->body, 10);
  7163. }
  7164. $this->body = gzinflate($this->body);
  7165. }
  7166. }
  7167. }
  7168. else
  7169. {
  7170. $this->error = 'fsocket timed out';
  7171. $this->success = false;
  7172. }
  7173. fclose($fp);
  7174. }
  7175. }
  7176. }
  7177. else
  7178. {
  7179. $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
  7180. if (!$this->body = file_get_contents($url))
  7181. {
  7182. $this->error = 'file_get_contents could not read the file';
  7183. $this->success = false;
  7184. }
  7185. }
  7186. }
  7187. }
  7188. /**
  7189. * HTTP Response Parser
  7190. *
  7191. * @package SimplePie
  7192. */
  7193. class SimplePie_HTTP_Parser
  7194. {
  7195. /**
  7196. * HTTP Version
  7197. *
  7198. * @access public
  7199. * @var float
  7200. */
  7201. var $http_version = 0.0;
  7202. /**
  7203. * Status code
  7204. *
  7205. * @access public
  7206. * @var int
  7207. */
  7208. var $status_code = 0;
  7209. /**
  7210. * Reason phrase
  7211. *
  7212. * @access public
  7213. * @var string
  7214. */
  7215. var $reason = '';
  7216. /**
  7217. * Key/value pairs of the headers
  7218. *
  7219. * @access public
  7220. * @var array
  7221. */
  7222. var $headers = array();
  7223. /**
  7224. * Body of the response
  7225. *
  7226. * @access public
  7227. * @var string
  7228. */
  7229. var $body = '';
  7230. /**
  7231. * Current state of the state machine
  7232. *
  7233. * @access private
  7234. * @var string
  7235. */
  7236. var $state = 'http_version';
  7237. /**
  7238. * Input data
  7239. *
  7240. * @access private
  7241. * @var string
  7242. */
  7243. var $data = '';
  7244. /**
  7245. * Input data length (to avoid calling strlen() everytime this is needed)
  7246. *
  7247. * @access private
  7248. * @var int
  7249. */
  7250. var $data_length = 0;
  7251. /**
  7252. * Current position of the pointer
  7253. *
  7254. * @var int
  7255. * @access private
  7256. */
  7257. var $position = 0;
  7258. /**
  7259. * Name of the hedaer currently being parsed
  7260. *
  7261. * @access private
  7262. * @var string
  7263. */
  7264. var $name = '';
  7265. /**
  7266. * Value of the hedaer currently being parsed
  7267. *
  7268. * @access private
  7269. * @var string
  7270. */
  7271. var $value = '';
  7272. /**
  7273. * Create an instance of the class with the input data
  7274. *
  7275. * @access public
  7276. * @param string $data Input data
  7277. */
  7278. function SimplePie_HTTP_Parser($data)
  7279. {
  7280. $this->data = $data;
  7281. $this->data_length = strlen($this->data);
  7282. }
  7283. /**
  7284. * Parse the input data
  7285. *
  7286. * @access public
  7287. * @return bool true on success, false on failure
  7288. */
  7289. function parse()
  7290. {
  7291. while ($this->state && $this->state !== 'emit' && $this->has_data())
  7292. {
  7293. $state = $this->state;
  7294. $this->$state();
  7295. }
  7296. $this->data = '';
  7297. if ($this->state === 'emit')
  7298. {
  7299. return true;
  7300. }
  7301. else
  7302. {
  7303. $this->http_version = '';
  7304. $this->status_code = '';
  7305. $this->reason = '';
  7306. $this->headers = array();
  7307. $this->body = '';
  7308. return false;
  7309. }
  7310. }
  7311. /**
  7312. * Check whether there is data beyond the pointer
  7313. *
  7314. * @access private
  7315. * @return bool true if there is further data, false if not
  7316. */
  7317. function has_data()
  7318. {
  7319. return (bool) ($this->position < $this->data_length);
  7320. }
  7321. /**
  7322. * See if the next character is LWS
  7323. *
  7324. * @access private
  7325. * @return bool true if the next character is LWS, false if not
  7326. */
  7327. function is_linear_whitespace()
  7328. {
  7329. return (bool) ($this->data[$this->position] === "\x09"
  7330. || $this->data[$this->position] === "\x20"
  7331. || ($this->data[$this->position] === "\x0A"
  7332. && isset($this->data[$this->position + 1])
  7333. && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
  7334. }
  7335. /**
  7336. * Parse the HTTP version
  7337. *
  7338. * @access private
  7339. */
  7340. function http_version()
  7341. {
  7342. if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
  7343. {
  7344. $len = strspn($this->data, '0123456789.', 5);
  7345. $this->http_version = substr($this->data, 5, $len);
  7346. $this->position += 5 + $len;
  7347. if (substr_count($this->http_version, '.') <= 1)
  7348. {
  7349. $this->http_version = (float) $this->http_version;
  7350. $this->position += strspn($this->data, "\x09\x20", $this->position);
  7351. $this->state = 'status';
  7352. }
  7353. else
  7354. {
  7355. $this->state = false;
  7356. }
  7357. }
  7358. else
  7359. {
  7360. $this->state = false;
  7361. }
  7362. }
  7363. /**
  7364. * Parse the status code
  7365. *
  7366. * @access private
  7367. */
  7368. function status()
  7369. {
  7370. if ($len = strspn($this->data, '0123456789', $this->position))
  7371. {
  7372. $this->status_code = (int) substr($this->data, $this->position, $len);
  7373. $this->position += $len;
  7374. $this->state = 'reason';
  7375. }
  7376. else
  7377. {
  7378. $this->state = false;
  7379. }
  7380. }
  7381. /**
  7382. * Parse the reason phrase
  7383. *
  7384. * @access private
  7385. */
  7386. function reason()
  7387. {
  7388. $len = strcspn($this->data, "\x0A", $this->position);
  7389. $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
  7390. $this->position += $len + 1;
  7391. $this->state = 'new_line';
  7392. }
  7393. /**
  7394. * Deal with a new line, shifting data around as needed
  7395. *
  7396. * @access private
  7397. */
  7398. function new_line()
  7399. {
  7400. $this->value = trim($this->value, "\x0D\x20");
  7401. if ($this->name !== '' && $this->value !== '')
  7402. {
  7403. $this->name = strtolower($this->name);
  7404. if (isset($this->headers[$this->name]))
  7405. {
  7406. $this->headers[$this->name] .= ', ' . $this->value;
  7407. }
  7408. else
  7409. {
  7410. $this->headers[$this->name] = $this->value;
  7411. }
  7412. }
  7413. $this->name = '';
  7414. $this->value = '';
  7415. if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
  7416. {
  7417. $this->position += 2;
  7418. $this->state = 'body';
  7419. }
  7420. elseif ($this->data[$this->position] === "\x0A")
  7421. {
  7422. $this->position++;
  7423. $this->state = 'body';
  7424. }
  7425. else
  7426. {
  7427. $this->state = 'name';
  7428. }
  7429. }
  7430. /**
  7431. * Parse a header name
  7432. *
  7433. * @access private
  7434. */
  7435. function name()
  7436. {
  7437. $len = strcspn($this->data, "\x0A:", $this->position);
  7438. if (isset($this->data[$this->position + $len]))
  7439. {
  7440. if ($this->data[$this->position + $len] === "\x0A")
  7441. {
  7442. $this->position += $len;
  7443. $this->state = 'new_line';
  7444. }
  7445. else
  7446. {
  7447. $this->name = substr($this->data, $this->position, $len);
  7448. $this->position += $len + 1;
  7449. $this->state = 'value';
  7450. }
  7451. }
  7452. else
  7453. {
  7454. $this->state = false;
  7455. }
  7456. }
  7457. /**
  7458. * Parse LWS, replacing consecutive LWS characters with a single space
  7459. *
  7460. * @access private
  7461. */
  7462. function linear_whitespace()
  7463. {
  7464. do
  7465. {
  7466. if (substr($this->data, $this->position, 2) === "\x0D\x0A")
  7467. {
  7468. $this->position += 2;
  7469. }
  7470. elseif ($this->data[$this->position] === "\x0A")
  7471. {
  7472. $this->position++;
  7473. }
  7474. $this->position += strspn($this->data, "\x09\x20", $this->position);
  7475. } while ($this->has_data() && $this->is_linear_whitespace());
  7476. $this->value .= "\x20";
  7477. }
  7478. /**
  7479. * See what state to move to while within non-quoted header values
  7480. *
  7481. * @access private
  7482. */
  7483. function value()
  7484. {
  7485. if ($this->is_linear_whitespace())
  7486. {
  7487. $this->linear_whitespace();
  7488. }
  7489. else
  7490. {
  7491. switch ($this->data[$this->position])
  7492. {
  7493. case '"':
  7494. $this->position++;
  7495. $this->state = 'quote';
  7496. break;
  7497. case "\x0A":
  7498. $this->position++;
  7499. $this->state = 'new_line';
  7500. break;
  7501. default:
  7502. $this->state = 'value_char';
  7503. break;
  7504. }
  7505. }
  7506. }
  7507. /**
  7508. * Parse a header value while outside quotes
  7509. *
  7510. * @access private
  7511. */
  7512. function value_char()
  7513. {
  7514. $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
  7515. $this->value .= substr($this->data, $this->position, $len);
  7516. $this->position += $len;
  7517. $this->state = 'value';
  7518. }
  7519. /**
  7520. * See what state to move to while within quoted header values
  7521. *
  7522. * @access private
  7523. */
  7524. function quote()
  7525. {
  7526. if ($this->is_linear_whitespace())
  7527. {
  7528. $this->linear_whitespace();
  7529. }
  7530. else
  7531. {
  7532. switch ($this->data[$this->position])
  7533. {
  7534. case '"':
  7535. $this->position++;
  7536. $this->state = 'value';
  7537. break;
  7538. case "\x0A":
  7539. $this->position++;
  7540. $this->state = 'new_line';
  7541. break;
  7542. case '\\':
  7543. $this->position++;
  7544. $this->state = 'quote_escaped';
  7545. break;
  7546. default:
  7547. $this->state = 'quote_char';
  7548. break;
  7549. }
  7550. }
  7551. }
  7552. /**
  7553. * Parse a header value while within quotes
  7554. *
  7555. * @access private
  7556. */
  7557. function quote_char()
  7558. {
  7559. $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
  7560. $this->value .= substr($this->data, $this->position, $len);
  7561. $this->position += $len;
  7562. $this->state = 'value';
  7563. }
  7564. /**
  7565. * Parse an escaped character within quotes
  7566. *
  7567. * @access private
  7568. */
  7569. function quote_escaped()
  7570. {
  7571. $this->value .= $this->data[$this->position];
  7572. $this->position++;
  7573. $this->state = 'quote';
  7574. }
  7575. /**
  7576. * Parse the body
  7577. *
  7578. * @access private
  7579. */
  7580. function body()
  7581. {
  7582. $this->body = substr($this->data, $this->position);
  7583. $this->state = 'emit';
  7584. }
  7585. }
  7586. class SimplePie_Cache
  7587. {
  7588. /**
  7589. * Don't call the constructor. Please.
  7590. *
  7591. * @access private
  7592. */
  7593. function SimplePie_Cache()
  7594. {
  7595. trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
  7596. }
  7597. /**
  7598. * Create a new SimplePie_Cache object
  7599. *
  7600. * @static
  7601. * @access public
  7602. */
  7603. function create($location, $filename, $extension)
  7604. {
  7605. return new SimplePie_Cache_File($location, $filename, $extension);
  7606. }
  7607. }
  7608. class SimplePie_Cache_File
  7609. {
  7610. var $location;
  7611. var $filename;
  7612. var $extension;
  7613. var $name;
  7614. function SimplePie_Cache_File($location, $filename, $extension)
  7615. {
  7616. $this->location = $location;
  7617. $this->filename = rawurlencode($filename);
  7618. $this->extension = rawurlencode($extension);
  7619. $this->name = "$location/$this->filename.$this->extension";
  7620. }
  7621. function save($data)
  7622. {
  7623. if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
  7624. {
  7625. if (is_a($data, 'SimplePie'))
  7626. {
  7627. $data = $data->data;
  7628. }
  7629. $data = serialize($data);
  7630. if (function_exists('file_put_contents'))
  7631. {
  7632. return (bool) file_put_contents($this->name, $data);
  7633. }
  7634. else
  7635. {
  7636. $fp = fopen($this->name, 'wb');
  7637. if ($fp)
  7638. {
  7639. fwrite($fp, $data);
  7640. fclose($fp);
  7641. return true;
  7642. }
  7643. }
  7644. }
  7645. return false;
  7646. }
  7647. function load()
  7648. {
  7649. if (file_exists($this->name) && is_readable($this->name))
  7650. {
  7651. return unserialize(file_get_contents($this->name));
  7652. }
  7653. return false;
  7654. }
  7655. function mtime()
  7656. {
  7657. if (file_exists($this->name))
  7658. {
  7659. return filemtime($this->name);
  7660. }
  7661. return false;
  7662. }
  7663. function touch()
  7664. {
  7665. if (file_exists($this->name))
  7666. {
  7667. return touch($this->name);
  7668. }
  7669. return false;
  7670. }
  7671. function unlink()
  7672. {
  7673. if (file_exists($this->name))
  7674. {
  7675. return unlink($this->name);
  7676. }
  7677. return false;
  7678. }
  7679. }
  7680. class SimplePie_Misc
  7681. {
  7682. function time_hms($seconds)
  7683. {
  7684. $time = '';
  7685. $hours = floor($seconds / 3600);
  7686. $remainder = $seconds % 3600;
  7687. if ($hours > 0)
  7688. {
  7689. $time .= $hours.':';
  7690. }
  7691. $minutes = floor($remainder / 60);
  7692. $seconds = $remainder % 60;
  7693. if ($minutes < 10 && $hours > 0)
  7694. {
  7695. $minutes = '0' . $minutes;
  7696. }
  7697. if ($seconds < 10)
  7698. {
  7699. $seconds = '0' . $seconds;
  7700. }
  7701. $time .= $minutes.':';
  7702. $time .= $seconds;
  7703. return $time;
  7704. }
  7705. function absolutize_url($relative, $base)
  7706. {
  7707. if ($relative !== '')
  7708. {
  7709. $relative = SimplePie_Misc::parse_url($relative);
  7710. if ($relative['scheme'] !== '')
  7711. {
  7712. $target = $relative;
  7713. }
  7714. elseif ($base !== '')
  7715. {
  7716. $base = SimplePie_Misc::parse_url($base);
  7717. $target = SimplePie_Misc::parse_url('');
  7718. if ($relative['authority'] !== '')
  7719. {
  7720. $target = $relative;
  7721. $target['scheme'] = $base['scheme'];
  7722. }
  7723. else
  7724. {
  7725. $target['scheme'] = $base['scheme'];
  7726. $target['authority'] = $base['authority'];
  7727. if ($relative['path'] !== '')
  7728. {
  7729. if (strpos($relative['path'], '/') === 0)
  7730. {
  7731. $target['path'] = $relative['path'];
  7732. }
  7733. elseif ($base['authority'] !== '' && $base['path'] === '')
  7734. {
  7735. $target['path'] = '/' . $relative['path'];
  7736. }
  7737. elseif (($last_segment = strrpos($base['path'], '/')) !== false)
  7738. {
  7739. $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
  7740. }
  7741. else
  7742. {
  7743. $target['path'] = $relative['path'];
  7744. }
  7745. $target['query'] = $relative['query'];
  7746. }
  7747. else
  7748. {
  7749. $target['path'] = $base['path'];
  7750. if ($relative['query'] !== '')
  7751. {
  7752. $target['query'] = $relative['query'];
  7753. }
  7754. elseif ($base['query'] !== '')
  7755. {
  7756. $target['query'] = $base['query'];
  7757. }
  7758. }
  7759. }
  7760. $target['fragment'] = $relative['fragment'];
  7761. }
  7762. else
  7763. {
  7764. // No base URL, just return the relative URL
  7765. $target = $relative;
  7766. }
  7767. $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
  7768. }
  7769. else
  7770. {
  7771. $return = $base;
  7772. }
  7773. $return = SimplePie_Misc::normalize_url($return);
  7774. return $return;
  7775. }
  7776. function remove_dot_segments($input)
  7777. {
  7778. $output = '';
  7779. while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
  7780. {
  7781. // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
  7782. if (strpos($input, '../') === 0)
  7783. {
  7784. $input = substr($input, 3);
  7785. }
  7786. elseif (strpos($input, './') === 0)
  7787. {
  7788. $input = substr($input, 2);
  7789. }
  7790. // 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,
  7791. elseif (strpos($input, '/./') === 0)
  7792. {
  7793. $input = substr_replace($input, '/', 0, 3);
  7794. }
  7795. elseif ($input == '/.')
  7796. {
  7797. $input = '/';
  7798. }
  7799. // 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,
  7800. elseif (strpos($input, '/../') === 0)
  7801. {
  7802. $input = substr_replace($input, '/', 0, 4);
  7803. $output = substr_replace($output, '', strrpos($output, '/'));
  7804. }
  7805. elseif ($input == '/..')
  7806. {
  7807. $input = '/';
  7808. $output = substr_replace($output, '', strrpos($output, '/'));
  7809. }
  7810. // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
  7811. elseif ($input == '.' || $input == '..')
  7812. {
  7813. $input = '';
  7814. }
  7815. // 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
  7816. elseif (($pos = strpos($input, '/', 1)) !== false)
  7817. {
  7818. $output .= substr($input, 0, $pos);
  7819. $input = substr_replace($input, '', 0, $pos);
  7820. }
  7821. else
  7822. {
  7823. $output .= $input;
  7824. $input = '';
  7825. }
  7826. }
  7827. return $output . $input;
  7828. }
  7829. function get_element($realname, $string)
  7830. {
  7831. $return = array();
  7832. $name = preg_quote($realname, '/');
  7833. if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
  7834. {
  7835. for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
  7836. {
  7837. $return[$i]['tag'] = $realname;
  7838. $return[$i]['full'] = $matches[$i][0][0];
  7839. $return[$i]['offset'] = $matches[$i][0][1];
  7840. if (strlen($matches[$i][3][0]) <= 2)
  7841. {
  7842. $return[$i]['self_closing'] = true;
  7843. }
  7844. else
  7845. {
  7846. $return[$i]['self_closing'] = false;
  7847. $return[$i]['content'] = $matches[$i][4][0];
  7848. }
  7849. $return[$i]['attribs'] = array();
  7850. if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
  7851. {
  7852. for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
  7853. {
  7854. if (count($attribs[$j]) == 2)
  7855. {
  7856. $attribs[$j][2] = $attribs[$j][1];
  7857. }
  7858. $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
  7859. }
  7860. }
  7861. }
  7862. }
  7863. return $return;
  7864. }
  7865. function element_implode($element)
  7866. {
  7867. $full = "<$element[tag]";
  7868. foreach ($element['attribs'] as $key => $value)
  7869. {
  7870. $key = strtolower($key);
  7871. $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
  7872. }
  7873. if ($element['self_closing'])
  7874. {
  7875. $full .= ' />';
  7876. }
  7877. else
  7878. {
  7879. $full .= ">$element[content]</$element[tag]>";
  7880. }
  7881. return $full;
  7882. }
  7883. function error($message, $level, $file, $line)
  7884. {
  7885. switch ($level)
  7886. {
  7887. case E_USER_ERROR:
  7888. $note = 'PHP Error';
  7889. break;
  7890. case E_USER_WARNING:
  7891. $note = 'PHP Warning';
  7892. break;
  7893. case E_USER_NOTICE:
  7894. $note = 'PHP Notice';
  7895. break;
  7896. default:
  7897. $note = 'Unknown Error';
  7898. break;
  7899. }
  7900. error_log("$note: $message in $file on line $line", 0);
  7901. return $message;
  7902. }
  7903. /**
  7904. * If a file has been cached, retrieve and display it.
  7905. *
  7906. * This is most useful for caching images (get_favicon(), etc.),
  7907. * however it works for all cached files. This WILL NOT display ANY
  7908. * file/image/page/whatever, but rather only display what has already
  7909. * been cached by SimplePie.
  7910. *
  7911. * @access public
  7912. * @see SimplePie::get_favicon()
  7913. * @param str $identifier_url URL that is used to identify the content.
  7914. * This may or may not be the actual URL of the live content.
  7915. * @param str $cache_location Location of SimplePie's cache. Defaults
  7916. * to './cache'.
  7917. * @param str $cache_extension The file extension that the file was
  7918. * cached with. Defaults to 'spc'.
  7919. * @param str $cache_class Name of the cache-handling class being used
  7920. * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
  7921. * as-is unless you've overloaded the class.
  7922. * @param str $cache_name_function Obsolete. Exists for backwards
  7923. * compatibility reasons only.
  7924. */
  7925. function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
  7926. {
  7927. $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
  7928. if ($file = $cache->load())
  7929. {
  7930. if (isset($file['headers']['content-type']))
  7931. {
  7932. header('Content-type:' . $file['headers']['content-type']);
  7933. }
  7934. else
  7935. {
  7936. header('Content-type: application/octet-stream');
  7937. }
  7938. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  7939. echo $file['body'];
  7940. exit;
  7941. }
  7942. die('Cached file for ' . $identifier_url . ' cannot be found.');
  7943. }
  7944. function fix_protocol($url, $http = 1)
  7945. {
  7946. $url = SimplePie_Misc::normalize_url($url);
  7947. $parsed = SimplePie_Misc::parse_url($url);
  7948. if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
  7949. {
  7950. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
  7951. }
  7952. if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
  7953. {
  7954. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
  7955. }
  7956. if ($http == 2 && $parsed['scheme'] !== '')
  7957. {
  7958. return "feed:$url";
  7959. }
  7960. elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
  7961. {
  7962. return substr_replace($url, 'podcast', 0, 4);
  7963. }
  7964. elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
  7965. {
  7966. return substr_replace($url, 'itpc', 0, 4);
  7967. }
  7968. else
  7969. {
  7970. return $url;
  7971. }
  7972. }
  7973. function parse_url($url)
  7974. {
  7975. static $cache = array();
  7976. if (isset($cache[$url]))
  7977. {
  7978. return $cache[$url];
  7979. }
  7980. elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
  7981. {
  7982. for ($i = count($match); $i <= 9; $i++)
  7983. {
  7984. $match[$i] = '';
  7985. }
  7986. return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
  7987. }
  7988. else
  7989. {
  7990. return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
  7991. }
  7992. }
  7993. function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
  7994. {
  7995. $return = '';
  7996. if ($scheme !== '')
  7997. {
  7998. $return .= "$scheme:";
  7999. }
  8000. if ($authority !== '')
  8001. {
  8002. $return .= "//$authority";
  8003. }
  8004. if ($path !== '')
  8005. {
  8006. $return .= $path;
  8007. }
  8008. if ($query !== '')
  8009. {
  8010. $return .= "?$query";
  8011. }
  8012. if ($fragment !== '')
  8013. {
  8014. $return .= "#$fragment";
  8015. }
  8016. return $return;
  8017. }
  8018. function normalize_url($url)
  8019. {
  8020. $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
  8021. $url = SimplePie_Misc::parse_url($url);
  8022. $url['scheme'] = strtolower($url['scheme']);
  8023. if ($url['authority'] !== '')
  8024. {
  8025. $url['authority'] = strtolower($url['authority']);
  8026. $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
  8027. }
  8028. return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
  8029. }
  8030. function percent_encoding_normalization($match)
  8031. {
  8032. $integer = hexdec($match[1]);
  8033. if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
  8034. {
  8035. return chr($integer);
  8036. }
  8037. else
  8038. {
  8039. return strtoupper($match[0]);
  8040. }
  8041. }
  8042. /**
  8043. * Remove bad UTF-8 bytes
  8044. *
  8045. * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
  8046. * FAQ: Multilingual Forms (modified to include full ASCII range)
  8047. *
  8048. * @author Geoffrey Sneddon
  8049. * @see http://www.w3.org/International/questions/qa-forms-utf-8
  8050. * @param string $str String to remove bad UTF-8 bytes from
  8051. * @return string UTF-8 string
  8052. */
  8053. function utf8_bad_replace($str)
  8054. {
  8055. if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
  8056. {
  8057. return $return;
  8058. }
  8059. elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
  8060. {
  8061. return $return;
  8062. }
  8063. elseif (preg_match_all('/(?:[\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})+/', $str, $matches))
  8064. {
  8065. return implode("\xEF\xBF\xBD", $matches[0]);
  8066. }
  8067. elseif ($str !== '')
  8068. {
  8069. return "\xEF\xBF\xBD";
  8070. }
  8071. else
  8072. {
  8073. return '';
  8074. }
  8075. }
  8076. /**
  8077. * Converts a Windows-1252 encoded string to a UTF-8 encoded string
  8078. *
  8079. * @static
  8080. * @access public
  8081. * @param string $string Windows-1252 encoded string
  8082. * @return string UTF-8 encoded string
  8083. */
  8084. function windows_1252_to_utf8($string)
  8085. {
  8086. static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF");
  8087. return strtr($string, $convert_table);
  8088. }
  8089. function change_encoding($data, $input, $output)
  8090. {
  8091. $input = SimplePie_Misc::encoding($input);
  8092. $output = SimplePie_Misc::encoding($output);
  8093. // We fail to fail on non US-ASCII bytes
  8094. if ($input === 'US-ASCII')
  8095. {
  8096. static $non_ascii_octects = '';
  8097. if (!$non_ascii_octects)
  8098. {
  8099. for ($i = 0x80; $i <= 0xFF; $i++)
  8100. {
  8101. $non_ascii_octects .= chr($i);
  8102. }
  8103. }
  8104. $data = substr($data, 0, strcspn($data, $non_ascii_octects));
  8105. }
  8106. if (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
  8107. {
  8108. return $return;
  8109. }
  8110. elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
  8111. {
  8112. return $return;
  8113. }
  8114. elseif ($input == 'windows-1252' && $output == 'UTF-8')
  8115. {
  8116. return SimplePie_Misc::windows_1252_to_utf8($data);
  8117. }
  8118. elseif ($input == 'UTF-8' && $output == 'windows-1252')
  8119. {
  8120. return utf8_decode($data);
  8121. }
  8122. return $data;
  8123. }
  8124. function encoding($encoding)
  8125. {
  8126. // Character sets are case-insensitive (though we'll return them in the form given in their registration)
  8127. switch (strtoupper($encoding))
  8128. {
  8129. case 'ANSI_X3.110-1983':
  8130. case 'CSA_T500-1983':
  8131. case 'CSISO99NAPLPS':
  8132. case 'ISO-IR-99':
  8133. case 'NAPLPS':
  8134. return 'ANSI_X3.110-1983';
  8135. case 'ARABIC7':
  8136. case 'ASMO_449':
  8137. case 'CSISO89ASMO449':
  8138. case 'ISO-IR-89':
  8139. case 'ISO_9036':
  8140. return 'ASMO_449';
  8141. case 'ADOBE-STANDARD-ENCODING':
  8142. case 'CSADOBESTANDARDENCODING':
  8143. return 'Adobe-Standard-Encoding';
  8144. case 'ADOBE-SYMBOL-ENCODING':
  8145. case 'CSHPPSMATH':
  8146. return 'Adobe-Symbol-Encoding';
  8147. case 'AMI-1251':
  8148. case 'AMI1251':
  8149. case 'AMIGA-1251':
  8150. case 'AMIGA1251':
  8151. return 'Amiga-1251';
  8152. case 'BOCU-1':
  8153. case 'CSBOCU-1':
  8154. return 'BOCU-1';
  8155. case 'BRF':
  8156. case 'CSBRF':
  8157. return 'BRF';
  8158. case 'BS_4730':
  8159. case 'CSISO4UNITEDKINGDOM':
  8160. case 'GB':
  8161. case 'ISO-IR-4':
  8162. case 'ISO646-GB':
  8163. case 'UK':
  8164. return 'BS_4730';
  8165. case 'BS_VIEWDATA':
  8166. case 'CSISO47BSVIEWDATA':
  8167. case 'ISO-IR-47':
  8168. return 'BS_viewdata';
  8169. case 'BIG5':
  8170. case 'CSBIG5':
  8171. return 'Big5';
  8172. case 'BIG5-HKSCS':
  8173. return 'Big5-HKSCS';
  8174. case 'CESU-8':
  8175. case 'CSCESU-8':
  8176. return 'CESU-8';
  8177. case 'CA':
  8178. case 'CSA7-1':
  8179. case 'CSA_Z243.4-1985-1':
  8180. case 'CSISO121CANADIAN1':
  8181. case 'ISO-IR-121':
  8182. case 'ISO646-CA':
  8183. return 'CSA_Z243.4-1985-1';
  8184. case 'CSA7-2':
  8185. case 'CSA_Z243.4-1985-2':
  8186. case 'CSISO122CANADIAN2':
  8187. case 'ISO-IR-122':
  8188. case 'ISO646-CA2':
  8189. return 'CSA_Z243.4-1985-2';
  8190. case 'CSA_Z243.4-1985-GR':
  8191. case 'CSISO123CSAZ24341985GR':
  8192. case 'ISO-IR-123':
  8193. return 'CSA_Z243.4-1985-gr';
  8194. case 'CSISO139CSN369103':
  8195. case 'CSN_369103':
  8196. case 'ISO-IR-139':
  8197. return 'CSN_369103';
  8198. case 'CSDECMCS':
  8199. case 'DEC':
  8200. case 'DEC-MCS':
  8201. return 'DEC-MCS';
  8202. case 'CSISO21GERMAN':
  8203. case 'DE':
  8204. case 'DIN_66003':
  8205. case 'ISO-IR-21':
  8206. case 'ISO646-DE':
  8207. return 'DIN_66003';
  8208. case 'CSISO646DANISH':
  8209. case 'DK':
  8210. case 'DS2089':
  8211. case 'DS_2089':
  8212. case 'ISO646-DK':
  8213. return 'DS_2089';
  8214. case 'CSIBMEBCDICATDE':
  8215. case 'EBCDIC-AT-DE':
  8216. return 'EBCDIC-AT-DE';
  8217. case 'CSEBCDICATDEA':
  8218. case 'EBCDIC-AT-DE-A':
  8219. return 'EBCDIC-AT-DE-A';
  8220. case 'CSEBCDICCAFR':
  8221. case 'EBCDIC-CA-FR':
  8222. return 'EBCDIC-CA-FR';
  8223. case 'CSEBCDICDKNO':
  8224. case 'EBCDIC-DK-NO':
  8225. return 'EBCDIC-DK-NO';
  8226. case 'CSEBCDICDKNOA':
  8227. case 'EBCDIC-DK-NO-A':
  8228. return 'EBCDIC-DK-NO-A';
  8229. case 'CSEBCDICES':
  8230. case 'EBCDIC-ES':
  8231. return 'EBCDIC-ES';
  8232. case 'CSEBCDICESA':
  8233. case 'EBCDIC-ES-A':
  8234. return 'EBCDIC-ES-A';
  8235. case 'CSEBCDICESS':
  8236. case 'EBCDIC-ES-S':
  8237. return 'EBCDIC-ES-S';
  8238. case 'CSEBCDICFISE':
  8239. case 'EBCDIC-FI-SE':
  8240. return 'EBCDIC-FI-SE';
  8241. case 'CSEBCDICFISEA':
  8242. case 'EBCDIC-FI-SE-A':
  8243. return 'EBCDIC-FI-SE-A';
  8244. case 'CSEBCDICFR':
  8245. case 'EBCDIC-FR':
  8246. return 'EBCDIC-FR';
  8247. case 'CSEBCDICIT':
  8248. case 'EBCDIC-IT':
  8249. return 'EBCDIC-IT';
  8250. case 'CSEBCDICPT':
  8251. case 'EBCDIC-PT':
  8252. return 'EBCDIC-PT';
  8253. case 'CSEBCDICUK':
  8254. case 'EBCDIC-UK':
  8255. return 'EBCDIC-UK';
  8256. case 'CSEBCDICUS':
  8257. case 'EBCDIC-US':
  8258. return 'EBCDIC-US';
  8259. case 'CSISO111ECMACYRILLIC':
  8260. case 'ECMA-CYRILLIC':
  8261. case 'ISO-IR-111':
  8262. case 'KOI8-E':
  8263. return 'ECMA-cyrillic';
  8264. case 'CSISO17SPANISH':
  8265. case 'ES':
  8266. case 'ISO-IR-17':
  8267. case 'ISO646-ES':
  8268. return 'ES';
  8269. case 'CSISO85SPANISH2':
  8270. case 'ES2':
  8271. case 'ISO-IR-85':
  8272. case 'ISO646-ES2':
  8273. return 'ES2';
  8274. case 'CSEUCPKDFMTJAPANESE':
  8275. case 'EUC-JP':
  8276. case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
  8277. return 'EUC-JP';
  8278. case 'CSEUCKR':
  8279. case 'EUC-KR':
  8280. return 'EUC-KR';
  8281. case 'CSEUCFIXWIDJAPANESE':
  8282. case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
  8283. return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
  8284. case 'GB18030':
  8285. return 'GB18030';
  8286. case 'CSGB2312':
  8287. case 'GB2312':
  8288. return 'GB2312';
  8289. case 'CP936':
  8290. case 'GBK':
  8291. case 'MS936':
  8292. case 'WINDOWS-936':
  8293. return 'GBK';
  8294. case 'CN':
  8295. case 'CSISO57GB1988':
  8296. case 'GB_1988-80':
  8297. case 'ISO-IR-57':
  8298. case 'ISO646-CN':
  8299. return 'GB_1988-80';
  8300. case 'CHINESE':
  8301. case 'CSISO58GB231280':
  8302. case 'GB_2312-80':
  8303. case 'ISO-IR-58':
  8304. return 'GB_2312-80';
  8305. case 'CSISO153GOST1976874':
  8306. case 'GOST_19768-74':
  8307. case 'ISO-IR-153':
  8308. case 'ST_SEV_358-88':
  8309. return 'GOST_19768-74';
  8310. case 'CSHPDESKTOP':
  8311. case 'HP-DESKTOP':
  8312. return 'HP-DeskTop';
  8313. case 'CSHPLEGAL':
  8314. case 'HP-LEGAL':
  8315. return 'HP-Legal';
  8316. case 'CSHPMATH8':
  8317. case 'HP-MATH8':
  8318. return 'HP-Math8';
  8319. case 'CSHPPIFONT':
  8320. case 'HP-PI-FONT':
  8321. return 'HP-Pi-font';
  8322. case 'HZ-GB-2312':
  8323. return 'HZ-GB-2312';
  8324. case 'CSIBMSYMBOLS':
  8325. case 'IBM-SYMBOLS':
  8326. return 'IBM-Symbols';
  8327. case 'CSIBMTHAI':
  8328. case 'IBM-THAI':
  8329. return 'IBM-Thai';
  8330. case 'CCSID00858':
  8331. case 'CP00858':
  8332. case 'IBM00858':
  8333. case 'PC-MULTILINGUAL-850+EURO':
  8334. return 'IBM00858';
  8335. case 'CCSID00924':
  8336. case 'CP00924':
  8337. case 'EBCDIC-LATIN9--EURO':
  8338. case 'IBM00924':
  8339. return 'IBM00924';
  8340. case 'CCSID01140':
  8341. case 'CP01140':
  8342. case 'EBCDIC-US-37+EURO':
  8343. case 'IBM01140':
  8344. return 'IBM01140';
  8345. case 'CCSID01141':
  8346. case 'CP01141':
  8347. case 'EBCDIC-DE-273+EURO':
  8348. case 'IBM01141':
  8349. return 'IBM01141';
  8350. case 'CCSID01142':
  8351. case 'CP01142':
  8352. case 'EBCDIC-DK-277+EURO':
  8353. case 'EBCDIC-NO-277+EURO':
  8354. case 'IBM01142':
  8355. return 'IBM01142';
  8356. case 'CCSID01143':
  8357. case 'CP01143':
  8358. case 'EBCDIC-FI-278+EURO':
  8359. case 'EBCDIC-SE-278+EURO':
  8360. case 'IBM01143':
  8361. return 'IBM01143';
  8362. case 'CCSID01144':
  8363. case 'CP01144':
  8364. case 'EBCDIC-IT-280+EURO':
  8365. case 'IBM01144':
  8366. return 'IBM01144';
  8367. case 'CCSID01145':
  8368. case 'CP01145':
  8369. case 'EBCDIC-ES-284+EURO':
  8370. case 'IBM01145':
  8371. return 'IBM01145';
  8372. case 'CCSID01146':
  8373. case 'CP01146':
  8374. case 'EBCDIC-GB-285+EURO':
  8375. case 'IBM01146':
  8376. return 'IBM01146';
  8377. case 'CCSID01147':
  8378. case 'CP01147':
  8379. case 'EBCDIC-FR-297+EURO':
  8380. case 'IBM01147':
  8381. return 'IBM01147';
  8382. case 'CCSID01148':
  8383. case 'CP01148':
  8384. case 'EBCDIC-INTERNATIONAL-500+EURO':
  8385. case 'IBM01148':
  8386. return 'IBM01148';
  8387. case 'CCSID01149':
  8388. case 'CP01149':
  8389. case 'EBCDIC-IS-871+EURO':
  8390. case 'IBM01149':
  8391. return 'IBM01149';
  8392. case 'CP037':
  8393. case 'CSIBM037':
  8394. case 'EBCDIC-CP-CA':
  8395. case 'EBCDIC-CP-NL':
  8396. case 'EBCDIC-CP-US':
  8397. case 'EBCDIC-CP-WT':
  8398. case 'IBM037':
  8399. return 'IBM037';
  8400. case 'CP038':
  8401. case 'CSIBM038':
  8402. case 'EBCDIC-INT':
  8403. case 'IBM038':
  8404. return 'IBM038';
  8405. case 'CP1026':
  8406. case 'CSIBM1026':
  8407. case 'IBM1026':
  8408. return 'IBM1026';
  8409. case 'IBM-1047':
  8410. case 'IBM1047':
  8411. return 'IBM1047';
  8412. case 'CP273':
  8413. case 'CSIBM273':
  8414. case 'IBM273':
  8415. return 'IBM273';
  8416. case 'CP274':
  8417. case 'CSIBM274':
  8418. case 'EBCDIC-BE':
  8419. case 'IBM274':
  8420. return 'IBM274';
  8421. case 'CP275':
  8422. case 'CSIBM275':
  8423. case 'EBCDIC-BR':
  8424. case 'IBM275':
  8425. return 'IBM275';
  8426. case 'CSIBM277':
  8427. case 'EBCDIC-CP-DK':
  8428. case 'EBCDIC-CP-NO':
  8429. case 'IBM277':
  8430. return 'IBM277';
  8431. case 'CP278':
  8432. case 'CSIBM278':
  8433. case 'EBCDIC-CP-FI':
  8434. case 'EBCDIC-CP-SE':
  8435. case 'IBM278':
  8436. return 'IBM278';
  8437. case 'CP280':
  8438. case 'CSIBM280':
  8439. case 'EBCDIC-CP-IT':
  8440. case 'IBM280':
  8441. return 'IBM280';
  8442. case 'CP281':
  8443. case 'CSIBM281':
  8444. case 'EBCDIC-JP-E':
  8445. case 'IBM281':
  8446. return 'IBM281';
  8447. case 'CP284':
  8448. case 'CSIBM284':
  8449. case 'EBCDIC-CP-ES':
  8450. case 'IBM284':
  8451. return 'IBM284';
  8452. case 'CP285':
  8453. case 'CSIBM285':
  8454. case 'EBCDIC-CP-GB':
  8455. case 'IBM285':
  8456. return 'IBM285';
  8457. case 'CP290':
  8458. case 'CSIBM290':
  8459. case 'EBCDIC-JP-KANA':
  8460. case 'IBM290':
  8461. return 'IBM290';
  8462. case 'CP297':
  8463. case 'CSIBM297':
  8464. case 'EBCDIC-CP-FR':
  8465. case 'IBM297':
  8466. return 'IBM297';
  8467. case 'CP420':
  8468. case 'CSIBM420':
  8469. case 'EBCDIC-CP-AR1':
  8470. case 'IBM420':
  8471. return 'IBM420';
  8472. case 'CP423':
  8473. case 'CSIBM423':
  8474. case 'EBCDIC-CP-GR':
  8475. case 'IBM423':
  8476. return 'IBM423';
  8477. case 'CP424':
  8478. case 'CSIBM424':
  8479. case 'EBCDIC-CP-HE':
  8480. case 'IBM424':
  8481. return 'IBM424';
  8482. case '437':
  8483. case 'CP437':
  8484. case 'CSPC8CODEPAGE437':
  8485. case 'IBM437':
  8486. return 'IBM437';
  8487. case 'CP500':
  8488. case 'CSIBM500':
  8489. case 'EBCDIC-CP-BE':
  8490. case 'EBCDIC-CP-CH':
  8491. case 'IBM500':
  8492. return 'IBM500';
  8493. case 'CP775':
  8494. case 'CSPC775BALTIC':
  8495. case 'IBM775':
  8496. return 'IBM775';
  8497. case '850':
  8498. case 'CP850':
  8499. case 'CSPC850MULTILINGUAL':
  8500. case 'IBM850':
  8501. return 'IBM850';
  8502. case '851':
  8503. case 'CP851':
  8504. case 'CSIBM851':
  8505. case 'IBM851':
  8506. return 'IBM851';
  8507. case '852':
  8508. case 'CP852':
  8509. case 'CSPCP852':
  8510. case 'IBM852':
  8511. return 'IBM852';
  8512. case '855':
  8513. case 'CP855':
  8514. case 'CSIBM855':
  8515. case 'IBM855':
  8516. return 'IBM855';
  8517. case '857':
  8518. case 'CP857':
  8519. case 'CSIBM857':
  8520. case 'IBM857':
  8521. return 'IBM857';
  8522. case '860':
  8523. case 'CP860':
  8524. case 'CSIBM860':
  8525. case 'IBM860':
  8526. return 'IBM860';
  8527. case '861':
  8528. case 'CP-IS':
  8529. case 'CP861':
  8530. case 'CSIBM861':
  8531. case 'IBM861':
  8532. return 'IBM861';
  8533. case '862':
  8534. case 'CP862':
  8535. case 'CSPC862LATINHEBREW':
  8536. case 'IBM862':
  8537. return 'IBM862';
  8538. case '863':
  8539. case 'CP863':
  8540. case 'CSIBM863':
  8541. case 'IBM863':
  8542. return 'IBM863';
  8543. case 'CP864':
  8544. case 'CSIBM864':
  8545. case 'IBM864':
  8546. return 'IBM864';
  8547. case '865':
  8548. case 'CP865':
  8549. case 'CSIBM865':
  8550. case 'IBM865':
  8551. return 'IBM865';
  8552. case '866':
  8553. case 'CP866':
  8554. case 'CSIBM866':
  8555. case 'IBM866':
  8556. return 'IBM866';
  8557. case 'CP-AR':
  8558. case 'CP868':
  8559. case 'CSIBM868':
  8560. case 'IBM868':
  8561. return 'IBM868';
  8562. case '869':
  8563. case 'CP-GR':
  8564. case 'CP869':
  8565. case 'CSIBM869':
  8566. case 'IBM869':
  8567. return 'IBM869';
  8568. case 'CP870':
  8569. case 'CSIBM870':
  8570. case 'EBCDIC-CP-ROECE':
  8571. case 'EBCDIC-CP-YU':
  8572. case 'IBM870':
  8573. return 'IBM870';
  8574. case 'CP871':
  8575. case 'CSIBM871':
  8576. case 'EBCDIC-CP-IS':
  8577. case 'IBM871':
  8578. return 'IBM871';
  8579. case 'CP880':
  8580. case 'CSIBM880':
  8581. case 'EBCDIC-CYRILLIC':
  8582. case 'IBM880':
  8583. return 'IBM880';
  8584. case 'CP891':
  8585. case 'CSIBM891':
  8586. case 'IBM891':
  8587. return 'IBM891';
  8588. case 'CP903':
  8589. case 'CSIBM903':
  8590. case 'IBM903':
  8591. return 'IBM903';
  8592. case '904':
  8593. case 'CP904':
  8594. case 'CSIBBM904':
  8595. case 'IBM904':
  8596. return 'IBM904';
  8597. case 'CP905':
  8598. case 'CSIBM905':
  8599. case 'EBCDIC-CP-TR':
  8600. case 'IBM905':
  8601. return 'IBM905';
  8602. case 'CP918':
  8603. case 'CSIBM918':
  8604. case 'EBCDIC-CP-AR2':
  8605. case 'IBM918':
  8606. return 'IBM918';
  8607. case 'CSISO143IECP271':
  8608. case 'IEC_P27-1':
  8609. case 'ISO-IR-143':
  8610. return 'IEC_P27-1';
  8611. case 'CSISO49INIS':
  8612. case 'INIS':
  8613. case 'ISO-IR-49':
  8614. return 'INIS';
  8615. case 'CSISO50INIS8':
  8616. case 'INIS-8':
  8617. case 'ISO-IR-50':
  8618. return 'INIS-8';
  8619. case 'CSISO51INISCYRILLIC':
  8620. case 'INIS-CYRILLIC':
  8621. case 'ISO-IR-51':
  8622. return 'INIS-cyrillic';
  8623. case 'CSINVARIANT':
  8624. case 'INVARIANT':
  8625. return 'INVARIANT';
  8626. case 'ISO-10646-J-1':
  8627. return 'ISO-10646-J-1';
  8628. case 'CSUNICODE':
  8629. case 'ISO-10646-UCS-2':
  8630. return 'ISO-10646-UCS-2';
  8631. case 'CSUCS4':
  8632. case 'ISO-10646-UCS-4':
  8633. return 'ISO-10646-UCS-4';
  8634. case 'CSUNICODEASCII':
  8635. case 'ISO-10646-UCS-BASIC':
  8636. return 'ISO-10646-UCS-Basic';
  8637. case 'CSISO10646UTF1':
  8638. case 'ISO-10646-UTF-1':
  8639. return 'ISO-10646-UTF-1';
  8640. case 'CSUNICODELATIN1':
  8641. case 'ISO-10646':
  8642. case 'ISO-10646-UNICODE-LATIN1':
  8643. return 'ISO-10646-Unicode-Latin1';
  8644. case 'CSISO115481':
  8645. case 'ISO-11548-1':
  8646. case 'ISO_11548-1':
  8647. case 'ISO_TR_11548-1':
  8648. return 'ISO-11548-1';
  8649. case 'ISO-2022-CN':
  8650. return 'ISO-2022-CN';
  8651. case 'ISO-2022-CN-EXT':
  8652. return 'ISO-2022-CN-EXT';
  8653. case 'CSISO2022JP':
  8654. case 'ISO-2022-JP':
  8655. return 'ISO-2022-JP';
  8656. case 'CSISO2022JP2':
  8657. case 'ISO-2022-JP-2':
  8658. return 'ISO-2022-JP-2';
  8659. case 'CSISO2022KR':
  8660. case 'ISO-2022-KR':
  8661. return 'ISO-2022-KR';
  8662. case 'CSWINDOWS30LATIN1':
  8663. case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
  8664. return 'ISO-8859-1-Windows-3.0-Latin-1';
  8665. case 'CSWINDOWS31LATIN1':
  8666. case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
  8667. return 'ISO-8859-1-Windows-3.1-Latin-1';
  8668. case 'CSISOLATIN6':
  8669. case 'ISO-8859-10':
  8670. case 'ISO-IR-157':
  8671. case 'ISO_8859-10:1992':
  8672. case 'L6':
  8673. case 'LATIN6':
  8674. return 'ISO-8859-10';
  8675. case 'ISO-8859-13':
  8676. return 'ISO-8859-13';
  8677. case 'ISO-8859-14':
  8678. case 'ISO-CELTIC':
  8679. case 'ISO-IR-199':
  8680. case 'ISO_8859-14':
  8681. case 'ISO_8859-14:1998':
  8682. case 'L8':
  8683. case 'LATIN8':
  8684. return 'ISO-8859-14';
  8685. case 'ISO-8859-15':
  8686. case 'ISO_8859-15':
  8687. case 'LATIN-9':
  8688. return 'ISO-8859-15';
  8689. case 'ISO-8859-16':
  8690. case 'ISO-IR-226':
  8691. case 'ISO_8859-16':
  8692. case 'ISO_8859-16:2001':
  8693. case 'L10':
  8694. case 'LATIN10':
  8695. return 'ISO-8859-16';
  8696. case 'CSISOLATIN2':
  8697. case 'ISO-8859-2':
  8698. case 'ISO-IR-101':
  8699. case 'ISO_8859-2':
  8700. case 'ISO_8859-2:1987':
  8701. case 'L2':
  8702. case 'LATIN2':
  8703. return 'ISO-8859-2';
  8704. case 'CSWINDOWS31LATIN2':
  8705. case 'ISO-8859-2-WINDOWS-LATIN-2':
  8706. return 'ISO-8859-2-Windows-Latin-2';
  8707. case 'CSISOLATIN3':
  8708. case 'ISO-8859-3':
  8709. case 'ISO-IR-109':
  8710. case 'ISO_8859-3':
  8711. case 'ISO_8859-3:1988':
  8712. case 'L3':
  8713. case 'LATIN3':
  8714. return 'ISO-8859-3';
  8715. case 'CSISOLATIN4':
  8716. case 'ISO-8859-4':
  8717. case 'ISO-IR-110':
  8718. case 'ISO_8859-4':
  8719. case 'ISO_8859-4:1988':
  8720. case 'L4':
  8721. case 'LATIN4':
  8722. return 'ISO-8859-4';
  8723. case 'CSISOLATINCYRILLIC':
  8724. case 'CYRILLIC':
  8725. case 'ISO-8859-5':
  8726. case 'ISO-IR-144':
  8727. case 'ISO_8859-5':
  8728. case 'ISO_8859-5:1988':
  8729. return 'ISO-8859-5';
  8730. case 'ARABIC':
  8731. case 'ASMO-708':
  8732. case 'CSISOLATINARABIC':
  8733. case 'ECMA-114':
  8734. case 'ISO-8859-6':
  8735. case 'ISO-IR-127':
  8736. case 'ISO_8859-6':
  8737. case 'ISO_8859-6:1987':
  8738. return 'ISO-8859-6';
  8739. case 'CSISO88596E':
  8740. case 'ISO-8859-6-E':
  8741. case 'ISO_8859-6-E':
  8742. return 'ISO-8859-6-E';
  8743. case 'CSISO88596I':
  8744. case 'ISO-8859-6-I':
  8745. case 'ISO_8859-6-I':
  8746. return 'ISO-8859-6-I';
  8747. case 'CSISOLATINGREEK':
  8748. case 'ECMA-118':
  8749. case 'ELOT_928':
  8750. case 'GREEK':
  8751. case 'GREEK8':
  8752. case 'ISO-8859-7':
  8753. case 'ISO-IR-126':
  8754. case 'ISO_8859-7':
  8755. case 'ISO_8859-7:1987':
  8756. return 'ISO-8859-7';
  8757. case 'CSISOLATINHEBREW':
  8758. case 'HEBREW':
  8759. case 'ISO-8859-8':
  8760. case 'ISO-IR-138':
  8761. case 'ISO_8859-8':
  8762. case 'ISO_8859-8:1988':
  8763. return 'ISO-8859-8';
  8764. case 'CSISO88598E':
  8765. case 'ISO-8859-8-E':
  8766. case 'ISO_8859-8-E':
  8767. return 'ISO-8859-8-E';
  8768. case 'CSISO88598I':
  8769. case 'ISO-8859-8-I':
  8770. case 'ISO_8859-8-I':
  8771. return 'ISO-8859-8-I';
  8772. case 'CSISOLATIN5':
  8773. case 'ISO-8859-9':
  8774. case 'ISO-IR-148':
  8775. case 'ISO_8859-9':
  8776. case 'ISO_8859-9:1989':
  8777. case 'L5':
  8778. case 'LATIN5':
  8779. return 'ISO-8859-9';
  8780. case 'CSWINDOWS31LATIN5':
  8781. case 'ISO-8859-9-WINDOWS-LATIN-5':
  8782. return 'ISO-8859-9-Windows-Latin-5';
  8783. case 'CSUNICODEIBM1261':
  8784. case 'ISO-UNICODE-IBM-1261':
  8785. return 'ISO-Unicode-IBM-1261';
  8786. case 'CSUNICODEIBM1264':
  8787. case 'ISO-UNICODE-IBM-1264':
  8788. return 'ISO-Unicode-IBM-1264';
  8789. case 'CSUNICODEIBM1265':
  8790. case 'ISO-UNICODE-IBM-1265':
  8791. return 'ISO-Unicode-IBM-1265';
  8792. case 'CSUNICODEIBM1268':
  8793. case 'ISO-UNICODE-IBM-1268':
  8794. return 'ISO-Unicode-IBM-1268';
  8795. case 'CSUNICODEIBM1276':
  8796. case 'ISO-UNICODE-IBM-1276':
  8797. return 'ISO-Unicode-IBM-1276';
  8798. case 'CSISO10367BOX':
  8799. case 'ISO-IR-155':
  8800. case 'ISO_10367-BOX':
  8801. return 'ISO_10367-box';
  8802. case 'CSISO2033':
  8803. case 'E13B':
  8804. case 'ISO-IR-98':
  8805. case 'ISO_2033-1983':
  8806. return 'ISO_2033-1983';
  8807. case 'CSISO5427CYRILLIC':
  8808. case 'ISO-IR-37':
  8809. case 'ISO_5427':
  8810. return 'ISO_5427';
  8811. case 'ISO-IR-54':
  8812. case 'ISO5427CYRILLIC1981':
  8813. case 'ISO_5427:1981':
  8814. return 'ISO_5427:1981';
  8815. case 'CSISO5428GREEK':
  8816. case 'ISO-IR-55':
  8817. case 'ISO_5428:1980':
  8818. return 'ISO_5428:1980';
  8819. case 'CSISO646BASIC1983':
  8820. case 'ISO_646.BASIC:1983':
  8821. case 'REF':
  8822. return 'ISO_646.basic:1983';
  8823. case 'CSISO2INTLREFVERSION':
  8824. case 'IRV':
  8825. case 'ISO-IR-2':
  8826. case 'ISO_646.IRV:1983':
  8827. return 'ISO_646.irv:1983';
  8828. case 'CSISO6937ADD':
  8829. case 'ISO-IR-152':
  8830. case 'ISO_6937-2-25':
  8831. return 'ISO_6937-2-25';
  8832. case 'CSISOTEXTCOMM':
  8833. case 'ISO-IR-142':
  8834. case 'ISO_6937-2-ADD':
  8835. return 'ISO_6937-2-add';
  8836. case 'CSISO8859SUPP':
  8837. case 'ISO-IR-154':
  8838. case 'ISO_8859-SUPP':
  8839. case 'LATIN1-2-5':
  8840. return 'ISO_8859-supp';
  8841. case 'CSISO15ITALIAN':
  8842. case 'ISO-IR-15':
  8843. case 'ISO646-IT':
  8844. case 'IT':
  8845. return 'IT';
  8846. case 'CSISO13JISC6220JP':
  8847. case 'ISO-IR-13':
  8848. case 'JIS_C6220-1969':
  8849. case 'JIS_C6220-1969-JP':
  8850. case 'KATAKANA':
  8851. case 'X0201-7':
  8852. return 'JIS_C6220-1969-jp';
  8853. case 'CSISO14JISC6220RO':
  8854. case 'ISO-IR-14':
  8855. case 'ISO646-JP':
  8856. case 'JIS_C6220-1969-RO':
  8857. case 'JP':
  8858. return 'JIS_C6220-1969-ro';
  8859. case 'CSISO42JISC62261978':
  8860. case 'ISO-IR-42':
  8861. case 'JIS_C6226-1978':
  8862. return 'JIS_C6226-1978';
  8863. case 'CSISO87JISX0208':
  8864. case 'ISO-IR-87':
  8865. case 'JIS_C6226-1983':
  8866. case 'JIS_X0208-1983':
  8867. case 'X0208':
  8868. return 'JIS_C6226-1983';
  8869. case 'CSISO91JISC62291984A':
  8870. case 'ISO-IR-91':
  8871. case 'JIS_C6229-1984-A':
  8872. case 'JP-OCR-A':
  8873. return 'JIS_C6229-1984-a';
  8874. case 'CSISO92JISC62991984B':
  8875. case 'ISO-IR-92':
  8876. case 'ISO646-JP-OCR-B':
  8877. case 'JIS_C6229-1984-B':
  8878. case 'JP-OCR-B':
  8879. return 'JIS_C6229-1984-b';
  8880. case 'CSISO93JIS62291984BADD':
  8881. case 'ISO-IR-93':
  8882. case 'JIS_C6229-1984-B-ADD':
  8883. case 'JP-OCR-B-ADD':
  8884. return 'JIS_C6229-1984-b-add';
  8885. case 'CSISO94JIS62291984HAND':
  8886. case 'ISO-IR-94':
  8887. case 'JIS_C6229-1984-HAND':
  8888. case 'JP-OCR-HAND':
  8889. return 'JIS_C6229-1984-hand';
  8890. case 'CSISO95JIS62291984HANDADD':
  8891. case 'ISO-IR-95':
  8892. case 'JIS_C6229-1984-HAND-ADD':
  8893. case 'JP-OCR-HAND-ADD':
  8894. return 'JIS_C6229-1984-hand-add';
  8895. case 'CSISO96JISC62291984KANA':
  8896. case 'ISO-IR-96':
  8897. case 'JIS_C6229-1984-KANA':
  8898. return 'JIS_C6229-1984-kana';
  8899. case 'CSJISENCODING':
  8900. case 'JIS_ENCODING':
  8901. return 'JIS_Encoding';
  8902. case 'CSHALFWIDTHKATAKANA':
  8903. case 'JIS_X0201':
  8904. case 'X0201':
  8905. return 'JIS_X0201';
  8906. case 'CSISO159JISX02121990':
  8907. case 'ISO-IR-159':
  8908. case 'JIS_X0212-1990':
  8909. case 'X0212':
  8910. return 'JIS_X0212-1990';
  8911. case 'CSISO141JUSIB1002':
  8912. case 'ISO-IR-141':
  8913. case 'ISO646-YU':
  8914. case 'JS':
  8915. case 'JUS_I.B1.002':
  8916. case 'YU':
  8917. return 'JUS_I.B1.002';
  8918. case 'CSISO147MACEDONIAN':
  8919. case 'ISO-IR-147':
  8920. case 'JUS_I.B1.003-MAC':
  8921. case 'MACEDONIAN':
  8922. return 'JUS_I.B1.003-mac';
  8923. case 'CSISO146SERBIAN':
  8924. case 'ISO-IR-146':
  8925. case 'JUS_I.B1.003-SERB':
  8926. case 'SERBIAN':
  8927. return 'JUS_I.B1.003-serb';
  8928. case 'KOI7-SWITCHED':
  8929. return 'KOI7-switched';
  8930. case 'CSKOI8R':
  8931. case 'KOI8-R':
  8932. return 'KOI8-R';
  8933. case 'KOI8-U':
  8934. return 'KOI8-U';
  8935. case 'CSKSC5636':
  8936. case 'ISO646-KR':
  8937. case 'KSC5636':
  8938. return 'KSC5636';
  8939. case 'CSKSC56011987':
  8940. case 'ISO-IR-149':
  8941. case 'KOREAN':
  8942. case 'KSC_5601':
  8943. case 'KS_C_5601-1987':
  8944. case 'KS_C_5601-1989':
  8945. return 'KS_C_5601-1987';
  8946. case 'CSKZ1048':
  8947. case 'KZ-1048':
  8948. case 'RK1048':
  8949. case 'STRK1048-2002':
  8950. return 'KZ-1048';
  8951. case 'CSISO27LATINGREEK1':
  8952. case 'ISO-IR-27':
  8953. case 'LATIN-GREEK-1':
  8954. return 'Latin-greek-1';
  8955. case 'CSMNEM':
  8956. case 'MNEM':
  8957. return 'MNEM';
  8958. case 'CSMNEMONIC':
  8959. case 'MNEMONIC':
  8960. return 'MNEMONIC';
  8961. case 'CSISO86HUNGARIAN':
  8962. case 'HU':
  8963. case 'ISO-IR-86':
  8964. case 'ISO646-HU':
  8965. case 'MSZ_7795.3':
  8966. return 'MSZ_7795.3';
  8967. case 'CSMICROSOFTPUBLISHING':
  8968. case 'MICROSOFT-PUBLISHING':
  8969. return 'Microsoft-Publishing';
  8970. case 'CSNATSDANO':
  8971. case 'ISO-IR-9-1':
  8972. case 'NATS-DANO':
  8973. return 'NATS-DANO';
  8974. case 'CSNATSDANOADD':
  8975. case 'ISO-IR-9-2':
  8976. case 'NATS-DANO-ADD':
  8977. return 'NATS-DANO-ADD';
  8978. case 'CSNATSSEFI':
  8979. case 'ISO-IR-8-1':
  8980. case 'NATS-SEFI':
  8981. return 'NATS-SEFI';
  8982. case 'CSNATSSEFIADD':
  8983. case 'ISO-IR-8-2':
  8984. case 'NATS-SEFI-ADD':
  8985. return 'NATS-SEFI-ADD';
  8986. case 'CSISO151CUBA':
  8987. case 'CUBA':
  8988. case 'ISO-IR-151':
  8989. case 'ISO646-CU':
  8990. case 'NC_NC00-10:81':
  8991. return 'NC_NC00-10:81';
  8992. case 'CSISO69FRENCH':
  8993. case 'FR':
  8994. case 'ISO-IR-69':
  8995. case 'ISO646-FR':
  8996. case 'NF_Z_62-010':
  8997. return 'NF_Z_62-010';
  8998. case 'CSISO25FRENCH':
  8999. case 'ISO-IR-25':
  9000. case 'ISO646-FR1':
  9001. case 'NF_Z_62-010_(1973)':
  9002. return 'NF_Z_62-010_(1973)';
  9003. case 'CSISO60DANISHNORWEGIAN':
  9004. case 'CSISO60NORWEGIAN1':
  9005. case 'ISO-IR-60':
  9006. case 'ISO646-NO':
  9007. case 'NO':
  9008. case 'NS_4551-1':
  9009. return 'NS_4551-1';
  9010. case 'CSISO61NORWEGIAN2':
  9011. case 'ISO-IR-61':
  9012. case 'ISO646-NO2':
  9013. case 'NO2':
  9014. case 'NS_4551-2':
  9015. return 'NS_4551-2';
  9016. case 'OSD_EBCDIC_DF03_IRV':
  9017. return 'OSD_EBCDIC_DF03_IRV';
  9018. case 'OSD_EBCDIC_DF04_1':
  9019. return 'OSD_EBCDIC_DF04_1';
  9020. case 'OSD_EBCDIC_DF04_15':
  9021. return 'OSD_EBCDIC_DF04_15';
  9022. case 'CSPC8DANISHNORWEGIAN':
  9023. case 'PC8-DANISH-NORWEGIAN':
  9024. return 'PC8-Danish-Norwegian';
  9025. case 'CSPC8TURKISH':
  9026. case 'PC8-TURKISH':
  9027. return 'PC8-Turkish';
  9028. case 'CSISO16PORTUGUESE':
  9029. case 'ISO-IR-16':
  9030. case 'ISO646-PT':
  9031. case 'PT':
  9032. return 'PT';
  9033. case 'CSISO84PORTUGUESE2':
  9034. case 'ISO-IR-84':
  9035. case 'ISO646-PT2':
  9036. case 'PT2':
  9037. return 'PT2';
  9038. case 'CP154':
  9039. case 'CSPTCP154':
  9040. case 'CYRILLIC-ASIAN':
  9041. case 'PT154':
  9042. case 'PTCP154':
  9043. return 'PTCP154';
  9044. case 'SCSU':
  9045. return 'SCSU';
  9046. case 'CSISO10SWEDISH':
  9047. case 'FI':
  9048. case 'ISO-IR-10':
  9049. case 'ISO646-FI':
  9050. case 'ISO646-SE':
  9051. case 'SE':
  9052. case 'SEN_850200_B':
  9053. return 'SEN_850200_B';
  9054. case 'CSISO11SWEDISHFORNAMES':
  9055. case 'ISO-IR-11':
  9056. case 'ISO646-SE2':
  9057. case 'SE2':
  9058. case 'SEN_850200_C':
  9059. return 'SEN_850200_C';
  9060. case 'CSSHIFTJIS':
  9061. case 'MS_KANJI':
  9062. case 'SHIFT_JIS':
  9063. return 'Shift_JIS';
  9064. case 'CSISO128T101G2':
  9065. case 'ISO-IR-128':
  9066. case 'T.101-G2':
  9067. return 'T.101-G2';
  9068. case 'CSISO102T617BIT':
  9069. case 'ISO-IR-102':
  9070. case 'T.61-7BIT':
  9071. return 'T.61-7bit';
  9072. case 'CSISO103T618BIT':
  9073. case 'ISO-IR-103':
  9074. case 'T.61':
  9075. case 'T.61-8BIT':
  9076. return 'T.61-8bit';
  9077. case 'CSTSCII':
  9078. case 'TSCII':
  9079. return 'TSCII';
  9080. case 'CSUNICODE11':
  9081. case 'UNICODE-1-1':
  9082. return 'UNICODE-1-1';
  9083. case 'CSUNICODE11UTF7':
  9084. case 'UNICODE-1-1-UTF-7':
  9085. return 'UNICODE-1-1-UTF-7';
  9086. case 'CSUNKNOWN8BIT':
  9087. case 'UNKNOWN-8BIT':
  9088. return 'UNKNOWN-8BIT';
  9089. case 'ANSI':
  9090. case 'ANSI_X3.4-1968':
  9091. case 'ANSI_X3.4-1986':
  9092. case 'ASCII':
  9093. case 'CP367':
  9094. case 'CSASCII':
  9095. case 'IBM367':
  9096. case 'ISO-IR-6':
  9097. case 'ISO646-US':
  9098. case 'ISO_646.IRV:1991':
  9099. case 'US':
  9100. case 'US-ASCII':
  9101. return 'US-ASCII';
  9102. case 'UTF-16':
  9103. return 'UTF-16';
  9104. case 'UTF-16BE':
  9105. return 'UTF-16BE';
  9106. case 'UTF-16LE':
  9107. return 'UTF-16LE';
  9108. case 'UTF-32':
  9109. return 'UTF-32';
  9110. case 'UTF-32BE':
  9111. return 'UTF-32BE';
  9112. case 'UTF-32LE':
  9113. return 'UTF-32LE';
  9114. case 'UTF-7':
  9115. return 'UTF-7';
  9116. case 'UTF-8':
  9117. return 'UTF-8';
  9118. case 'CSVIQR':
  9119. case 'VIQR':
  9120. return 'VIQR';
  9121. case 'CSVISCII':
  9122. case 'VISCII':
  9123. return 'VISCII';
  9124. case 'CSVENTURAINTERNATIONAL':
  9125. case 'VENTURA-INTERNATIONAL':
  9126. return 'Ventura-International';
  9127. case 'CSVENTURAMATH':
  9128. case 'VENTURA-MATH':
  9129. return 'Ventura-Math';
  9130. case 'CSVENTURAUS':
  9131. case 'VENTURA-US':
  9132. return 'Ventura-US';
  9133. case 'CSWINDOWS31J':
  9134. case 'WINDOWS-31J':
  9135. return 'Windows-31J';
  9136. case 'CSDKUS':
  9137. case 'DK-US':
  9138. return 'dk-us';
  9139. case 'CSISO150':
  9140. case 'CSISO150GREEKCCITT':
  9141. case 'GREEK-CCITT':
  9142. case 'ISO-IR-150':
  9143. return 'greek-ccitt';
  9144. case 'CSISO88GREEK7':
  9145. case 'GREEK7':
  9146. case 'ISO-IR-88':
  9147. return 'greek7';
  9148. case 'CSISO18GREEK7OLD':
  9149. case 'GREEK7-OLD':
  9150. case 'ISO-IR-18':
  9151. return 'greek7-old';
  9152. case 'CSHPROMAN8':
  9153. case 'HP-ROMAN8':
  9154. case 'R8':
  9155. case 'ROMAN8':
  9156. return 'hp-roman8';
  9157. case 'CSISO90':
  9158. case 'ISO-IR-90':
  9159. return 'iso-ir-90';
  9160. case 'CSISO19LATINGREEK':
  9161. case 'ISO-IR-19':
  9162. case 'LATIN-GREEK':
  9163. return 'latin-greek';
  9164. case 'CSISO158LAP':
  9165. case 'ISO-IR-158':
  9166. case 'LAP':
  9167. case 'LATIN-LAP':
  9168. return 'latin-lap';
  9169. case 'CSMACINTOSH':
  9170. case 'MAC':
  9171. case 'MACINTOSH':
  9172. return 'macintosh';
  9173. case 'CSUSDK':
  9174. case 'US-DK':
  9175. return 'us-dk';
  9176. case 'CSISO70VIDEOTEXSUPP1':
  9177. case 'ISO-IR-70':
  9178. case 'VIDEOTEX-SUPPL':
  9179. return 'videotex-suppl';
  9180. case 'WINDOWS-1250':
  9181. return 'windows-1250';
  9182. case 'WINDOWS-1251':
  9183. return 'windows-1251';
  9184. case 'CP819':
  9185. case 'CSISOLATIN1':
  9186. case 'IBM819':
  9187. case 'ISO-8859-1':
  9188. case 'ISO-IR-100':
  9189. case 'ISO_8859-1':
  9190. case 'ISO_8859-1:1987':
  9191. case 'L1':
  9192. case 'LATIN1':
  9193. case 'WINDOWS-1252':
  9194. return 'windows-1252';
  9195. case 'WINDOWS-1253':
  9196. return 'windows-1253';
  9197. case 'WINDOWS-1254':
  9198. return 'windows-1254';
  9199. case 'WINDOWS-1255':
  9200. return 'windows-1255';
  9201. case 'WINDOWS-1256':
  9202. return 'windows-1256';
  9203. case 'WINDOWS-1257':
  9204. return 'windows-1257';
  9205. case 'WINDOWS-1258':
  9206. return 'windows-1258';
  9207. default:
  9208. return $encoding;
  9209. }
  9210. }
  9211. function get_curl_version()
  9212. {
  9213. if (is_array($curl = curl_version()))
  9214. {
  9215. $curl = $curl['version'];
  9216. }
  9217. elseif (substr($curl, 0, 5) == 'curl/')
  9218. {
  9219. $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
  9220. }
  9221. elseif (substr($curl, 0, 8) == 'libcurl/')
  9222. {
  9223. $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
  9224. }
  9225. else
  9226. {
  9227. $curl = 0;
  9228. }
  9229. return $curl;
  9230. }
  9231. function is_subclass_of($class1, $class2)
  9232. {
  9233. if (func_num_args() != 2)
  9234. {
  9235. trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
  9236. }
  9237. elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
  9238. {
  9239. return is_subclass_of($class1, $class2);
  9240. }
  9241. elseif (is_string($class1) && is_string($class2))
  9242. {
  9243. if (class_exists($class1))
  9244. {
  9245. if (class_exists($class2))
  9246. {
  9247. $class2 = strtolower($class2);
  9248. while ($class1 = strtolower(get_parent_class($class1)))
  9249. {
  9250. if ($class1 == $class2)
  9251. {
  9252. return true;
  9253. }
  9254. }
  9255. }
  9256. }
  9257. else
  9258. {
  9259. trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
  9260. }
  9261. }
  9262. return false;
  9263. }
  9264. /**
  9265. * Strip HTML comments
  9266. *
  9267. * @access public
  9268. * @param string $data Data to strip comments from
  9269. * @return string Comment stripped string
  9270. */
  9271. function strip_comments($data)
  9272. {
  9273. $output = '';
  9274. while (($start = strpos($data, '<!--')) !== false)
  9275. {
  9276. $output .= substr($data, 0, $start);
  9277. if (($end = strpos($data, '-->', $start)) !== false)
  9278. {
  9279. $data = substr_replace($data, '', 0, $end + 3);
  9280. }
  9281. else
  9282. {
  9283. $data = '';
  9284. }
  9285. }
  9286. return $output . $data;
  9287. }
  9288. function parse_date($dt)
  9289. {
  9290. $parser = SimplePie_Parse_Date::get();
  9291. return $parser->parse($dt);
  9292. }
  9293. /**
  9294. * Decode HTML entities
  9295. *
  9296. * @static
  9297. * @access public
  9298. * @param string $data Input data
  9299. * @return string Output data
  9300. */
  9301. function entities_decode($data)
  9302. {
  9303. $decoder = new SimplePie_Decode_HTML_Entities($data);
  9304. return $decoder->parse();
  9305. }
  9306. /**
  9307. * Remove RFC822 comments
  9308. *
  9309. * @access public
  9310. * @param string $data Data to strip comments from
  9311. * @return string Comment stripped string
  9312. */
  9313. function uncomment_rfc822($string)
  9314. {
  9315. $string = (string) $string;
  9316. $position = 0;
  9317. $length = strlen($string);
  9318. $depth = 0;
  9319. $output = '';
  9320. while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
  9321. {
  9322. $output .= substr($string, $position, $pos - $position);
  9323. $position = $pos + 1;
  9324. if ($string[$pos - 1] !== '\\')
  9325. {
  9326. $depth++;
  9327. while ($depth && $position < $length)
  9328. {
  9329. $position += strcspn($string, '()', $position);
  9330. if ($string[$position - 1] === '\\')
  9331. {
  9332. $position++;
  9333. continue;
  9334. }
  9335. elseif (isset($string[$position]))
  9336. {
  9337. switch ($string[$position])
  9338. {
  9339. case '(':
  9340. $depth++;
  9341. break;
  9342. case ')':
  9343. $depth--;
  9344. break;
  9345. }
  9346. $position++;
  9347. }
  9348. else
  9349. {
  9350. break;
  9351. }
  9352. }
  9353. }
  9354. else
  9355. {
  9356. $output .= '(';
  9357. }
  9358. }
  9359. $output .= substr($string, $position);
  9360. return $output;
  9361. }
  9362. function parse_mime($mime)
  9363. {
  9364. if (($pos = strpos($mime, ';')) === false)
  9365. {
  9366. return trim($mime);
  9367. }
  9368. else
  9369. {
  9370. return trim(substr($mime, 0, $pos));
  9371. }
  9372. }
  9373. function htmlspecialchars_decode($string, $quote_style)
  9374. {
  9375. if (function_exists('htmlspecialchars_decode'))
  9376. {
  9377. return htmlspecialchars_decode($string, $quote_style);
  9378. }
  9379. else
  9380. {
  9381. return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
  9382. }
  9383. }
  9384. function atom_03_construct_type($attribs)
  9385. {
  9386. if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
  9387. {
  9388. $mode = SIMPLEPIE_CONSTRUCT_BASE64;
  9389. }
  9390. else
  9391. {
  9392. $mode = SIMPLEPIE_CONSTRUCT_NONE;
  9393. }
  9394. if (isset($attribs['']['type']))
  9395. {
  9396. switch (strtolower(trim($attribs['']['type'])))
  9397. {
  9398. case 'text':
  9399. case 'text/plain':
  9400. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  9401. case 'html':
  9402. case 'text/html':
  9403. return SIMPLEPIE_CONSTRUCT_HTML | $mode;
  9404. case 'xhtml':
  9405. case 'application/xhtml+xml':
  9406. return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
  9407. default:
  9408. return SIMPLEPIE_CONSTRUCT_NONE | $mode;
  9409. }
  9410. }
  9411. else
  9412. {
  9413. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  9414. }
  9415. }
  9416. function atom_10_construct_type($attribs)
  9417. {
  9418. if (isset($attribs['']['type']))
  9419. {
  9420. switch (strtolower(trim($attribs['']['type'])))
  9421. {
  9422. case 'text':
  9423. return SIMPLEPIE_CONSTRUCT_TEXT;
  9424. case 'html':
  9425. return SIMPLEPIE_CONSTRUCT_HTML;
  9426. case 'xhtml':
  9427. return SIMPLEPIE_CONSTRUCT_XHTML;
  9428. default:
  9429. return SIMPLEPIE_CONSTRUCT_NONE;
  9430. }
  9431. }
  9432. return SIMPLEPIE_CONSTRUCT_TEXT;
  9433. }
  9434. function atom_10_content_construct_type($attribs)
  9435. {
  9436. if (isset($attribs['']['type']))
  9437. {
  9438. $type = strtolower(trim($attribs['']['type']));
  9439. switch ($type)
  9440. {
  9441. case 'text':
  9442. return SIMPLEPIE_CONSTRUCT_TEXT;
  9443. case 'html':
  9444. return SIMPLEPIE_CONSTRUCT_HTML;
  9445. case 'xhtml':
  9446. return SIMPLEPIE_CONSTRUCT_XHTML;
  9447. }
  9448. if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
  9449. {
  9450. return SIMPLEPIE_CONSTRUCT_NONE;
  9451. }
  9452. else
  9453. {
  9454. return SIMPLEPIE_CONSTRUCT_BASE64;
  9455. }
  9456. }
  9457. else
  9458. {
  9459. return SIMPLEPIE_CONSTRUCT_TEXT;
  9460. }
  9461. }
  9462. function is_isegment_nz_nc($string)
  9463. {
  9464. 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);
  9465. }
  9466. function space_seperated_tokens($string)
  9467. {
  9468. $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
  9469. $string_length = strlen($string);
  9470. $position = strspn($string, $space_characters);
  9471. $tokens = array();
  9472. while ($position < $string_length)
  9473. {
  9474. $len = strcspn($string, $space_characters, $position);
  9475. $tokens[] = substr($string, $position, $len);
  9476. $position += $len;
  9477. $position += strspn($string, $space_characters, $position);
  9478. }
  9479. return $tokens;
  9480. }
  9481. function array_unique($array)
  9482. {
  9483. if (version_compare(PHP_VERSION, '5.2', '>='))
  9484. {
  9485. return array_unique($array);
  9486. }
  9487. else
  9488. {
  9489. $array = (array) $array;
  9490. $new_array = array();
  9491. $new_array_strings = array();
  9492. foreach ($array as $key => $value)
  9493. {
  9494. if (is_object($value))
  9495. {
  9496. if (method_exists($value, '__toString'))
  9497. {
  9498. $cmp = $value->__toString();
  9499. }
  9500. else
  9501. {
  9502. trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
  9503. }
  9504. }
  9505. elseif (is_array($value))
  9506. {
  9507. $cmp = (string) reset($value);
  9508. }
  9509. else
  9510. {
  9511. $cmp = (string) $value;
  9512. }
  9513. if (!in_array($cmp, $new_array_strings))
  9514. {
  9515. $new_array[$key] = $value;
  9516. $new_array_strings[] = $cmp;
  9517. }
  9518. }
  9519. return $new_array;
  9520. }
  9521. }
  9522. /**
  9523. * Converts a unicode codepoint to a UTF-8 character
  9524. *
  9525. * @static
  9526. * @access public
  9527. * @param int $codepoint Unicode codepoint
  9528. * @return string UTF-8 character
  9529. */
  9530. function codepoint_to_utf8($codepoint)
  9531. {
  9532. static $cache = array();
  9533. $codepoint = (int) $codepoint;
  9534. if (isset($cache[$codepoint]))
  9535. {
  9536. return $cache[$codepoint];
  9537. }
  9538. elseif ($codepoint < 0)
  9539. {
  9540. return $cache[$codepoint] = false;
  9541. }
  9542. else if ($codepoint <= 0x7f)
  9543. {
  9544. return $cache[$codepoint] = chr($codepoint);
  9545. }
  9546. else if ($codepoint <= 0x7ff)
  9547. {
  9548. return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
  9549. }
  9550. else if ($codepoint <= 0xffff)
  9551. {
  9552. return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  9553. }
  9554. else if ($codepoint <= 0x10ffff)
  9555. {
  9556. return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  9557. }
  9558. else
  9559. {
  9560. // U+FFFD REPLACEMENT CHARACTER
  9561. return $cache[$codepoint] = "\xEF\xBF\xBD";
  9562. }
  9563. }
  9564. /**
  9565. * Re-implementation of PHP 5's stripos()
  9566. *
  9567. * Returns the numeric position of the first occurrence of needle in the
  9568. * haystack string.
  9569. *
  9570. * @static
  9571. * @access string
  9572. * @param object $haystack
  9573. * @param string $needle Note that the needle may be a string of one or more
  9574. * characters. If needle is not a string, it is converted to an integer
  9575. * and applied as the ordinal value of a character.
  9576. * @param int $offset The optional offset parameter allows you to specify which
  9577. * character in haystack to start searching. The position returned is still
  9578. * relative to the beginning of haystack.
  9579. * @return bool If needle is not found, stripos() will return boolean false.
  9580. */
  9581. function stripos($haystack, $needle, $offset = 0)
  9582. {
  9583. if (function_exists('stripos'))
  9584. {
  9585. return stripos($haystack, $needle, $offset);
  9586. }
  9587. else
  9588. {
  9589. if (is_string($needle))
  9590. {
  9591. $needle = strtolower($needle);
  9592. }
  9593. elseif (is_int($needle) || is_bool($needle) || is_double($needle))
  9594. {
  9595. $needle = strtolower(chr($needle));
  9596. }
  9597. else
  9598. {
  9599. trigger_error('needle is not a string or an integer', E_USER_WARNING);
  9600. return false;
  9601. }
  9602. return strpos(strtolower($haystack), $needle, $offset);
  9603. }
  9604. }
  9605. /**
  9606. * Similar to parse_str()
  9607. *
  9608. * Returns an associative array of name/value pairs, where the value is an
  9609. * array of values that have used the same name
  9610. *
  9611. * @static
  9612. * @access string
  9613. * @param string $str The input string.
  9614. * @return array
  9615. */
  9616. function parse_str($str)
  9617. {
  9618. $return = array();
  9619. $str = explode('&', $str);
  9620. foreach ($str as $section)
  9621. {
  9622. if (strpos($section, '=') !== false)
  9623. {
  9624. list($name, $value) = explode('=', $section, 2);
  9625. $return[urldecode($name)][] = urldecode($value);
  9626. }
  9627. else
  9628. {
  9629. $return[urldecode($section)][] = null;
  9630. }
  9631. }
  9632. return $return;
  9633. }
  9634. /**
  9635. * Detect XML encoding, as per XML 1.0 Appendix F.1
  9636. *
  9637. * @todo Add support for EBCDIC
  9638. * @param string $data XML data
  9639. * @return array Possible encodings
  9640. */
  9641. function xml_encoding($data)
  9642. {
  9643. // UTF-32 Big Endian BOM
  9644. if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
  9645. {
  9646. $encoding[] = 'UTF-32BE';
  9647. }
  9648. // UTF-32 Little Endian BOM
  9649. elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
  9650. {
  9651. $encoding[] = 'UTF-32LE';
  9652. }
  9653. // UTF-16 Big Endian BOM
  9654. elseif (substr($data, 0, 2) === "\xFE\xFF")
  9655. {
  9656. $encoding[] = 'UTF-16BE';
  9657. }
  9658. // UTF-16 Little Endian BOM
  9659. elseif (substr($data, 0, 2) === "\xFF\xFE")
  9660. {
  9661. $encoding[] = 'UTF-16LE';
  9662. }
  9663. // UTF-8 BOM
  9664. elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
  9665. {
  9666. $encoding[] = 'UTF-8';
  9667. }
  9668. // UTF-32 Big Endian Without BOM
  9669. elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C")
  9670. {
  9671. if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
  9672. {
  9673. $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
  9674. if ($parser->parse())
  9675. {
  9676. $encoding[] = $parser->encoding;
  9677. }
  9678. }
  9679. $encoding[] = 'UTF-32BE';
  9680. }
  9681. // UTF-32 Little Endian Without BOM
  9682. elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00")
  9683. {
  9684. if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
  9685. {
  9686. $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
  9687. if ($parser->parse())
  9688. {
  9689. $encoding[] = $parser->encoding;
  9690. }
  9691. }
  9692. $encoding[] = 'UTF-32LE';
  9693. }
  9694. // UTF-16 Big Endian Without BOM
  9695. elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
  9696. {
  9697. if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
  9698. {
  9699. $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
  9700. if ($parser->parse())
  9701. {
  9702. $encoding[] = $parser->encoding;
  9703. }
  9704. }
  9705. $encoding[] = 'UTF-16BE';
  9706. }
  9707. // UTF-16 Little Endian Without BOM
  9708. elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
  9709. {
  9710. if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
  9711. {
  9712. $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
  9713. if ($parser->parse())
  9714. {
  9715. $encoding[] = $parser->encoding;
  9716. }
  9717. }
  9718. $encoding[] = 'UTF-16LE';
  9719. }
  9720. // US-ASCII (or superset)
  9721. elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
  9722. {
  9723. if ($pos = strpos($data, "\x3F\x3E"))
  9724. {
  9725. $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
  9726. if ($parser->parse())
  9727. {
  9728. $encoding[] = $parser->encoding;
  9729. }
  9730. }
  9731. $encoding[] = 'UTF-8';
  9732. }
  9733. // Fallback to UTF-8
  9734. else
  9735. {
  9736. $encoding[] = 'UTF-8';
  9737. }
  9738. return $encoding;
  9739. }
  9740. }
  9741. /**
  9742. * Decode HTML Entities
  9743. *
  9744. * This implements HTML5 as of revision 967 (2007-06-28)
  9745. *
  9746. * @package SimplePie
  9747. */
  9748. class SimplePie_Decode_HTML_Entities
  9749. {
  9750. /**
  9751. * Data to be parsed
  9752. *
  9753. * @access private
  9754. * @var string
  9755. */
  9756. var $data = '';
  9757. /**
  9758. * Currently consumed bytes
  9759. *
  9760. * @access private
  9761. * @var string
  9762. */
  9763. var $consumed = '';
  9764. /**
  9765. * Position of the current byte being parsed
  9766. *
  9767. * @access private
  9768. * @var int
  9769. */
  9770. var $position = 0;
  9771. /**
  9772. * Create an instance of the class with the input data
  9773. *
  9774. * @access public
  9775. * @param string $data Input data
  9776. */
  9777. function SimplePie_Decode_HTML_Entities($data)
  9778. {
  9779. $this->data = $data;
  9780. }
  9781. /**
  9782. * Parse the input data
  9783. *
  9784. * @access public
  9785. * @return string Output data
  9786. */
  9787. function parse()
  9788. {
  9789. while (($this->position = strpos($this->data, '&', $this->position)) !== false)
  9790. {
  9791. $this->consume();
  9792. $this->entity();
  9793. $this->consumed = '';
  9794. }
  9795. return $this->data;
  9796. }
  9797. /**
  9798. * Consume the next byte
  9799. *
  9800. * @access private
  9801. * @return mixed The next byte, or false, if there is no more data
  9802. */
  9803. function consume()
  9804. {
  9805. if (isset($this->data[$this->position]))
  9806. {
  9807. $this->consumed .= $this->data[$this->position];
  9808. return $this->data[$this->position++];
  9809. }
  9810. else
  9811. {
  9812. $this->consumed = false;
  9813. return false;
  9814. }
  9815. }
  9816. /**
  9817. * Consume a range of characters
  9818. *
  9819. * @access private
  9820. * @param string $chars Characters to consume
  9821. * @return mixed A series of characters that match the range, or false
  9822. */
  9823. function consume_range($chars)
  9824. {
  9825. if ($len = strspn($this->data, $chars, $this->position))
  9826. {
  9827. $data = substr($this->data, $this->position, $len);
  9828. $this->consumed .= $data;
  9829. $this->position += $len;
  9830. return $data;
  9831. }
  9832. else
  9833. {
  9834. $this->consumed = false;
  9835. return false;
  9836. }
  9837. }
  9838. /**
  9839. * Unconsume one byte
  9840. *
  9841. * @access private
  9842. */
  9843. function unconsume()
  9844. {
  9845. $this->consumed = substr($this->consumed, 0, -1);
  9846. $this->position--;
  9847. }
  9848. /**
  9849. * Decode an entity
  9850. *
  9851. * @access private
  9852. */
  9853. function entity()
  9854. {
  9855. switch ($this->consume())
  9856. {
  9857. case "\x09":
  9858. case "\x0A":
  9859. case "\x0B":
  9860. case "\x0B":
  9861. case "\x0C":
  9862. case "\x20":
  9863. case "\x3C":
  9864. case "\x26":
  9865. case false:
  9866. break;
  9867. case "\x23":
  9868. switch ($this->consume())
  9869. {
  9870. case "\x78":
  9871. case "\x58":
  9872. $range = '0123456789ABCDEFabcdef';
  9873. $hex = true;
  9874. break;
  9875. default:
  9876. $range = '0123456789';
  9877. $hex = false;
  9878. $this->unconsume();
  9879. break;
  9880. }
  9881. if ($codepoint = $this->consume_range($range))
  9882. {
  9883. static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8");
  9884. if ($hex)
  9885. {
  9886. $codepoint = hexdec($codepoint);
  9887. }
  9888. else
  9889. {
  9890. $codepoint = intval($codepoint);
  9891. }
  9892. if (isset($windows_1252_specials[$codepoint]))
  9893. {
  9894. $replacement = $windows_1252_specials[$codepoint];
  9895. }
  9896. else
  9897. {
  9898. $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
  9899. }
  9900. if ($this->consume() != ';')
  9901. {
  9902. $this->unconsume();
  9903. }
  9904. $consumed_length = strlen($this->consumed);
  9905. $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
  9906. $this->position += strlen($replacement) - $consumed_length;
  9907. }
  9908. break;
  9909. default:
  9910. static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C");
  9911. for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
  9912. {
  9913. $consumed = substr($this->consumed, 1);
  9914. if (isset($entities[$consumed]))
  9915. {
  9916. $match = $consumed;
  9917. }
  9918. }
  9919. if ($match !== null)
  9920. {
  9921. $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
  9922. $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
  9923. }
  9924. break;
  9925. }
  9926. }
  9927. }
  9928. /**
  9929. * Date Parser
  9930. *
  9931. * @package SimplePie
  9932. */
  9933. class SimplePie_Parse_Date
  9934. {
  9935. /**
  9936. * Input data
  9937. *
  9938. * @access protected
  9939. * @var string
  9940. */
  9941. var $date;
  9942. /**
  9943. * List of days, calendar day name => ordinal day number in the week
  9944. *
  9945. * @access protected
  9946. * @var array
  9947. */
  9948. var $day = array(
  9949. // English
  9950. 'mon' => 1,
  9951. 'monday' => 1,
  9952. 'tue' => 2,
  9953. 'tuesday' => 2,
  9954. 'wed' => 3,
  9955. 'wednesday' => 3,
  9956. 'thu' => 4,
  9957. 'thursday' => 4,
  9958. 'fri' => 5,
  9959. 'friday' => 5,
  9960. 'sat' => 6,
  9961. 'saturday' => 6,
  9962. 'sun' => 7,
  9963. 'sunday' => 7,
  9964. // Dutch
  9965. 'maandag' => 1,
  9966. 'dinsdag' => 2,
  9967. 'woensdag' => 3,
  9968. 'donderdag' => 4,
  9969. 'vrijdag' => 5,
  9970. 'zaterdag' => 6,
  9971. 'zondag' => 7,
  9972. // French
  9973. 'lundi' => 1,
  9974. 'mardi' => 2,
  9975. 'mercredi' => 3,
  9976. 'jeudi' => 4,
  9977. 'vendredi' => 5,
  9978. 'samedi' => 6,
  9979. 'dimanche' => 7,
  9980. // German
  9981. 'montag' => 1,
  9982. 'dienstag' => 2,
  9983. 'mittwoch' => 3,
  9984. 'donnerstag' => 4,
  9985. 'freitag' => 5,
  9986. 'samstag' => 6,
  9987. 'sonnabend' => 6,
  9988. 'sonntag' => 7,
  9989. // Italian
  9990. 'lunedì' => 1,
  9991. 'martedì' => 2,
  9992. 'mercoledì' => 3,
  9993. 'giovedì' => 4,
  9994. 'venerdì' => 5,
  9995. 'sabato' => 6,
  9996. 'domenica' => 7,
  9997. // Spanish
  9998. 'lunes' => 1,
  9999. 'martes' => 2,
  10000. 'miércoles' => 3,
  10001. 'jueves' => 4,
  10002. 'viernes' => 5,
  10003. 'sábado' => 6,
  10004. 'domingo' => 7,
  10005. // Finnish
  10006. 'maanantai' => 1,
  10007. 'tiistai' => 2,
  10008. 'keskiviikko' => 3,
  10009. 'torstai' => 4,
  10010. 'perjantai' => 5,
  10011. 'lauantai' => 6,
  10012. 'sunnuntai' => 7,
  10013. // Hungarian
  10014. 'hétfő' => 1,
  10015. 'kedd' => 2,
  10016. 'szerda' => 3,
  10017. 'csütörtok' => 4,
  10018. 'péntek' => 5,
  10019. 'szombat' => 6,
  10020. 'vasárnap' => 7,
  10021. // Greek
  10022. 'Δευ' => 1,
  10023. 'Τρι' => 2,
  10024. 'Τετ' => 3,
  10025. 'Πεμ' => 4,
  10026. 'Παρ' => 5,
  10027. 'Σαβ' => 6,
  10028. 'Κυρ' => 7,
  10029. );
  10030. /**
  10031. * List of months, calendar month name => calendar month number
  10032. *
  10033. * @access protected
  10034. * @var array
  10035. */
  10036. var $month = array(
  10037. // English
  10038. 'jan' => 1,
  10039. 'january' => 1,
  10040. 'feb' => 2,
  10041. 'february' => 2,
  10042. 'mar' => 3,
  10043. 'march' => 3,
  10044. 'apr' => 4,
  10045. 'april' => 4,
  10046. 'may' => 5,
  10047. // No long form of May
  10048. 'jun' => 6,
  10049. 'june' => 6,
  10050. 'jul' => 7,
  10051. 'july' => 7,
  10052. 'aug' => 8,
  10053. 'august' => 8,
  10054. 'sep' => 9,
  10055. 'september' => 8,
  10056. 'oct' => 10,
  10057. 'october' => 10,
  10058. 'nov' => 11,
  10059. 'november' => 11,
  10060. 'dec' => 12,
  10061. 'december' => 12,
  10062. // Dutch
  10063. 'januari' => 1,
  10064. 'februari' => 2,
  10065. 'maart' => 3,
  10066. 'april' => 4,
  10067. 'mei' => 5,
  10068. 'juni' => 6,
  10069. 'juli' => 7,
  10070. 'augustus' => 8,
  10071. 'september' => 9,
  10072. 'oktober' => 10,
  10073. 'november' => 11,
  10074. 'december' => 12,
  10075. // French
  10076. 'janvier' => 1,
  10077. 'février' => 2,
  10078. 'mars' => 3,
  10079. 'avril' => 4,
  10080. 'mai' => 5,
  10081. 'juin' => 6,
  10082. 'juillet' => 7,
  10083. 'août' => 8,
  10084. 'septembre' => 9,
  10085. 'octobre' => 10,
  10086. 'novembre' => 11,
  10087. 'décembre' => 12,
  10088. // German
  10089. 'januar' => 1,
  10090. 'februar' => 2,
  10091. 'märz' => 3,
  10092. 'april' => 4,
  10093. 'mai' => 5,
  10094. 'juni' => 6,
  10095. 'juli' => 7,
  10096. 'august' => 8,
  10097. 'september' => 9,
  10098. 'oktober' => 10,
  10099. 'november' => 11,
  10100. 'dezember' => 12,
  10101. // Italian
  10102. 'gennaio' => 1,
  10103. 'febbraio' => 2,
  10104. 'marzo' => 3,
  10105. 'aprile' => 4,
  10106. 'maggio' => 5,
  10107. 'giugno' => 6,
  10108. 'luglio' => 7,
  10109. 'agosto' => 8,
  10110. 'settembre' => 9,
  10111. 'ottobre' => 10,
  10112. 'novembre' => 11,
  10113. 'dicembre' => 12,
  10114. // Spanish
  10115. 'enero' => 1,
  10116. 'febrero' => 2,
  10117. 'marzo' => 3,
  10118. 'abril' => 4,
  10119. 'mayo' => 5,
  10120. 'junio' => 6,
  10121. 'julio' => 7,
  10122. 'agosto' => 8,
  10123. 'septiembre' => 9,
  10124. 'setiembre' => 9,
  10125. 'octubre' => 10,
  10126. 'noviembre' => 11,
  10127. 'diciembre' => 12,
  10128. // Finnish
  10129. 'tammikuu' => 1,
  10130. 'helmikuu' => 2,
  10131. 'maaliskuu' => 3,
  10132. 'huhtikuu' => 4,
  10133. 'toukokuu' => 5,
  10134. 'kesäkuu' => 6,
  10135. 'heinäkuu' => 7,
  10136. 'elokuu' => 8,
  10137. 'suuskuu' => 9,
  10138. 'lokakuu' => 10,
  10139. 'marras' => 11,
  10140. 'joulukuu' => 12,
  10141. // Hungarian
  10142. 'január' => 1,
  10143. 'február' => 2,
  10144. 'március' => 3,
  10145. 'április' => 4,
  10146. 'május' => 5,
  10147. 'június' => 6,
  10148. 'július' => 7,
  10149. 'augusztus' => 8,
  10150. 'szeptember' => 9,
  10151. 'október' => 10,
  10152. 'november' => 11,
  10153. 'december' => 12,
  10154. // Greek
  10155. 'Ιαν' => 1,
  10156. 'Φεβ' => 2,
  10157. 'Μάώ' => 3,
  10158. 'Μαώ' => 3,
  10159. 'Απρ' => 4,
  10160. 'Μάι' => 5,
  10161. 'Μαϊ' => 5,
  10162. 'Μαι' => 5,
  10163. 'Ιούν' => 6,
  10164. 'Ιον' => 6,
  10165. 'Ιούλ' => 7,
  10166. 'Ιολ' => 7,
  10167. 'Αύγ' => 8,
  10168. 'Αυγ' => 8,
  10169. 'Σεπ' => 9,
  10170. 'Οκτ' => 10,
  10171. 'Νοέ' => 11,
  10172. 'Δεκ' => 12,
  10173. );
  10174. /**
  10175. * List of timezones, abbreviation => offset from UTC
  10176. *
  10177. * @access protected
  10178. * @var array
  10179. */
  10180. var $timezone = array(
  10181. 'ACDT' => 37800,
  10182. 'ACIT' => 28800,
  10183. 'ACST' => 34200,
  10184. 'ACT' => -18000,
  10185. 'ACWDT' => 35100,
  10186. 'ACWST' => 31500,
  10187. 'AEDT' => 39600,
  10188. 'AEST' => 36000,
  10189. 'AFT' => 16200,
  10190. 'AKDT' => -28800,
  10191. 'AKST' => -32400,
  10192. 'AMDT' => 18000,
  10193. 'AMT' => -14400,
  10194. 'ANAST' => 46800,
  10195. 'ANAT' => 43200,
  10196. 'ART' => -10800,
  10197. 'AZOST' => -3600,
  10198. 'AZST' => 18000,
  10199. 'AZT' => 14400,
  10200. 'BIOT' => 21600,
  10201. 'BIT' => -43200,
  10202. 'BOT' => -14400,
  10203. 'BRST' => -7200,
  10204. 'BRT' => -10800,
  10205. 'BST' => 3600,
  10206. 'BTT' => 21600,
  10207. 'CAST' => 18000,
  10208. 'CAT' => 7200,
  10209. 'CCT' => 23400,
  10210. 'CDT' => -18000,
  10211. 'CEDT' => 7200,
  10212. 'CET' => 3600,
  10213. 'CGST' => -7200,
  10214. 'CGT' => -10800,
  10215. 'CHADT' => 49500,
  10216. 'CHAST' => 45900,
  10217. 'CIST' => -28800,
  10218. 'CKT' => -36000,
  10219. 'CLDT' => -10800,
  10220. 'CLST' => -14400,
  10221. 'COT' => -18000,
  10222. 'CST' => -21600,
  10223. 'CVT' => -3600,
  10224. 'CXT' => 25200,
  10225. 'DAVT' => 25200,
  10226. 'DTAT' => 36000,
  10227. 'EADT' => -18000,
  10228. 'EAST' => -21600,
  10229. 'EAT' => 10800,
  10230. 'ECT' => -18000,
  10231. 'EDT' => -14400,
  10232. 'EEST' => 10800,
  10233. 'EET' => 7200,
  10234. 'EGT' => -3600,
  10235. 'EKST' => 21600,
  10236. 'EST' => -18000,
  10237. 'FJT' => 43200,
  10238. 'FKDT' => -10800,
  10239. 'FKST' => -14400,
  10240. 'FNT' => -7200,
  10241. 'GALT' => -21600,
  10242. 'GEDT' => 14400,
  10243. 'GEST' => 10800,
  10244. 'GFT' => -10800,
  10245. 'GILT' => 43200,
  10246. 'GIT' => -32400,
  10247. 'GST' => 14400,
  10248. 'GST' => -7200,
  10249. 'GYT' => -14400,
  10250. 'HAA' => -10800,
  10251. 'HAC' => -18000,
  10252. 'HADT' => -32400,
  10253. 'HAE' => -14400,
  10254. 'HAP' => -25200,
  10255. 'HAR' => -21600,
  10256. 'HAST' => -36000,
  10257. 'HAT' => -9000,
  10258. 'HAY' => -28800,
  10259. 'HKST' => 28800,
  10260. 'HMT' => 18000,
  10261. 'HNA' => -14400,
  10262. 'HNC' => -21600,
  10263. 'HNE' => -18000,
  10264. 'HNP' => -28800,
  10265. 'HNR' => -25200,
  10266. 'HNT' => -12600,
  10267. 'HNY' => -32400,
  10268. 'IRDT' => 16200,
  10269. 'IRKST' => 32400,
  10270. 'IRKT' => 28800,
  10271. 'IRST' => 12600,
  10272. 'JFDT' => -10800,
  10273. 'JFST' => -14400,
  10274. 'JST' => 32400,
  10275. 'KGST' => 21600,
  10276. 'KGT' => 18000,
  10277. 'KOST' => 39600,
  10278. 'KOVST' => 28800,
  10279. 'KOVT' => 25200,
  10280. 'KRAST' => 28800,
  10281. 'KRAT' => 25200,
  10282. 'KST' => 32400,
  10283. 'LHDT' => 39600,
  10284. 'LHST' => 37800,
  10285. 'LINT' => 50400,
  10286. 'LKT' => 21600,
  10287. 'MAGST' => 43200,
  10288. 'MAGT' => 39600,
  10289. 'MAWT' => 21600,
  10290. 'MDT' => -21600,
  10291. 'MESZ' => 7200,
  10292. 'MEZ' => 3600,
  10293. 'MHT' => 43200,
  10294. 'MIT' => -34200,
  10295. 'MNST' => 32400,
  10296. 'MSDT' => 14400,
  10297. 'MSST' => 10800,
  10298. 'MST' => -25200,
  10299. 'MUT' => 14400,
  10300. 'MVT' => 18000,
  10301. 'MYT' => 28800,
  10302. 'NCT' => 39600,
  10303. 'NDT' => -9000,
  10304. 'NFT' => 41400,
  10305. 'NMIT' => 36000,
  10306. 'NOVST' => 25200,
  10307. 'NOVT' => 21600,
  10308. 'NPT' => 20700,
  10309. 'NRT' => 43200,
  10310. 'NST' => -12600,
  10311. 'NUT' => -39600,
  10312. 'NZDT' => 46800,
  10313. 'NZST' => 43200,
  10314. 'OMSST' => 25200,
  10315. 'OMST' => 21600,
  10316. 'PDT' => -25200,
  10317. 'PET' => -18000,
  10318. 'PETST' => 46800,
  10319. 'PETT' => 43200,
  10320. 'PGT' => 36000,
  10321. 'PHOT' => 46800,
  10322. 'PHT' => 28800,
  10323. 'PKT' => 18000,
  10324. 'PMDT' => -7200,
  10325. 'PMST' => -10800,
  10326. 'PONT' => 39600,
  10327. 'PST' => -28800,
  10328. 'PWT' => 32400,
  10329. 'PYST' => -10800,
  10330. 'PYT' => -14400,
  10331. 'RET' => 14400,
  10332. 'ROTT' => -10800,
  10333. 'SAMST' => 18000,
  10334. 'SAMT' => 14400,
  10335. 'SAST' => 7200,
  10336. 'SBT' => 39600,
  10337. 'SCDT' => 46800,
  10338. 'SCST' => 43200,
  10339. 'SCT' => 14400,
  10340. 'SEST' => 3600,
  10341. 'SGT' => 28800,
  10342. 'SIT' => 28800,
  10343. 'SRT' => -10800,
  10344. 'SST' => -39600,
  10345. 'SYST' => 10800,
  10346. 'SYT' => 7200,
  10347. 'TFT' => 18000,
  10348. 'THAT' => -36000,
  10349. 'TJT' => 18000,
  10350. 'TKT' => -36000,
  10351. 'TMT' => 18000,
  10352. 'TOT' => 46800,
  10353. 'TPT' => 32400,
  10354. 'TRUT' => 36000,
  10355. 'TVT' => 43200,
  10356. 'TWT' => 28800,
  10357. 'UYST' => -7200,
  10358. 'UYT' => -10800,
  10359. 'UZT' => 18000,
  10360. 'VET' => -14400,
  10361. 'VLAST' => 39600,
  10362. 'VLAT' => 36000,
  10363. 'VOST' => 21600,
  10364. 'VUT' => 39600,
  10365. 'WAST' => 7200,
  10366. 'WAT' => 3600,
  10367. 'WDT' => 32400,
  10368. 'WEST' => 3600,
  10369. 'WFT' => 43200,
  10370. 'WIB' => 25200,
  10371. 'WIT' => 32400,
  10372. 'WITA' => 28800,
  10373. 'WKST' => 18000,
  10374. 'WST' => 28800,
  10375. 'YAKST' => 36000,
  10376. 'YAKT' => 32400,
  10377. 'YAPT' => 36000,
  10378. 'YEKST' => 21600,
  10379. 'YEKT' => 18000,
  10380. );
  10381. /**
  10382. * Cached PCRE for SimplePie_Parse_Date::$day
  10383. *
  10384. * @access protected
  10385. * @var string
  10386. */
  10387. var $day_pcre;
  10388. /**
  10389. * Cached PCRE for SimplePie_Parse_Date::$month
  10390. *
  10391. * @access protected
  10392. * @var string
  10393. */
  10394. var $month_pcre;
  10395. /**
  10396. * Array of user-added callback methods
  10397. *
  10398. * @access private
  10399. * @var array
  10400. */
  10401. var $built_in = array();
  10402. /**
  10403. * Array of user-added callback methods
  10404. *
  10405. * @access private
  10406. * @var array
  10407. */
  10408. var $user = array();
  10409. /**
  10410. * Create new SimplePie_Parse_Date object, and set self::day_pcre,
  10411. * self::month_pcre, and self::built_in
  10412. *
  10413. * @access private
  10414. */
  10415. function SimplePie_Parse_Date()
  10416. {
  10417. $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
  10418. $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
  10419. static $cache;
  10420. if (!isset($cache[get_class($this)]))
  10421. {
  10422. if (extension_loaded('Reflection'))
  10423. {
  10424. $class = new ReflectionClass(get_class($this));
  10425. $methods = $class->getMethods();
  10426. $all_methods = array();
  10427. foreach ($methods as $method)
  10428. {
  10429. $all_methods[] = $method->getName();
  10430. }
  10431. }
  10432. else
  10433. {
  10434. $all_methods = get_class_methods($this);
  10435. }
  10436. foreach ($all_methods as $method)
  10437. {
  10438. if (strtolower(substr($method, 0, 5)) === 'date_')
  10439. {
  10440. $cache[get_class($this)][] = $method;
  10441. }
  10442. }
  10443. }
  10444. foreach ($cache[get_class($this)] as $method)
  10445. {
  10446. $this->built_in[] = $method;
  10447. }
  10448. }
  10449. /**
  10450. * Get the object
  10451. *
  10452. * @access public
  10453. */
  10454. function get()
  10455. {
  10456. static $object;
  10457. if (!$object)
  10458. {
  10459. $object = new SimplePie_Parse_Date;
  10460. }
  10461. return $object;
  10462. }
  10463. /**
  10464. * Parse a date
  10465. *
  10466. * @final
  10467. * @access public
  10468. * @param string $date Date to parse
  10469. * @return int Timestamp corresponding to date string, or false on failure
  10470. */
  10471. function parse($date)
  10472. {
  10473. foreach ($this->user as $method)
  10474. {
  10475. if (($returned = call_user_func($method, $date)) !== false)
  10476. {
  10477. return $returned;
  10478. }
  10479. }
  10480. foreach ($this->built_in as $method)
  10481. {
  10482. if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
  10483. {
  10484. return $returned;
  10485. }
  10486. }
  10487. return false;
  10488. }
  10489. /**
  10490. * Add a callback method to parse a date
  10491. *
  10492. * @final
  10493. * @access public
  10494. * @param callback $callback
  10495. */
  10496. function add_callback($callback)
  10497. {
  10498. if (is_callable($callback))
  10499. {
  10500. $this->user[] = $callback;
  10501. }
  10502. else
  10503. {
  10504. trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
  10505. }
  10506. }
  10507. /**
  10508. * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
  10509. * well as allowing any of upper or lower case "T", horizontal tabs, or
  10510. * spaces to be used as the time seperator (including more than one))
  10511. *
  10512. * @access protected
  10513. * @return int Timestamp
  10514. */
  10515. function date_w3cdtf($date)
  10516. {
  10517. static $pcre;
  10518. if (!$pcre)
  10519. {
  10520. $year = '([0-9]{4})';
  10521. $month = $day = $hour = $minute = $second = '([0-9]{2})';
  10522. $decimal = '([0-9]*)';
  10523. $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
  10524. $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
  10525. }
  10526. if (preg_match($pcre, $date, $match))
  10527. {
  10528. /*
  10529. Capturing subpatterns:
  10530. 1: Year
  10531. 2: Month
  10532. 3: Day
  10533. 4: Hour
  10534. 5: Minute
  10535. 6: Second
  10536. 7: Decimal fraction of a second
  10537. 8: Zulu
  10538. 9: Timezone ±
  10539. 10: Timezone hours
  10540. 11: Timezone minutes
  10541. */
  10542. // Fill in empty matches
  10543. for ($i = count($match); $i <= 3; $i++)
  10544. {
  10545. $match[$i] = '1';
  10546. }
  10547. for ($i = count($match); $i <= 7; $i++)
  10548. {
  10549. $match[$i] = '0';
  10550. }
  10551. // Numeric timezone
  10552. if (isset($match[9]) && $match[9] !== '')
  10553. {
  10554. $timezone = $match[10] * 3600;
  10555. $timezone += $match[11] * 60;
  10556. if ($match[9] === '-')
  10557. {
  10558. $timezone = 0 - $timezone;
  10559. }
  10560. }
  10561. else
  10562. {
  10563. $timezone = 0;
  10564. }
  10565. // Convert the number of seconds to an integer, taking decimals into account
  10566. $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
  10567. return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
  10568. }
  10569. else
  10570. {
  10571. return false;
  10572. }
  10573. }
  10574. /**
  10575. * Remove RFC822 comments
  10576. *
  10577. * @access protected
  10578. * @param string $data Data to strip comments from
  10579. * @return string Comment stripped string
  10580. */
  10581. function remove_rfc2822_comments($string)
  10582. {
  10583. $string = (string) $string;
  10584. $position = 0;
  10585. $length = strlen($string);
  10586. $depth = 0;
  10587. $output = '';
  10588. while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
  10589. {
  10590. $output .= substr($string, $position, $pos - $position);
  10591. $position = $pos + 1;
  10592. if ($string[$pos - 1] !== '\\')
  10593. {
  10594. $depth++;
  10595. while ($depth && $position < $length)
  10596. {
  10597. $position += strcspn($string, '()', $position);
  10598. if ($string[$position - 1] === '\\')
  10599. {
  10600. $position++;
  10601. continue;
  10602. }
  10603. elseif (isset($string[$position]))
  10604. {
  10605. switch ($string[$position])
  10606. {
  10607. case '(':
  10608. $depth++;
  10609. break;
  10610. case ')':
  10611. $depth--;
  10612. break;
  10613. }
  10614. $position++;
  10615. }
  10616. else
  10617. {
  10618. break;
  10619. }
  10620. }
  10621. }
  10622. else
  10623. {
  10624. $output .= '(';
  10625. }
  10626. }
  10627. $output .= substr($string, $position);
  10628. return $output;
  10629. }
  10630. /**
  10631. * Parse RFC2822's date format
  10632. *
  10633. * @access protected
  10634. * @return int Timestamp
  10635. */
  10636. function date_rfc2822($date)
  10637. {
  10638. static $pcre;
  10639. if (!$pcre)
  10640. {
  10641. $wsp = '[\x09\x20]';
  10642. $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
  10643. $optional_fws = $fws . '?';
  10644. $day_name = $this->day_pcre;
  10645. $month = $this->month_pcre;
  10646. $day = '([0-9]{1,2})';
  10647. $hour = $minute = $second = '([0-9]{2})';
  10648. $year = '([0-9]{2,4})';
  10649. $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
  10650. $character_zone = '([A-Z]{1,5})';
  10651. $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
  10652. $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
  10653. }
  10654. if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
  10655. {
  10656. /*
  10657. Capturing subpatterns:
  10658. 1: Day name
  10659. 2: Day
  10660. 3: Month
  10661. 4: Year
  10662. 5: Hour
  10663. 6: Minute
  10664. 7: Second
  10665. 8: Timezone ±
  10666. 9: Timezone hours
  10667. 10: Timezone minutes
  10668. 11: Alphabetic timezone
  10669. */
  10670. // Find the month number
  10671. $month = $this->month[strtolower($match[3])];
  10672. // Numeric timezone
  10673. if ($match[8] !== '')
  10674. {
  10675. $timezone = $match[9] * 3600;
  10676. $timezone += $match[10] * 60;
  10677. if ($match[8] === '-')
  10678. {
  10679. $timezone = 0 - $timezone;
  10680. }
  10681. }
  10682. // Character timezone
  10683. elseif (isset($this->timezone[strtoupper($match[11])]))
  10684. {
  10685. $timezone = $this->timezone[strtoupper($match[11])];
  10686. }
  10687. // Assume everything else to be -0000
  10688. else
  10689. {
  10690. $timezone = 0;
  10691. }
  10692. // Deal with 2/3 digit years
  10693. if ($match[4] < 50)
  10694. {
  10695. $match[4] += 2000;
  10696. }
  10697. elseif ($match[4] < 1000)
  10698. {
  10699. $match[4] += 1900;
  10700. }
  10701. // Second is optional, if it is empty set it to zero
  10702. if ($match[7] !== '')
  10703. {
  10704. $second = $match[7];
  10705. }
  10706. else
  10707. {
  10708. $second = 0;
  10709. }
  10710. return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
  10711. }
  10712. else
  10713. {
  10714. return false;
  10715. }
  10716. }
  10717. /**
  10718. * Parse RFC850's date format
  10719. *
  10720. * @access protected
  10721. * @return int Timestamp
  10722. */
  10723. function date_rfc850($date)
  10724. {
  10725. static $pcre;
  10726. if (!$pcre)
  10727. {
  10728. $space = '[\x09\x20]+';
  10729. $day_name = $this->day_pcre;
  10730. $month = $this->month_pcre;
  10731. $day = '([0-9]{1,2})';
  10732. $year = $hour = $minute = $second = '([0-9]{2})';
  10733. $zone = '([A-Z]{1,5})';
  10734. $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
  10735. }
  10736. if (preg_match($pcre, $date, $match))
  10737. {
  10738. /*
  10739. Capturing subpatterns:
  10740. 1: Day name
  10741. 2: Day
  10742. 3: Month
  10743. 4: Year
  10744. 5: Hour
  10745. 6: Minute
  10746. 7: Second
  10747. 8: Timezone
  10748. */
  10749. // Month
  10750. $month = $this->month[strtolower($match[3])];
  10751. // Character timezone
  10752. if (isset($this->timezone[strtoupper($match[8])]))
  10753. {
  10754. $timezone = $this->timezone[strtoupper($match[8])];
  10755. }
  10756. // Assume everything else to be -0000
  10757. else
  10758. {
  10759. $timezone = 0;
  10760. }
  10761. // Deal with 2 digit year
  10762. if ($match[4] < 50)
  10763. {
  10764. $match[4] += 2000;
  10765. }
  10766. else
  10767. {
  10768. $match[4] += 1900;
  10769. }
  10770. return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
  10771. }
  10772. else
  10773. {
  10774. return false;
  10775. }
  10776. }
  10777. /**
  10778. * Parse C99's asctime()'s date format
  10779. *
  10780. * @access protected
  10781. * @return int Timestamp
  10782. */
  10783. function date_asctime($date)
  10784. {
  10785. static $pcre;
  10786. if (!$pcre)
  10787. {
  10788. $space = '[\x09\x20]+';
  10789. $wday_name = $this->day_pcre;
  10790. $mon_name = $this->month_pcre;
  10791. $day = '([0-9]{1,2})';
  10792. $hour = $sec = $min = '([0-9]{2})';
  10793. $year = '([0-9]{4})';
  10794. $terminator = '\x0A?\x00?';
  10795. $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
  10796. }
  10797. if (preg_match($pcre, $date, $match))
  10798. {
  10799. /*
  10800. Capturing subpatterns:
  10801. 1: Day name
  10802. 2: Month
  10803. 3: Day
  10804. 4: Hour
  10805. 5: Minute
  10806. 6: Second
  10807. 7: Year
  10808. */
  10809. $month = $this->month[strtolower($match[2])];
  10810. return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
  10811. }
  10812. else
  10813. {
  10814. return false;
  10815. }
  10816. }
  10817. /**
  10818. * Parse dates using strtotime()
  10819. *
  10820. * @access protected
  10821. * @return int Timestamp
  10822. */
  10823. function date_strtotime($date)
  10824. {
  10825. $strtotime = strtotime($date);
  10826. if ($strtotime === -1 || $strtotime === false)
  10827. {
  10828. return false;
  10829. }
  10830. else
  10831. {
  10832. return $strtotime;
  10833. }
  10834. }
  10835. }
  10836. /**
  10837. * Content-type sniffing
  10838. *
  10839. * @package SimplePie
  10840. */
  10841. class SimplePie_Content_Type_Sniffer
  10842. {
  10843. /**
  10844. * File object
  10845. *
  10846. * @var SimplePie_File
  10847. * @access private
  10848. */
  10849. var $file;
  10850. /**
  10851. * Create an instance of the class with the input file
  10852. *
  10853. * @access public
  10854. * @param SimplePie_Content_Type_Sniffer $file Input file
  10855. */
  10856. function SimplePie_Content_Type_Sniffer($file)
  10857. {
  10858. $this->file = $file;
  10859. }
  10860. /**
  10861. * Get the Content-Type of the specified file
  10862. *
  10863. * @access public
  10864. * @return string Actual Content-Type
  10865. */
  10866. function get_type()
  10867. {
  10868. if (isset($this->file->headers['content-type']))
  10869. {
  10870. if (!isset($this->file->headers['content-encoding'])
  10871. && ($this->file->headers['content-type'] === 'text/plain'
  10872. || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
  10873. || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
  10874. {
  10875. return $this->text_or_binary();
  10876. }
  10877. if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
  10878. {
  10879. $official = substr($this->file->headers['content-type'], 0, $pos);
  10880. }
  10881. else
  10882. {
  10883. $official = $this->file->headers['content-type'];
  10884. }
  10885. $official = strtolower($official);
  10886. if ($official === 'unknown/unknown'
  10887. || $official === 'application/unknown')
  10888. {
  10889. return $this->unknown();
  10890. }
  10891. elseif (substr($official, -4) === '+xml'
  10892. || $official === 'text/xml'
  10893. || $official === 'application/xml')
  10894. {
  10895. return $official;
  10896. }
  10897. elseif (substr($official, 0, 6) === 'image/')
  10898. {
  10899. if ($return = $this->image())
  10900. {
  10901. return $return;
  10902. }
  10903. else
  10904. {
  10905. return $official;
  10906. }
  10907. }
  10908. elseif ($official === 'text/html')
  10909. {
  10910. return $this->feed_or_html();
  10911. }
  10912. else
  10913. {
  10914. return $official;
  10915. }
  10916. }
  10917. else
  10918. {
  10919. return $this->unknown();
  10920. }
  10921. }
  10922. /**
  10923. * Sniff text or binary
  10924. *
  10925. * @access private
  10926. * @return string Actual Content-Type
  10927. */
  10928. function text_or_binary()
  10929. {
  10930. if (substr($this->file->body, 0, 2) === "\xFE\xFF"
  10931. || substr($this->file->body, 0, 2) === "\xFF\xFE"
  10932. || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
  10933. || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
  10934. {
  10935. return 'text/plain';
  10936. }
  10937. elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
  10938. {
  10939. return 'application/octect-stream';
  10940. }
  10941. else
  10942. {
  10943. return 'text/plain';
  10944. }
  10945. }
  10946. /**
  10947. * Sniff unknown
  10948. *
  10949. * @access private
  10950. * @return string Actual Content-Type
  10951. */
  10952. function unknown()
  10953. {
  10954. $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
  10955. if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
  10956. || strtolower(substr($this->file->body, $ws, 5)) === '<html'
  10957. || strtolower(substr($this->file->body, $ws, 7)) === '<script')
  10958. {
  10959. return 'text/html';
  10960. }
  10961. elseif (substr($this->file->body, 0, 5) === '%PDF-')
  10962. {
  10963. return 'application/pdf';
  10964. }
  10965. elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
  10966. {
  10967. return 'application/postscript';
  10968. }
  10969. elseif (substr($this->file->body, 0, 6) === 'GIF87a'
  10970. || substr($this->file->body, 0, 6) === 'GIF89a')
  10971. {
  10972. return 'image/gif';
  10973. }
  10974. elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
  10975. {
  10976. return 'image/png';
  10977. }
  10978. elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
  10979. {
  10980. return 'image/jpeg';
  10981. }
  10982. elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
  10983. {
  10984. return 'image/bmp';
  10985. }
  10986. else
  10987. {
  10988. return $this->text_or_binary();
  10989. }
  10990. }
  10991. /**
  10992. * Sniff images
  10993. *
  10994. * @access private
  10995. * @return string Actual Content-Type
  10996. */
  10997. function image()
  10998. {
  10999. if (substr($this->file->body, 0, 6) === 'GIF87a'
  11000. || substr($this->file->body, 0, 6) === 'GIF89a')
  11001. {
  11002. return 'image/gif';
  11003. }
  11004. elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
  11005. {
  11006. return 'image/png';
  11007. }
  11008. elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
  11009. {
  11010. return 'image/jpeg';
  11011. }
  11012. elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
  11013. {
  11014. return 'image/bmp';
  11015. }
  11016. else
  11017. {
  11018. return false;
  11019. }
  11020. }
  11021. /**
  11022. * Sniff HTML
  11023. *
  11024. * @access private
  11025. * @return string Actual Content-Type
  11026. */
  11027. function feed_or_html()
  11028. {
  11029. $len = strlen($this->file->body);
  11030. $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
  11031. while ($pos < $len)
  11032. {
  11033. switch ($this->file->body[$pos])
  11034. {
  11035. case "\x09":
  11036. case "\x0A":
  11037. case "\x0D":
  11038. case "\x20":
  11039. $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
  11040. continue 2;
  11041. case '<':
  11042. $pos++;
  11043. break;
  11044. default:
  11045. return 'text/html';
  11046. }
  11047. if (substr($this->file->body, $pos, 3) === '!--')
  11048. {
  11049. $pos += 3;
  11050. if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
  11051. {
  11052. $pos += 3;
  11053. }
  11054. else
  11055. {
  11056. return 'text/html';
  11057. }
  11058. }
  11059. elseif (substr($this->file->body, $pos, 1) === '!')
  11060. {
  11061. if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
  11062. {
  11063. $pos++;
  11064. }
  11065. else
  11066. {
  11067. return 'text/html';
  11068. }
  11069. }
  11070. elseif (substr($this->file->body, $pos, 1) === '?')
  11071. {
  11072. if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
  11073. {
  11074. $pos += 2;
  11075. }
  11076. else
  11077. {
  11078. return 'text/html';
  11079. }
  11080. }
  11081. elseif (substr($this->file->body, $pos, 3) === 'rss'
  11082. || substr($this->file->body, $pos, 7) === 'rdf:RDF')
  11083. {
  11084. return 'application/rss+xml';
  11085. }
  11086. elseif (substr($this->file->body, $pos, 4) === 'feed')
  11087. {
  11088. return 'application/atom+xml';
  11089. }
  11090. else
  11091. {
  11092. return 'text/html';
  11093. }
  11094. }
  11095. return 'text/html';
  11096. }
  11097. }
  11098. /**
  11099. * Parses the XML Declaration
  11100. *
  11101. * @package SimplePie
  11102. */
  11103. class SimplePie_XML_Declaration_Parser
  11104. {
  11105. /**
  11106. * XML Version
  11107. *
  11108. * @access public
  11109. * @var string
  11110. */
  11111. var $version = '1.0';
  11112. /**
  11113. * Encoding
  11114. *
  11115. * @access public
  11116. * @var string
  11117. */
  11118. var $encoding = 'UTF-8';
  11119. /**
  11120. * Standalone
  11121. *
  11122. * @access public
  11123. * @var bool
  11124. */
  11125. var $standalone = false;
  11126. /**
  11127. * Current state of the state machine
  11128. *
  11129. * @access private
  11130. * @var string
  11131. */
  11132. var $state = 'before_version_name';
  11133. /**
  11134. * Input data
  11135. *
  11136. * @access private
  11137. * @var string
  11138. */
  11139. var $data = '';
  11140. /**
  11141. * Input data length (to avoid calling strlen() everytime this is needed)
  11142. *
  11143. * @access private
  11144. * @var int
  11145. */
  11146. var $data_length = 0;
  11147. /**
  11148. * Current position of the pointer
  11149. *
  11150. * @var int
  11151. * @access private
  11152. */
  11153. var $position = 0;
  11154. /**
  11155. * Create an instance of the class with the input data
  11156. *
  11157. * @access public
  11158. * @param string $data Input data
  11159. */
  11160. function SimplePie_XML_Declaration_Parser($data)
  11161. {
  11162. $this->data = $data;
  11163. $this->data_length = strlen($this->data);
  11164. }
  11165. /**
  11166. * Parse the input data
  11167. *
  11168. * @access public
  11169. * @return bool true on success, false on failure
  11170. */
  11171. function parse()
  11172. {
  11173. while ($this->state && $this->state !== 'emit' && $this->has_data())
  11174. {
  11175. $state = $this->state;
  11176. $this->$state();
  11177. }
  11178. $this->data = '';
  11179. if ($this->state === 'emit')
  11180. {
  11181. return true;
  11182. }
  11183. else
  11184. {
  11185. $this->version = '';
  11186. $this->encoding = '';
  11187. $this->standalone = '';
  11188. return false;
  11189. }
  11190. }
  11191. /**
  11192. * Check whether there is data beyond the pointer
  11193. *
  11194. * @access private
  11195. * @return bool true if there is further data, false if not
  11196. */
  11197. function has_data()
  11198. {
  11199. return (bool) ($this->position < $this->data_length);
  11200. }
  11201. /**
  11202. * Advance past any whitespace
  11203. *
  11204. * @return int Number of whitespace characters passed
  11205. */
  11206. function skip_whitespace()
  11207. {
  11208. $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
  11209. $this->position += $whitespace;
  11210. return $whitespace;
  11211. }
  11212. /**
  11213. * Read value
  11214. */
  11215. function get_value()
  11216. {
  11217. $quote = substr($this->data, $this->position, 1);
  11218. if ($quote === '"' || $quote === "'")
  11219. {
  11220. $this->position++;
  11221. $len = strcspn($this->data, $quote, $this->position);
  11222. if ($this->has_data())
  11223. {
  11224. $value = substr($this->data, $this->position, $len);
  11225. $this->position += $len + 1;
  11226. return $value;
  11227. }
  11228. }
  11229. return false;
  11230. }
  11231. function before_version_name()
  11232. {
  11233. if ($this->skip_whitespace())
  11234. {
  11235. $this->state = 'version_name';
  11236. }
  11237. else
  11238. {
  11239. $this->state = false;
  11240. }
  11241. }
  11242. function version_name()
  11243. {
  11244. if (substr($this->data, $this->position, 7) === 'version')
  11245. {
  11246. $this->position += 7;
  11247. $this->skip_whitespace();
  11248. $this->state = 'version_equals';
  11249. }
  11250. else
  11251. {
  11252. $this->state = false;
  11253. }
  11254. }
  11255. function version_equals()
  11256. {
  11257. if (substr($this->data, $this->position, 1) === '=')
  11258. {
  11259. $this->position++;
  11260. $this->skip_whitespace();
  11261. $this->state = 'version_value';
  11262. }
  11263. else
  11264. {
  11265. $this->state = false;
  11266. }
  11267. }
  11268. function version_value()
  11269. {
  11270. if ($this->version = $this->get_value())
  11271. {
  11272. $this->skip_whitespace();
  11273. if ($this->has_data())
  11274. {
  11275. $this->state = 'encoding_name';
  11276. }
  11277. else
  11278. {
  11279. $this->state = 'emit';
  11280. }
  11281. }
  11282. else
  11283. {
  11284. $this->state = 'standalone_name';
  11285. }
  11286. }
  11287. function encoding_name()
  11288. {
  11289. if (substr($this->data, $this->position, 8) === 'encoding')
  11290. {
  11291. $this->position += 8;
  11292. $this->skip_whitespace();
  11293. $this->state = 'encoding_equals';
  11294. }
  11295. else
  11296. {
  11297. $this->state = false;
  11298. }
  11299. }
  11300. function encoding_equals()
  11301. {
  11302. if (substr($this->data, $this->position, 1) === '=')
  11303. {
  11304. $this->position++;
  11305. $this->skip_whitespace();
  11306. $this->state = 'encoding_value';
  11307. }
  11308. else
  11309. {
  11310. $this->state = false;
  11311. }
  11312. }
  11313. function encoding_value()
  11314. {
  11315. if ($this->encoding = $this->get_value())
  11316. {
  11317. $this->skip_whitespace();
  11318. if ($this->has_data())
  11319. {
  11320. $this->state = 'standalone_name';
  11321. }
  11322. else
  11323. {
  11324. $this->state = 'emit';
  11325. }
  11326. }
  11327. else
  11328. {
  11329. $this->state = false;
  11330. }
  11331. }
  11332. function standalone_name()
  11333. {
  11334. if (substr($this->data, $this->position, 10) === 'standalone')
  11335. {
  11336. $this->position += 10;
  11337. $this->skip_whitespace();
  11338. $this->state = 'standalone_equals';
  11339. }
  11340. else
  11341. {
  11342. $this->state = false;
  11343. }
  11344. }
  11345. function standalone_equals()
  11346. {
  11347. if (substr($this->data, $this->position, 1) === '=')
  11348. {
  11349. $this->position++;
  11350. $this->skip_whitespace();
  11351. $this->state = 'standalone_value';
  11352. }
  11353. else
  11354. {
  11355. $this->state = false;
  11356. }
  11357. }
  11358. function standalone_value()
  11359. {
  11360. if ($standalone = $this->get_value())
  11361. {
  11362. switch ($standalone)
  11363. {
  11364. case 'yes':
  11365. $this->standalone = true;
  11366. break;
  11367. case 'no':
  11368. $this->standalone = false;
  11369. break;
  11370. default:
  11371. $this->state = false;
  11372. return;
  11373. }
  11374. $this->skip_whitespace();
  11375. if ($this->has_data())
  11376. {
  11377. $this->state = false;
  11378. }
  11379. else
  11380. {
  11381. $this->state = 'emit';
  11382. }
  11383. }
  11384. else
  11385. {
  11386. $this->state = false;
  11387. }
  11388. }
  11389. }
  11390. class SimplePie_Locator
  11391. {
  11392. var $useragent;
  11393. var $timeout;
  11394. var $file;
  11395. var $local = array();
  11396. var $elsewhere = array();
  11397. var $file_class = 'SimplePie_File';
  11398. var $cached_entities = array();
  11399. var $http_base;
  11400. var $base;
  11401. var $base_location = 0;
  11402. var $checked_feeds = 0;
  11403. var $max_checked_feeds = 10;
  11404. var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
  11405. function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
  11406. {
  11407. $this->file =& $file;
  11408. $this->file_class = $file_class;
  11409. $this->useragent = $useragent;
  11410. $this->timeout = $timeout;
  11411. $this->max_checked_feeds = $max_checked_feeds;
  11412. $this->content_type_sniffer_class;
  11413. }
  11414. function find($type = SIMPLEPIE_LOCATOR_ALL)
  11415. {
  11416. if ($this->is_feed($this->file))
  11417. {
  11418. return $this->file;
  11419. }
  11420. if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
  11421. {
  11422. $sniffer = new $this->content_type_sniffer_class($this->file);
  11423. if ($sniffer->get_type() !== 'text/html')
  11424. {
  11425. return null;
  11426. }
  11427. }
  11428. if ($type & ~SIMPLEPIE_LOCATOR_NONE)
  11429. {
  11430. $this->get_base();
  11431. }
  11432. if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
  11433. {
  11434. return $working;
  11435. }
  11436. if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
  11437. {
  11438. if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
  11439. {
  11440. return $working;
  11441. }
  11442. if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
  11443. {
  11444. return $working;
  11445. }
  11446. if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
  11447. {
  11448. return $working;
  11449. }
  11450. if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
  11451. {
  11452. return $working;
  11453. }
  11454. }
  11455. return null;
  11456. }
  11457. function is_feed(&$file)
  11458. {
  11459. if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
  11460. {
  11461. $sniffer = new $this->content_type_sniffer_class($file);
  11462. $sniffed = $sniffer->get_type();
  11463. if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'application/atom+xml', 'text/xml', 'application/xml', 'text/plain')))
  11464. {
  11465. return true;
  11466. }
  11467. else
  11468. {
  11469. return false;
  11470. }
  11471. }
  11472. elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
  11473. {
  11474. return true;
  11475. }
  11476. else
  11477. {
  11478. return false;
  11479. }
  11480. }
  11481. function get_base()
  11482. {
  11483. $this->http_base = $this->file->url;
  11484. $this->base = $this->http_base;
  11485. $elements = SimplePie_Misc::get_element('base', $this->file->body);
  11486. foreach ($elements as $element)
  11487. {
  11488. if ($element['attribs']['href']['data'] !== '')
  11489. {
  11490. $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
  11491. $this->base_location = $element['offset'];
  11492. break;
  11493. }
  11494. }
  11495. }
  11496. function autodiscovery()
  11497. {
  11498. $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));
  11499. $done = array();
  11500. foreach ($links as $link)
  11501. {
  11502. if ($this->checked_feeds == $this->max_checked_feeds)
  11503. {
  11504. break;
  11505. }
  11506. if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
  11507. {
  11508. $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
  11509. if ($this->base_location < $link['offset'])
  11510. {
  11511. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
  11512. }
  11513. else
  11514. {
  11515. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
  11516. }
  11517. 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'))))
  11518. {
  11519. $this->checked_feeds++;
  11520. $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
  11521. if ($this->is_feed($feed))
  11522. {
  11523. return $feed;
  11524. }
  11525. }
  11526. $done[] = $href;
  11527. }
  11528. }
  11529. return null;
  11530. }
  11531. function get_links()
  11532. {
  11533. $links = SimplePie_Misc::get_element('a', $this->file->body);
  11534. foreach ($links as $link)
  11535. {
  11536. if (isset($link['attribs']['href']['data']))
  11537. {
  11538. $href = trim($link['attribs']['href']['data']);
  11539. $parsed = SimplePie_Misc::parse_url($href);
  11540. if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
  11541. {
  11542. if ($this->base_location < $link['offset'])
  11543. {
  11544. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
  11545. }
  11546. else
  11547. {
  11548. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
  11549. }
  11550. $current = SimplePie_Misc::parse_url($this->file->url);
  11551. if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
  11552. {
  11553. $this->local[] = $href;
  11554. }
  11555. else
  11556. {
  11557. $this->elsewhere[] = $href;
  11558. }
  11559. }
  11560. }
  11561. }
  11562. $this->local = array_unique($this->local);
  11563. $this->elsewhere = array_unique($this->elsewhere);
  11564. if (!empty($this->local) || !empty($this->elsewhere))
  11565. {
  11566. return true;
  11567. }
  11568. return null;
  11569. }
  11570. function extension(&$array)
  11571. {
  11572. foreach ($array as $key => $value)
  11573. {
  11574. if ($this->checked_feeds == $this->max_checked_feeds)
  11575. {
  11576. break;
  11577. }
  11578. if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
  11579. {
  11580. $this->checked_feeds++;
  11581. $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
  11582. if ($this->is_feed($feed))
  11583. {
  11584. return $feed;
  11585. }
  11586. else
  11587. {
  11588. unset($array[$key]);
  11589. }
  11590. }
  11591. }
  11592. return null;
  11593. }
  11594. function body(&$array)
  11595. {
  11596. foreach ($array as $key => $value)
  11597. {
  11598. if ($this->checked_feeds == $this->max_checked_feeds)
  11599. {
  11600. break;
  11601. }
  11602. if (preg_match('/(rss|rdf|atom|xml)/i', $value))
  11603. {
  11604. $this->checked_feeds++;
  11605. $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
  11606. if ($this->is_feed($feed))
  11607. {
  11608. return $feed;
  11609. }
  11610. else
  11611. {
  11612. unset($array[$key]);
  11613. }
  11614. }
  11615. }
  11616. return null;
  11617. }
  11618. }
  11619. class SimplePie_Parser
  11620. {
  11621. var $error_code;
  11622. var $error_string;
  11623. var $current_line;
  11624. var $current_column;
  11625. var $current_byte;
  11626. var $separator = ' ';
  11627. var $feed = false;
  11628. var $namespace = array('');
  11629. var $element = array('');
  11630. var $xml_base = array('');
  11631. var $xml_base_explicit = array(false);
  11632. var $xml_lang = array('');
  11633. var $data = array();
  11634. var $datas = array(array());
  11635. var $current_xhtml_construct = -1;
  11636. var $encoding;
  11637. function parse(&$data, $encoding)
  11638. {
  11639. // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
  11640. if (strtoupper($encoding) == 'US-ASCII')
  11641. {
  11642. $this->encoding = 'UTF-8';
  11643. }
  11644. else
  11645. {
  11646. $this->encoding = $encoding;
  11647. }
  11648. // Strip BOM:
  11649. // UTF-32 Big Endian BOM
  11650. if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
  11651. {
  11652. $data = substr($data, 4);
  11653. }
  11654. // UTF-32 Little Endian BOM
  11655. elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
  11656. {
  11657. $data = substr($data, 4);
  11658. }
  11659. // UTF-16 Big Endian BOM
  11660. elseif (substr($data, 0, 2) === "\xFE\xFF")
  11661. {
  11662. $data = substr($data, 2);
  11663. }
  11664. // UTF-16 Little Endian BOM
  11665. elseif (substr($data, 0, 2) === "\xFF\xFE")
  11666. {
  11667. $data = substr($data, 2);
  11668. }
  11669. // UTF-8 BOM
  11670. elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
  11671. {
  11672. $data = substr($data, 3);
  11673. }
  11674. if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
  11675. {
  11676. $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
  11677. if ($declaration->parse())
  11678. {
  11679. $data = substr($data, $pos + 2);
  11680. $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
  11681. }
  11682. else
  11683. {
  11684. $this->error_string = 'SimplePie bug! Please report this!';
  11685. return false;
  11686. }
  11687. }
  11688. $return = true;
  11689. // Create the parser
  11690. $xml = xml_parser_create_ns($this->encoding, $this->separator);
  11691. xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
  11692. xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
  11693. xml_set_object($xml, $this);
  11694. xml_set_character_data_handler($xml, 'cdata');
  11695. xml_set_element_handler($xml, 'tag_open', 'tag_close');
  11696. // Parse!
  11697. if (!xml_parse($xml, $data, true))
  11698. {
  11699. $this->error_code = xml_get_error_code($xml);
  11700. $this->error_string = xml_error_string($this->error_code);
  11701. $return = false;
  11702. }
  11703. $this->current_line = xml_get_current_line_number($xml);
  11704. $this->current_column = xml_get_current_column_number($xml);
  11705. $this->current_byte = xml_get_current_byte_index($xml);
  11706. xml_parser_free($xml);
  11707. return $return;
  11708. }
  11709. function get_error_code()
  11710. {
  11711. return $this->error_code;
  11712. }
  11713. function get_error_string()
  11714. {
  11715. return $this->error_string;
  11716. }
  11717. function get_current_line()
  11718. {
  11719. return $this->current_line;
  11720. }
  11721. function get_current_column()
  11722. {
  11723. return $this->current_column;
  11724. }
  11725. function get_current_byte()
  11726. {
  11727. return $this->current_byte;
  11728. }
  11729. function get_data()
  11730. {
  11731. return $this->data;
  11732. }
  11733. function tag_open($parser, $tag, $attributes)
  11734. {
  11735. if ($this->feed === 0)
  11736. {
  11737. return;
  11738. }
  11739. elseif ($this->feed == false)
  11740. {
  11741. if (in_array($tag, array(
  11742. SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
  11743. SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
  11744. 'rss',
  11745. SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
  11746. )))
  11747. {
  11748. $this->feed = 1;
  11749. }
  11750. }
  11751. else
  11752. {
  11753. $this->feed++;
  11754. }
  11755. list($this->namespace[], $this->element[]) = $this->split_ns($tag);
  11756. $attribs = array();
  11757. foreach ($attributes as $name => $value)
  11758. {
  11759. list($attrib_namespace, $attribute) = $this->split_ns($name);
  11760. $attribs[$attrib_namespace][$attribute] = $value;
  11761. }
  11762. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
  11763. {
  11764. $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
  11765. $this->xml_base_explicit[] = true;
  11766. }
  11767. else
  11768. {
  11769. $this->xml_base[] = end($this->xml_base);
  11770. $this->xml_base_explicit[] = end($this->xml_base_explicit);
  11771. }
  11772. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
  11773. {
  11774. $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
  11775. }
  11776. else
  11777. {
  11778. $this->xml_lang[] = end($this->xml_lang);
  11779. }
  11780. if ($this->current_xhtml_construct >= 0)
  11781. {
  11782. $this->current_xhtml_construct++;
  11783. if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
  11784. {
  11785. $this->data['data'] .= '<' . end($this->element);
  11786. if (isset($attribs['']))
  11787. {
  11788. foreach ($attribs[''] as $name => $value)
  11789. {
  11790. $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
  11791. }
  11792. }
  11793. $this->data['data'] .= '>';
  11794. }
  11795. }
  11796. else
  11797. {
  11798. $this->datas[] =& $this->data;
  11799. $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
  11800. $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));
  11801. 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')
  11802. || (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'))
  11803. {
  11804. $this->current_xhtml_construct = 0;
  11805. }
  11806. }
  11807. }
  11808. function cdata($parser, $cdata)
  11809. {
  11810. if ($this->current_xhtml_construct >= 0)
  11811. {
  11812. $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
  11813. }
  11814. elseif ($this->feed > 1)
  11815. {
  11816. $this->data['data'] .= $cdata;
  11817. }
  11818. }
  11819. function tag_close($parser, $tag)
  11820. {
  11821. if (!$this->feed)
  11822. {
  11823. return;
  11824. }
  11825. if ($this->current_xhtml_construct >= 0)
  11826. {
  11827. $this->current_xhtml_construct--;
  11828. 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')))
  11829. {
  11830. $this->data['data'] .= '</' . end($this->element) . '>';
  11831. }
  11832. }
  11833. if ($this->current_xhtml_construct == -1)
  11834. {
  11835. $this->data =& $this->datas[$this->feed];
  11836. array_pop($this->datas);
  11837. }
  11838. array_pop($this->element);
  11839. array_pop($this->namespace);
  11840. array_pop($this->xml_base);
  11841. array_pop($this->xml_base_explicit);
  11842. array_pop($this->xml_lang);
  11843. $this->feed--;
  11844. }
  11845. function split_ns($string)
  11846. {
  11847. static $cache = array();
  11848. if (!isset($cache[$string]))
  11849. {
  11850. if ($pos = strpos($string, $this->separator))
  11851. {
  11852. static $separator_length;
  11853. if (!$separator_length)
  11854. {
  11855. $separator_length = strlen($this->separator);
  11856. }
  11857. $namespace = substr($string, 0, $pos);
  11858. $local_name = substr($string, $pos + $separator_length);
  11859. if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
  11860. {
  11861. $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
  11862. }
  11863. $cache[$string] = array($namespace, $local_name);
  11864. }
  11865. else
  11866. {
  11867. $cache[$string] = array('', $string);
  11868. }
  11869. }
  11870. return $cache[$string];
  11871. }
  11872. }
  11873. /**
  11874. * @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
  11875. */
  11876. class SimplePie_Sanitize
  11877. {
  11878. // Private vars
  11879. var $base;
  11880. // Options
  11881. var $remove_div = true;
  11882. var $image_handler = '';
  11883. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  11884. var $encode_instead_of_strip = false;
  11885. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  11886. var $strip_comments = false;
  11887. var $output_encoding = 'UTF-8';
  11888. var $enable_cache = true;
  11889. var $cache_location = './cache';
  11890. var $cache_name_function = 'md5';
  11891. var $cache_class = 'SimplePie_Cache';
  11892. var $file_class = 'SimplePie_File';
  11893. var $timeout = 10;
  11894. var $useragent = '';
  11895. var $force_fsockopen = false;
  11896. var $replace_url_attributes = array(
  11897. 'a' => 'href',
  11898. 'area' => 'href',
  11899. 'blockquote' => 'cite',
  11900. 'del' => 'cite',
  11901. 'form' => 'action',
  11902. 'img' => array('longdesc', 'src'),
  11903. 'input' => 'src',
  11904. 'ins' => 'cite',
  11905. 'q' => 'cite'
  11906. );
  11907. function remove_div($enable = true)
  11908. {
  11909. $this->remove_div = (bool) $enable;
  11910. }
  11911. function set_image_handler($page = false)
  11912. {
  11913. if ($page)
  11914. {
  11915. $this->image_handler = (string) $page;
  11916. }
  11917. else
  11918. {
  11919. $this->image_handler = false;
  11920. }
  11921. }
  11922. function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
  11923. {
  11924. if (isset($enable_cache))
  11925. {
  11926. $this->enable_cache = (bool) $enable_cache;
  11927. }
  11928. if ($cache_location)
  11929. {
  11930. $this->cache_location = (string) $cache_location;
  11931. }
  11932. if ($cache_name_function)
  11933. {
  11934. $this->cache_name_function = (string) $cache_name_function;
  11935. }
  11936. if ($cache_class)
  11937. {
  11938. $this->cache_class = (string) $cache_class;
  11939. }
  11940. }
  11941. function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
  11942. {
  11943. if ($file_class)
  11944. {
  11945. $this->file_class = (string) $file_class;
  11946. }
  11947. if ($timeout)
  11948. {
  11949. $this->timeout = (string) $timeout;
  11950. }
  11951. if ($useragent)
  11952. {
  11953. $this->useragent = (string) $useragent;
  11954. }
  11955. if ($force_fsockopen)
  11956. {
  11957. $this->force_fsockopen = (string) $force_fsockopen;
  11958. }
  11959. }
  11960. function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
  11961. {
  11962. if ($tags)
  11963. {
  11964. if (is_array($tags))
  11965. {
  11966. $this->strip_htmltags = $tags;
  11967. }
  11968. else
  11969. {
  11970. $this->strip_htmltags = explode(',', $tags);
  11971. }
  11972. }
  11973. else
  11974. {
  11975. $this->strip_htmltags = false;
  11976. }
  11977. }
  11978. function encode_instead_of_strip($encode = false)
  11979. {
  11980. $this->encode_instead_of_strip = (bool) $encode;
  11981. }
  11982. function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
  11983. {
  11984. if ($attribs)
  11985. {
  11986. if (is_array($attribs))
  11987. {
  11988. $this->strip_attributes = $attribs;
  11989. }
  11990. else
  11991. {
  11992. $this->strip_attributes = explode(',', $attribs);
  11993. }
  11994. }
  11995. else
  11996. {
  11997. $this->strip_attributes = false;
  11998. }
  11999. }
  12000. function strip_comments($strip = false)
  12001. {
  12002. $this->strip_comments = (bool) $strip;
  12003. }
  12004. function set_output_encoding($encoding = 'UTF-8')
  12005. {
  12006. $this->output_encoding = (string) $encoding;
  12007. }
  12008. /**
  12009. * Set element/attribute key/value pairs of HTML attributes
  12010. * containing URLs that need to be resolved relative to the feed
  12011. *
  12012. * @access public
  12013. * @since 1.0
  12014. * @param array $element_attribute Element/attribute key/value pairs
  12015. */
  12016. function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
  12017. {
  12018. $this->replace_url_attributes = (array) $element_attribute;
  12019. }
  12020. function sanitize($data, $type, $base = '')
  12021. {
  12022. $data = trim($data);
  12023. if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
  12024. {
  12025. if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
  12026. {
  12027. if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
  12028. {
  12029. $type |= SIMPLEPIE_CONSTRUCT_HTML;
  12030. }
  12031. else
  12032. {
  12033. $type |= SIMPLEPIE_CONSTRUCT_TEXT;
  12034. }
  12035. }
  12036. if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
  12037. {
  12038. $data = base64_decode($data);
  12039. }
  12040. if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
  12041. {
  12042. if ($this->remove_div)
  12043. {
  12044. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
  12045. $data = preg_replace('/<\/div>$/', '', $data);
  12046. }
  12047. else
  12048. {
  12049. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
  12050. }
  12051. }
  12052. if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
  12053. {
  12054. // Strip comments
  12055. if ($this->strip_comments)
  12056. {
  12057. $data = SimplePie_Misc::strip_comments($data);
  12058. }
  12059. // Strip out HTML tags and attributes that might cause various security problems.
  12060. // Based on recommendations by Mark Pilgrim at:
  12061. // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
  12062. if ($this->strip_htmltags)
  12063. {
  12064. foreach ($this->strip_htmltags as $tag)
  12065. {
  12066. $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
  12067. while (preg_match($pcre, $data))
  12068. {
  12069. $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
  12070. }
  12071. }
  12072. }
  12073. if ($this->strip_attributes)
  12074. {
  12075. foreach ($this->strip_attributes as $attrib)
  12076. {
  12077. $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data);
  12078. }
  12079. }
  12080. // Replace relative URLs
  12081. $this->base = $base;
  12082. foreach ($this->replace_url_attributes as $element => $attributes)
  12083. {
  12084. $data = $this->replace_urls($data, $element, $attributes);
  12085. }
  12086. // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
  12087. if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
  12088. {
  12089. $images = SimplePie_Misc::get_element('img', $data);
  12090. foreach ($images as $img)
  12091. {
  12092. if (isset($img['attribs']['src']['data']))
  12093. {
  12094. $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
  12095. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
  12096. if ($cache->load())
  12097. {
  12098. $img['attribs']['src']['data'] = $this->image_handler . $image_url;
  12099. $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
  12100. }
  12101. else
  12102. {
  12103. $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
  12104. $headers = $file->headers;
  12105. if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
  12106. {
  12107. if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  12108. {
  12109. $img['attribs']['src']['data'] = $this->image_handler . $image_url;
  12110. $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
  12111. }
  12112. else
  12113. {
  12114. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  12115. }
  12116. }
  12117. }
  12118. }
  12119. }
  12120. }
  12121. // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
  12122. $data = trim($data);
  12123. }
  12124. if ($type & SIMPLEPIE_CONSTRUCT_IRI)
  12125. {
  12126. $data = SimplePie_Misc::absolutize_url($data, $base);
  12127. }
  12128. if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
  12129. {
  12130. $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
  12131. }
  12132. if ($this->output_encoding != 'UTF-8')
  12133. {
  12134. $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
  12135. }
  12136. }
  12137. return $data;
  12138. }
  12139. function replace_urls($data, $tag, $attributes)
  12140. {
  12141. if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
  12142. {
  12143. $elements = SimplePie_Misc::get_element($tag, $data);
  12144. foreach ($elements as $element)
  12145. {
  12146. if (is_array($attributes))
  12147. {
  12148. foreach ($attributes as $attribute)
  12149. {
  12150. if (isset($element['attribs'][$attribute]['data']))
  12151. {
  12152. $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
  12153. $new_element = SimplePie_Misc::element_implode($element);
  12154. $data = str_replace($element['full'], $new_element, $data);
  12155. $element['full'] = $new_element;
  12156. }
  12157. }
  12158. }
  12159. elseif (isset($element['attribs'][$attributes]['data']))
  12160. {
  12161. $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
  12162. $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
  12163. }
  12164. }
  12165. }
  12166. return $data;
  12167. }
  12168. function do_strip_htmltags($match)
  12169. {
  12170. if ($this->encode_instead_of_strip)
  12171. {
  12172. if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  12173. {
  12174. $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
  12175. $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
  12176. return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
  12177. }
  12178. else
  12179. {
  12180. return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
  12181. }
  12182. }
  12183. elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  12184. {
  12185. return $match[4];
  12186. }
  12187. else
  12188. {
  12189. return '';
  12190. }
  12191. }
  12192. }
  12193. ?>