PageRenderTime 73ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 2ms

/wordpress3.4.2/wp-includes/class-simplepie.php

https://bitbucket.org/ch3tag/mothers
PHP | 15300 lines | 12060 code | 1084 blank | 2156 comment | 1174 complexity | 05891a7601c417cb8f548d5d2bbd74fa MD5 | raw file
  1. <?php
  2. if ( ! class_exists( 'SimplePie' ) ) :
  3. /**
  4. * SimplePie
  5. *
  6. * A PHP-Based RSS and Atom Feed Framework.
  7. * Takes the hard work out of managing a complete RSS/Atom solution.
  8. *
  9. * Copyright (c) 2004-2011, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
  10. * All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or without modification, are
  13. * permitted provided that the following conditions are met:
  14. *
  15. * * Redistributions of source code must retain the above copyright notice, this list of
  16. * conditions and the following disclaimer.
  17. *
  18. * * Redistributions in binary form must reproduce the above copyright notice, this list
  19. * of conditions and the following disclaimer in the documentation and/or other materials
  20. * provided with the distribution.
  21. *
  22. * * Neither the name of the SimplePie Team nor the names of its contributors may be used
  23. * to endorse or promote products derived from this software without specific prior
  24. * written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  27. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  28. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
  29. * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  30. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  31. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  33. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34. * POSSIBILITY OF SUCH DAMAGE.
  35. *
  36. * @package SimplePie
  37. * @version 1.2.1
  38. * @copyright 2004-2011 Ryan Parman, Geoffrey Sneddon, Ryan McCue
  39. * @author Ryan Parman
  40. * @author Geoffrey Sneddon
  41. * @author Ryan McCue
  42. * @link http://simplepie.org/ SimplePie
  43. * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
  44. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  45. * @todo phpDoc comments
  46. */
  47. /**
  48. * SimplePie Name
  49. */
  50. define('SIMPLEPIE_NAME', 'SimplePie');
  51. /**
  52. * SimplePie Version
  53. */
  54. define('SIMPLEPIE_VERSION', '1.2.1');
  55. /**
  56. * SimplePie Build
  57. */
  58. define('SIMPLEPIE_BUILD', '20111015034325');
  59. /**
  60. * SimplePie Website URL
  61. */
  62. define('SIMPLEPIE_URL', 'http://simplepie.org');
  63. /**
  64. * SimplePie Useragent
  65. * @see SimplePie::set_useragent()
  66. */
  67. define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
  68. /**
  69. * SimplePie Linkback
  70. */
  71. define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
  72. /**
  73. * No Autodiscovery
  74. * @see SimplePie::set_autodiscovery_level()
  75. */
  76. define('SIMPLEPIE_LOCATOR_NONE', 0);
  77. /**
  78. * Feed Link Element Autodiscovery
  79. * @see SimplePie::set_autodiscovery_level()
  80. */
  81. define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
  82. /**
  83. * Local Feed Extension Autodiscovery
  84. * @see SimplePie::set_autodiscovery_level()
  85. */
  86. define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
  87. /**
  88. * Local Feed Body Autodiscovery
  89. * @see SimplePie::set_autodiscovery_level()
  90. */
  91. define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
  92. /**
  93. * Remote Feed Extension Autodiscovery
  94. * @see SimplePie::set_autodiscovery_level()
  95. */
  96. define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
  97. /**
  98. * Remote Feed Body Autodiscovery
  99. * @see SimplePie::set_autodiscovery_level()
  100. */
  101. define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
  102. /**
  103. * All Feed Autodiscovery
  104. * @see SimplePie::set_autodiscovery_level()
  105. */
  106. define('SIMPLEPIE_LOCATOR_ALL', 31);
  107. /**
  108. * No known feed type
  109. */
  110. define('SIMPLEPIE_TYPE_NONE', 0);
  111. /**
  112. * RSS 0.90
  113. */
  114. define('SIMPLEPIE_TYPE_RSS_090', 1);
  115. /**
  116. * RSS 0.91 (Netscape)
  117. */
  118. define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
  119. /**
  120. * RSS 0.91 (Userland)
  121. */
  122. define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
  123. /**
  124. * RSS 0.91 (both Netscape and Userland)
  125. */
  126. define('SIMPLEPIE_TYPE_RSS_091', 6);
  127. /**
  128. * RSS 0.92
  129. */
  130. define('SIMPLEPIE_TYPE_RSS_092', 8);
  131. /**
  132. * RSS 0.93
  133. */
  134. define('SIMPLEPIE_TYPE_RSS_093', 16);
  135. /**
  136. * RSS 0.94
  137. */
  138. define('SIMPLEPIE_TYPE_RSS_094', 32);
  139. /**
  140. * RSS 1.0
  141. */
  142. define('SIMPLEPIE_TYPE_RSS_10', 64);
  143. /**
  144. * RSS 2.0
  145. */
  146. define('SIMPLEPIE_TYPE_RSS_20', 128);
  147. /**
  148. * RDF-based RSS
  149. */
  150. define('SIMPLEPIE_TYPE_RSS_RDF', 65);
  151. /**
  152. * Non-RDF-based RSS (truly intended as syndication format)
  153. */
  154. define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
  155. /**
  156. * All RSS
  157. */
  158. define('SIMPLEPIE_TYPE_RSS_ALL', 255);
  159. /**
  160. * Atom 0.3
  161. */
  162. define('SIMPLEPIE_TYPE_ATOM_03', 256);
  163. /**
  164. * Atom 1.0
  165. */
  166. define('SIMPLEPIE_TYPE_ATOM_10', 512);
  167. /**
  168. * All Atom
  169. */
  170. define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
  171. /**
  172. * All feed types
  173. */
  174. define('SIMPLEPIE_TYPE_ALL', 1023);
  175. /**
  176. * No construct
  177. */
  178. define('SIMPLEPIE_CONSTRUCT_NONE', 0);
  179. /**
  180. * Text construct
  181. */
  182. define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
  183. /**
  184. * HTML construct
  185. */
  186. define('SIMPLEPIE_CONSTRUCT_HTML', 2);
  187. /**
  188. * XHTML construct
  189. */
  190. define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
  191. /**
  192. * base64-encoded construct
  193. */
  194. define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
  195. /**
  196. * IRI construct
  197. */
  198. define('SIMPLEPIE_CONSTRUCT_IRI', 16);
  199. /**
  200. * A construct that might be HTML
  201. */
  202. define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
  203. /**
  204. * All constructs
  205. */
  206. define('SIMPLEPIE_CONSTRUCT_ALL', 63);
  207. /**
  208. * Don't change case
  209. */
  210. define('SIMPLEPIE_SAME_CASE', 1);
  211. /**
  212. * Change to lowercase
  213. */
  214. define('SIMPLEPIE_LOWERCASE', 2);
  215. /**
  216. * Change to uppercase
  217. */
  218. define('SIMPLEPIE_UPPERCASE', 4);
  219. /**
  220. * PCRE for HTML attributes
  221. */
  222. 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]*');
  223. /**
  224. * PCRE for XML attributes
  225. */
  226. define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
  227. /**
  228. * XML Namespace
  229. */
  230. define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
  231. /**
  232. * Atom 1.0 Namespace
  233. */
  234. define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
  235. /**
  236. * Atom 0.3 Namespace
  237. */
  238. define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
  239. /**
  240. * RDF Namespace
  241. */
  242. define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
  243. /**
  244. * RSS 0.90 Namespace
  245. */
  246. define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
  247. /**
  248. * RSS 1.0 Namespace
  249. */
  250. define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
  251. /**
  252. * RSS 1.0 Content Module Namespace
  253. */
  254. define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
  255. /**
  256. * RSS 2.0 Namespace
  257. * (Stupid, I know, but I'm certain it will confuse people less with support.)
  258. */
  259. define('SIMPLEPIE_NAMESPACE_RSS_20', '');
  260. /**
  261. * DC 1.0 Namespace
  262. */
  263. define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
  264. /**
  265. * DC 1.1 Namespace
  266. */
  267. define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
  268. /**
  269. * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
  270. */
  271. define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
  272. /**
  273. * GeoRSS Namespace
  274. */
  275. define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
  276. /**
  277. * Media RSS Namespace
  278. */
  279. define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
  280. /**
  281. * Wrong Media RSS Namespace
  282. */
  283. define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
  284. /**
  285. * iTunes RSS Namespace
  286. */
  287. define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
  288. /**
  289. * XHTML Namespace
  290. */
  291. define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
  292. /**
  293. * IANA Link Relations Registry
  294. */
  295. define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
  296. /**
  297. * Whether we're running on PHP5
  298. */
  299. define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
  300. /**
  301. * No file source
  302. */
  303. define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
  304. /**
  305. * Remote file source
  306. */
  307. define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
  308. /**
  309. * Local file source
  310. */
  311. define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
  312. /**
  313. * fsockopen() file source
  314. */
  315. define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
  316. /**
  317. * cURL file source
  318. */
  319. define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
  320. /**
  321. * file_get_contents() file source
  322. */
  323. define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
  324. /**
  325. * SimplePie
  326. *
  327. * @package SimplePie
  328. */
  329. class SimplePie
  330. {
  331. /**
  332. * @var array Raw data
  333. * @access private
  334. */
  335. var $data = array();
  336. /**
  337. * @var mixed Error string
  338. * @access private
  339. */
  340. var $error;
  341. /**
  342. * @var object Instance of SimplePie_Sanitize (or other class)
  343. * @see SimplePie::set_sanitize_class()
  344. * @access private
  345. */
  346. var $sanitize;
  347. /**
  348. * @var string SimplePie Useragent
  349. * @see SimplePie::set_useragent()
  350. * @access private
  351. */
  352. var $useragent = SIMPLEPIE_USERAGENT;
  353. /**
  354. * @var string Feed URL
  355. * @see SimplePie::set_feed_url()
  356. * @access private
  357. */
  358. var $feed_url;
  359. /**
  360. * @var object Instance of SimplePie_File to use as a feed
  361. * @see SimplePie::set_file()
  362. * @access private
  363. */
  364. var $file;
  365. /**
  366. * @var string Raw feed data
  367. * @see SimplePie::set_raw_data()
  368. * @access private
  369. */
  370. var $raw_data;
  371. /**
  372. * @var int Timeout for fetching remote files
  373. * @see SimplePie::set_timeout()
  374. * @access private
  375. */
  376. var $timeout = 10;
  377. /**
  378. * @var bool Forces fsockopen() to be used for remote files instead
  379. * of cURL, even if a new enough version is installed
  380. * @see SimplePie::force_fsockopen()
  381. * @access private
  382. */
  383. var $force_fsockopen = false;
  384. /**
  385. * @var bool Force the given data/URL to be treated as a feed no matter what
  386. * it appears like
  387. * @see SimplePie::force_feed()
  388. * @access private
  389. */
  390. var $force_feed = false;
  391. /**
  392. * @var bool Enable/Disable XML dump
  393. * @see SimplePie::enable_xml_dump()
  394. * @access private
  395. */
  396. var $xml_dump = false;
  397. /**
  398. * @var bool Enable/Disable Caching
  399. * @see SimplePie::enable_cache()
  400. * @access private
  401. */
  402. var $cache = true;
  403. /**
  404. * @var int Cache duration (in seconds)
  405. * @see SimplePie::set_cache_duration()
  406. * @access private
  407. */
  408. var $cache_duration = 3600;
  409. /**
  410. * @var int Auto-discovery cache duration (in seconds)
  411. * @see SimplePie::set_autodiscovery_cache_duration()
  412. * @access private
  413. */
  414. var $autodiscovery_cache_duration = 604800; // 7 Days.
  415. /**
  416. * @var string Cache location (relative to executing script)
  417. * @see SimplePie::set_cache_location()
  418. * @access private
  419. */
  420. var $cache_location = './cache';
  421. /**
  422. * @var string Function that creates the cache filename
  423. * @see SimplePie::set_cache_name_function()
  424. * @access private
  425. */
  426. var $cache_name_function = 'md5';
  427. /**
  428. * @var bool Reorder feed by date descending
  429. * @see SimplePie::enable_order_by_date()
  430. * @access private
  431. */
  432. var $order_by_date = true;
  433. /**
  434. * @var mixed Force input encoding to be set to the follow value
  435. * (false, or anything type-cast to false, disables this feature)
  436. * @see SimplePie::set_input_encoding()
  437. * @access private
  438. */
  439. var $input_encoding = false;
  440. /**
  441. * @var int Feed Autodiscovery Level
  442. * @see SimplePie::set_autodiscovery_level()
  443. * @access private
  444. */
  445. var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
  446. /**
  447. * @var string Class used for caching feeds
  448. * @see SimplePie::set_cache_class()
  449. * @access private
  450. */
  451. var $cache_class = 'SimplePie_Cache';
  452. /**
  453. * @var string Class used for locating feeds
  454. * @see SimplePie::set_locator_class()
  455. * @access private
  456. */
  457. var $locator_class = 'SimplePie_Locator';
  458. /**
  459. * @var string Class used for parsing feeds
  460. * @see SimplePie::set_parser_class()
  461. * @access private
  462. */
  463. var $parser_class = 'SimplePie_Parser';
  464. /**
  465. * @var string Class used for fetching feeds
  466. * @see SimplePie::set_file_class()
  467. * @access private
  468. */
  469. var $file_class = 'SimplePie_File';
  470. /**
  471. * @var string Class used for items
  472. * @see SimplePie::set_item_class()
  473. * @access private
  474. */
  475. var $item_class = 'SimplePie_Item';
  476. /**
  477. * @var string Class used for authors
  478. * @see SimplePie::set_author_class()
  479. * @access private
  480. */
  481. var $author_class = 'SimplePie_Author';
  482. /**
  483. * @var string Class used for categories
  484. * @see SimplePie::set_category_class()
  485. * @access private
  486. */
  487. var $category_class = 'SimplePie_Category';
  488. /**
  489. * @var string Class used for enclosures
  490. * @see SimplePie::set_enclosures_class()
  491. * @access private
  492. */
  493. var $enclosure_class = 'SimplePie_Enclosure';
  494. /**
  495. * @var string Class used for Media RSS <media:text> captions
  496. * @see SimplePie::set_caption_class()
  497. * @access private
  498. */
  499. var $caption_class = 'SimplePie_Caption';
  500. /**
  501. * @var string Class used for Media RSS <media:copyright>
  502. * @see SimplePie::set_copyright_class()
  503. * @access private
  504. */
  505. var $copyright_class = 'SimplePie_Copyright';
  506. /**
  507. * @var string Class used for Media RSS <media:credit>
  508. * @see SimplePie::set_credit_class()
  509. * @access private
  510. */
  511. var $credit_class = 'SimplePie_Credit';
  512. /**
  513. * @var string Class used for Media RSS <media:rating>
  514. * @see SimplePie::set_rating_class()
  515. * @access private
  516. */
  517. var $rating_class = 'SimplePie_Rating';
  518. /**
  519. * @var string Class used for Media RSS <media:restriction>
  520. * @see SimplePie::set_restriction_class()
  521. * @access private
  522. */
  523. var $restriction_class = 'SimplePie_Restriction';
  524. /**
  525. * @var string Class used for content-type sniffing
  526. * @see SimplePie::set_content_type_sniffer_class()
  527. * @access private
  528. */
  529. var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
  530. /**
  531. * @var string Class used for item sources.
  532. * @see SimplePie::set_source_class()
  533. * @access private
  534. */
  535. var $source_class = 'SimplePie_Source';
  536. /**
  537. * @var mixed Set javascript query string parameter (false, or
  538. * anything type-cast to false, disables this feature)
  539. * @see SimplePie::set_javascript()
  540. * @access private
  541. */
  542. var $javascript = 'js';
  543. /**
  544. * @var int Maximum number of feeds to check with autodiscovery
  545. * @see SimplePie::set_max_checked_feeds()
  546. * @access private
  547. */
  548. var $max_checked_feeds = 10;
  549. /**
  550. * @var array All the feeds found during the autodiscovery process
  551. * @see SimplePie::get_all_discovered_feeds()
  552. * @access private
  553. */
  554. var $all_discovered_feeds = array();
  555. /**
  556. * @var string Web-accessible path to the handler_favicon.php file.
  557. * @see SimplePie::set_favicon_handler()
  558. * @access private
  559. */
  560. var $favicon_handler = '';
  561. /**
  562. * @var string Web-accessible path to the handler_image.php file.
  563. * @see SimplePie::set_image_handler()
  564. * @access private
  565. */
  566. var $image_handler = '';
  567. /**
  568. * @var array Stores the URLs when multiple feeds are being initialized.
  569. * @see SimplePie::set_feed_url()
  570. * @access private
  571. */
  572. var $multifeed_url = array();
  573. /**
  574. * @var array Stores SimplePie objects when multiple feeds initialized.
  575. * @access private
  576. */
  577. var $multifeed_objects = array();
  578. /**
  579. * @var array Stores the get_object_vars() array for use with multifeeds.
  580. * @see SimplePie::set_feed_url()
  581. * @access private
  582. */
  583. var $config_settings = null;
  584. /**
  585. * @var integer Stores the number of items to return per-feed with multifeeds.
  586. * @see SimplePie::set_item_limit()
  587. * @access private
  588. */
  589. var $item_limit = 0;
  590. /**
  591. * @var array Stores the default attributes to be stripped by strip_attributes().
  592. * @see SimplePie::strip_attributes()
  593. * @access private
  594. */
  595. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  596. /**
  597. * @var array Stores the default tags to be stripped by strip_htmltags().
  598. * @see SimplePie::strip_htmltags()
  599. * @access private
  600. */
  601. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  602. /**
  603. * The SimplePie class contains feed level data and options
  604. *
  605. * There are two ways that you can create a new SimplePie object. The first
  606. * is by passing a feed URL as a parameter to the SimplePie constructor
  607. * (as well as optionally setting the cache location and cache expiry). This
  608. * will initialise the whole feed with all of the default settings, and you
  609. * can begin accessing methods and properties immediately.
  610. *
  611. * The second way is to create the SimplePie object with no parameters
  612. * at all. This will enable you to set configuration options. After setting
  613. * them, you must initialise the feed using $feed->init(). At that point the
  614. * object's methods and properties will be available to you. This format is
  615. * what is used throughout this documentation.
  616. *
  617. * @access public
  618. * @since 1.0 Preview Release
  619. * @param string $feed_url This is the URL you want to parse.
  620. * @param string $cache_location This is where you want the cache to be stored.
  621. * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
  622. */
  623. function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
  624. {
  625. // Other objects, instances created here so we can set options on them
  626. $this->sanitize =& new SimplePie_Sanitize;
  627. // Set options if they're passed to the constructor
  628. if ($cache_location !== null)
  629. {
  630. $this->set_cache_location($cache_location);
  631. }
  632. if ($cache_duration !== null)
  633. {
  634. $this->set_cache_duration($cache_duration);
  635. }
  636. // Only init the script if we're passed a feed URL
  637. if ($feed_url !== null)
  638. {
  639. $this->set_feed_url($feed_url);
  640. $this->init();
  641. }
  642. }
  643. /**
  644. * Used for converting object to a string
  645. */
  646. function __toString()
  647. {
  648. return md5(serialize($this->data));
  649. }
  650. /**
  651. * Remove items that link back to this before destroying this object
  652. */
  653. function __destruct()
  654. {
  655. if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
  656. {
  657. if (!empty($this->data['items']))
  658. {
  659. foreach ($this->data['items'] as $item)
  660. {
  661. $item->__destruct();
  662. }
  663. unset($item, $this->data['items']);
  664. }
  665. if (!empty($this->data['ordered_items']))
  666. {
  667. foreach ($this->data['ordered_items'] as $item)
  668. {
  669. $item->__destruct();
  670. }
  671. unset($item, $this->data['ordered_items']);
  672. }
  673. }
  674. }
  675. /**
  676. * Force the given data/URL to be treated as a feed no matter what it
  677. * appears like
  678. *
  679. * @access public
  680. * @since 1.1
  681. * @param bool $enable Force the given data/URL to be treated as a feed
  682. */
  683. function force_feed($enable = false)
  684. {
  685. $this->force_feed = (bool) $enable;
  686. }
  687. /**
  688. * This is the URL of the feed you want to parse.
  689. *
  690. * This allows you to enter the URL of the feed you want to parse, or the
  691. * website you want to try to use auto-discovery on. This takes priority
  692. * over any set raw data.
  693. *
  694. * You can set multiple feeds to mash together by passing an array instead
  695. * of a string for the $url. Remember that with each additional feed comes
  696. * additional processing and resources.
  697. *
  698. * @access public
  699. * @since 1.0 Preview Release
  700. * @param mixed $url This is the URL (or array of URLs) that you want to parse.
  701. * @see SimplePie::set_raw_data()
  702. */
  703. function set_feed_url($url)
  704. {
  705. if (is_array($url))
  706. {
  707. $this->multifeed_url = array();
  708. foreach ($url as $value)
  709. {
  710. $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
  711. }
  712. }
  713. else
  714. {
  715. $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
  716. }
  717. }
  718. /**
  719. * Provides an instance of SimplePie_File to use as a feed
  720. *
  721. * @access public
  722. * @param object &$file Instance of SimplePie_File (or subclass)
  723. * @return bool True on success, false on failure
  724. */
  725. function set_file(&$file)
  726. {
  727. if (is_a($file, 'SimplePie_File'))
  728. {
  729. $this->feed_url = $file->url;
  730. $this->file =& $file;
  731. return true;
  732. }
  733. return false;
  734. }
  735. /**
  736. * Allows you to use a string of RSS/Atom data instead of a remote feed.
  737. *
  738. * If you have a feed available as a string in PHP, you can tell SimplePie
  739. * to parse that data string instead of a remote feed. Any set feed URL
  740. * takes precedence.
  741. *
  742. * @access public
  743. * @since 1.0 Beta 3
  744. * @param string $data RSS or Atom data as a string.
  745. * @see SimplePie::set_feed_url()
  746. */
  747. function set_raw_data($data)
  748. {
  749. $this->raw_data = $data;
  750. }
  751. /**
  752. * Allows you to override the default timeout for fetching remote feeds.
  753. *
  754. * This allows you to change the maximum time the feed's server to respond
  755. * and send the feed back.
  756. *
  757. * @access public
  758. * @since 1.0 Beta 3
  759. * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
  760. */
  761. function set_timeout($timeout = 10)
  762. {
  763. $this->timeout = (int) $timeout;
  764. }
  765. /**
  766. * Forces SimplePie to use fsockopen() instead of the preferred cURL
  767. * functions.
  768. *
  769. * @access public
  770. * @since 1.0 Beta 3
  771. * @param bool $enable Force fsockopen() to be used
  772. */
  773. function force_fsockopen($enable = false)
  774. {
  775. $this->force_fsockopen = (bool) $enable;
  776. }
  777. /**
  778. * Outputs the raw XML content of the feed, after it has gone through
  779. * SimplePie's filters.
  780. *
  781. * Used only for debugging, this function will output the XML content as
  782. * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
  783. * before trying to parse it. Many parts of the feed are re-written in
  784. * memory, and in the end, you have a parsable feed. XML dump shows you the
  785. * actual XML that SimplePie tries to parse, which may or may not be very
  786. * different from the original feed.
  787. *
  788. * @access public
  789. * @since 1.0 Preview Release
  790. * @param bool $enable Enable XML dump
  791. */
  792. function enable_xml_dump($enable = false)
  793. {
  794. $this->xml_dump = (bool) $enable;
  795. }
  796. /**
  797. * Enables/disables caching in SimplePie.
  798. *
  799. * This option allows you to disable caching all-together in SimplePie.
  800. * However, disabling the cache can lead to longer load times.
  801. *
  802. * @access public
  803. * @since 1.0 Preview Release
  804. * @param bool $enable Enable caching
  805. */
  806. function enable_cache($enable = true)
  807. {
  808. $this->cache = (bool) $enable;
  809. }
  810. /**
  811. * Set the length of time (in seconds) that the contents of a feed
  812. * will be cached.
  813. *
  814. * @access public
  815. * @param int $seconds The feed content cache duration.
  816. */
  817. function set_cache_duration($seconds = 3600)
  818. {
  819. $this->cache_duration = (int) $seconds;
  820. }
  821. /**
  822. * Set the length of time (in seconds) that the autodiscovered feed
  823. * URL will be cached.
  824. *
  825. * @access public
  826. * @param int $seconds The autodiscovered feed URL cache duration.
  827. */
  828. function set_autodiscovery_cache_duration($seconds = 604800)
  829. {
  830. $this->autodiscovery_cache_duration = (int) $seconds;
  831. }
  832. /**
  833. * Set the file system location where the cached files should be stored.
  834. *
  835. * @access public
  836. * @param string $location The file system location.
  837. */
  838. function set_cache_location($location = './cache')
  839. {
  840. $this->cache_location = (string) $location;
  841. }
  842. /**
  843. * Determines whether feed items should be sorted into reverse chronological order.
  844. *
  845. * @access public
  846. * @param bool $enable Sort as reverse chronological order.
  847. */
  848. function enable_order_by_date($enable = true)
  849. {
  850. $this->order_by_date = (bool) $enable;
  851. }
  852. /**
  853. * Allows you to override the character encoding reported by the feed.
  854. *
  855. * @access public
  856. * @param string $encoding Character encoding.
  857. */
  858. function set_input_encoding($encoding = false)
  859. {
  860. if ($encoding)
  861. {
  862. $this->input_encoding = (string) $encoding;
  863. }
  864. else
  865. {
  866. $this->input_encoding = false;
  867. }
  868. }
  869. /**
  870. * Set how much feed autodiscovery to do
  871. *
  872. * @access public
  873. * @see SIMPLEPIE_LOCATOR_NONE
  874. * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
  875. * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
  876. * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
  877. * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
  878. * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
  879. * @see SIMPLEPIE_LOCATOR_ALL
  880. * @param int $level Feed Autodiscovery Level (level can be a
  881. * combination of the above constants, see bitwise OR operator)
  882. */
  883. function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
  884. {
  885. $this->autodiscovery = (int) $level;
  886. }
  887. /**
  888. * Allows you to change which class SimplePie uses for caching.
  889. * Useful when you are overloading or extending SimplePie's default classes.
  890. *
  891. * @access public
  892. * @param string $class Name of custom class.
  893. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  894. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  895. */
  896. function set_cache_class($class = 'SimplePie_Cache')
  897. {
  898. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
  899. {
  900. $this->cache_class = $class;
  901. return true;
  902. }
  903. return false;
  904. }
  905. /**
  906. * Allows you to change which class SimplePie uses for auto-discovery.
  907. * Useful when you are overloading or extending SimplePie's default classes.
  908. *
  909. * @access public
  910. * @param string $class Name of custom class.
  911. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  912. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  913. */
  914. function set_locator_class($class = 'SimplePie_Locator')
  915. {
  916. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
  917. {
  918. $this->locator_class = $class;
  919. return true;
  920. }
  921. return false;
  922. }
  923. /**
  924. * Allows you to change which class SimplePie uses for XML parsing.
  925. * Useful when you are overloading or extending SimplePie's default classes.
  926. *
  927. * @access public
  928. * @param string $class Name of custom class.
  929. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  930. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  931. */
  932. function set_parser_class($class = 'SimplePie_Parser')
  933. {
  934. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
  935. {
  936. $this->parser_class = $class;
  937. return true;
  938. }
  939. return false;
  940. }
  941. /**
  942. * Allows you to change which class SimplePie uses for remote file fetching.
  943. * Useful when you are overloading or extending SimplePie's default classes.
  944. *
  945. * @access public
  946. * @param string $class Name of custom class.
  947. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  948. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  949. */
  950. function set_file_class($class = 'SimplePie_File')
  951. {
  952. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
  953. {
  954. $this->file_class = $class;
  955. return true;
  956. }
  957. return false;
  958. }
  959. /**
  960. * Allows you to change which class SimplePie uses for data sanitization.
  961. * Useful when you are overloading or extending SimplePie's default classes.
  962. *
  963. * @access public
  964. * @param string $class Name of custom class.
  965. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  966. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  967. */
  968. function set_sanitize_class($class = 'SimplePie_Sanitize')
  969. {
  970. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
  971. {
  972. $this->sanitize =& new $class;
  973. return true;
  974. }
  975. return false;
  976. }
  977. /**
  978. * Allows you to change which class SimplePie uses for handling feed items.
  979. * Useful when you are overloading or extending SimplePie's default classes.
  980. *
  981. * @access public
  982. * @param string $class Name of custom class.
  983. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  984. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  985. */
  986. function set_item_class($class = 'SimplePie_Item')
  987. {
  988. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
  989. {
  990. $this->item_class = $class;
  991. return true;
  992. }
  993. return false;
  994. }
  995. /**
  996. * Allows you to change which class SimplePie uses for handling author data.
  997. * Useful when you are overloading or extending SimplePie's default classes.
  998. *
  999. * @access public
  1000. * @param string $class Name of custom class.
  1001. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1002. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1003. */
  1004. function set_author_class($class = 'SimplePie_Author')
  1005. {
  1006. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
  1007. {
  1008. $this->author_class = $class;
  1009. return true;
  1010. }
  1011. return false;
  1012. }
  1013. /**
  1014. * Allows you to change which class SimplePie uses for handling category data.
  1015. * Useful when you are overloading or extending SimplePie's default classes.
  1016. *
  1017. * @access public
  1018. * @param string $class Name of custom class.
  1019. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1020. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1021. */
  1022. function set_category_class($class = 'SimplePie_Category')
  1023. {
  1024. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
  1025. {
  1026. $this->category_class = $class;
  1027. return true;
  1028. }
  1029. return false;
  1030. }
  1031. /**
  1032. * Allows you to change which class SimplePie uses for feed enclosures.
  1033. * Useful when you are overloading or extending SimplePie's default classes.
  1034. *
  1035. * @access public
  1036. * @param string $class Name of custom class.
  1037. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1038. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1039. */
  1040. function set_enclosure_class($class = 'SimplePie_Enclosure')
  1041. {
  1042. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
  1043. {
  1044. $this->enclosure_class = $class;
  1045. return true;
  1046. }
  1047. return false;
  1048. }
  1049. /**
  1050. * Allows you to change which class SimplePie uses for <media:text> captions
  1051. * Useful when you are overloading or extending SimplePie's default classes.
  1052. *
  1053. * @access public
  1054. * @param string $class Name of custom class.
  1055. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1056. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1057. */
  1058. function set_caption_class($class = 'SimplePie_Caption')
  1059. {
  1060. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
  1061. {
  1062. $this->caption_class = $class;
  1063. return true;
  1064. }
  1065. return false;
  1066. }
  1067. /**
  1068. * Allows you to change which class SimplePie uses for <media:copyright>
  1069. * Useful when you are overloading or extending SimplePie's default classes.
  1070. *
  1071. * @access public
  1072. * @param string $class Name of custom class.
  1073. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1074. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1075. */
  1076. function set_copyright_class($class = 'SimplePie_Copyright')
  1077. {
  1078. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
  1079. {
  1080. $this->copyright_class = $class;
  1081. return true;
  1082. }
  1083. return false;
  1084. }
  1085. /**
  1086. * Allows you to change which class SimplePie uses for <media:credit>
  1087. * Useful when you are overloading or extending SimplePie's default classes.
  1088. *
  1089. * @access public
  1090. * @param string $class Name of custom class.
  1091. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1092. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1093. */
  1094. function set_credit_class($class = 'SimplePie_Credit')
  1095. {
  1096. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
  1097. {
  1098. $this->credit_class = $class;
  1099. return true;
  1100. }
  1101. return false;
  1102. }
  1103. /**
  1104. * Allows you to change which class SimplePie uses for <media:rating>
  1105. * Useful when you are overloading or extending SimplePie's default classes.
  1106. *
  1107. * @access public
  1108. * @param string $class Name of custom class.
  1109. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1110. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1111. */
  1112. function set_rating_class($class = 'SimplePie_Rating')
  1113. {
  1114. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
  1115. {
  1116. $this->rating_class = $class;
  1117. return true;
  1118. }
  1119. return false;
  1120. }
  1121. /**
  1122. * Allows you to change which class SimplePie uses for <media:restriction>
  1123. * Useful when you are overloading or extending SimplePie's default classes.
  1124. *
  1125. * @access public
  1126. * @param string $class Name of custom class.
  1127. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1128. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1129. */
  1130. function set_restriction_class($class = 'SimplePie_Restriction')
  1131. {
  1132. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
  1133. {
  1134. $this->restriction_class = $class;
  1135. return true;
  1136. }
  1137. return false;
  1138. }
  1139. /**
  1140. * Allows you to change which class SimplePie uses for content-type sniffing.
  1141. * Useful when you are overloading or extending SimplePie's default classes.
  1142. *
  1143. * @access public
  1144. * @param string $class Name of custom class.
  1145. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1146. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1147. */
  1148. function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
  1149. {
  1150. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
  1151. {
  1152. $this->content_type_sniffer_class = $class;
  1153. return true;
  1154. }
  1155. return false;
  1156. }
  1157. /**
  1158. * Allows you to change which class SimplePie uses item sources.
  1159. * Useful when you are overloading or extending SimplePie's default classes.
  1160. *
  1161. * @access public
  1162. * @param string $class Name of custom class.
  1163. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1164. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1165. */
  1166. function set_source_class($class = 'SimplePie_Source')
  1167. {
  1168. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
  1169. {
  1170. $this->source_class = $class;
  1171. return true;
  1172. }
  1173. return false;
  1174. }
  1175. /**
  1176. * Allows you to override the default user agent string.
  1177. *
  1178. * @access public
  1179. * @param string $ua New user agent string.
  1180. */
  1181. function set_useragent($ua = SIMPLEPIE_USERAGENT)
  1182. {
  1183. $this->useragent = (string) $ua;
  1184. }
  1185. /**
  1186. * Set callback function to create cache filename with
  1187. *
  1188. * @access public
  1189. * @param mixed $function Callback function
  1190. */
  1191. function set_cache_name_function($function = 'md5')
  1192. {
  1193. if (is_callable($function))
  1194. {
  1195. $this->cache_name_function = $function;
  1196. }
  1197. }
  1198. /**
  1199. * Set javascript query string parameter
  1200. *
  1201. * @access public
  1202. * @param mixed $get Javascript query string parameter
  1203. */
  1204. function set_javascript($get = 'js')
  1205. {
  1206. if ($get)
  1207. {
  1208. $this->javascript = (string) $get;
  1209. }
  1210. else
  1211. {
  1212. $this->javascript = false;
  1213. }
  1214. }
  1215. /**
  1216. * Set options to make SP as fast as possible. Forgoes a
  1217. * substantial amount of data sanitization in favor of speed.
  1218. *
  1219. * @access public
  1220. * @param bool $set Whether to set them or not
  1221. */
  1222. function set_stupidly_fast($set = false)
  1223. {
  1224. if ($set)
  1225. {
  1226. $this->enable_order_by_date(false);
  1227. $this->remove_div(false);
  1228. $this->strip_comments(false);
  1229. $this->strip_htmltags(false);
  1230. $this->strip_attributes(false);
  1231. $this->set_image_handler(false);
  1232. }
  1233. }
  1234. /**
  1235. * Set maximum number of feeds to check with autodiscovery
  1236. *
  1237. * @access public
  1238. * @param int $max Maximum number of feeds to check
  1239. */
  1240. function set_max_checked_feeds($max = 10)
  1241. {
  1242. $this->max_checked_feeds = (int) $max;
  1243. }
  1244. function remove_div($enable = true)
  1245. {
  1246. $this->sanitize->remove_div($enable);
  1247. }
  1248. function strip_htmltags($tags = '', $encode = null)
  1249. {
  1250. if ($tags === '')
  1251. {
  1252. $tags = $this->strip_htmltags;
  1253. }
  1254. $this->sanitize->strip_htmltags($tags);
  1255. if ($encode !== null)
  1256. {
  1257. $this->sanitize->encode_instead_of_strip($tags);
  1258. }
  1259. }
  1260. function encode_instead_of_strip($enable = true)
  1261. {
  1262. $this->sanitize->encode_instead_of_strip($enable);
  1263. }
  1264. function strip_attributes($attribs = '')
  1265. {
  1266. if ($attribs === '')
  1267. {
  1268. $attribs = $this->strip_attributes;
  1269. }
  1270. $this->sanitize->strip_attributes($attribs);
  1271. }
  1272. function set_output_encoding($encoding = 'UTF-8')
  1273. {
  1274. $this->sanitize->set_output_encoding($encoding);
  1275. }
  1276. function strip_comments($strip = false)
  1277. {
  1278. $this->sanitize->strip_comments($strip);
  1279. }
  1280. /**
  1281. * Set element/attribute key/value pairs of HTML attributes
  1282. * containing URLs that need to be resolved relative to the feed
  1283. *
  1284. * @access public
  1285. * @since 1.0
  1286. * @param array $element_attribute Element/attribute key/value pairs
  1287. */
  1288. 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'))
  1289. {
  1290. $this->sanitize->set_url_replacements($element_attribute);
  1291. }
  1292. /**
  1293. * Set the handler to enable the display of cached favicons.
  1294. *
  1295. * @access public
  1296. * @param str $page Web-accessible path to the handler_favicon.php file.
  1297. * @param str $qs The query string that the value should be passed to.
  1298. */
  1299. function set_favicon_handler($page = false, $qs = 'i')
  1300. {
  1301. if ($page !== false)
  1302. {
  1303. $this->favicon_handler = $page . '?' . $qs . '=';
  1304. }
  1305. else
  1306. {
  1307. $this->favicon_handler = '';
  1308. }
  1309. }
  1310. /**
  1311. * Set the handler to enable the display of cached images.
  1312. *
  1313. * @access public
  1314. * @param str $page Web-accessible path to the handler_image.php file.
  1315. * @param str $qs The query string that the value should be passed to.
  1316. */
  1317. function set_image_handler($page = false, $qs = 'i')
  1318. {
  1319. if ($page !== false)
  1320. {
  1321. $this->sanitize->set_image_handler($page . '?' . $qs . '=');
  1322. }
  1323. else
  1324. {
  1325. $this->image_handler = '';
  1326. }
  1327. }
  1328. /**
  1329. * Set the limit for items returned per-feed with multifeeds.
  1330. *
  1331. * @access public
  1332. * @param integer $limit The maximum number of items to return.
  1333. */
  1334. function set_item_limit($limit = 0)
  1335. {
  1336. $this->item_limit = (int) $limit;
  1337. }
  1338. function init()
  1339. {
  1340. // Check absolute bare minimum requirements.
  1341. if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
  1342. {
  1343. return false;
  1344. }
  1345. // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader.
  1346. elseif (!extension_loaded('xmlreader'))
  1347. {
  1348. static $xml_is_sane = null;
  1349. if ($xml_is_sane === null)
  1350. {
  1351. $parser_check = xml_parser_create();
  1352. xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
  1353. xml_parser_free($parser_check);
  1354. $xml_is_sane = isset($values[0]['value']);
  1355. }
  1356. if (!$xml_is_sane)
  1357. {
  1358. return false;
  1359. }
  1360. }
  1361. if (isset($_GET[$this->javascript]))
  1362. {
  1363. SimplePie_Misc::output_javascript();
  1364. exit;
  1365. }
  1366. // Pass whatever was set with config options over to the sanitizer.
  1367. $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
  1368. $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
  1369. if ($this->feed_url !== null || $this->raw_data !== null)
  1370. {
  1371. $this->data = array();
  1372. $this->multifeed_objects = array();
  1373. $cache = false;
  1374. if ($this->feed_url !== null)
  1375. {
  1376. $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
  1377. // Decide whether to enable caching
  1378. if ($this->cache && $parsed_feed_url['scheme'] !== '')
  1379. {
  1380. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
  1381. }
  1382. // If it's enabled and we don't want an XML dump, use the cache
  1383. if ($cache && !$this->xml_dump)
  1384. {
  1385. // Load the Cache
  1386. $this->data = $cache->load();
  1387. if (!empty($this->data))
  1388. {
  1389. // If the cache is for an outdated build of SimplePie
  1390. if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
  1391. {
  1392. $cache->unlink();
  1393. $this->data = array();
  1394. }
  1395. // If we've hit a collision just rerun it with caching disabled
  1396. elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
  1397. {
  1398. $cache = false;
  1399. $this->data = array();
  1400. }
  1401. // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
  1402. elseif (isset($this->data['feed_url']))
  1403. {
  1404. // If the autodiscovery cache is still valid use it.
  1405. if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
  1406. {
  1407. // Do not need to do feed autodiscovery yet.
  1408. if ($this->data['feed_url'] === $this->data['url'])
  1409. {
  1410. $cache->unlink();
  1411. $this->data = array();
  1412. }
  1413. else
  1414. {
  1415. $this->set_feed_url($this->data['feed_url']);
  1416. return $this->init();
  1417. }
  1418. }
  1419. }
  1420. // Check if the cache has been updated
  1421. elseif ($cache->mtime() + $this->cache_duration < time())
  1422. {
  1423. // If we have last-modified and/or etag set
  1424. if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
  1425. {
  1426. $headers = array();
  1427. if (isset($this->data['headers']['last-modified']))
  1428. {
  1429. $headers['if-modified-since'] = $this->data['headers']['last-modified'];
  1430. }
  1431. if (isset($this->data['headers']['etag']))
  1432. {
  1433. $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
  1434. }
  1435. $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
  1436. if ($file->success)
  1437. {
  1438. if ($file->status_code === 304)
  1439. {
  1440. $cache->touch();
  1441. return true;
  1442. }
  1443. else
  1444. {
  1445. $headers = $file->headers;
  1446. }
  1447. }
  1448. else
  1449. {
  1450. unset($file);
  1451. }
  1452. }
  1453. }
  1454. // If the cache is still valid, just return true
  1455. else
  1456. {
  1457. return true;
  1458. }
  1459. }
  1460. // If the cache is empty, delete it
  1461. else
  1462. {
  1463. $cache->unlink();
  1464. $this->data = array();
  1465. }
  1466. }
  1467. // 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.
  1468. if (!isset($file))
  1469. {
  1470. if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url)
  1471. {
  1472. $file =& $this->file;
  1473. }
  1474. else
  1475. {
  1476. $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
  1477. }
  1478. }
  1479. // If the file connection has an error, set SimplePie::error to that and quit
  1480. if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
  1481. {
  1482. $this->error = $file->error;
  1483. if (!empty($this->data))
  1484. {
  1485. return true;
  1486. }
  1487. else
  1488. {
  1489. return false;
  1490. }
  1491. }
  1492. if (!$this->force_feed)
  1493. {
  1494. // Check if the supplied URL is a feed, if it isn't, look for it.
  1495. $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
  1496. if (!$locate->is_feed($file))
  1497. {
  1498. // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
  1499. unset($file);
  1500. if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))
  1501. {
  1502. if ($cache)
  1503. {
  1504. $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
  1505. if (!$cache->save($this))
  1506. {
  1507. trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
  1508. }
  1509. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
  1510. }
  1511. $this->feed_url = $file->url;
  1512. }
  1513. else
  1514. {
  1515. $this->error = "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME . " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed.";
  1516. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1517. return false;
  1518. }
  1519. }
  1520. $locate = null;
  1521. }
  1522. $headers = $file->headers;
  1523. $data = $file->body;
  1524. $sniffer =& new $this->content_type_sniffer_class($file);
  1525. $sniffed = $sniffer->get_type();
  1526. }
  1527. else
  1528. {
  1529. $data = $this->raw_data;
  1530. }
  1531. // Set up array of possible encodings
  1532. $encodings = array();
  1533. // First check to see if input has been overridden.
  1534. if ($this->input_encoding !== false)
  1535. {
  1536. $encodings[] = $this->input_encoding;
  1537. }
  1538. $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
  1539. $text_types = array('text/xml', 'text/xml-external-parsed-entity');
  1540. // RFC 3023 (only applies to sniffed content)
  1541. if (isset($sniffed))
  1542. {
  1543. if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
  1544. {
  1545. if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  1546. {
  1547. $encodings[] = strtoupper($charset[1]);
  1548. }
  1549. $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
  1550. $encodings[] = 'UTF-8';
  1551. }
  1552. elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
  1553. {
  1554. if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  1555. {
  1556. $encodings[] = $charset[1];
  1557. }
  1558. $encodings[] = 'US-ASCII';
  1559. }
  1560. // Text MIME-type default
  1561. elseif (substr($sniffed, 0, 5) === 'text/')
  1562. {
  1563. $encodings[] = 'US-ASCII';
  1564. }
  1565. }
  1566. // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
  1567. $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
  1568. $encodings[] = 'UTF-8';
  1569. $encodings[] = 'ISO-8859-1';
  1570. // There's no point in trying an encoding twice
  1571. $encodings = array_unique($encodings);
  1572. // If we want the XML, just output that with the most likely encoding and quit
  1573. if ($this->xml_dump)
  1574. {
  1575. header('Content-type: text/xml; charset=' . $encodings[0]);
  1576. echo $data;
  1577. exit;
  1578. }
  1579. // Loop through each possible encoding, till we return something, or run out of possibilities
  1580. foreach ($encodings as $encoding)
  1581. {
  1582. // Change the encoding to UTF-8 (as we always use UTF-8 internally)
  1583. if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
  1584. {
  1585. // Create new parser
  1586. $parser =& new $this->parser_class();
  1587. // If it's parsed fine
  1588. if ($parser->parse($utf8_data, 'UTF-8'))
  1589. {
  1590. $this->data = $parser->get_data();
  1591. if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
  1592. {
  1593. if (isset($headers))
  1594. {
  1595. $this->data['headers'] = $headers;
  1596. }
  1597. $this->data['build'] = SIMPLEPIE_BUILD;
  1598. // Cache the file if caching is enabled
  1599. if ($cache && !$cache->save($this))
  1600. {
  1601. trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
  1602. }
  1603. return true;
  1604. }
  1605. else
  1606. {
  1607. $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
  1608. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1609. return false;
  1610. }
  1611. }
  1612. }
  1613. }
  1614. if (isset($parser))
  1615. {
  1616. // We have an error, just set SimplePie_Misc::error to it and quit
  1617. $this->error = sprintf('This XML document is invalid, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
  1618. }
  1619. else
  1620. {
  1621. $this->error = 'The data could not be converted to UTF-8. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.';
  1622. }
  1623. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1624. return false;
  1625. }
  1626. elseif (!empty($this->multifeed_url))
  1627. {
  1628. $i = 0;
  1629. $success = 0;
  1630. $this->multifeed_objects = array();
  1631. foreach ($this->multifeed_url as $url)
  1632. {
  1633. if (SIMPLEPIE_PHP5)
  1634. {
  1635. // This keyword needs to defy coding standards for PHP4 compatibility
  1636. $this->multifeed_objects[$i] = clone($this);
  1637. }
  1638. else
  1639. {
  1640. $this->multifeed_objects[$i] = $this;
  1641. }
  1642. $this->multifeed_objects[$i]->set_feed_url($url);
  1643. $success |= $this->multifeed_objects[$i]->init();
  1644. $i++;
  1645. }
  1646. return (bool) $success;
  1647. }
  1648. else
  1649. {
  1650. return false;
  1651. }
  1652. }
  1653. /**
  1654. * Return the error message for the occured error
  1655. *
  1656. * @access public
  1657. * @return string Error message
  1658. */
  1659. function error()
  1660. {
  1661. return $this->error;
  1662. }
  1663. function get_encoding()
  1664. {
  1665. return $this->sanitize->output_encoding;
  1666. }
  1667. function handle_content_type($mime = 'text/html')
  1668. {
  1669. if (!headers_sent())
  1670. {
  1671. $header = "Content-type: $mime;";
  1672. if ($this->get_encoding())
  1673. {
  1674. $header .= ' charset=' . $this->get_encoding();
  1675. }
  1676. else
  1677. {
  1678. $header .= ' charset=UTF-8';
  1679. }
  1680. header($header);
  1681. }
  1682. }
  1683. function get_type()
  1684. {
  1685. if (!isset($this->data['type']))
  1686. {
  1687. $this->data['type'] = SIMPLEPIE_TYPE_ALL;
  1688. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
  1689. {
  1690. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
  1691. }
  1692. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
  1693. {
  1694. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
  1695. }
  1696. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
  1697. {
  1698. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
  1699. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
  1700. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
  1701. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
  1702. {
  1703. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
  1704. }
  1705. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
  1706. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
  1707. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
  1708. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
  1709. {
  1710. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
  1711. }
  1712. }
  1713. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
  1714. {
  1715. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
  1716. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
  1717. {
  1718. switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
  1719. {
  1720. case '0.91':
  1721. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
  1722. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
  1723. {
  1724. switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
  1725. {
  1726. case '0':
  1727. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
  1728. break;
  1729. case '24':
  1730. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
  1731. break;
  1732. }
  1733. }
  1734. break;
  1735. case '0.92':
  1736. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
  1737. break;
  1738. case '0.93':
  1739. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
  1740. break;
  1741. case '0.94':
  1742. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
  1743. break;
  1744. case '2.0':
  1745. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
  1746. break;
  1747. }
  1748. }
  1749. }
  1750. else
  1751. {
  1752. $this->data['type'] = SIMPLEPIE_TYPE_NONE;
  1753. }
  1754. }
  1755. return $this->data['type'];
  1756. }
  1757. /**
  1758. * Returns the URL for the favicon of the feed's website.
  1759. *
  1760. * @todo Cache atom:icon
  1761. * @access public
  1762. * @since 1.0
  1763. */
  1764. function get_favicon()
  1765. {
  1766. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  1767. {
  1768. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1769. }
  1770. elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
  1771. {
  1772. $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
  1773. if ($this->cache && $this->favicon_handler)
  1774. {
  1775. $favicon_filename = call_user_func($this->cache_name_function, $favicon);
  1776. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
  1777. if ($cache->load())
  1778. {
  1779. return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
  1780. }
  1781. else
  1782. {
  1783. $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
  1784. if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
  1785. {
  1786. $sniffer =& new $this->content_type_sniffer_class($file);
  1787. if (substr($sniffer->get_type(), 0, 6) === 'image/')
  1788. {
  1789. if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  1790. {
  1791. return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
  1792. }
  1793. else
  1794. {
  1795. trigger_error("$cache->name is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
  1796. return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
  1797. }
  1798. }
  1799. // not an image
  1800. else
  1801. {
  1802. return false;
  1803. }
  1804. }
  1805. }
  1806. }
  1807. else
  1808. {
  1809. return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
  1810. }
  1811. }
  1812. return false;
  1813. }
  1814. /**
  1815. * @todo If we have a perm redirect we should return the new URL
  1816. * @todo When we make the above change, let's support <itunes:new-feed-url> as well
  1817. * @todo Also, |atom:link|@rel=self
  1818. */
  1819. function subscribe_url()
  1820. {
  1821. if ($this->feed_url !== null)
  1822. {
  1823. return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
  1824. }
  1825. else
  1826. {
  1827. return null;
  1828. }
  1829. }
  1830. function subscribe_feed()
  1831. {
  1832. if ($this->feed_url !== null)
  1833. {
  1834. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
  1835. }
  1836. else
  1837. {
  1838. return null;
  1839. }
  1840. }
  1841. function subscribe_outlook()
  1842. {
  1843. if ($this->feed_url !== null)
  1844. {
  1845. return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
  1846. }
  1847. else
  1848. {
  1849. return null;
  1850. }
  1851. }
  1852. function subscribe_podcast()
  1853. {
  1854. if ($this->feed_url !== null)
  1855. {
  1856. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
  1857. }
  1858. else
  1859. {
  1860. return null;
  1861. }
  1862. }
  1863. function subscribe_itunes()
  1864. {
  1865. if ($this->feed_url !== null)
  1866. {
  1867. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
  1868. }
  1869. else
  1870. {
  1871. return null;
  1872. }
  1873. }
  1874. /**
  1875. * Creates the subscribe_* methods' return data
  1876. *
  1877. * @access private
  1878. * @param string $feed_url String to prefix to the feed URL
  1879. * @param string $site_url String to prefix to the site URL (and
  1880. * suffix to the feed URL)
  1881. * @return mixed URL if feed exists, false otherwise
  1882. */
  1883. function subscribe_service($feed_url, $site_url = null)
  1884. {
  1885. if ($this->subscribe_url())
  1886. {
  1887. $return = $feed_url . rawurlencode($this->feed_url);
  1888. if ($site_url !== null && $this->get_link() !== null)
  1889. {
  1890. $return .= $site_url . rawurlencode($this->get_link());
  1891. }
  1892. return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
  1893. }
  1894. else
  1895. {
  1896. return null;
  1897. }
  1898. }
  1899. function subscribe_aol()
  1900. {
  1901. return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
  1902. }
  1903. function subscribe_bloglines()
  1904. {
  1905. return $this->subscribe_service('http://www.bloglines.com/sub/');
  1906. }
  1907. function subscribe_eskobo()
  1908. {
  1909. return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
  1910. }
  1911. function subscribe_feedfeeds()
  1912. {
  1913. return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
  1914. }
  1915. function subscribe_feedster()
  1916. {
  1917. return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
  1918. }
  1919. function subscribe_google()
  1920. {
  1921. return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
  1922. }
  1923. function subscribe_gritwire()
  1924. {
  1925. return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
  1926. }
  1927. function subscribe_msn()
  1928. {
  1929. return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
  1930. }
  1931. function subscribe_netvibes()
  1932. {
  1933. return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
  1934. }
  1935. function subscribe_newsburst()
  1936. {
  1937. return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
  1938. }
  1939. function subscribe_newsgator()
  1940. {
  1941. return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
  1942. }
  1943. function subscribe_odeo()
  1944. {
  1945. return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
  1946. }
  1947. function subscribe_podnova()
  1948. {
  1949. return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
  1950. }
  1951. function subscribe_rojo()
  1952. {
  1953. return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
  1954. }
  1955. function subscribe_yahoo()
  1956. {
  1957. return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
  1958. }
  1959. function get_feed_tags($namespace, $tag)
  1960. {
  1961. $type = $this->get_type();
  1962. if ($type & SIMPLEPIE_TYPE_ATOM_10)
  1963. {
  1964. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
  1965. {
  1966. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
  1967. }
  1968. }
  1969. if ($type & SIMPLEPIE_TYPE_ATOM_03)
  1970. {
  1971. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
  1972. {
  1973. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
  1974. }
  1975. }
  1976. if ($type & SIMPLEPIE_TYPE_RSS_RDF)
  1977. {
  1978. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
  1979. {
  1980. return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
  1981. }
  1982. }
  1983. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  1984. {
  1985. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
  1986. {
  1987. return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
  1988. }
  1989. }
  1990. return null;
  1991. }
  1992. function get_channel_tags($namespace, $tag)
  1993. {
  1994. $type = $this->get_type();
  1995. if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
  1996. {
  1997. if ($return = $this->get_feed_tags($namespace, $tag))
  1998. {
  1999. return $return;
  2000. }
  2001. }
  2002. if ($type & SIMPLEPIE_TYPE_RSS_10)
  2003. {
  2004. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
  2005. {
  2006. if (isset($channel[0]['child'][$namespace][$tag]))
  2007. {
  2008. return $channel[0]['child'][$namespace][$tag];
  2009. }
  2010. }
  2011. }
  2012. if ($type & SIMPLEPIE_TYPE_RSS_090)
  2013. {
  2014. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
  2015. {
  2016. if (isset($channel[0]['child'][$namespace][$tag]))
  2017. {
  2018. return $channel[0]['child'][$namespace][$tag];
  2019. }
  2020. }
  2021. }
  2022. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  2023. {
  2024. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
  2025. {
  2026. if (isset($channel[0]['child'][$namespace][$tag]))
  2027. {
  2028. return $channel[0]['child'][$namespace][$tag];
  2029. }
  2030. }
  2031. }
  2032. return null;
  2033. }
  2034. function get_image_tags($namespace, $tag)
  2035. {
  2036. $type = $this->get_type();
  2037. if ($type & SIMPLEPIE_TYPE_RSS_10)
  2038. {
  2039. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
  2040. {
  2041. if (isset($image[0]['child'][$namespace][$tag]))
  2042. {
  2043. return $image[0]['child'][$namespace][$tag];
  2044. }
  2045. }
  2046. }
  2047. if ($type & SIMPLEPIE_TYPE_RSS_090)
  2048. {
  2049. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
  2050. {
  2051. if (isset($image[0]['child'][$namespace][$tag]))
  2052. {
  2053. return $image[0]['child'][$namespace][$tag];
  2054. }
  2055. }
  2056. }
  2057. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  2058. {
  2059. if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
  2060. {
  2061. if (isset($image[0]['child'][$namespace][$tag]))
  2062. {
  2063. return $image[0]['child'][$namespace][$tag];
  2064. }
  2065. }
  2066. }
  2067. return null;
  2068. }
  2069. function get_base($element = array())
  2070. {
  2071. if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
  2072. {
  2073. return $element['xml_base'];
  2074. }
  2075. elseif ($this->get_link() !== null)
  2076. {
  2077. return $this->get_link();
  2078. }
  2079. else
  2080. {
  2081. return $this->subscribe_url();
  2082. }
  2083. }
  2084. function sanitize($data, $type, $base = '')
  2085. {
  2086. return $this->sanitize->sanitize($data, $type, $base);
  2087. }
  2088. function get_title()
  2089. {
  2090. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  2091. {
  2092. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2093. }
  2094. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  2095. {
  2096. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2097. }
  2098. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2099. {
  2100. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2101. }
  2102. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2103. {
  2104. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2105. }
  2106. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  2107. {
  2108. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2109. }
  2110. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2111. {
  2112. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2113. }
  2114. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2115. {
  2116. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2117. }
  2118. else
  2119. {
  2120. return null;
  2121. }
  2122. }
  2123. function get_category($key = 0)
  2124. {
  2125. $categories = $this->get_categories();
  2126. if (isset($categories[$key]))
  2127. {
  2128. return $categories[$key];
  2129. }
  2130. else
  2131. {
  2132. return null;
  2133. }
  2134. }
  2135. function get_categories()
  2136. {
  2137. $categories = array();
  2138. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  2139. {
  2140. $term = null;
  2141. $scheme = null;
  2142. $label = null;
  2143. if (isset($category['attribs']['']['term']))
  2144. {
  2145. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  2146. }
  2147. if (isset($category['attribs']['']['scheme']))
  2148. {
  2149. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  2150. }
  2151. if (isset($category['attribs']['']['label']))
  2152. {
  2153. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  2154. }
  2155. $categories[] =& new $this->category_class($term, $scheme, $label);
  2156. }
  2157. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
  2158. {
  2159. // This is really the label, but keep this as the term also for BC.
  2160. // Label will also work on retrieving because that falls back to term.
  2161. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2162. if (isset($category['attribs']['']['domain']))
  2163. {
  2164. $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
  2165. }
  2166. else
  2167. {
  2168. $scheme = null;
  2169. }
  2170. $categories[] =& new $this->category_class($term, $scheme, null);
  2171. }
  2172. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  2173. {
  2174. $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2175. }
  2176. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  2177. {
  2178. $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2179. }
  2180. if (!empty($categories))
  2181. {
  2182. return SimplePie_Misc::array_unique($categories);
  2183. }
  2184. else
  2185. {
  2186. return null;
  2187. }
  2188. }
  2189. function get_author($key = 0)
  2190. {
  2191. $authors = $this->get_authors();
  2192. if (isset($authors[$key]))
  2193. {
  2194. return $authors[$key];
  2195. }
  2196. else
  2197. {
  2198. return null;
  2199. }
  2200. }
  2201. function get_authors()
  2202. {
  2203. $authors = array();
  2204. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  2205. {
  2206. $name = null;
  2207. $uri = null;
  2208. $email = null;
  2209. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  2210. {
  2211. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2212. }
  2213. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  2214. {
  2215. $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]));
  2216. }
  2217. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  2218. {
  2219. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2220. }
  2221. if ($name !== null || $email !== null || $uri !== null)
  2222. {
  2223. $authors[] =& new $this->author_class($name, $uri, $email);
  2224. }
  2225. }
  2226. if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  2227. {
  2228. $name = null;
  2229. $url = null;
  2230. $email = null;
  2231. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  2232. {
  2233. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2234. }
  2235. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  2236. {
  2237. $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]));
  2238. }
  2239. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  2240. {
  2241. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2242. }
  2243. if ($name !== null || $email !== null || $url !== null)
  2244. {
  2245. $authors[] =& new $this->author_class($name, $url, $email);
  2246. }
  2247. }
  2248. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  2249. {
  2250. $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2251. }
  2252. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  2253. {
  2254. $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2255. }
  2256. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  2257. {
  2258. $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2259. }
  2260. if (!empty($authors))
  2261. {
  2262. return SimplePie_Misc::array_unique($authors);
  2263. }
  2264. else
  2265. {
  2266. return null;
  2267. }
  2268. }
  2269. function get_contributor($key = 0)
  2270. {
  2271. $contributors = $this->get_contributors();
  2272. if (isset($contributors[$key]))
  2273. {
  2274. return $contributors[$key];
  2275. }
  2276. else
  2277. {
  2278. return null;
  2279. }
  2280. }
  2281. function get_contributors()
  2282. {
  2283. $contributors = array();
  2284. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  2285. {
  2286. $name = null;
  2287. $uri = null;
  2288. $email = null;
  2289. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  2290. {
  2291. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2292. }
  2293. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  2294. {
  2295. $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]));
  2296. }
  2297. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  2298. {
  2299. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2300. }
  2301. if ($name !== null || $email !== null || $uri !== null)
  2302. {
  2303. $contributors[] =& new $this->author_class($name, $uri, $email);
  2304. }
  2305. }
  2306. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  2307. {
  2308. $name = null;
  2309. $url = null;
  2310. $email = null;
  2311. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  2312. {
  2313. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2314. }
  2315. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  2316. {
  2317. $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]));
  2318. }
  2319. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  2320. {
  2321. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2322. }
  2323. if ($name !== null || $email !== null || $url !== null)
  2324. {
  2325. $contributors[] =& new $this->author_class($name, $url, $email);
  2326. }
  2327. }
  2328. if (!empty($contributors))
  2329. {
  2330. return SimplePie_Misc::array_unique($contributors);
  2331. }
  2332. else
  2333. {
  2334. return null;
  2335. }
  2336. }
  2337. function get_link($key = 0, $rel = 'alternate')
  2338. {
  2339. $links = $this->get_links($rel);
  2340. if (isset($links[$key]))
  2341. {
  2342. return $links[$key];
  2343. }
  2344. else
  2345. {
  2346. return null;
  2347. }
  2348. }
  2349. /**
  2350. * Added for parity between the parent-level and the item/entry-level.
  2351. */
  2352. function get_permalink()
  2353. {
  2354. return $this->get_link(0);
  2355. }
  2356. function get_links($rel = 'alternate')
  2357. {
  2358. if (!isset($this->data['links']))
  2359. {
  2360. $this->data['links'] = array();
  2361. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  2362. {
  2363. foreach ($links as $link)
  2364. {
  2365. if (isset($link['attribs']['']['href']))
  2366. {
  2367. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2368. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2369. }
  2370. }
  2371. }
  2372. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  2373. {
  2374. foreach ($links as $link)
  2375. {
  2376. if (isset($link['attribs']['']['href']))
  2377. {
  2378. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2379. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2380. }
  2381. }
  2382. }
  2383. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2384. {
  2385. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2386. }
  2387. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2388. {
  2389. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2390. }
  2391. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  2392. {
  2393. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2394. }
  2395. $keys = array_keys($this->data['links']);
  2396. foreach ($keys as $key)
  2397. {
  2398. if (SimplePie_Misc::is_isegment_nz_nc($key))
  2399. {
  2400. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  2401. {
  2402. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  2403. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  2404. }
  2405. else
  2406. {
  2407. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  2408. }
  2409. }
  2410. elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  2411. {
  2412. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  2413. }
  2414. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  2415. }
  2416. }
  2417. if (isset($this->data['links'][$rel]))
  2418. {
  2419. return $this->data['links'][$rel];
  2420. }
  2421. else
  2422. {
  2423. return null;
  2424. }
  2425. }
  2426. function get_all_discovered_feeds()
  2427. {
  2428. return $this->all_discovered_feeds;
  2429. }
  2430. function get_description()
  2431. {
  2432. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  2433. {
  2434. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2435. }
  2436. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  2437. {
  2438. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2439. }
  2440. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  2441. {
  2442. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2443. }
  2444. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  2445. {
  2446. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2447. }
  2448. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
  2449. {
  2450. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2451. }
  2452. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  2453. {
  2454. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2455. }
  2456. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  2457. {
  2458. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2459. }
  2460. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  2461. {
  2462. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2463. }
  2464. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  2465. {
  2466. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2467. }
  2468. else
  2469. {
  2470. return null;
  2471. }
  2472. }
  2473. function get_copyright()
  2474. {
  2475. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  2476. {
  2477. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2478. }
  2479. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
  2480. {
  2481. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2482. }
  2483. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
  2484. {
  2485. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2486. }
  2487. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  2488. {
  2489. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2490. }
  2491. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  2492. {
  2493. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2494. }
  2495. else
  2496. {
  2497. return null;
  2498. }
  2499. }
  2500. function get_language()
  2501. {
  2502. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
  2503. {
  2504. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2505. }
  2506. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  2507. {
  2508. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2509. }
  2510. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  2511. {
  2512. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2513. }
  2514. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
  2515. {
  2516. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2517. }
  2518. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
  2519. {
  2520. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2521. }
  2522. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
  2523. {
  2524. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2525. }
  2526. elseif (isset($this->data['headers']['content-language']))
  2527. {
  2528. return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
  2529. }
  2530. else
  2531. {
  2532. return null;
  2533. }
  2534. }
  2535. function get_latitude()
  2536. {
  2537. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  2538. {
  2539. return (float) $return[0]['data'];
  2540. }
  2541. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  2542. {
  2543. return (float) $match[1];
  2544. }
  2545. else
  2546. {
  2547. return null;
  2548. }
  2549. }
  2550. function get_longitude()
  2551. {
  2552. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  2553. {
  2554. return (float) $return[0]['data'];
  2555. }
  2556. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  2557. {
  2558. return (float) $return[0]['data'];
  2559. }
  2560. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  2561. {
  2562. return (float) $match[2];
  2563. }
  2564. else
  2565. {
  2566. return null;
  2567. }
  2568. }
  2569. function get_image_title()
  2570. {
  2571. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2572. {
  2573. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2574. }
  2575. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2576. {
  2577. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2578. }
  2579. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  2580. {
  2581. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2582. }
  2583. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2584. {
  2585. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2586. }
  2587. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2588. {
  2589. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2590. }
  2591. else
  2592. {
  2593. return null;
  2594. }
  2595. }
  2596. function get_image_url()
  2597. {
  2598. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  2599. {
  2600. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  2601. }
  2602. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  2603. {
  2604. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2605. }
  2606. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  2607. {
  2608. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2609. }
  2610. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
  2611. {
  2612. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2613. }
  2614. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
  2615. {
  2616. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2617. }
  2618. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2619. {
  2620. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2621. }
  2622. else
  2623. {
  2624. return null;
  2625. }
  2626. }
  2627. function get_image_link()
  2628. {
  2629. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2630. {
  2631. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2632. }
  2633. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2634. {
  2635. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2636. }
  2637. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  2638. {
  2639. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2640. }
  2641. else
  2642. {
  2643. return null;
  2644. }
  2645. }
  2646. function get_image_width()
  2647. {
  2648. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
  2649. {
  2650. return round($return[0]['data']);
  2651. }
  2652. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2653. {
  2654. return 88.0;
  2655. }
  2656. else
  2657. {
  2658. return null;
  2659. }
  2660. }
  2661. function get_image_height()
  2662. {
  2663. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
  2664. {
  2665. return round($return[0]['data']);
  2666. }
  2667. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2668. {
  2669. return 31.0;
  2670. }
  2671. else
  2672. {
  2673. return null;
  2674. }
  2675. }
  2676. function get_item_quantity($max = 0)
  2677. {
  2678. $max = (int) $max;
  2679. $qty = count($this->get_items());
  2680. if ($max === 0)
  2681. {
  2682. return $qty;
  2683. }
  2684. else
  2685. {
  2686. return ($qty > $max) ? $max : $qty;
  2687. }
  2688. }
  2689. function get_item($key = 0)
  2690. {
  2691. $items = $this->get_items();
  2692. if (isset($items[$key]))
  2693. {
  2694. return $items[$key];
  2695. }
  2696. else
  2697. {
  2698. return null;
  2699. }
  2700. }
  2701. function get_items($start = 0, $end = 0)
  2702. {
  2703. if (!isset($this->data['items']))
  2704. {
  2705. if (!empty($this->multifeed_objects))
  2706. {
  2707. $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
  2708. }
  2709. else
  2710. {
  2711. $this->data['items'] = array();
  2712. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
  2713. {
  2714. $keys = array_keys($items);
  2715. foreach ($keys as $key)
  2716. {
  2717. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2718. }
  2719. }
  2720. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
  2721. {
  2722. $keys = array_keys($items);
  2723. foreach ($keys as $key)
  2724. {
  2725. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2726. }
  2727. }
  2728. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
  2729. {
  2730. $keys = array_keys($items);
  2731. foreach ($keys as $key)
  2732. {
  2733. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2734. }
  2735. }
  2736. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
  2737. {
  2738. $keys = array_keys($items);
  2739. foreach ($keys as $key)
  2740. {
  2741. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2742. }
  2743. }
  2744. if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
  2745. {
  2746. $keys = array_keys($items);
  2747. foreach ($keys as $key)
  2748. {
  2749. $this->data['items'][] =& new $this->item_class($this, $items[$key]);
  2750. }
  2751. }
  2752. }
  2753. }
  2754. if (!empty($this->data['items']))
  2755. {
  2756. // If we want to order it by date, check if all items have a date, and then sort it
  2757. if ($this->order_by_date && empty($this->multifeed_objects))
  2758. {
  2759. if (!isset($this->data['ordered_items']))
  2760. {
  2761. $do_sort = true;
  2762. foreach ($this->data['items'] as $item)
  2763. {
  2764. if (!$item->get_date('U'))
  2765. {
  2766. $do_sort = false;
  2767. break;
  2768. }
  2769. }
  2770. $item = null;
  2771. $this->data['ordered_items'] = $this->data['items'];
  2772. if ($do_sort)
  2773. {
  2774. usort($this->data['ordered_items'], array(&$this, 'sort_items'));
  2775. }
  2776. }
  2777. $items = $this->data['ordered_items'];
  2778. }
  2779. else
  2780. {
  2781. $items = $this->data['items'];
  2782. }
  2783. // Slice the data as desired
  2784. if ($end === 0)
  2785. {
  2786. return array_slice($items, $start);
  2787. }
  2788. else
  2789. {
  2790. return array_slice($items, $start, $end);
  2791. }
  2792. }
  2793. else
  2794. {
  2795. return array();
  2796. }
  2797. }
  2798. /**
  2799. * @static
  2800. */
  2801. function sort_items($a, $b)
  2802. {
  2803. return $a->get_date('U') <= $b->get_date('U');
  2804. }
  2805. /**
  2806. * @static
  2807. */
  2808. function merge_items($urls, $start = 0, $end = 0, $limit = 0)
  2809. {
  2810. if (is_array($urls) && sizeof($urls) > 0)
  2811. {
  2812. $items = array();
  2813. foreach ($urls as $arg)
  2814. {
  2815. if (is_a($arg, 'SimplePie'))
  2816. {
  2817. $items = array_merge($items, $arg->get_items(0, $limit));
  2818. }
  2819. else
  2820. {
  2821. trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
  2822. }
  2823. }
  2824. $do_sort = true;
  2825. foreach ($items as $item)
  2826. {
  2827. if (!$item->get_date('U'))
  2828. {
  2829. $do_sort = false;
  2830. break;
  2831. }
  2832. }
  2833. $item = null;
  2834. if ($do_sort)
  2835. {
  2836. usort($items, array('SimplePie', 'sort_items'));
  2837. }
  2838. if ($end === 0)
  2839. {
  2840. return array_slice($items, $start);
  2841. }
  2842. else
  2843. {
  2844. return array_slice($items, $start, $end);
  2845. }
  2846. }
  2847. else
  2848. {
  2849. trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
  2850. return array();
  2851. }
  2852. }
  2853. }
  2854. class SimplePie_Item
  2855. {
  2856. var $feed;
  2857. var $data = array();
  2858. function SimplePie_Item($feed, $data)
  2859. {
  2860. $this->feed = $feed;
  2861. $this->data = $data;
  2862. }
  2863. function __toString()
  2864. {
  2865. return md5(serialize($this->data));
  2866. }
  2867. /**
  2868. * Remove items that link back to this before destroying this object
  2869. */
  2870. function __destruct()
  2871. {
  2872. if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
  2873. {
  2874. unset($this->feed);
  2875. }
  2876. }
  2877. function get_item_tags($namespace, $tag)
  2878. {
  2879. if (isset($this->data['child'][$namespace][$tag]))
  2880. {
  2881. return $this->data['child'][$namespace][$tag];
  2882. }
  2883. else
  2884. {
  2885. return null;
  2886. }
  2887. }
  2888. function get_base($element = array())
  2889. {
  2890. return $this->feed->get_base($element);
  2891. }
  2892. function sanitize($data, $type, $base = '')
  2893. {
  2894. return $this->feed->sanitize($data, $type, $base);
  2895. }
  2896. function get_feed()
  2897. {
  2898. return $this->feed;
  2899. }
  2900. function get_id($hash = false)
  2901. {
  2902. if (!$hash)
  2903. {
  2904. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
  2905. {
  2906. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2907. }
  2908. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
  2909. {
  2910. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2911. }
  2912. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
  2913. {
  2914. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2915. }
  2916. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
  2917. {
  2918. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2919. }
  2920. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
  2921. {
  2922. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2923. }
  2924. elseif (($return = $this->get_permalink()) !== null)
  2925. {
  2926. return $return;
  2927. }
  2928. elseif (($return = $this->get_title()) !== null)
  2929. {
  2930. return $return;
  2931. }
  2932. }
  2933. if ($this->get_permalink() !== null || $this->get_title() !== null)
  2934. {
  2935. return md5($this->get_permalink() . $this->get_title());
  2936. }
  2937. else
  2938. {
  2939. return md5(serialize($this->data));
  2940. }
  2941. }
  2942. function get_title()
  2943. {
  2944. if (!isset($this->data['title']))
  2945. {
  2946. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  2947. {
  2948. $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2949. }
  2950. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  2951. {
  2952. $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2953. }
  2954. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2955. {
  2956. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2957. }
  2958. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2959. {
  2960. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2961. }
  2962. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  2963. {
  2964. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2965. }
  2966. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2967. {
  2968. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2969. }
  2970. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2971. {
  2972. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2973. }
  2974. else
  2975. {
  2976. $this->data['title'] = null;
  2977. }
  2978. }
  2979. return $this->data['title'];
  2980. }
  2981. function get_description($description_only = false)
  2982. {
  2983. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
  2984. {
  2985. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2986. }
  2987. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
  2988. {
  2989. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2990. }
  2991. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  2992. {
  2993. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2994. }
  2995. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
  2996. {
  2997. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2998. }
  2999. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  3000. {
  3001. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3002. }
  3003. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  3004. {
  3005. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3006. }
  3007. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  3008. {
  3009. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  3010. }
  3011. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  3012. {
  3013. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3014. }
  3015. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  3016. {
  3017. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
  3018. }
  3019. elseif (!$description_only)
  3020. {
  3021. return $this->get_content(true);
  3022. }
  3023. else
  3024. {
  3025. return null;
  3026. }
  3027. }
  3028. function get_content($content_only = false)
  3029. {
  3030. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
  3031. {
  3032. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  3033. }
  3034. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
  3035. {
  3036. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  3037. }
  3038. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
  3039. {
  3040. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  3041. }
  3042. elseif (!$content_only)
  3043. {
  3044. return $this->get_description(true);
  3045. }
  3046. else
  3047. {
  3048. return null;
  3049. }
  3050. }
  3051. function get_category($key = 0)
  3052. {
  3053. $categories = $this->get_categories();
  3054. if (isset($categories[$key]))
  3055. {
  3056. return $categories[$key];
  3057. }
  3058. else
  3059. {
  3060. return null;
  3061. }
  3062. }
  3063. function get_categories()
  3064. {
  3065. $categories = array();
  3066. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  3067. {
  3068. $term = null;
  3069. $scheme = null;
  3070. $label = null;
  3071. if (isset($category['attribs']['']['term']))
  3072. {
  3073. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  3074. }
  3075. if (isset($category['attribs']['']['scheme']))
  3076. {
  3077. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3078. }
  3079. if (isset($category['attribs']['']['label']))
  3080. {
  3081. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3082. }
  3083. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  3084. }
  3085. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
  3086. {
  3087. // This is really the label, but keep this as the term also for BC.
  3088. // Label will also work on retrieving because that falls back to term.
  3089. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3090. if (isset($category['attribs']['']['domain']))
  3091. {
  3092. $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
  3093. }
  3094. else
  3095. {
  3096. $scheme = null;
  3097. }
  3098. $categories[] =& new $this->feed->category_class($term, $scheme, null);
  3099. }
  3100. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  3101. {
  3102. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3103. }
  3104. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  3105. {
  3106. $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3107. }
  3108. if (!empty($categories))
  3109. {
  3110. return SimplePie_Misc::array_unique($categories);
  3111. }
  3112. else
  3113. {
  3114. return null;
  3115. }
  3116. }
  3117. function get_author($key = 0)
  3118. {
  3119. $authors = $this->get_authors();
  3120. if (isset($authors[$key]))
  3121. {
  3122. return $authors[$key];
  3123. }
  3124. else
  3125. {
  3126. return null;
  3127. }
  3128. }
  3129. function get_contributor($key = 0)
  3130. {
  3131. $contributors = $this->get_contributors();
  3132. if (isset($contributors[$key]))
  3133. {
  3134. return $contributors[$key];
  3135. }
  3136. else
  3137. {
  3138. return null;
  3139. }
  3140. }
  3141. function get_contributors()
  3142. {
  3143. $contributors = array();
  3144. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  3145. {
  3146. $name = null;
  3147. $uri = null;
  3148. $email = null;
  3149. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  3150. {
  3151. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3152. }
  3153. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  3154. {
  3155. $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]));
  3156. }
  3157. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  3158. {
  3159. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3160. }
  3161. if ($name !== null || $email !== null || $uri !== null)
  3162. {
  3163. $contributors[] =& new $this->feed->author_class($name, $uri, $email);
  3164. }
  3165. }
  3166. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  3167. {
  3168. $name = null;
  3169. $url = null;
  3170. $email = null;
  3171. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  3172. {
  3173. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3174. }
  3175. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  3176. {
  3177. $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]));
  3178. }
  3179. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  3180. {
  3181. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3182. }
  3183. if ($name !== null || $email !== null || $url !== null)
  3184. {
  3185. $contributors[] =& new $this->feed->author_class($name, $url, $email);
  3186. }
  3187. }
  3188. if (!empty($contributors))
  3189. {
  3190. return SimplePie_Misc::array_unique($contributors);
  3191. }
  3192. else
  3193. {
  3194. return null;
  3195. }
  3196. }
  3197. function get_authors()
  3198. {
  3199. $authors = array();
  3200. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  3201. {
  3202. $name = null;
  3203. $uri = null;
  3204. $email = null;
  3205. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  3206. {
  3207. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3208. }
  3209. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  3210. {
  3211. $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]));
  3212. }
  3213. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  3214. {
  3215. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3216. }
  3217. if ($name !== null || $email !== null || $uri !== null)
  3218. {
  3219. $authors[] =& new $this->feed->author_class($name, $uri, $email);
  3220. }
  3221. }
  3222. if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  3223. {
  3224. $name = null;
  3225. $url = null;
  3226. $email = null;
  3227. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  3228. {
  3229. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3230. }
  3231. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  3232. {
  3233. $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]));
  3234. }
  3235. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  3236. {
  3237. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3238. }
  3239. if ($name !== null || $email !== null || $url !== null)
  3240. {
  3241. $authors[] =& new $this->feed->author_class($name, $url, $email);
  3242. }
  3243. }
  3244. if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
  3245. {
  3246. $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3247. }
  3248. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  3249. {
  3250. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3251. }
  3252. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  3253. {
  3254. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3255. }
  3256. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  3257. {
  3258. $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3259. }
  3260. if (!empty($authors))
  3261. {
  3262. return SimplePie_Misc::array_unique($authors);
  3263. }
  3264. elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
  3265. {
  3266. return $authors;
  3267. }
  3268. elseif ($authors = $this->feed->get_authors())
  3269. {
  3270. return $authors;
  3271. }
  3272. else
  3273. {
  3274. return null;
  3275. }
  3276. }
  3277. function get_copyright()
  3278. {
  3279. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  3280. {
  3281. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  3282. }
  3283. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  3284. {
  3285. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3286. }
  3287. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  3288. {
  3289. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3290. }
  3291. else
  3292. {
  3293. return null;
  3294. }
  3295. }
  3296. function get_date($date_format = 'j F Y, g:i a')
  3297. {
  3298. if (!isset($this->data['date']))
  3299. {
  3300. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
  3301. {
  3302. $this->data['date']['raw'] = $return[0]['data'];
  3303. }
  3304. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
  3305. {
  3306. $this->data['date']['raw'] = $return[0]['data'];
  3307. }
  3308. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
  3309. {
  3310. $this->data['date']['raw'] = $return[0]['data'];
  3311. }
  3312. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
  3313. {
  3314. $this->data['date']['raw'] = $return[0]['data'];
  3315. }
  3316. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
  3317. {
  3318. $this->data['date']['raw'] = $return[0]['data'];
  3319. }
  3320. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
  3321. {
  3322. $this->data['date']['raw'] = $return[0]['data'];
  3323. }
  3324. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
  3325. {
  3326. $this->data['date']['raw'] = $return[0]['data'];
  3327. }
  3328. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
  3329. {
  3330. $this->data['date']['raw'] = $return[0]['data'];
  3331. }
  3332. if (!empty($this->data['date']['raw']))
  3333. {
  3334. $parser = SimplePie_Parse_Date::get();
  3335. $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
  3336. }
  3337. else
  3338. {
  3339. $this->data['date'] = null;
  3340. }
  3341. }
  3342. if ($this->data['date'])
  3343. {
  3344. $date_format = (string) $date_format;
  3345. switch ($date_format)
  3346. {
  3347. case '':
  3348. return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
  3349. case 'U':
  3350. return $this->data['date']['parsed'];
  3351. default:
  3352. return date($date_format, $this->data['date']['parsed']);
  3353. }
  3354. }
  3355. else
  3356. {
  3357. return null;
  3358. }
  3359. }
  3360. function get_local_date($date_format = '%c')
  3361. {
  3362. if (!$date_format)
  3363. {
  3364. return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
  3365. }
  3366. elseif (($date = $this->get_date('U')) !== null && $date !== false)
  3367. {
  3368. return strftime($date_format, $date);
  3369. }
  3370. else
  3371. {
  3372. return null;
  3373. }
  3374. }
  3375. function get_permalink()
  3376. {
  3377. $link = $this->get_link();
  3378. $enclosure = $this->get_enclosure(0);
  3379. if ($link !== null)
  3380. {
  3381. return $link;
  3382. }
  3383. elseif ($enclosure !== null)
  3384. {
  3385. return $enclosure->get_link();
  3386. }
  3387. else
  3388. {
  3389. return null;
  3390. }
  3391. }
  3392. function get_link($key = 0, $rel = 'alternate')
  3393. {
  3394. $links = $this->get_links($rel);
  3395. if ($links[$key] !== null)
  3396. {
  3397. return $links[$key];
  3398. }
  3399. else
  3400. {
  3401. return null;
  3402. }
  3403. }
  3404. function get_links($rel = 'alternate')
  3405. {
  3406. if (!isset($this->data['links']))
  3407. {
  3408. $this->data['links'] = array();
  3409. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  3410. {
  3411. if (isset($link['attribs']['']['href']))
  3412. {
  3413. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  3414. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  3415. }
  3416. }
  3417. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  3418. {
  3419. if (isset($link['attribs']['']['href']))
  3420. {
  3421. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  3422. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  3423. }
  3424. }
  3425. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  3426. {
  3427. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3428. }
  3429. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  3430. {
  3431. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3432. }
  3433. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  3434. {
  3435. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3436. }
  3437. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
  3438. {
  3439. if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')
  3440. {
  3441. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3442. }
  3443. }
  3444. $keys = array_keys($this->data['links']);
  3445. foreach ($keys as $key)
  3446. {
  3447. if (SimplePie_Misc::is_isegment_nz_nc($key))
  3448. {
  3449. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  3450. {
  3451. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  3452. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  3453. }
  3454. else
  3455. {
  3456. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  3457. }
  3458. }
  3459. elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  3460. {
  3461. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  3462. }
  3463. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  3464. }
  3465. }
  3466. if (isset($this->data['links'][$rel]))
  3467. {
  3468. return $this->data['links'][$rel];
  3469. }
  3470. else
  3471. {
  3472. return null;
  3473. }
  3474. }
  3475. /**
  3476. * @todo Add ability to prefer one type of content over another (in a media group).
  3477. */
  3478. function get_enclosure($key = 0, $prefer = null)
  3479. {
  3480. $enclosures = $this->get_enclosures();
  3481. if (isset($enclosures[$key]))
  3482. {
  3483. return $enclosures[$key];
  3484. }
  3485. else
  3486. {
  3487. return null;
  3488. }
  3489. }
  3490. /**
  3491. * Grabs all available enclosures (podcasts, etc.)
  3492. *
  3493. * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
  3494. *
  3495. * 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.
  3496. *
  3497. * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
  3498. * @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).
  3499. */
  3500. function get_enclosures()
  3501. {
  3502. if (!isset($this->data['enclosures']))
  3503. {
  3504. $this->data['enclosures'] = array();
  3505. // Elements
  3506. $captions_parent = null;
  3507. $categories_parent = null;
  3508. $copyrights_parent = null;
  3509. $credits_parent = null;
  3510. $description_parent = null;
  3511. $duration_parent = null;
  3512. $hashes_parent = null;
  3513. $keywords_parent = null;
  3514. $player_parent = null;
  3515. $ratings_parent = null;
  3516. $restrictions_parent = null;
  3517. $thumbnails_parent = null;
  3518. $title_parent = null;
  3519. // Let's do the channel and item-level ones first, and just re-use them if we need to.
  3520. $parent = $this->get_feed();
  3521. // CAPTIONS
  3522. if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  3523. {
  3524. foreach ($captions as $caption)
  3525. {
  3526. $caption_type = null;
  3527. $caption_lang = null;
  3528. $caption_startTime = null;
  3529. $caption_endTime = null;
  3530. $caption_text = null;
  3531. if (isset($caption['attribs']['']['type']))
  3532. {
  3533. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3534. }
  3535. if (isset($caption['attribs']['']['lang']))
  3536. {
  3537. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3538. }
  3539. if (isset($caption['attribs']['']['start']))
  3540. {
  3541. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3542. }
  3543. if (isset($caption['attribs']['']['end']))
  3544. {
  3545. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3546. }
  3547. if (isset($caption['data']))
  3548. {
  3549. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3550. }
  3551. $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3552. }
  3553. }
  3554. elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  3555. {
  3556. foreach ($captions as $caption)
  3557. {
  3558. $caption_type = null;
  3559. $caption_lang = null;
  3560. $caption_startTime = null;
  3561. $caption_endTime = null;
  3562. $caption_text = null;
  3563. if (isset($caption['attribs']['']['type']))
  3564. {
  3565. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3566. }
  3567. if (isset($caption['attribs']['']['lang']))
  3568. {
  3569. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3570. }
  3571. if (isset($caption['attribs']['']['start']))
  3572. {
  3573. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3574. }
  3575. if (isset($caption['attribs']['']['end']))
  3576. {
  3577. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3578. }
  3579. if (isset($caption['data']))
  3580. {
  3581. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3582. }
  3583. $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3584. }
  3585. }
  3586. if (is_array($captions_parent))
  3587. {
  3588. $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
  3589. }
  3590. // CATEGORIES
  3591. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  3592. {
  3593. $term = null;
  3594. $scheme = null;
  3595. $label = null;
  3596. if (isset($category['data']))
  3597. {
  3598. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3599. }
  3600. if (isset($category['attribs']['']['scheme']))
  3601. {
  3602. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3603. }
  3604. else
  3605. {
  3606. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3607. }
  3608. if (isset($category['attribs']['']['label']))
  3609. {
  3610. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3611. }
  3612. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3613. }
  3614. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  3615. {
  3616. $term = null;
  3617. $scheme = null;
  3618. $label = null;
  3619. if (isset($category['data']))
  3620. {
  3621. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3622. }
  3623. if (isset($category['attribs']['']['scheme']))
  3624. {
  3625. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3626. }
  3627. else
  3628. {
  3629. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3630. }
  3631. if (isset($category['attribs']['']['label']))
  3632. {
  3633. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3634. }
  3635. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3636. }
  3637. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
  3638. {
  3639. $term = null;
  3640. $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
  3641. $label = null;
  3642. if (isset($category['attribs']['']['text']))
  3643. {
  3644. $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  3645. }
  3646. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3647. if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
  3648. {
  3649. foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
  3650. {
  3651. if (isset($subcategory['attribs']['']['text']))
  3652. {
  3653. $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  3654. }
  3655. $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
  3656. }
  3657. }
  3658. }
  3659. if (is_array($categories_parent))
  3660. {
  3661. $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
  3662. }
  3663. // COPYRIGHT
  3664. if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  3665. {
  3666. $copyright_url = null;
  3667. $copyright_label = null;
  3668. if (isset($copyright[0]['attribs']['']['url']))
  3669. {
  3670. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3671. }
  3672. if (isset($copyright[0]['data']))
  3673. {
  3674. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3675. }
  3676. $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  3677. }
  3678. elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  3679. {
  3680. $copyright_url = null;
  3681. $copyright_label = null;
  3682. if (isset($copyright[0]['attribs']['']['url']))
  3683. {
  3684. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3685. }
  3686. if (isset($copyright[0]['data']))
  3687. {
  3688. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3689. }
  3690. $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  3691. }
  3692. // CREDITS
  3693. if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  3694. {
  3695. foreach ($credits as $credit)
  3696. {
  3697. $credit_role = null;
  3698. $credit_scheme = null;
  3699. $credit_name = null;
  3700. if (isset($credit['attribs']['']['role']))
  3701. {
  3702. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3703. }
  3704. if (isset($credit['attribs']['']['scheme']))
  3705. {
  3706. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3707. }
  3708. else
  3709. {
  3710. $credit_scheme = 'urn:ebu';
  3711. }
  3712. if (isset($credit['data']))
  3713. {
  3714. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3715. }
  3716. $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3717. }
  3718. }
  3719. elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  3720. {
  3721. foreach ($credits as $credit)
  3722. {
  3723. $credit_role = null;
  3724. $credit_scheme = null;
  3725. $credit_name = null;
  3726. if (isset($credit['attribs']['']['role']))
  3727. {
  3728. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3729. }
  3730. if (isset($credit['attribs']['']['scheme']))
  3731. {
  3732. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3733. }
  3734. else
  3735. {
  3736. $credit_scheme = 'urn:ebu';
  3737. }
  3738. if (isset($credit['data']))
  3739. {
  3740. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3741. }
  3742. $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3743. }
  3744. }
  3745. if (is_array($credits_parent))
  3746. {
  3747. $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
  3748. }
  3749. // DESCRIPTION
  3750. if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  3751. {
  3752. if (isset($description_parent[0]['data']))
  3753. {
  3754. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3755. }
  3756. }
  3757. elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  3758. {
  3759. if (isset($description_parent[0]['data']))
  3760. {
  3761. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3762. }
  3763. }
  3764. // DURATION
  3765. if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
  3766. {
  3767. $seconds = null;
  3768. $minutes = null;
  3769. $hours = null;
  3770. if (isset($duration_parent[0]['data']))
  3771. {
  3772. $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3773. if (sizeof($temp) > 0)
  3774. {
  3775. $seconds = (int) array_pop($temp);
  3776. }
  3777. if (sizeof($temp) > 0)
  3778. {
  3779. $minutes = (int) array_pop($temp);
  3780. $seconds += $minutes * 60;
  3781. }
  3782. if (sizeof($temp) > 0)
  3783. {
  3784. $hours = (int) array_pop($temp);
  3785. $seconds += $hours * 3600;
  3786. }
  3787. unset($temp);
  3788. $duration_parent = $seconds;
  3789. }
  3790. }
  3791. // HASHES
  3792. if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  3793. {
  3794. foreach ($hashes_iterator as $hash)
  3795. {
  3796. $value = null;
  3797. $algo = null;
  3798. if (isset($hash['data']))
  3799. {
  3800. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3801. }
  3802. if (isset($hash['attribs']['']['algo']))
  3803. {
  3804. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3805. }
  3806. else
  3807. {
  3808. $algo = 'md5';
  3809. }
  3810. $hashes_parent[] = $algo.':'.$value;
  3811. }
  3812. }
  3813. elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  3814. {
  3815. foreach ($hashes_iterator as $hash)
  3816. {
  3817. $value = null;
  3818. $algo = null;
  3819. if (isset($hash['data']))
  3820. {
  3821. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3822. }
  3823. if (isset($hash['attribs']['']['algo']))
  3824. {
  3825. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3826. }
  3827. else
  3828. {
  3829. $algo = 'md5';
  3830. }
  3831. $hashes_parent[] = $algo.':'.$value;
  3832. }
  3833. }
  3834. if (is_array($hashes_parent))
  3835. {
  3836. $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
  3837. }
  3838. // KEYWORDS
  3839. if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  3840. {
  3841. if (isset($keywords[0]['data']))
  3842. {
  3843. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3844. foreach ($temp as $word)
  3845. {
  3846. $keywords_parent[] = trim($word);
  3847. }
  3848. }
  3849. unset($temp);
  3850. }
  3851. elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  3852. {
  3853. if (isset($keywords[0]['data']))
  3854. {
  3855. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3856. foreach ($temp as $word)
  3857. {
  3858. $keywords_parent[] = trim($word);
  3859. }
  3860. }
  3861. unset($temp);
  3862. }
  3863. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  3864. {
  3865. if (isset($keywords[0]['data']))
  3866. {
  3867. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3868. foreach ($temp as $word)
  3869. {
  3870. $keywords_parent[] = trim($word);
  3871. }
  3872. }
  3873. unset($temp);
  3874. }
  3875. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  3876. {
  3877. if (isset($keywords[0]['data']))
  3878. {
  3879. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3880. foreach ($temp as $word)
  3881. {
  3882. $keywords_parent[] = trim($word);
  3883. }
  3884. }
  3885. unset($temp);
  3886. }
  3887. if (is_array($keywords_parent))
  3888. {
  3889. $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
  3890. }
  3891. // PLAYER
  3892. if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  3893. {
  3894. if (isset($player_parent[0]['attribs']['']['url']))
  3895. {
  3896. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3897. }
  3898. }
  3899. elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  3900. {
  3901. if (isset($player_parent[0]['attribs']['']['url']))
  3902. {
  3903. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3904. }
  3905. }
  3906. // RATINGS
  3907. if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  3908. {
  3909. foreach ($ratings as $rating)
  3910. {
  3911. $rating_scheme = null;
  3912. $rating_value = null;
  3913. if (isset($rating['attribs']['']['scheme']))
  3914. {
  3915. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3916. }
  3917. else
  3918. {
  3919. $rating_scheme = 'urn:simple';
  3920. }
  3921. if (isset($rating['data']))
  3922. {
  3923. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3924. }
  3925. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3926. }
  3927. }
  3928. elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  3929. {
  3930. foreach ($ratings as $rating)
  3931. {
  3932. $rating_scheme = 'urn:itunes';
  3933. $rating_value = null;
  3934. if (isset($rating['data']))
  3935. {
  3936. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3937. }
  3938. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3939. }
  3940. }
  3941. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  3942. {
  3943. foreach ($ratings as $rating)
  3944. {
  3945. $rating_scheme = null;
  3946. $rating_value = null;
  3947. if (isset($rating['attribs']['']['scheme']))
  3948. {
  3949. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3950. }
  3951. else
  3952. {
  3953. $rating_scheme = 'urn:simple';
  3954. }
  3955. if (isset($rating['data']))
  3956. {
  3957. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3958. }
  3959. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3960. }
  3961. }
  3962. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  3963. {
  3964. foreach ($ratings as $rating)
  3965. {
  3966. $rating_scheme = 'urn:itunes';
  3967. $rating_value = null;
  3968. if (isset($rating['data']))
  3969. {
  3970. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3971. }
  3972. $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  3973. }
  3974. }
  3975. if (is_array($ratings_parent))
  3976. {
  3977. $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
  3978. }
  3979. // RESTRICTIONS
  3980. if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  3981. {
  3982. foreach ($restrictions as $restriction)
  3983. {
  3984. $restriction_relationship = null;
  3985. $restriction_type = null;
  3986. $restriction_value = null;
  3987. if (isset($restriction['attribs']['']['relationship']))
  3988. {
  3989. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  3990. }
  3991. if (isset($restriction['attribs']['']['type']))
  3992. {
  3993. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3994. }
  3995. if (isset($restriction['data']))
  3996. {
  3997. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3998. }
  3999. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4000. }
  4001. }
  4002. elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  4003. {
  4004. foreach ($restrictions as $restriction)
  4005. {
  4006. $restriction_relationship = 'allow';
  4007. $restriction_type = null;
  4008. $restriction_value = 'itunes';
  4009. if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
  4010. {
  4011. $restriction_relationship = 'deny';
  4012. }
  4013. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4014. }
  4015. }
  4016. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  4017. {
  4018. foreach ($restrictions as $restriction)
  4019. {
  4020. $restriction_relationship = null;
  4021. $restriction_type = null;
  4022. $restriction_value = null;
  4023. if (isset($restriction['attribs']['']['relationship']))
  4024. {
  4025. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4026. }
  4027. if (isset($restriction['attribs']['']['type']))
  4028. {
  4029. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4030. }
  4031. if (isset($restriction['data']))
  4032. {
  4033. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4034. }
  4035. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4036. }
  4037. }
  4038. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  4039. {
  4040. foreach ($restrictions as $restriction)
  4041. {
  4042. $restriction_relationship = 'allow';
  4043. $restriction_type = null;
  4044. $restriction_value = 'itunes';
  4045. if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
  4046. {
  4047. $restriction_relationship = 'deny';
  4048. }
  4049. $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4050. }
  4051. }
  4052. if (is_array($restrictions_parent))
  4053. {
  4054. $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
  4055. }
  4056. // THUMBNAILS
  4057. if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  4058. {
  4059. foreach ($thumbnails as $thumbnail)
  4060. {
  4061. if (isset($thumbnail['attribs']['']['url']))
  4062. {
  4063. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4064. }
  4065. }
  4066. }
  4067. elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  4068. {
  4069. foreach ($thumbnails as $thumbnail)
  4070. {
  4071. if (isset($thumbnail['attribs']['']['url']))
  4072. {
  4073. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4074. }
  4075. }
  4076. }
  4077. // TITLES
  4078. if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  4079. {
  4080. if (isset($title_parent[0]['data']))
  4081. {
  4082. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4083. }
  4084. }
  4085. elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  4086. {
  4087. if (isset($title_parent[0]['data']))
  4088. {
  4089. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4090. }
  4091. }
  4092. // Clear the memory
  4093. unset($parent);
  4094. // Attributes
  4095. $bitrate = null;
  4096. $channels = null;
  4097. $duration = null;
  4098. $expression = null;
  4099. $framerate = null;
  4100. $height = null;
  4101. $javascript = null;
  4102. $lang = null;
  4103. $length = null;
  4104. $medium = null;
  4105. $samplingrate = null;
  4106. $type = null;
  4107. $url = null;
  4108. $width = null;
  4109. // Elements
  4110. $captions = null;
  4111. $categories = null;
  4112. $copyrights = null;
  4113. $credits = null;
  4114. $description = null;
  4115. $hashes = null;
  4116. $keywords = null;
  4117. $player = null;
  4118. $ratings = null;
  4119. $restrictions = null;
  4120. $thumbnails = null;
  4121. $title = null;
  4122. // If we have media:group tags, loop through them.
  4123. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
  4124. {
  4125. if(isset($group['child']) && isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
  4126. {
  4127. // If we have media:content tags, loop through them.
  4128. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  4129. {
  4130. if (isset($content['attribs']['']['url']))
  4131. {
  4132. // Attributes
  4133. $bitrate = null;
  4134. $channels = null;
  4135. $duration = null;
  4136. $expression = null;
  4137. $framerate = null;
  4138. $height = null;
  4139. $javascript = null;
  4140. $lang = null;
  4141. $length = null;
  4142. $medium = null;
  4143. $samplingrate = null;
  4144. $type = null;
  4145. $url = null;
  4146. $width = null;
  4147. // Elements
  4148. $captions = null;
  4149. $categories = null;
  4150. $copyrights = null;
  4151. $credits = null;
  4152. $description = null;
  4153. $hashes = null;
  4154. $keywords = null;
  4155. $player = null;
  4156. $ratings = null;
  4157. $restrictions = null;
  4158. $thumbnails = null;
  4159. $title = null;
  4160. // Start checking the attributes of media:content
  4161. if (isset($content['attribs']['']['bitrate']))
  4162. {
  4163. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4164. }
  4165. if (isset($content['attribs']['']['channels']))
  4166. {
  4167. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  4168. }
  4169. if (isset($content['attribs']['']['duration']))
  4170. {
  4171. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  4172. }
  4173. else
  4174. {
  4175. $duration = $duration_parent;
  4176. }
  4177. if (isset($content['attribs']['']['expression']))
  4178. {
  4179. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  4180. }
  4181. if (isset($content['attribs']['']['framerate']))
  4182. {
  4183. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4184. }
  4185. if (isset($content['attribs']['']['height']))
  4186. {
  4187. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  4188. }
  4189. if (isset($content['attribs']['']['lang']))
  4190. {
  4191. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4192. }
  4193. if (isset($content['attribs']['']['fileSize']))
  4194. {
  4195. $length = ceil($content['attribs']['']['fileSize']);
  4196. }
  4197. if (isset($content['attribs']['']['medium']))
  4198. {
  4199. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  4200. }
  4201. if (isset($content['attribs']['']['samplingrate']))
  4202. {
  4203. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4204. }
  4205. if (isset($content['attribs']['']['type']))
  4206. {
  4207. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4208. }
  4209. if (isset($content['attribs']['']['width']))
  4210. {
  4211. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  4212. }
  4213. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4214. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  4215. // CAPTIONS
  4216. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4217. {
  4218. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4219. {
  4220. $caption_type = null;
  4221. $caption_lang = null;
  4222. $caption_startTime = null;
  4223. $caption_endTime = null;
  4224. $caption_text = null;
  4225. if (isset($caption['attribs']['']['type']))
  4226. {
  4227. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4228. }
  4229. if (isset($caption['attribs']['']['lang']))
  4230. {
  4231. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4232. }
  4233. if (isset($caption['attribs']['']['start']))
  4234. {
  4235. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4236. }
  4237. if (isset($caption['attribs']['']['end']))
  4238. {
  4239. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4240. }
  4241. if (isset($caption['data']))
  4242. {
  4243. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4244. }
  4245. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4246. }
  4247. if (is_array($captions))
  4248. {
  4249. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4250. }
  4251. }
  4252. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4253. {
  4254. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4255. {
  4256. $caption_type = null;
  4257. $caption_lang = null;
  4258. $caption_startTime = null;
  4259. $caption_endTime = null;
  4260. $caption_text = null;
  4261. if (isset($caption['attribs']['']['type']))
  4262. {
  4263. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4264. }
  4265. if (isset($caption['attribs']['']['lang']))
  4266. {
  4267. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4268. }
  4269. if (isset($caption['attribs']['']['start']))
  4270. {
  4271. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4272. }
  4273. if (isset($caption['attribs']['']['end']))
  4274. {
  4275. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4276. }
  4277. if (isset($caption['data']))
  4278. {
  4279. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4280. }
  4281. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4282. }
  4283. if (is_array($captions))
  4284. {
  4285. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4286. }
  4287. }
  4288. else
  4289. {
  4290. $captions = $captions_parent;
  4291. }
  4292. // CATEGORIES
  4293. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4294. {
  4295. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4296. {
  4297. $term = null;
  4298. $scheme = null;
  4299. $label = null;
  4300. if (isset($category['data']))
  4301. {
  4302. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4303. }
  4304. if (isset($category['attribs']['']['scheme']))
  4305. {
  4306. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4307. }
  4308. else
  4309. {
  4310. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4311. }
  4312. if (isset($category['attribs']['']['label']))
  4313. {
  4314. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4315. }
  4316. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4317. }
  4318. }
  4319. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4320. {
  4321. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4322. {
  4323. $term = null;
  4324. $scheme = null;
  4325. $label = null;
  4326. if (isset($category['data']))
  4327. {
  4328. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4329. }
  4330. if (isset($category['attribs']['']['scheme']))
  4331. {
  4332. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4333. }
  4334. else
  4335. {
  4336. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4337. }
  4338. if (isset($category['attribs']['']['label']))
  4339. {
  4340. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4341. }
  4342. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4343. }
  4344. }
  4345. if (is_array($categories) && is_array($categories_parent))
  4346. {
  4347. $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
  4348. }
  4349. elseif (is_array($categories))
  4350. {
  4351. $categories = array_values(SimplePie_Misc::array_unique($categories));
  4352. }
  4353. elseif (is_array($categories_parent))
  4354. {
  4355. $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
  4356. }
  4357. // COPYRIGHTS
  4358. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4359. {
  4360. $copyright_url = null;
  4361. $copyright_label = null;
  4362. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4363. {
  4364. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4365. }
  4366. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4367. {
  4368. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4369. }
  4370. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4371. }
  4372. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4373. {
  4374. $copyright_url = null;
  4375. $copyright_label = null;
  4376. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4377. {
  4378. $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4379. }
  4380. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4381. {
  4382. $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4383. }
  4384. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4385. }
  4386. else
  4387. {
  4388. $copyrights = $copyrights_parent;
  4389. }
  4390. // CREDITS
  4391. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4392. {
  4393. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4394. {
  4395. $credit_role = null;
  4396. $credit_scheme = null;
  4397. $credit_name = null;
  4398. if (isset($credit['attribs']['']['role']))
  4399. {
  4400. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4401. }
  4402. if (isset($credit['attribs']['']['scheme']))
  4403. {
  4404. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4405. }
  4406. else
  4407. {
  4408. $credit_scheme = 'urn:ebu';
  4409. }
  4410. if (isset($credit['data']))
  4411. {
  4412. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4413. }
  4414. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4415. }
  4416. if (is_array($credits))
  4417. {
  4418. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4419. }
  4420. }
  4421. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4422. {
  4423. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4424. {
  4425. $credit_role = null;
  4426. $credit_scheme = null;
  4427. $credit_name = null;
  4428. if (isset($credit['attribs']['']['role']))
  4429. {
  4430. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4431. }
  4432. if (isset($credit['attribs']['']['scheme']))
  4433. {
  4434. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4435. }
  4436. else
  4437. {
  4438. $credit_scheme = 'urn:ebu';
  4439. }
  4440. if (isset($credit['data']))
  4441. {
  4442. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4443. }
  4444. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4445. }
  4446. if (is_array($credits))
  4447. {
  4448. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4449. }
  4450. }
  4451. else
  4452. {
  4453. $credits = $credits_parent;
  4454. }
  4455. // DESCRIPTION
  4456. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4457. {
  4458. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4459. }
  4460. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4461. {
  4462. $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4463. }
  4464. else
  4465. {
  4466. $description = $description_parent;
  4467. }
  4468. // HASHES
  4469. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4470. {
  4471. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4472. {
  4473. $value = null;
  4474. $algo = null;
  4475. if (isset($hash['data']))
  4476. {
  4477. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4478. }
  4479. if (isset($hash['attribs']['']['algo']))
  4480. {
  4481. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4482. }
  4483. else
  4484. {
  4485. $algo = 'md5';
  4486. }
  4487. $hashes[] = $algo.':'.$value;
  4488. }
  4489. if (is_array($hashes))
  4490. {
  4491. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4492. }
  4493. }
  4494. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4495. {
  4496. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4497. {
  4498. $value = null;
  4499. $algo = null;
  4500. if (isset($hash['data']))
  4501. {
  4502. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4503. }
  4504. if (isset($hash['attribs']['']['algo']))
  4505. {
  4506. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4507. }
  4508. else
  4509. {
  4510. $algo = 'md5';
  4511. }
  4512. $hashes[] = $algo.':'.$value;
  4513. }
  4514. if (is_array($hashes))
  4515. {
  4516. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4517. }
  4518. }
  4519. else
  4520. {
  4521. $hashes = $hashes_parent;
  4522. }
  4523. // KEYWORDS
  4524. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4525. {
  4526. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4527. {
  4528. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4529. foreach ($temp as $word)
  4530. {
  4531. $keywords[] = trim($word);
  4532. }
  4533. unset($temp);
  4534. }
  4535. if (is_array($keywords))
  4536. {
  4537. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4538. }
  4539. }
  4540. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4541. {
  4542. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4543. {
  4544. $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4545. foreach ($temp as $word)
  4546. {
  4547. $keywords[] = trim($word);
  4548. }
  4549. unset($temp);
  4550. }
  4551. if (is_array($keywords))
  4552. {
  4553. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4554. }
  4555. }
  4556. else
  4557. {
  4558. $keywords = $keywords_parent;
  4559. }
  4560. // PLAYER
  4561. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4562. {
  4563. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4564. }
  4565. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4566. {
  4567. $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4568. }
  4569. else
  4570. {
  4571. $player = $player_parent;
  4572. }
  4573. // RATINGS
  4574. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4575. {
  4576. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4577. {
  4578. $rating_scheme = null;
  4579. $rating_value = null;
  4580. if (isset($rating['attribs']['']['scheme']))
  4581. {
  4582. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4583. }
  4584. else
  4585. {
  4586. $rating_scheme = 'urn:simple';
  4587. }
  4588. if (isset($rating['data']))
  4589. {
  4590. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4591. }
  4592. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4593. }
  4594. if (is_array($ratings))
  4595. {
  4596. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4597. }
  4598. }
  4599. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4600. {
  4601. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4602. {
  4603. $rating_scheme = null;
  4604. $rating_value = null;
  4605. if (isset($rating['attribs']['']['scheme']))
  4606. {
  4607. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4608. }
  4609. else
  4610. {
  4611. $rating_scheme = 'urn:simple';
  4612. }
  4613. if (isset($rating['data']))
  4614. {
  4615. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4616. }
  4617. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  4618. }
  4619. if (is_array($ratings))
  4620. {
  4621. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4622. }
  4623. }
  4624. else
  4625. {
  4626. $ratings = $ratings_parent;
  4627. }
  4628. // RESTRICTIONS
  4629. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4630. {
  4631. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4632. {
  4633. $restriction_relationship = null;
  4634. $restriction_type = null;
  4635. $restriction_value = null;
  4636. if (isset($restriction['attribs']['']['relationship']))
  4637. {
  4638. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4639. }
  4640. if (isset($restriction['attribs']['']['type']))
  4641. {
  4642. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4643. }
  4644. if (isset($restriction['data']))
  4645. {
  4646. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4647. }
  4648. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4649. }
  4650. if (is_array($restrictions))
  4651. {
  4652. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4653. }
  4654. }
  4655. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4656. {
  4657. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4658. {
  4659. $restriction_relationship = null;
  4660. $restriction_type = null;
  4661. $restriction_value = null;
  4662. if (isset($restriction['attribs']['']['relationship']))
  4663. {
  4664. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4665. }
  4666. if (isset($restriction['attribs']['']['type']))
  4667. {
  4668. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4669. }
  4670. if (isset($restriction['data']))
  4671. {
  4672. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4673. }
  4674. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4675. }
  4676. if (is_array($restrictions))
  4677. {
  4678. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4679. }
  4680. }
  4681. else
  4682. {
  4683. $restrictions = $restrictions_parent;
  4684. }
  4685. // THUMBNAILS
  4686. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4687. {
  4688. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4689. {
  4690. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4691. }
  4692. if (is_array($thumbnails))
  4693. {
  4694. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4695. }
  4696. }
  4697. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4698. {
  4699. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4700. {
  4701. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4702. }
  4703. if (is_array($thumbnails))
  4704. {
  4705. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4706. }
  4707. }
  4708. else
  4709. {
  4710. $thumbnails = $thumbnails_parent;
  4711. }
  4712. // TITLES
  4713. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4714. {
  4715. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4716. }
  4717. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4718. {
  4719. $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4720. }
  4721. else
  4722. {
  4723. $title = $title_parent;
  4724. }
  4725. $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);
  4726. }
  4727. }
  4728. }
  4729. }
  4730. // If we have standalone media:content tags, loop through them.
  4731. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
  4732. {
  4733. foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  4734. {
  4735. if (isset($content['attribs']['']['url']) || isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4736. {
  4737. // Attributes
  4738. $bitrate = null;
  4739. $channels = null;
  4740. $duration = null;
  4741. $expression = null;
  4742. $framerate = null;
  4743. $height = null;
  4744. $javascript = null;
  4745. $lang = null;
  4746. $length = null;
  4747. $medium = null;
  4748. $samplingrate = null;
  4749. $type = null;
  4750. $url = null;
  4751. $width = null;
  4752. // Elements
  4753. $captions = null;
  4754. $categories = null;
  4755. $copyrights = null;
  4756. $credits = null;
  4757. $description = null;
  4758. $hashes = null;
  4759. $keywords = null;
  4760. $player = null;
  4761. $ratings = null;
  4762. $restrictions = null;
  4763. $thumbnails = null;
  4764. $title = null;
  4765. // Start checking the attributes of media:content
  4766. if (isset($content['attribs']['']['bitrate']))
  4767. {
  4768. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4769. }
  4770. if (isset($content['attribs']['']['channels']))
  4771. {
  4772. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  4773. }
  4774. if (isset($content['attribs']['']['duration']))
  4775. {
  4776. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  4777. }
  4778. else
  4779. {
  4780. $duration = $duration_parent;
  4781. }
  4782. if (isset($content['attribs']['']['expression']))
  4783. {
  4784. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  4785. }
  4786. if (isset($content['attribs']['']['framerate']))
  4787. {
  4788. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4789. }
  4790. if (isset($content['attribs']['']['height']))
  4791. {
  4792. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  4793. }
  4794. if (isset($content['attribs']['']['lang']))
  4795. {
  4796. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4797. }
  4798. if (isset($content['attribs']['']['fileSize']))
  4799. {
  4800. $length = ceil($content['attribs']['']['fileSize']);
  4801. }
  4802. if (isset($content['attribs']['']['medium']))
  4803. {
  4804. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  4805. }
  4806. if (isset($content['attribs']['']['samplingrate']))
  4807. {
  4808. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4809. }
  4810. if (isset($content['attribs']['']['type']))
  4811. {
  4812. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4813. }
  4814. if (isset($content['attribs']['']['width']))
  4815. {
  4816. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  4817. }
  4818. if (isset($content['attribs']['']['url']))
  4819. {
  4820. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4821. }
  4822. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  4823. // CAPTIONS
  4824. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4825. {
  4826. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4827. {
  4828. $caption_type = null;
  4829. $caption_lang = null;
  4830. $caption_startTime = null;
  4831. $caption_endTime = null;
  4832. $caption_text = null;
  4833. if (isset($caption['attribs']['']['type']))
  4834. {
  4835. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4836. }
  4837. if (isset($caption['attribs']['']['lang']))
  4838. {
  4839. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4840. }
  4841. if (isset($caption['attribs']['']['start']))
  4842. {
  4843. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4844. }
  4845. if (isset($caption['attribs']['']['end']))
  4846. {
  4847. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4848. }
  4849. if (isset($caption['data']))
  4850. {
  4851. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4852. }
  4853. $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4854. }
  4855. if (is_array($captions))
  4856. {
  4857. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4858. }
  4859. }
  4860. else
  4861. {
  4862. $captions = $captions_parent;
  4863. }
  4864. // CATEGORIES
  4865. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4866. {
  4867. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4868. {
  4869. $term = null;
  4870. $scheme = null;
  4871. $label = null;
  4872. if (isset($category['data']))
  4873. {
  4874. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4875. }
  4876. if (isset($category['attribs']['']['scheme']))
  4877. {
  4878. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4879. }
  4880. else
  4881. {
  4882. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4883. }
  4884. if (isset($category['attribs']['']['label']))
  4885. {
  4886. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4887. }
  4888. $categories[] =& new $this->feed->category_class($term, $scheme, $label);
  4889. }
  4890. }
  4891. if (is_array($categories) && is_array($categories_parent))
  4892. {
  4893. $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
  4894. }
  4895. elseif (is_array($categories))
  4896. {
  4897. $categories = array_values(SimplePie_Misc::array_unique($categories));
  4898. }
  4899. elseif (is_array($categories_parent))
  4900. {
  4901. $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
  4902. }
  4903. else
  4904. {
  4905. $categories = null;
  4906. }
  4907. // COPYRIGHTS
  4908. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4909. {
  4910. $copyright_url = null;
  4911. $copyright_label = null;
  4912. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4913. {
  4914. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4915. }
  4916. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4917. {
  4918. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4919. }
  4920. $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
  4921. }
  4922. else
  4923. {
  4924. $copyrights = $copyrights_parent;
  4925. }
  4926. // CREDITS
  4927. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4928. {
  4929. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4930. {
  4931. $credit_role = null;
  4932. $credit_scheme = null;
  4933. $credit_name = null;
  4934. if (isset($credit['attribs']['']['role']))
  4935. {
  4936. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4937. }
  4938. if (isset($credit['attribs']['']['scheme']))
  4939. {
  4940. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4941. }
  4942. else
  4943. {
  4944. $credit_scheme = 'urn:ebu';
  4945. }
  4946. if (isset($credit['data']))
  4947. {
  4948. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4949. }
  4950. $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4951. }
  4952. if (is_array($credits))
  4953. {
  4954. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4955. }
  4956. }
  4957. else
  4958. {
  4959. $credits = $credits_parent;
  4960. }
  4961. // DESCRIPTION
  4962. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4963. {
  4964. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4965. }
  4966. else
  4967. {
  4968. $description = $description_parent;
  4969. }
  4970. // HASHES
  4971. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4972. {
  4973. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4974. {
  4975. $value = null;
  4976. $algo = null;
  4977. if (isset($hash['data']))
  4978. {
  4979. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4980. }
  4981. if (isset($hash['attribs']['']['algo']))
  4982. {
  4983. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4984. }
  4985. else
  4986. {
  4987. $algo = 'md5';
  4988. }
  4989. $hashes[] = $algo.':'.$value;
  4990. }
  4991. if (is_array($hashes))
  4992. {
  4993. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4994. }
  4995. }
  4996. else
  4997. {
  4998. $hashes = $hashes_parent;
  4999. }
  5000. // KEYWORDS
  5001. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  5002. {
  5003. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  5004. {
  5005. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  5006. foreach ($temp as $word)
  5007. {
  5008. $keywords[] = trim($word);
  5009. }
  5010. unset($temp);
  5011. }
  5012. if (is_array($keywords))
  5013. {
  5014. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  5015. }
  5016. }
  5017. else
  5018. {
  5019. $keywords = $keywords_parent;
  5020. }
  5021. // PLAYER
  5022. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  5023. {
  5024. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  5025. }
  5026. else
  5027. {
  5028. $player = $player_parent;
  5029. }
  5030. // RATINGS
  5031. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  5032. {
  5033. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  5034. {
  5035. $rating_scheme = null;
  5036. $rating_value = null;
  5037. if (isset($rating['attribs']['']['scheme']))
  5038. {
  5039. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  5040. }
  5041. else
  5042. {
  5043. $rating_scheme = 'urn:simple';
  5044. }
  5045. if (isset($rating['data']))
  5046. {
  5047. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5048. }
  5049. $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
  5050. }
  5051. if (is_array($ratings))
  5052. {
  5053. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  5054. }
  5055. }
  5056. else
  5057. {
  5058. $ratings = $ratings_parent;
  5059. }
  5060. // RESTRICTIONS
  5061. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  5062. {
  5063. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  5064. {
  5065. $restriction_relationship = null;
  5066. $restriction_type = null;
  5067. $restriction_value = null;
  5068. if (isset($restriction['attribs']['']['relationship']))
  5069. {
  5070. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  5071. }
  5072. if (isset($restriction['attribs']['']['type']))
  5073. {
  5074. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5075. }
  5076. if (isset($restriction['data']))
  5077. {
  5078. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5079. }
  5080. $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  5081. }
  5082. if (is_array($restrictions))
  5083. {
  5084. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  5085. }
  5086. }
  5087. else
  5088. {
  5089. $restrictions = $restrictions_parent;
  5090. }
  5091. // THUMBNAILS
  5092. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  5093. {
  5094. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  5095. {
  5096. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  5097. }
  5098. if (is_array($thumbnails))
  5099. {
  5100. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  5101. }
  5102. }
  5103. else
  5104. {
  5105. $thumbnails = $thumbnails_parent;
  5106. }
  5107. // TITLES
  5108. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  5109. {
  5110. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5111. }
  5112. else
  5113. {
  5114. $title = $title_parent;
  5115. }
  5116. $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);
  5117. }
  5118. }
  5119. }
  5120. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  5121. {
  5122. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
  5123. {
  5124. // Attributes
  5125. $bitrate = null;
  5126. $channels = null;
  5127. $duration = null;
  5128. $expression = null;
  5129. $framerate = null;
  5130. $height = null;
  5131. $javascript = null;
  5132. $lang = null;
  5133. $length = null;
  5134. $medium = null;
  5135. $samplingrate = null;
  5136. $type = null;
  5137. $url = null;
  5138. $width = null;
  5139. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5140. if (isset($link['attribs']['']['type']))
  5141. {
  5142. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5143. }
  5144. if (isset($link['attribs']['']['length']))
  5145. {
  5146. $length = ceil($link['attribs']['']['length']);
  5147. }
  5148. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5149. $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);
  5150. }
  5151. }
  5152. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  5153. {
  5154. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
  5155. {
  5156. // Attributes
  5157. $bitrate = null;
  5158. $channels = null;
  5159. $duration = null;
  5160. $expression = null;
  5161. $framerate = null;
  5162. $height = null;
  5163. $javascript = null;
  5164. $lang = null;
  5165. $length = null;
  5166. $medium = null;
  5167. $samplingrate = null;
  5168. $type = null;
  5169. $url = null;
  5170. $width = null;
  5171. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5172. if (isset($link['attribs']['']['type']))
  5173. {
  5174. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5175. }
  5176. if (isset($link['attribs']['']['length']))
  5177. {
  5178. $length = ceil($link['attribs']['']['length']);
  5179. }
  5180. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5181. $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);
  5182. }
  5183. }
  5184. if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure'))
  5185. {
  5186. if (isset($enclosure[0]['attribs']['']['url']))
  5187. {
  5188. // Attributes
  5189. $bitrate = null;
  5190. $channels = null;
  5191. $duration = null;
  5192. $expression = null;
  5193. $framerate = null;
  5194. $height = null;
  5195. $javascript = null;
  5196. $lang = null;
  5197. $length = null;
  5198. $medium = null;
  5199. $samplingrate = null;
  5200. $type = null;
  5201. $url = null;
  5202. $width = null;
  5203. $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
  5204. if (isset($enclosure[0]['attribs']['']['type']))
  5205. {
  5206. $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5207. }
  5208. if (isset($enclosure[0]['attribs']['']['length']))
  5209. {
  5210. $length = ceil($enclosure[0]['attribs']['']['length']);
  5211. }
  5212. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5213. $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);
  5214. }
  5215. }
  5216. if (sizeof($this->data['enclosures']) === 0 && ($url || $type || $length || $bitrate || $captions_parent || $categories_parent || $channels || $copyrights_parent || $credits_parent || $description_parent || $duration_parent || $expression || $framerate || $hashes_parent || $height || $keywords_parent || $lang || $medium || $player_parent || $ratings_parent || $restrictions_parent || $samplingrate || $thumbnails_parent || $title_parent || $width))
  5217. {
  5218. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5219. $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);
  5220. }
  5221. $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
  5222. }
  5223. if (!empty($this->data['enclosures']))
  5224. {
  5225. return $this->data['enclosures'];
  5226. }
  5227. else
  5228. {
  5229. return null;
  5230. }
  5231. }
  5232. function get_latitude()
  5233. {
  5234. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  5235. {
  5236. return (float) $return[0]['data'];
  5237. }
  5238. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  5239. {
  5240. return (float) $match[1];
  5241. }
  5242. else
  5243. {
  5244. return null;
  5245. }
  5246. }
  5247. function get_longitude()
  5248. {
  5249. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  5250. {
  5251. return (float) $return[0]['data'];
  5252. }
  5253. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  5254. {
  5255. return (float) $return[0]['data'];
  5256. }
  5257. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  5258. {
  5259. return (float) $match[2];
  5260. }
  5261. else
  5262. {
  5263. return null;
  5264. }
  5265. }
  5266. function get_source()
  5267. {
  5268. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
  5269. {
  5270. return new $this->feed->source_class($this, $return[0]);
  5271. }
  5272. else
  5273. {
  5274. return null;
  5275. }
  5276. }
  5277. /**
  5278. * Creates the add_to_* methods' return data
  5279. *
  5280. * @access private
  5281. * @param string $item_url String to prefix to the item permalink
  5282. * @param string $title_url String to prefix to the item title
  5283. * (and suffix to the item permalink)
  5284. * @return mixed URL if feed exists, false otherwise
  5285. */
  5286. function add_to_service($item_url, $title_url = null, $summary_url = null)
  5287. {
  5288. if ($this->get_permalink() !== null)
  5289. {
  5290. $return = $item_url . rawurlencode($this->get_permalink());
  5291. if ($title_url !== null && $this->get_title() !== null)
  5292. {
  5293. $return .= $title_url . rawurlencode($this->get_title());
  5294. }
  5295. if ($summary_url !== null && $this->get_description() !== null)
  5296. {
  5297. $return .= $summary_url . rawurlencode($this->get_description());
  5298. }
  5299. return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
  5300. }
  5301. else
  5302. {
  5303. return null;
  5304. }
  5305. }
  5306. function add_to_blinklist()
  5307. {
  5308. return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
  5309. }
  5310. function add_to_blogmarks()
  5311. {
  5312. return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
  5313. }
  5314. function add_to_delicious()
  5315. {
  5316. return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
  5317. }
  5318. function add_to_digg()
  5319. {
  5320. return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
  5321. }
  5322. function add_to_furl()
  5323. {
  5324. return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
  5325. }
  5326. function add_to_magnolia()
  5327. {
  5328. return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
  5329. }
  5330. function add_to_myweb20()
  5331. {
  5332. return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
  5333. }
  5334. function add_to_newsvine()
  5335. {
  5336. return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
  5337. }
  5338. function add_to_reddit()
  5339. {
  5340. return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
  5341. }
  5342. function add_to_segnalo()
  5343. {
  5344. return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
  5345. }
  5346. function add_to_simpy()
  5347. {
  5348. return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
  5349. }
  5350. function add_to_spurl()
  5351. {
  5352. return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
  5353. }
  5354. function add_to_wists()
  5355. {
  5356. return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
  5357. }
  5358. function search_technorati()
  5359. {
  5360. return $this->add_to_service('http://www.technorati.com/search/');
  5361. }
  5362. }
  5363. class SimplePie_Source
  5364. {
  5365. var $item;
  5366. var $data = array();
  5367. function SimplePie_Source($item, $data)
  5368. {
  5369. $this->item = $item;
  5370. $this->data = $data;
  5371. }
  5372. function __toString()
  5373. {
  5374. return md5(serialize($this->data));
  5375. }
  5376. function get_source_tags($namespace, $tag)
  5377. {
  5378. if (isset($this->data['child'][$namespace][$tag]))
  5379. {
  5380. return $this->data['child'][$namespace][$tag];
  5381. }
  5382. else
  5383. {
  5384. return null;
  5385. }
  5386. }
  5387. function get_base($element = array())
  5388. {
  5389. return $this->item->get_base($element);
  5390. }
  5391. function sanitize($data, $type, $base = '')
  5392. {
  5393. return $this->item->sanitize($data, $type, $base);
  5394. }
  5395. function get_item()
  5396. {
  5397. return $this->item;
  5398. }
  5399. function get_title()
  5400. {
  5401. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  5402. {
  5403. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5404. }
  5405. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  5406. {
  5407. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5408. }
  5409. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  5410. {
  5411. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5412. }
  5413. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  5414. {
  5415. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5416. }
  5417. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  5418. {
  5419. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5420. }
  5421. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  5422. {
  5423. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5424. }
  5425. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  5426. {
  5427. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5428. }
  5429. else
  5430. {
  5431. return null;
  5432. }
  5433. }
  5434. function get_category($key = 0)
  5435. {
  5436. $categories = $this->get_categories();
  5437. if (isset($categories[$key]))
  5438. {
  5439. return $categories[$key];
  5440. }
  5441. else
  5442. {
  5443. return null;
  5444. }
  5445. }
  5446. function get_categories()
  5447. {
  5448. $categories = array();
  5449. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  5450. {
  5451. $term = null;
  5452. $scheme = null;
  5453. $label = null;
  5454. if (isset($category['attribs']['']['term']))
  5455. {
  5456. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  5457. }
  5458. if (isset($category['attribs']['']['scheme']))
  5459. {
  5460. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  5461. }
  5462. if (isset($category['attribs']['']['label']))
  5463. {
  5464. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  5465. }
  5466. $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
  5467. }
  5468. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
  5469. {
  5470. // This is really the label, but keep this as the term also for BC.
  5471. // Label will also work on retrieving because that falls back to term.
  5472. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5473. if (isset($category['attribs']['']['domain']))
  5474. {
  5475. $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
  5476. }
  5477. else
  5478. {
  5479. $scheme = null;
  5480. }
  5481. $categories[] =& new $this->item->feed->category_class($term, $scheme, null);
  5482. }
  5483. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  5484. {
  5485. $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5486. }
  5487. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  5488. {
  5489. $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5490. }
  5491. if (!empty($categories))
  5492. {
  5493. return SimplePie_Misc::array_unique($categories);
  5494. }
  5495. else
  5496. {
  5497. return null;
  5498. }
  5499. }
  5500. function get_author($key = 0)
  5501. {
  5502. $authors = $this->get_authors();
  5503. if (isset($authors[$key]))
  5504. {
  5505. return $authors[$key];
  5506. }
  5507. else
  5508. {
  5509. return null;
  5510. }
  5511. }
  5512. function get_authors()
  5513. {
  5514. $authors = array();
  5515. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  5516. {
  5517. $name = null;
  5518. $uri = null;
  5519. $email = null;
  5520. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  5521. {
  5522. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5523. }
  5524. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  5525. {
  5526. $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]));
  5527. }
  5528. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  5529. {
  5530. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5531. }
  5532. if ($name !== null || $email !== null || $uri !== null)
  5533. {
  5534. $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
  5535. }
  5536. }
  5537. if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  5538. {
  5539. $name = null;
  5540. $url = null;
  5541. $email = null;
  5542. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  5543. {
  5544. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5545. }
  5546. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  5547. {
  5548. $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]));
  5549. }
  5550. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  5551. {
  5552. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5553. }
  5554. if ($name !== null || $email !== null || $url !== null)
  5555. {
  5556. $authors[] =& new $this->item->feed->author_class($name, $url, $email);
  5557. }
  5558. }
  5559. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  5560. {
  5561. $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5562. }
  5563. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  5564. {
  5565. $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5566. }
  5567. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  5568. {
  5569. $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5570. }
  5571. if (!empty($authors))
  5572. {
  5573. return SimplePie_Misc::array_unique($authors);
  5574. }
  5575. else
  5576. {
  5577. return null;
  5578. }
  5579. }
  5580. function get_contributor($key = 0)
  5581. {
  5582. $contributors = $this->get_contributors();
  5583. if (isset($contributors[$key]))
  5584. {
  5585. return $contributors[$key];
  5586. }
  5587. else
  5588. {
  5589. return null;
  5590. }
  5591. }
  5592. function get_contributors()
  5593. {
  5594. $contributors = array();
  5595. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  5596. {
  5597. $name = null;
  5598. $uri = null;
  5599. $email = null;
  5600. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  5601. {
  5602. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5603. }
  5604. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  5605. {
  5606. $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]));
  5607. }
  5608. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  5609. {
  5610. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5611. }
  5612. if ($name !== null || $email !== null || $uri !== null)
  5613. {
  5614. $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
  5615. }
  5616. }
  5617. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  5618. {
  5619. $name = null;
  5620. $url = null;
  5621. $email = null;
  5622. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  5623. {
  5624. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5625. }
  5626. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  5627. {
  5628. $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]));
  5629. }
  5630. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  5631. {
  5632. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5633. }
  5634. if ($name !== null || $email !== null || $url !== null)
  5635. {
  5636. $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
  5637. }
  5638. }
  5639. if (!empty($contributors))
  5640. {
  5641. return SimplePie_Misc::array_unique($contributors);
  5642. }
  5643. else
  5644. {
  5645. return null;
  5646. }
  5647. }
  5648. function get_link($key = 0, $rel = 'alternate')
  5649. {
  5650. $links = $this->get_links($rel);
  5651. if (isset($links[$key]))
  5652. {
  5653. return $links[$key];
  5654. }
  5655. else
  5656. {
  5657. return null;
  5658. }
  5659. }
  5660. /**
  5661. * Added for parity between the parent-level and the item/entry-level.
  5662. */
  5663. function get_permalink()
  5664. {
  5665. return $this->get_link(0);
  5666. }
  5667. function get_links($rel = 'alternate')
  5668. {
  5669. if (!isset($this->data['links']))
  5670. {
  5671. $this->data['links'] = array();
  5672. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  5673. {
  5674. foreach ($links as $link)
  5675. {
  5676. if (isset($link['attribs']['']['href']))
  5677. {
  5678. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  5679. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5680. }
  5681. }
  5682. }
  5683. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  5684. {
  5685. foreach ($links as $link)
  5686. {
  5687. if (isset($link['attribs']['']['href']))
  5688. {
  5689. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  5690. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5691. }
  5692. }
  5693. }
  5694. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  5695. {
  5696. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5697. }
  5698. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  5699. {
  5700. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5701. }
  5702. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  5703. {
  5704. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5705. }
  5706. $keys = array_keys($this->data['links']);
  5707. foreach ($keys as $key)
  5708. {
  5709. if (SimplePie_Misc::is_isegment_nz_nc($key))
  5710. {
  5711. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  5712. {
  5713. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  5714. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  5715. }
  5716. else
  5717. {
  5718. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  5719. }
  5720. }
  5721. elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  5722. {
  5723. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  5724. }
  5725. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  5726. }
  5727. }
  5728. if (isset($this->data['links'][$rel]))
  5729. {
  5730. return $this->data['links'][$rel];
  5731. }
  5732. else
  5733. {
  5734. return null;
  5735. }
  5736. }
  5737. function get_description()
  5738. {
  5739. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  5740. {
  5741. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5742. }
  5743. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  5744. {
  5745. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5746. }
  5747. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  5748. {
  5749. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5750. }
  5751. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  5752. {
  5753. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5754. }
  5755. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
  5756. {
  5757. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5758. }
  5759. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  5760. {
  5761. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5762. }
  5763. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  5764. {
  5765. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5766. }
  5767. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  5768. {
  5769. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5770. }
  5771. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  5772. {
  5773. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5774. }
  5775. else
  5776. {
  5777. return null;
  5778. }
  5779. }
  5780. function get_copyright()
  5781. {
  5782. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  5783. {
  5784. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5785. }
  5786. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
  5787. {
  5788. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5789. }
  5790. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
  5791. {
  5792. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5793. }
  5794. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  5795. {
  5796. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5797. }
  5798. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  5799. {
  5800. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5801. }
  5802. else
  5803. {
  5804. return null;
  5805. }
  5806. }
  5807. function get_language()
  5808. {
  5809. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
  5810. {
  5811. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5812. }
  5813. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  5814. {
  5815. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5816. }
  5817. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  5818. {
  5819. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5820. }
  5821. elseif (isset($this->data['xml_lang']))
  5822. {
  5823. return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  5824. }
  5825. else
  5826. {
  5827. return null;
  5828. }
  5829. }
  5830. function get_latitude()
  5831. {
  5832. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  5833. {
  5834. return (float) $return[0]['data'];
  5835. }
  5836. elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  5837. {
  5838. return (float) $match[1];
  5839. }
  5840. else
  5841. {
  5842. return null;
  5843. }
  5844. }
  5845. function get_longitude()
  5846. {
  5847. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  5848. {
  5849. return (float) $return[0]['data'];
  5850. }
  5851. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  5852. {
  5853. return (float) $return[0]['data'];
  5854. }
  5855. elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  5856. {
  5857. return (float) $match[2];
  5858. }
  5859. else
  5860. {
  5861. return null;
  5862. }
  5863. }
  5864. function get_image_url()
  5865. {
  5866. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  5867. {
  5868. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  5869. }
  5870. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  5871. {
  5872. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  5873. }
  5874. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  5875. {
  5876. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  5877. }
  5878. else
  5879. {
  5880. return null;
  5881. }
  5882. }
  5883. }
  5884. class SimplePie_Author
  5885. {
  5886. var $name;
  5887. var $link;
  5888. var $email;
  5889. // Constructor, used to input the data
  5890. function SimplePie_Author($name = null, $link = null, $email = null)
  5891. {
  5892. $this->name = $name;
  5893. $this->link = $link;
  5894. $this->email = $email;
  5895. }
  5896. function __toString()
  5897. {
  5898. // There is no $this->data here
  5899. return md5(serialize($this));
  5900. }
  5901. function get_name()
  5902. {
  5903. if ($this->name !== null)
  5904. {
  5905. return $this->name;
  5906. }
  5907. else
  5908. {
  5909. return null;
  5910. }
  5911. }
  5912. function get_link()
  5913. {
  5914. if ($this->link !== null)
  5915. {
  5916. return $this->link;
  5917. }
  5918. else
  5919. {
  5920. return null;
  5921. }
  5922. }
  5923. function get_email()
  5924. {
  5925. if ($this->email !== null)
  5926. {
  5927. return $this->email;
  5928. }
  5929. else
  5930. {
  5931. return null;
  5932. }
  5933. }
  5934. }
  5935. class SimplePie_Category
  5936. {
  5937. var $term;
  5938. var $scheme;
  5939. var $label;
  5940. // Constructor, used to input the data
  5941. function SimplePie_Category($term = null, $scheme = null, $label = null)
  5942. {
  5943. $this->term = $term;
  5944. $this->scheme = $scheme;
  5945. $this->label = $label;
  5946. }
  5947. function __toString()
  5948. {
  5949. // There is no $this->data here
  5950. return md5(serialize($this));
  5951. }
  5952. function get_term()
  5953. {
  5954. if ($this->term !== null)
  5955. {
  5956. return $this->term;
  5957. }
  5958. else
  5959. {
  5960. return null;
  5961. }
  5962. }
  5963. function get_scheme()
  5964. {
  5965. if ($this->scheme !== null)
  5966. {
  5967. return $this->scheme;
  5968. }
  5969. else
  5970. {
  5971. return null;
  5972. }
  5973. }
  5974. function get_label()
  5975. {
  5976. if ($this->label !== null)
  5977. {
  5978. return $this->label;
  5979. }
  5980. else
  5981. {
  5982. return $this->get_term();
  5983. }
  5984. }
  5985. }
  5986. class SimplePie_Enclosure
  5987. {
  5988. var $bitrate;
  5989. var $captions;
  5990. var $categories;
  5991. var $channels;
  5992. var $copyright;
  5993. var $credits;
  5994. var $description;
  5995. var $duration;
  5996. var $expression;
  5997. var $framerate;
  5998. var $handler;
  5999. var $hashes;
  6000. var $height;
  6001. var $javascript;
  6002. var $keywords;
  6003. var $lang;
  6004. var $length;
  6005. var $link;
  6006. var $medium;
  6007. var $player;
  6008. var $ratings;
  6009. var $restrictions;
  6010. var $samplingrate;
  6011. var $thumbnails;
  6012. var $title;
  6013. var $type;
  6014. var $width;
  6015. // Constructor, used to input the data
  6016. 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)
  6017. {
  6018. $this->bitrate = $bitrate;
  6019. $this->captions = $captions;
  6020. $this->categories = $categories;
  6021. $this->channels = $channels;
  6022. $this->copyright = $copyright;
  6023. $this->credits = $credits;
  6024. $this->description = $description;
  6025. $this->duration = $duration;
  6026. $this->expression = $expression;
  6027. $this->framerate = $framerate;
  6028. $this->hashes = $hashes;
  6029. $this->height = $height;
  6030. $this->javascript = $javascript;
  6031. $this->keywords = $keywords;
  6032. $this->lang = $lang;
  6033. $this->length = $length;
  6034. $this->link = $link;
  6035. $this->medium = $medium;
  6036. $this->player = $player;
  6037. $this->ratings = $ratings;
  6038. $this->restrictions = $restrictions;
  6039. $this->samplingrate = $samplingrate;
  6040. $this->thumbnails = $thumbnails;
  6041. $this->title = $title;
  6042. $this->type = $type;
  6043. $this->width = $width;
  6044. if (class_exists('idna_convert'))
  6045. {
  6046. $idn =& new idna_convert;
  6047. $parsed = SimplePie_Misc::parse_url($link);
  6048. $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  6049. }
  6050. $this->handler = $this->get_handler(); // Needs to load last
  6051. }
  6052. function __toString()
  6053. {
  6054. // There is no $this->data here
  6055. return md5(serialize($this));
  6056. }
  6057. function get_bitrate()
  6058. {
  6059. if ($this->bitrate !== null)
  6060. {
  6061. return $this->bitrate;
  6062. }
  6063. else
  6064. {
  6065. return null;
  6066. }
  6067. }
  6068. function get_caption($key = 0)
  6069. {
  6070. $captions = $this->get_captions();
  6071. if (isset($captions[$key]))
  6072. {
  6073. return $captions[$key];
  6074. }
  6075. else
  6076. {
  6077. return null;
  6078. }
  6079. }
  6080. function get_captions()
  6081. {
  6082. if ($this->captions !== null)
  6083. {
  6084. return $this->captions;
  6085. }
  6086. else
  6087. {
  6088. return null;
  6089. }
  6090. }
  6091. function get_category($key = 0)
  6092. {
  6093. $categories = $this->get_categories();
  6094. if (isset($categories[$key]))
  6095. {
  6096. return $categories[$key];
  6097. }
  6098. else
  6099. {
  6100. return null;
  6101. }
  6102. }
  6103. function get_categories()
  6104. {
  6105. if ($this->categories !== null)
  6106. {
  6107. return $this->categories;
  6108. }
  6109. else
  6110. {
  6111. return null;
  6112. }
  6113. }
  6114. function get_channels()
  6115. {
  6116. if ($this->channels !== null)
  6117. {
  6118. return $this->channels;
  6119. }
  6120. else
  6121. {
  6122. return null;
  6123. }
  6124. }
  6125. function get_copyright()
  6126. {
  6127. if ($this->copyright !== null)
  6128. {
  6129. return $this->copyright;
  6130. }
  6131. else
  6132. {
  6133. return null;
  6134. }
  6135. }
  6136. function get_credit($key = 0)
  6137. {
  6138. $credits = $this->get_credits();
  6139. if (isset($credits[$key]))
  6140. {
  6141. return $credits[$key];
  6142. }
  6143. else
  6144. {
  6145. return null;
  6146. }
  6147. }
  6148. function get_credits()
  6149. {
  6150. if ($this->credits !== null)
  6151. {
  6152. return $this->credits;
  6153. }
  6154. else
  6155. {
  6156. return null;
  6157. }
  6158. }
  6159. function get_description()
  6160. {
  6161. if ($this->description !== null)
  6162. {
  6163. return $this->description;
  6164. }
  6165. else
  6166. {
  6167. return null;
  6168. }
  6169. }
  6170. function get_duration($convert = false)
  6171. {
  6172. if ($this->duration !== null)
  6173. {
  6174. if ($convert)
  6175. {
  6176. $time = SimplePie_Misc::time_hms($this->duration);
  6177. return $time;
  6178. }
  6179. else
  6180. {
  6181. return $this->duration;
  6182. }
  6183. }
  6184. else
  6185. {
  6186. return null;
  6187. }
  6188. }
  6189. function get_expression()
  6190. {
  6191. if ($this->expression !== null)
  6192. {
  6193. return $this->expression;
  6194. }
  6195. else
  6196. {
  6197. return 'full';
  6198. }
  6199. }
  6200. function get_extension()
  6201. {
  6202. if ($this->link !== null)
  6203. {
  6204. $url = SimplePie_Misc::parse_url($this->link);
  6205. if ($url['path'] !== '')
  6206. {
  6207. return pathinfo($url['path'], PATHINFO_EXTENSION);
  6208. }
  6209. }
  6210. return null;
  6211. }
  6212. function get_framerate()
  6213. {
  6214. if ($this->framerate !== null)
  6215. {
  6216. return $this->framerate;
  6217. }
  6218. else
  6219. {
  6220. return null;
  6221. }
  6222. }
  6223. function get_handler()
  6224. {
  6225. return $this->get_real_type(true);
  6226. }
  6227. function get_hash($key = 0)
  6228. {
  6229. $hashes = $this->get_hashes();
  6230. if (isset($hashes[$key]))
  6231. {
  6232. return $hashes[$key];
  6233. }
  6234. else
  6235. {
  6236. return null;
  6237. }
  6238. }
  6239. function get_hashes()
  6240. {
  6241. if ($this->hashes !== null)
  6242. {
  6243. return $this->hashes;
  6244. }
  6245. else
  6246. {
  6247. return null;
  6248. }
  6249. }
  6250. function get_height()
  6251. {
  6252. if ($this->height !== null)
  6253. {
  6254. return $this->height;
  6255. }
  6256. else
  6257. {
  6258. return null;
  6259. }
  6260. }
  6261. function get_language()
  6262. {
  6263. if ($this->lang !== null)
  6264. {
  6265. return $this->lang;
  6266. }
  6267. else
  6268. {
  6269. return null;
  6270. }
  6271. }
  6272. function get_keyword($key = 0)
  6273. {
  6274. $keywords = $this->get_keywords();
  6275. if (isset($keywords[$key]))
  6276. {
  6277. return $keywords[$key];
  6278. }
  6279. else
  6280. {
  6281. return null;
  6282. }
  6283. }
  6284. function get_keywords()
  6285. {
  6286. if ($this->keywords !== null)
  6287. {
  6288. return $this->keywords;
  6289. }
  6290. else
  6291. {
  6292. return null;
  6293. }
  6294. }
  6295. function get_length()
  6296. {
  6297. if ($this->length !== null)
  6298. {
  6299. return $this->length;
  6300. }
  6301. else
  6302. {
  6303. return null;
  6304. }
  6305. }
  6306. function get_link()
  6307. {
  6308. if ($this->link !== null)
  6309. {
  6310. return urldecode($this->link);
  6311. }
  6312. else
  6313. {
  6314. return null;
  6315. }
  6316. }
  6317. function get_medium()
  6318. {
  6319. if ($this->medium !== null)
  6320. {
  6321. return $this->medium;
  6322. }
  6323. else
  6324. {
  6325. return null;
  6326. }
  6327. }
  6328. function get_player()
  6329. {
  6330. if ($this->player !== null)
  6331. {
  6332. return $this->player;
  6333. }
  6334. else
  6335. {
  6336. return null;
  6337. }
  6338. }
  6339. function get_rating($key = 0)
  6340. {
  6341. $ratings = $this->get_ratings();
  6342. if (isset($ratings[$key]))
  6343. {
  6344. return $ratings[$key];
  6345. }
  6346. else
  6347. {
  6348. return null;
  6349. }
  6350. }
  6351. function get_ratings()
  6352. {
  6353. if ($this->ratings !== null)
  6354. {
  6355. return $this->ratings;
  6356. }
  6357. else
  6358. {
  6359. return null;
  6360. }
  6361. }
  6362. function get_restriction($key = 0)
  6363. {
  6364. $restrictions = $this->get_restrictions();
  6365. if (isset($restrictions[$key]))
  6366. {
  6367. return $restrictions[$key];
  6368. }
  6369. else
  6370. {
  6371. return null;
  6372. }
  6373. }
  6374. function get_restrictions()
  6375. {
  6376. if ($this->restrictions !== null)
  6377. {
  6378. return $this->restrictions;
  6379. }
  6380. else
  6381. {
  6382. return null;
  6383. }
  6384. }
  6385. function get_sampling_rate()
  6386. {
  6387. if ($this->samplingrate !== null)
  6388. {
  6389. return $this->samplingrate;
  6390. }
  6391. else
  6392. {
  6393. return null;
  6394. }
  6395. }
  6396. function get_size()
  6397. {
  6398. $length = $this->get_length();
  6399. if ($length !== null)
  6400. {
  6401. return round($length/1048576, 2);
  6402. }
  6403. else
  6404. {
  6405. return null;
  6406. }
  6407. }
  6408. function get_thumbnail($key = 0)
  6409. {
  6410. $thumbnails = $this->get_thumbnails();
  6411. if (isset($thumbnails[$key]))
  6412. {
  6413. return $thumbnails[$key];
  6414. }
  6415. else
  6416. {
  6417. return null;
  6418. }
  6419. }
  6420. function get_thumbnails()
  6421. {
  6422. if ($this->thumbnails !== null)
  6423. {
  6424. return $this->thumbnails;
  6425. }
  6426. else
  6427. {
  6428. return null;
  6429. }
  6430. }
  6431. function get_title()
  6432. {
  6433. if ($this->title !== null)
  6434. {
  6435. return $this->title;
  6436. }
  6437. else
  6438. {
  6439. return null;
  6440. }
  6441. }
  6442. function get_type()
  6443. {
  6444. if ($this->type !== null)
  6445. {
  6446. return $this->type;
  6447. }
  6448. else
  6449. {
  6450. return null;
  6451. }
  6452. }
  6453. function get_width()
  6454. {
  6455. if ($this->width !== null)
  6456. {
  6457. return $this->width;
  6458. }
  6459. else
  6460. {
  6461. return null;
  6462. }
  6463. }
  6464. function native_embed($options='')
  6465. {
  6466. return $this->embed($options, true);
  6467. }
  6468. /**
  6469. * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
  6470. */
  6471. function embed($options = '', $native = false)
  6472. {
  6473. // Set up defaults
  6474. $audio = '';
  6475. $video = '';
  6476. $alt = '';
  6477. $altclass = '';
  6478. $loop = 'false';
  6479. $width = 'auto';
  6480. $height = 'auto';
  6481. $bgcolor = '#ffffff';
  6482. $mediaplayer = '';
  6483. $widescreen = false;
  6484. $handler = $this->get_handler();
  6485. $type = $this->get_real_type();
  6486. // Process options and reassign values as necessary
  6487. if (is_array($options))
  6488. {
  6489. extract($options);
  6490. }
  6491. else
  6492. {
  6493. $options = explode(',', $options);
  6494. foreach($options as $option)
  6495. {
  6496. $opt = explode(':', $option, 2);
  6497. if (isset($opt[0], $opt[1]))
  6498. {
  6499. $opt[0] = trim($opt[0]);
  6500. $opt[1] = trim($opt[1]);
  6501. switch ($opt[0])
  6502. {
  6503. case 'audio':
  6504. $audio = $opt[1];
  6505. break;
  6506. case 'video':
  6507. $video = $opt[1];
  6508. break;
  6509. case 'alt':
  6510. $alt = $opt[1];
  6511. break;
  6512. case 'altclass':
  6513. $altclass = $opt[1];
  6514. break;
  6515. case 'loop':
  6516. $loop = $opt[1];
  6517. break;
  6518. case 'width':
  6519. $width = $opt[1];
  6520. break;
  6521. case 'height':
  6522. $height = $opt[1];
  6523. break;
  6524. case 'bgcolor':
  6525. $bgcolor = $opt[1];
  6526. break;
  6527. case 'mediaplayer':
  6528. $mediaplayer = $opt[1];
  6529. break;
  6530. case 'widescreen':
  6531. $widescreen = $opt[1];
  6532. break;
  6533. }
  6534. }
  6535. }
  6536. }
  6537. $mime = explode('/', $type, 2);
  6538. $mime = $mime[0];
  6539. // Process values for 'auto'
  6540. if ($width === 'auto')
  6541. {
  6542. if ($mime === 'video')
  6543. {
  6544. if ($height === 'auto')
  6545. {
  6546. $width = 480;
  6547. }
  6548. elseif ($widescreen)
  6549. {
  6550. $width = round((intval($height)/9)*16);
  6551. }
  6552. else
  6553. {
  6554. $width = round((intval($height)/3)*4);
  6555. }
  6556. }
  6557. else
  6558. {
  6559. $width = '100%';
  6560. }
  6561. }
  6562. if ($height === 'auto')
  6563. {
  6564. if ($mime === 'audio')
  6565. {
  6566. $height = 0;
  6567. }
  6568. elseif ($mime === 'video')
  6569. {
  6570. if ($width === 'auto')
  6571. {
  6572. if ($widescreen)
  6573. {
  6574. $height = 270;
  6575. }
  6576. else
  6577. {
  6578. $height = 360;
  6579. }
  6580. }
  6581. elseif ($widescreen)
  6582. {
  6583. $height = round((intval($width)/16)*9);
  6584. }
  6585. else
  6586. {
  6587. $height = round((intval($width)/4)*3);
  6588. }
  6589. }
  6590. else
  6591. {
  6592. $height = 376;
  6593. }
  6594. }
  6595. elseif ($mime === 'audio')
  6596. {
  6597. $height = 0;
  6598. }
  6599. // Set proper placeholder value
  6600. if ($mime === 'audio')
  6601. {
  6602. $placeholder = $audio;
  6603. }
  6604. elseif ($mime === 'video')
  6605. {
  6606. $placeholder = $video;
  6607. }
  6608. $embed = '';
  6609. // Make sure the JS library is included
  6610. if (!$native)
  6611. {
  6612. static $javascript_outputted = null;
  6613. if (!$javascript_outputted && $this->javascript)
  6614. {
  6615. $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
  6616. $javascript_outputted = true;
  6617. }
  6618. }
  6619. // Odeo Feed MP3's
  6620. if ($handler === 'odeo')
  6621. {
  6622. if ($native)
  6623. {
  6624. $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>';
  6625. }
  6626. else
  6627. {
  6628. $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
  6629. }
  6630. }
  6631. // Flash
  6632. elseif ($handler === 'flash')
  6633. {
  6634. if ($native)
  6635. {
  6636. $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>";
  6637. }
  6638. else
  6639. {
  6640. $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
  6641. }
  6642. }
  6643. // Flash Media Player file types.
  6644. // Preferred handler for MP3 file types.
  6645. elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
  6646. {
  6647. $height += 20;
  6648. if ($native)
  6649. {
  6650. $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>";
  6651. }
  6652. else
  6653. {
  6654. $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
  6655. }
  6656. }
  6657. // QuickTime 7 file types. Need to test with QuickTime 6.
  6658. // Only handle MP3's if the Flash Media Player is not present.
  6659. elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
  6660. {
  6661. $height += 16;
  6662. if ($native)
  6663. {
  6664. if ($placeholder !== '')
  6665. {
  6666. $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>";
  6667. }
  6668. else
  6669. {
  6670. $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>";
  6671. }
  6672. }
  6673. else
  6674. {
  6675. $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
  6676. }
  6677. }
  6678. // Windows Media
  6679. elseif ($handler === 'wmedia')
  6680. {
  6681. $height += 45;
  6682. if ($native)
  6683. {
  6684. $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>";
  6685. }
  6686. else
  6687. {
  6688. $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
  6689. }
  6690. }
  6691. // Everything else
  6692. else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
  6693. return $embed;
  6694. }
  6695. function get_real_type($find_handler = false)
  6696. {
  6697. // If it's Odeo, let's get it out of the way.
  6698. if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')
  6699. {
  6700. return 'odeo';
  6701. }
  6702. // Mime-types by handler.
  6703. $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
  6704. $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
  6705. $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
  6706. $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
  6707. $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
  6708. if ($this->get_type() !== null)
  6709. {
  6710. $type = strtolower($this->type);
  6711. }
  6712. else
  6713. {
  6714. $type = null;
  6715. }
  6716. // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
  6717. if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
  6718. {
  6719. switch (strtolower($this->get_extension()))
  6720. {
  6721. // Audio mime-types
  6722. case 'aac':
  6723. case 'adts':
  6724. $type = 'audio/acc';
  6725. break;
  6726. case 'aif':
  6727. case 'aifc':
  6728. case 'aiff':
  6729. case 'cdda':
  6730. $type = 'audio/aiff';
  6731. break;
  6732. case 'bwf':
  6733. $type = 'audio/wav';
  6734. break;
  6735. case 'kar':
  6736. case 'mid':
  6737. case 'midi':
  6738. case 'smf':
  6739. $type = 'audio/midi';
  6740. break;
  6741. case 'm4a':
  6742. $type = 'audio/x-m4a';
  6743. break;
  6744. case 'mp3':
  6745. case 'swa':
  6746. $type = 'audio/mp3';
  6747. break;
  6748. case 'wav':
  6749. $type = 'audio/wav';
  6750. break;
  6751. case 'wax':
  6752. $type = 'audio/x-ms-wax';
  6753. break;
  6754. case 'wma':
  6755. $type = 'audio/x-ms-wma';
  6756. break;
  6757. // Video mime-types
  6758. case '3gp':
  6759. case '3gpp':
  6760. $type = 'video/3gpp';
  6761. break;
  6762. case '3g2':
  6763. case '3gp2':
  6764. $type = 'video/3gpp2';
  6765. break;
  6766. case 'asf':
  6767. $type = 'video/x-ms-asf';
  6768. break;
  6769. case 'flv':
  6770. $type = 'video/x-flv';
  6771. break;
  6772. case 'm1a':
  6773. case 'm1s':
  6774. case 'm1v':
  6775. case 'm15':
  6776. case 'm75':
  6777. case 'mp2':
  6778. case 'mpa':
  6779. case 'mpeg':
  6780. case 'mpg':
  6781. case 'mpm':
  6782. case 'mpv':
  6783. $type = 'video/mpeg';
  6784. break;
  6785. case 'm4v':
  6786. $type = 'video/x-m4v';
  6787. break;
  6788. case 'mov':
  6789. case 'qt':
  6790. $type = 'video/quicktime';
  6791. break;
  6792. case 'mp4':
  6793. case 'mpg4':
  6794. $type = 'video/mp4';
  6795. break;
  6796. case 'sdv':
  6797. $type = 'video/sd-video';
  6798. break;
  6799. case 'wm':
  6800. $type = 'video/x-ms-wm';
  6801. break;
  6802. case 'wmv':
  6803. $type = 'video/x-ms-wmv';
  6804. break;
  6805. case 'wvx':
  6806. $type = 'video/x-ms-wvx';
  6807. break;
  6808. // Flash mime-types
  6809. case 'spl':
  6810. $type = 'application/futuresplash';
  6811. break;
  6812. case 'swf':
  6813. $type = 'application/x-shockwave-flash';
  6814. break;
  6815. }
  6816. }
  6817. if ($find_handler)
  6818. {
  6819. if (in_array($type, $types_flash))
  6820. {
  6821. return 'flash';
  6822. }
  6823. elseif (in_array($type, $types_fmedia))
  6824. {
  6825. return 'fmedia';
  6826. }
  6827. elseif (in_array($type, $types_quicktime))
  6828. {
  6829. return 'quicktime';
  6830. }
  6831. elseif (in_array($type, $types_wmedia))
  6832. {
  6833. return 'wmedia';
  6834. }
  6835. elseif (in_array($type, $types_mp3))
  6836. {
  6837. return 'mp3';
  6838. }
  6839. else
  6840. {
  6841. return null;
  6842. }
  6843. }
  6844. else
  6845. {
  6846. return $type;
  6847. }
  6848. }
  6849. }
  6850. class SimplePie_Caption
  6851. {
  6852. var $type;
  6853. var $lang;
  6854. var $startTime;
  6855. var $endTime;
  6856. var $text;
  6857. // Constructor, used to input the data
  6858. function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
  6859. {
  6860. $this->type = $type;
  6861. $this->lang = $lang;
  6862. $this->startTime = $startTime;
  6863. $this->endTime = $endTime;
  6864. $this->text = $text;
  6865. }
  6866. function __toString()
  6867. {
  6868. // There is no $this->data here
  6869. return md5(serialize($this));
  6870. }
  6871. function get_endtime()
  6872. {
  6873. if ($this->endTime !== null)
  6874. {
  6875. return $this->endTime;
  6876. }
  6877. else
  6878. {
  6879. return null;
  6880. }
  6881. }
  6882. function get_language()
  6883. {
  6884. if ($this->lang !== null)
  6885. {
  6886. return $this->lang;
  6887. }
  6888. else
  6889. {
  6890. return null;
  6891. }
  6892. }
  6893. function get_starttime()
  6894. {
  6895. if ($this->startTime !== null)
  6896. {
  6897. return $this->startTime;
  6898. }
  6899. else
  6900. {
  6901. return null;
  6902. }
  6903. }
  6904. function get_text()
  6905. {
  6906. if ($this->text !== null)
  6907. {
  6908. return $this->text;
  6909. }
  6910. else
  6911. {
  6912. return null;
  6913. }
  6914. }
  6915. function get_type()
  6916. {
  6917. if ($this->type !== null)
  6918. {
  6919. return $this->type;
  6920. }
  6921. else
  6922. {
  6923. return null;
  6924. }
  6925. }
  6926. }
  6927. class SimplePie_Credit
  6928. {
  6929. var $role;
  6930. var $scheme;
  6931. var $name;
  6932. // Constructor, used to input the data
  6933. function SimplePie_Credit($role = null, $scheme = null, $name = null)
  6934. {
  6935. $this->role = $role;
  6936. $this->scheme = $scheme;
  6937. $this->name = $name;
  6938. }
  6939. function __toString()
  6940. {
  6941. // There is no $this->data here
  6942. return md5(serialize($this));
  6943. }
  6944. function get_role()
  6945. {
  6946. if ($this->role !== null)
  6947. {
  6948. return $this->role;
  6949. }
  6950. else
  6951. {
  6952. return null;
  6953. }
  6954. }
  6955. function get_scheme()
  6956. {
  6957. if ($this->scheme !== null)
  6958. {
  6959. return $this->scheme;
  6960. }
  6961. else
  6962. {
  6963. return null;
  6964. }
  6965. }
  6966. function get_name()
  6967. {
  6968. if ($this->name !== null)
  6969. {
  6970. return $this->name;
  6971. }
  6972. else
  6973. {
  6974. return null;
  6975. }
  6976. }
  6977. }
  6978. class SimplePie_Copyright
  6979. {
  6980. var $url;
  6981. var $label;
  6982. // Constructor, used to input the data
  6983. function SimplePie_Copyright($url = null, $label = null)
  6984. {
  6985. $this->url = $url;
  6986. $this->label = $label;
  6987. }
  6988. function __toString()
  6989. {
  6990. // There is no $this->data here
  6991. return md5(serialize($this));
  6992. }
  6993. function get_url()
  6994. {
  6995. if ($this->url !== null)
  6996. {
  6997. return $this->url;
  6998. }
  6999. else
  7000. {
  7001. return null;
  7002. }
  7003. }
  7004. function get_attribution()
  7005. {
  7006. if ($this->label !== null)
  7007. {
  7008. return $this->label;
  7009. }
  7010. else
  7011. {
  7012. return null;
  7013. }
  7014. }
  7015. }
  7016. class SimplePie_Rating
  7017. {
  7018. var $scheme;
  7019. var $value;
  7020. // Constructor, used to input the data
  7021. function SimplePie_Rating($scheme = null, $value = null)
  7022. {
  7023. $this->scheme = $scheme;
  7024. $this->value = $value;
  7025. }
  7026. function __toString()
  7027. {
  7028. // There is no $this->data here
  7029. return md5(serialize($this));
  7030. }
  7031. function get_scheme()
  7032. {
  7033. if ($this->scheme !== null)
  7034. {
  7035. return $this->scheme;
  7036. }
  7037. else
  7038. {
  7039. return null;
  7040. }
  7041. }
  7042. function get_value()
  7043. {
  7044. if ($this->value !== null)
  7045. {
  7046. return $this->value;
  7047. }
  7048. else
  7049. {
  7050. return null;
  7051. }
  7052. }
  7053. }
  7054. class SimplePie_Restriction
  7055. {
  7056. var $relationship;
  7057. var $type;
  7058. var $value;
  7059. // Constructor, used to input the data
  7060. function SimplePie_Restriction($relationship = null, $type = null, $value = null)
  7061. {
  7062. $this->relationship = $relationship;
  7063. $this->type = $type;
  7064. $this->value = $value;
  7065. }
  7066. function __toString()
  7067. {
  7068. // There is no $this->data here
  7069. return md5(serialize($this));
  7070. }
  7071. function get_relationship()
  7072. {
  7073. if ($this->relationship !== null)
  7074. {
  7075. return $this->relationship;
  7076. }
  7077. else
  7078. {
  7079. return null;
  7080. }
  7081. }
  7082. function get_type()
  7083. {
  7084. if ($this->type !== null)
  7085. {
  7086. return $this->type;
  7087. }
  7088. else
  7089. {
  7090. return null;
  7091. }
  7092. }
  7093. function get_value()
  7094. {
  7095. if ($this->value !== null)
  7096. {
  7097. return $this->value;
  7098. }
  7099. else
  7100. {
  7101. return null;
  7102. }
  7103. }
  7104. }
  7105. /**
  7106. * @todo Move to properly supporting RFC2616 (HTTP/1.1)
  7107. */
  7108. class SimplePie_File
  7109. {
  7110. var $url;
  7111. var $useragent;
  7112. var $success = true;
  7113. var $headers = array();
  7114. var $body;
  7115. var $status_code;
  7116. var $redirects = 0;
  7117. var $error;
  7118. var $method = SIMPLEPIE_FILE_SOURCE_NONE;
  7119. function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
  7120. {
  7121. if (class_exists('idna_convert'))
  7122. {
  7123. $idn =& new idna_convert;
  7124. $parsed = SimplePie_Misc::parse_url($url);
  7125. $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  7126. }
  7127. $this->url = $url;
  7128. $this->useragent = $useragent;
  7129. if (preg_match('/^http(s)?:\/\//i', $url))
  7130. {
  7131. if ($useragent === null)
  7132. {
  7133. $useragent = ini_get('user_agent');
  7134. $this->useragent = $useragent;
  7135. }
  7136. if (!is_array($headers))
  7137. {
  7138. $headers = array();
  7139. }
  7140. if (!$force_fsockopen && function_exists('curl_exec'))
  7141. {
  7142. $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
  7143. $fp = curl_init();
  7144. $headers2 = array();
  7145. foreach ($headers as $key => $value)
  7146. {
  7147. $headers2[] = "$key: $value";
  7148. }
  7149. if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
  7150. {
  7151. curl_setopt($fp, CURLOPT_ENCODING, '');
  7152. }
  7153. curl_setopt($fp, CURLOPT_URL, $url);
  7154. curl_setopt($fp, CURLOPT_HEADER, 1);
  7155. curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
  7156. curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
  7157. curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
  7158. curl_setopt($fp, CURLOPT_REFERER, $url);
  7159. curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
  7160. curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
  7161. if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
  7162. {
  7163. curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
  7164. curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
  7165. }
  7166. $this->headers = curl_exec($fp);
  7167. if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
  7168. {
  7169. curl_setopt($fp, CURLOPT_ENCODING, 'none');
  7170. $this->headers = curl_exec($fp);
  7171. }
  7172. if (curl_errno($fp))
  7173. {
  7174. $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
  7175. $this->success = false;
  7176. }
  7177. else
  7178. {
  7179. $info = curl_getinfo($fp);
  7180. curl_close($fp);
  7181. $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
  7182. $this->headers = array_pop($this->headers);
  7183. $parser =& new SimplePie_HTTP_Parser($this->headers);
  7184. if ($parser->parse())
  7185. {
  7186. $this->headers = $parser->headers;
  7187. $this->body = $parser->body;
  7188. $this->status_code = $parser->status_code;
  7189. if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  7190. {
  7191. $this->redirects++;
  7192. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  7193. return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  7194. }
  7195. }
  7196. }
  7197. }
  7198. else
  7199. {
  7200. $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
  7201. $url_parts = parse_url($url);
  7202. $socket_host = $url_parts['host'];
  7203. if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
  7204. {
  7205. $socket_host = "ssl://$url_parts[host]";
  7206. $url_parts['port'] = 443;
  7207. }
  7208. if (!isset($url_parts['port']))
  7209. {
  7210. $url_parts['port'] = 80;
  7211. }
  7212. $fp = @fsockopen($socket_host, $url_parts['port'], $errno, $errstr, $timeout);
  7213. if (!$fp)
  7214. {
  7215. $this->error = 'fsockopen error: ' . $errstr;
  7216. $this->success = false;
  7217. }
  7218. else
  7219. {
  7220. stream_set_timeout($fp, $timeout);
  7221. if (isset($url_parts['path']))
  7222. {
  7223. if (isset($url_parts['query']))
  7224. {
  7225. $get = "$url_parts[path]?$url_parts[query]";
  7226. }
  7227. else
  7228. {
  7229. $get = $url_parts['path'];
  7230. }
  7231. }
  7232. else
  7233. {
  7234. $get = '/';
  7235. }
  7236. $out = "GET $get HTTP/1.0\r\n";
  7237. $out .= "Host: $url_parts[host]\r\n";
  7238. $out .= "User-Agent: $useragent\r\n";
  7239. if (extension_loaded('zlib'))
  7240. {
  7241. $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
  7242. }
  7243. if (isset($url_parts['user']) && isset($url_parts['pass']))
  7244. {
  7245. $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
  7246. }
  7247. foreach ($headers as $key => $value)
  7248. {
  7249. $out .= "$key: $value\r\n";
  7250. }
  7251. $out .= "Connection: Close\r\n\r\n";
  7252. fwrite($fp, $out);
  7253. $info = stream_get_meta_data($fp);
  7254. $this->headers = '';
  7255. while (!$info['eof'] && !$info['timed_out'])
  7256. {
  7257. $this->headers .= fread($fp, 1160);
  7258. $info = stream_get_meta_data($fp);
  7259. }
  7260. if (!$info['timed_out'])
  7261. {
  7262. $parser =& new SimplePie_HTTP_Parser($this->headers);
  7263. if ($parser->parse())
  7264. {
  7265. $this->headers = $parser->headers;
  7266. $this->body = $parser->body;
  7267. $this->status_code = $parser->status_code;
  7268. if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  7269. {
  7270. $this->redirects++;
  7271. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  7272. return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  7273. }
  7274. if (isset($this->headers['content-encoding']))
  7275. {
  7276. // Hey, we act dumb elsewhere, so let's do that here too
  7277. switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
  7278. {
  7279. case 'gzip':
  7280. case 'x-gzip':
  7281. $decoder =& new SimplePie_gzdecode($this->body);
  7282. if (!$decoder->parse())
  7283. {
  7284. $this->error = 'Unable to decode HTTP "gzip" stream';
  7285. $this->success = false;
  7286. }
  7287. else
  7288. {
  7289. $this->body = $decoder->data;
  7290. }
  7291. break;
  7292. case 'deflate':
  7293. if (($body = gzuncompress($this->body)) === false)
  7294. {
  7295. if (($body = gzinflate($this->body)) === false)
  7296. {
  7297. $this->error = 'Unable to decode HTTP "deflate" stream';
  7298. $this->success = false;
  7299. }
  7300. }
  7301. $this->body = $body;
  7302. break;
  7303. default:
  7304. $this->error = 'Unknown content coding';
  7305. $this->success = false;
  7306. }
  7307. }
  7308. }
  7309. }
  7310. else
  7311. {
  7312. $this->error = 'fsocket timed out';
  7313. $this->success = false;
  7314. }
  7315. fclose($fp);
  7316. }
  7317. }
  7318. }
  7319. else
  7320. {
  7321. $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
  7322. if (!$this->body = file_get_contents($url))
  7323. {
  7324. $this->error = 'file_get_contents could not read the file';
  7325. $this->success = false;
  7326. }
  7327. }
  7328. }
  7329. }
  7330. /**
  7331. * HTTP Response Parser
  7332. *
  7333. * @package SimplePie
  7334. */
  7335. class SimplePie_HTTP_Parser
  7336. {
  7337. /**
  7338. * HTTP Version
  7339. *
  7340. * @access public
  7341. * @var float
  7342. */
  7343. var $http_version = 0.0;
  7344. /**
  7345. * Status code
  7346. *
  7347. * @access public
  7348. * @var int
  7349. */
  7350. var $status_code = 0;
  7351. /**
  7352. * Reason phrase
  7353. *
  7354. * @access public
  7355. * @var string
  7356. */
  7357. var $reason = '';
  7358. /**
  7359. * Key/value pairs of the headers
  7360. *
  7361. * @access public
  7362. * @var array
  7363. */
  7364. var $headers = array();
  7365. /**
  7366. * Body of the response
  7367. *
  7368. * @access public
  7369. * @var string
  7370. */
  7371. var $body = '';
  7372. /**
  7373. * Current state of the state machine
  7374. *
  7375. * @access private
  7376. * @var string
  7377. */
  7378. var $state = 'http_version';
  7379. /**
  7380. * Input data
  7381. *
  7382. * @access private
  7383. * @var string
  7384. */
  7385. var $data = '';
  7386. /**
  7387. * Input data length (to avoid calling strlen() everytime this is needed)
  7388. *
  7389. * @access private
  7390. * @var int
  7391. */
  7392. var $data_length = 0;
  7393. /**
  7394. * Current position of the pointer
  7395. *
  7396. * @var int
  7397. * @access private
  7398. */
  7399. var $position = 0;
  7400. /**
  7401. * Name of the hedaer currently being parsed
  7402. *
  7403. * @access private
  7404. * @var string
  7405. */
  7406. var $name = '';
  7407. /**
  7408. * Value of the hedaer currently being parsed
  7409. *
  7410. * @access private
  7411. * @var string
  7412. */
  7413. var $value = '';
  7414. /**
  7415. * Create an instance of the class with the input data
  7416. *
  7417. * @access public
  7418. * @param string $data Input data
  7419. */
  7420. function SimplePie_HTTP_Parser($data)
  7421. {
  7422. $this->data = $data;
  7423. $this->data_length = strlen($this->data);
  7424. }
  7425. /**
  7426. * Parse the input data
  7427. *
  7428. * @access public
  7429. * @return bool true on success, false on failure
  7430. */
  7431. function parse()
  7432. {
  7433. while ($this->state && $this->state !== 'emit' && $this->has_data())
  7434. {
  7435. $state = $this->state;
  7436. $this->$state();
  7437. }
  7438. $this->data = '';
  7439. if ($this->state === 'emit' || $this->state === 'body')
  7440. {
  7441. return true;
  7442. }
  7443. else
  7444. {
  7445. $this->http_version = '';
  7446. $this->status_code = '';
  7447. $this->reason = '';
  7448. $this->headers = array();
  7449. $this->body = '';
  7450. return false;
  7451. }
  7452. }
  7453. /**
  7454. * Check whether there is data beyond the pointer
  7455. *
  7456. * @access private
  7457. * @return bool true if there is further data, false if not
  7458. */
  7459. function has_data()
  7460. {
  7461. return (bool) ($this->position < $this->data_length);
  7462. }
  7463. /**
  7464. * See if the next character is LWS
  7465. *
  7466. * @access private
  7467. * @return bool true if the next character is LWS, false if not
  7468. */
  7469. function is_linear_whitespace()
  7470. {
  7471. return (bool) ($this->data[$this->position] === "\x09"
  7472. || $this->data[$this->position] === "\x20"
  7473. || ($this->data[$this->position] === "\x0A"
  7474. && isset($this->data[$this->position + 1])
  7475. && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
  7476. }
  7477. /**
  7478. * Parse the HTTP version
  7479. *
  7480. * @access private
  7481. */
  7482. function http_version()
  7483. {
  7484. if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
  7485. {
  7486. $len = strspn($this->data, '0123456789.', 5);
  7487. $this->http_version = substr($this->data, 5, $len);
  7488. $this->position += 5 + $len;
  7489. if (substr_count($this->http_version, '.') <= 1)
  7490. {
  7491. $this->http_version = (float) $this->http_version;
  7492. $this->position += strspn($this->data, "\x09\x20", $this->position);
  7493. $this->state = 'status';
  7494. }
  7495. else
  7496. {
  7497. $this->state = false;
  7498. }
  7499. }
  7500. else
  7501. {
  7502. $this->state = false;
  7503. }
  7504. }
  7505. /**
  7506. * Parse the status code
  7507. *
  7508. * @access private
  7509. */
  7510. function status()
  7511. {
  7512. if ($len = strspn($this->data, '0123456789', $this->position))
  7513. {
  7514. $this->status_code = (int) substr($this->data, $this->position, $len);
  7515. $this->position += $len;
  7516. $this->state = 'reason';
  7517. }
  7518. else
  7519. {
  7520. $this->state = false;
  7521. }
  7522. }
  7523. /**
  7524. * Parse the reason phrase
  7525. *
  7526. * @access private
  7527. */
  7528. function reason()
  7529. {
  7530. $len = strcspn($this->data, "\x0A", $this->position);
  7531. $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
  7532. $this->position += $len + 1;
  7533. $this->state = 'new_line';
  7534. }
  7535. /**
  7536. * Deal with a new line, shifting data around as needed
  7537. *
  7538. * @access private
  7539. */
  7540. function new_line()
  7541. {
  7542. $this->value = trim($this->value, "\x0D\x20");
  7543. if ($this->name !== '' && $this->value !== '')
  7544. {
  7545. $this->name = strtolower($this->name);
  7546. if (isset($this->headers[$this->name]))
  7547. {
  7548. $this->headers[$this->name] .= ', ' . $this->value;
  7549. }
  7550. else
  7551. {
  7552. $this->headers[$this->name] = $this->value;
  7553. }
  7554. }
  7555. $this->name = '';
  7556. $this->value = '';
  7557. if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
  7558. {
  7559. $this->position += 2;
  7560. $this->state = 'body';
  7561. }
  7562. elseif ($this->data[$this->position] === "\x0A")
  7563. {
  7564. $this->position++;
  7565. $this->state = 'body';
  7566. }
  7567. else
  7568. {
  7569. $this->state = 'name';
  7570. }
  7571. }
  7572. /**
  7573. * Parse a header name
  7574. *
  7575. * @access private
  7576. */
  7577. function name()
  7578. {
  7579. $len = strcspn($this->data, "\x0A:", $this->position);
  7580. if (isset($this->data[$this->position + $len]))
  7581. {
  7582. if ($this->data[$this->position + $len] === "\x0A")
  7583. {
  7584. $this->position += $len;
  7585. $this->state = 'new_line';
  7586. }
  7587. else
  7588. {
  7589. $this->name = substr($this->data, $this->position, $len);
  7590. $this->position += $len + 1;
  7591. $this->state = 'value';
  7592. }
  7593. }
  7594. else
  7595. {
  7596. $this->state = false;
  7597. }
  7598. }
  7599. /**
  7600. * Parse LWS, replacing consecutive LWS characters with a single space
  7601. *
  7602. * @access private
  7603. */
  7604. function linear_whitespace()
  7605. {
  7606. do
  7607. {
  7608. if (substr($this->data, $this->position, 2) === "\x0D\x0A")
  7609. {
  7610. $this->position += 2;
  7611. }
  7612. elseif ($this->data[$this->position] === "\x0A")
  7613. {
  7614. $this->position++;
  7615. }
  7616. $this->position += strspn($this->data, "\x09\x20", $this->position);
  7617. } while ($this->has_data() && $this->is_linear_whitespace());
  7618. $this->value .= "\x20";
  7619. }
  7620. /**
  7621. * See what state to move to while within non-quoted header values
  7622. *
  7623. * @access private
  7624. */
  7625. function value()
  7626. {
  7627. if ($this->is_linear_whitespace())
  7628. {
  7629. $this->linear_whitespace();
  7630. }
  7631. else
  7632. {
  7633. switch ($this->data[$this->position])
  7634. {
  7635. case '"':
  7636. $this->position++;
  7637. $this->state = 'quote';
  7638. break;
  7639. case "\x0A":
  7640. $this->position++;
  7641. $this->state = 'new_line';
  7642. break;
  7643. default:
  7644. $this->state = 'value_char';
  7645. break;
  7646. }
  7647. }
  7648. }
  7649. /**
  7650. * Parse a header value while outside quotes
  7651. *
  7652. * @access private
  7653. */
  7654. function value_char()
  7655. {
  7656. $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
  7657. $this->value .= substr($this->data, $this->position, $len);
  7658. $this->position += $len;
  7659. $this->state = 'value';
  7660. }
  7661. /**
  7662. * See what state to move to while within quoted header values
  7663. *
  7664. * @access private
  7665. */
  7666. function quote()
  7667. {
  7668. if ($this->is_linear_whitespace())
  7669. {
  7670. $this->linear_whitespace();
  7671. }
  7672. else
  7673. {
  7674. switch ($this->data[$this->position])
  7675. {
  7676. case '"':
  7677. $this->position++;
  7678. $this->state = 'value';
  7679. break;
  7680. case "\x0A":
  7681. $this->position++;
  7682. $this->state = 'new_line';
  7683. break;
  7684. case '\\':
  7685. $this->position++;
  7686. $this->state = 'quote_escaped';
  7687. break;
  7688. default:
  7689. $this->state = 'quote_char';
  7690. break;
  7691. }
  7692. }
  7693. }
  7694. /**
  7695. * Parse a header value while within quotes
  7696. *
  7697. * @access private
  7698. */
  7699. function quote_char()
  7700. {
  7701. $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
  7702. $this->value .= substr($this->data, $this->position, $len);
  7703. $this->position += $len;
  7704. $this->state = 'value';
  7705. }
  7706. /**
  7707. * Parse an escaped character within quotes
  7708. *
  7709. * @access private
  7710. */
  7711. function quote_escaped()
  7712. {
  7713. $this->value .= $this->data[$this->position];
  7714. $this->position++;
  7715. $this->state = 'quote';
  7716. }
  7717. /**
  7718. * Parse the body
  7719. *
  7720. * @access private
  7721. */
  7722. function body()
  7723. {
  7724. $this->body = substr($this->data, $this->position);
  7725. $this->state = 'emit';
  7726. }
  7727. }
  7728. /**
  7729. * gzdecode
  7730. *
  7731. * @package SimplePie
  7732. */
  7733. class SimplePie_gzdecode
  7734. {
  7735. /**
  7736. * Compressed data
  7737. *
  7738. * @access private
  7739. * @see gzdecode::$data
  7740. */
  7741. var $compressed_data;
  7742. /**
  7743. * Size of compressed data
  7744. *
  7745. * @access private
  7746. */
  7747. var $compressed_size;
  7748. /**
  7749. * Minimum size of a valid gzip string
  7750. *
  7751. * @access private
  7752. */
  7753. var $min_compressed_size = 18;
  7754. /**
  7755. * Current position of pointer
  7756. *
  7757. * @access private
  7758. */
  7759. var $position = 0;
  7760. /**
  7761. * Flags (FLG)
  7762. *
  7763. * @access private
  7764. */
  7765. var $flags;
  7766. /**
  7767. * Uncompressed data
  7768. *
  7769. * @access public
  7770. * @see gzdecode::$compressed_data
  7771. */
  7772. var $data;
  7773. /**
  7774. * Modified time
  7775. *
  7776. * @access public
  7777. */
  7778. var $MTIME;
  7779. /**
  7780. * Extra Flags
  7781. *
  7782. * @access public
  7783. */
  7784. var $XFL;
  7785. /**
  7786. * Operating System
  7787. *
  7788. * @access public
  7789. */
  7790. var $OS;
  7791. /**
  7792. * Subfield ID 1
  7793. *
  7794. * @access public
  7795. * @see gzdecode::$extra_field
  7796. * @see gzdecode::$SI2
  7797. */
  7798. var $SI1;
  7799. /**
  7800. * Subfield ID 2
  7801. *
  7802. * @access public
  7803. * @see gzdecode::$extra_field
  7804. * @see gzdecode::$SI1
  7805. */
  7806. var $SI2;
  7807. /**
  7808. * Extra field content
  7809. *
  7810. * @access public
  7811. * @see gzdecode::$SI1
  7812. * @see gzdecode::$SI2
  7813. */
  7814. var $extra_field;
  7815. /**
  7816. * Original filename
  7817. *
  7818. * @access public
  7819. */
  7820. var $filename;
  7821. /**
  7822. * Human readable comment
  7823. *
  7824. * @access public
  7825. */
  7826. var $comment;
  7827. /**
  7828. * Don't allow anything to be set
  7829. *
  7830. * @access public
  7831. */
  7832. function __set($name, $value)
  7833. {
  7834. trigger_error("Cannot write property $name", E_USER_ERROR);
  7835. }
  7836. /**
  7837. * Set the compressed string and related properties
  7838. *
  7839. * @access public
  7840. */
  7841. function SimplePie_gzdecode($data)
  7842. {
  7843. $this->compressed_data = $data;
  7844. $this->compressed_size = strlen($data);
  7845. }
  7846. /**
  7847. * Decode the GZIP stream
  7848. *
  7849. * @access public
  7850. */
  7851. function parse()
  7852. {
  7853. if ($this->compressed_size >= $this->min_compressed_size)
  7854. {
  7855. // Check ID1, ID2, and CM
  7856. if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
  7857. {
  7858. return false;
  7859. }
  7860. // Get the FLG (FLaGs)
  7861. $this->flags = ord($this->compressed_data[3]);
  7862. // FLG bits above (1 << 4) are reserved
  7863. if ($this->flags > 0x1F)
  7864. {
  7865. return false;
  7866. }
  7867. // Advance the pointer after the above
  7868. $this->position += 4;
  7869. // MTIME
  7870. $mtime = substr($this->compressed_data, $this->position, 4);
  7871. // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
  7872. if (current(unpack('S', "\x00\x01")) === 1)
  7873. {
  7874. $mtime = strrev($mtime);
  7875. }
  7876. $this->MTIME = current(unpack('l', $mtime));
  7877. $this->position += 4;
  7878. // Get the XFL (eXtra FLags)
  7879. $this->XFL = ord($this->compressed_data[$this->position++]);
  7880. // Get the OS (Operating System)
  7881. $this->OS = ord($this->compressed_data[$this->position++]);
  7882. // Parse the FEXTRA
  7883. if ($this->flags & 4)
  7884. {
  7885. // Read subfield IDs
  7886. $this->SI1 = $this->compressed_data[$this->position++];
  7887. $this->SI2 = $this->compressed_data[$this->position++];
  7888. // SI2 set to zero is reserved for future use
  7889. if ($this->SI2 === "\x00")
  7890. {
  7891. return false;
  7892. }
  7893. // Get the length of the extra field
  7894. $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
  7895. $this->position += 2;
  7896. // Check the length of the string is still valid
  7897. $this->min_compressed_size += $len + 4;
  7898. if ($this->compressed_size >= $this->min_compressed_size)
  7899. {
  7900. // Set the extra field to the given data
  7901. $this->extra_field = substr($this->compressed_data, $this->position, $len);
  7902. $this->position += $len;
  7903. }
  7904. else
  7905. {
  7906. return false;
  7907. }
  7908. }
  7909. // Parse the FNAME
  7910. if ($this->flags & 8)
  7911. {
  7912. // Get the length of the filename
  7913. $len = strcspn($this->compressed_data, "\x00", $this->position);
  7914. // Check the length of the string is still valid
  7915. $this->min_compressed_size += $len + 1;
  7916. if ($this->compressed_size >= $this->min_compressed_size)
  7917. {
  7918. // Set the original filename to the given string
  7919. $this->filename = substr($this->compressed_data, $this->position, $len);
  7920. $this->position += $len + 1;
  7921. }
  7922. else
  7923. {
  7924. return false;
  7925. }
  7926. }
  7927. // Parse the FCOMMENT
  7928. if ($this->flags & 16)
  7929. {
  7930. // Get the length of the comment
  7931. $len = strcspn($this->compressed_data, "\x00", $this->position);
  7932. // Check the length of the string is still valid
  7933. $this->min_compressed_size += $len + 1;
  7934. if ($this->compressed_size >= $this->min_compressed_size)
  7935. {
  7936. // Set the original comment to the given string
  7937. $this->comment = substr($this->compressed_data, $this->position, $len);
  7938. $this->position += $len + 1;
  7939. }
  7940. else
  7941. {
  7942. return false;
  7943. }
  7944. }
  7945. // Parse the FHCRC
  7946. if ($this->flags & 2)
  7947. {
  7948. // Check the length of the string is still valid
  7949. $this->min_compressed_size += $len + 2;
  7950. if ($this->compressed_size >= $this->min_compressed_size)
  7951. {
  7952. // Read the CRC
  7953. $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
  7954. // Check the CRC matches
  7955. if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
  7956. {
  7957. $this->position += 2;
  7958. }
  7959. else
  7960. {
  7961. return false;
  7962. }
  7963. }
  7964. else
  7965. {
  7966. return false;
  7967. }
  7968. }
  7969. // Decompress the actual data
  7970. if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
  7971. {
  7972. return false;
  7973. }
  7974. else
  7975. {
  7976. $this->position = $this->compressed_size - 8;
  7977. }
  7978. // Check CRC of data
  7979. $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
  7980. $this->position += 4;
  7981. /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
  7982. {
  7983. return false;
  7984. }*/
  7985. // Check ISIZE of data
  7986. $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
  7987. $this->position += 4;
  7988. if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
  7989. {
  7990. return false;
  7991. }
  7992. // Wow, against all odds, we've actually got a valid gzip string
  7993. return true;
  7994. }
  7995. else
  7996. {
  7997. return false;
  7998. }
  7999. }
  8000. }
  8001. class SimplePie_Cache
  8002. {
  8003. /**
  8004. * Don't call the constructor. Please.
  8005. *
  8006. * @access private
  8007. */
  8008. function SimplePie_Cache()
  8009. {
  8010. trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
  8011. }
  8012. /**
  8013. * Create a new SimplePie_Cache object
  8014. *
  8015. * @static
  8016. * @access public
  8017. */
  8018. function create($location, $filename, $extension)
  8019. {
  8020. $location_iri =& new SimplePie_IRI($location);
  8021. switch ($location_iri->get_scheme())
  8022. {
  8023. case 'mysql':
  8024. if (extension_loaded('mysql'))
  8025. {
  8026. return new SimplePie_Cache_MySQL($location_iri, $filename, $extension);
  8027. }
  8028. break;
  8029. default:
  8030. return new SimplePie_Cache_File($location, $filename, $extension);
  8031. }
  8032. }
  8033. }
  8034. class SimplePie_Cache_File
  8035. {
  8036. var $location;
  8037. var $filename;
  8038. var $extension;
  8039. var $name;
  8040. function SimplePie_Cache_File($location, $filename, $extension)
  8041. {
  8042. $this->location = $location;
  8043. $this->filename = $filename;
  8044. $this->extension = $extension;
  8045. $this->name = "$this->location/$this->filename.$this->extension";
  8046. }
  8047. function save($data)
  8048. {
  8049. if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
  8050. {
  8051. if (is_a($data, 'SimplePie'))
  8052. {
  8053. $data = $data->data;
  8054. }
  8055. $data = serialize($data);
  8056. if (function_exists('file_put_contents'))
  8057. {
  8058. return (bool) file_put_contents($this->name, $data);
  8059. }
  8060. else
  8061. {
  8062. $fp = fopen($this->name, 'wb');
  8063. if ($fp)
  8064. {
  8065. fwrite($fp, $data);
  8066. fclose($fp);
  8067. return true;
  8068. }
  8069. }
  8070. }
  8071. return false;
  8072. }
  8073. function load()
  8074. {
  8075. if (file_exists($this->name) && is_readable($this->name))
  8076. {
  8077. return unserialize(file_get_contents($this->name));
  8078. }
  8079. return false;
  8080. }
  8081. function mtime()
  8082. {
  8083. if (file_exists($this->name))
  8084. {
  8085. return filemtime($this->name);
  8086. }
  8087. return false;
  8088. }
  8089. function touch()
  8090. {
  8091. if (file_exists($this->name))
  8092. {
  8093. return touch($this->name);
  8094. }
  8095. return false;
  8096. }
  8097. function unlink()
  8098. {
  8099. if (file_exists($this->name))
  8100. {
  8101. return unlink($this->name);
  8102. }
  8103. return false;
  8104. }
  8105. }
  8106. class SimplePie_Cache_DB
  8107. {
  8108. function prepare_simplepie_object_for_cache($data)
  8109. {
  8110. $items = $data->get_items();
  8111. $items_by_id = array();
  8112. if (!empty($items))
  8113. {
  8114. foreach ($items as $item)
  8115. {
  8116. $items_by_id[$item->get_id()] = $item;
  8117. }
  8118. if (count($items_by_id) !== count($items))
  8119. {
  8120. $items_by_id = array();
  8121. foreach ($items as $item)
  8122. {
  8123. $items_by_id[$item->get_id(true)] = $item;
  8124. }
  8125. }
  8126. if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
  8127. {
  8128. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
  8129. }
  8130. elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
  8131. {
  8132. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
  8133. }
  8134. elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
  8135. {
  8136. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
  8137. }
  8138. elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
  8139. {
  8140. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
  8141. }
  8142. else
  8143. {
  8144. $channel = null;
  8145. }
  8146. if ($channel !== null)
  8147. {
  8148. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
  8149. {
  8150. unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
  8151. }
  8152. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
  8153. {
  8154. unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
  8155. }
  8156. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
  8157. {
  8158. unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
  8159. }
  8160. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
  8161. {
  8162. unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
  8163. }
  8164. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
  8165. {
  8166. unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
  8167. }
  8168. }
  8169. if (isset($data->data['items']))
  8170. {
  8171. unset($data->data['items']);
  8172. }
  8173. if (isset($data->data['ordered_items']))
  8174. {
  8175. unset($data->data['ordered_items']);
  8176. }
  8177. }
  8178. return array(serialize($data->data), $items_by_id);
  8179. }
  8180. }
  8181. class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
  8182. {
  8183. var $mysql;
  8184. var $options;
  8185. var $id;
  8186. function SimplePie_Cache_MySQL($mysql_location, $name, $extension)
  8187. {
  8188. $host = $mysql_location->get_host();
  8189. if (SimplePie_Misc::stripos($host, 'unix(') === 0 && substr($host, -1) === ')')
  8190. {
  8191. $server = ':' . substr($host, 5, -1);
  8192. }
  8193. else
  8194. {
  8195. $server = $host;
  8196. if ($mysql_location->get_port() !== null)
  8197. {
  8198. $server .= ':' . $mysql_location->get_port();
  8199. }
  8200. }
  8201. if (strpos($mysql_location->get_userinfo(), ':') !== false)
  8202. {
  8203. list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2);
  8204. }
  8205. else
  8206. {
  8207. $username = $mysql_location->get_userinfo();
  8208. $password = null;
  8209. }
  8210. if ($this->mysql = mysql_connect($server, $username, $password))
  8211. {
  8212. $this->id = $name . $extension;
  8213. $this->options = SimplePie_Misc::parse_str($mysql_location->get_query());
  8214. if (!isset($this->options['prefix'][0]))
  8215. {
  8216. $this->options['prefix'][0] = '';
  8217. }
  8218. if (mysql_select_db(ltrim($mysql_location->get_path(), '/'))
  8219. && mysql_query('SET NAMES utf8')
  8220. && ($query = mysql_unbuffered_query('SHOW TABLES')))
  8221. {
  8222. $db = array();
  8223. while ($row = mysql_fetch_row($query))
  8224. {
  8225. $db[] = $row[0];
  8226. }
  8227. if (!in_array($this->options['prefix'][0] . 'cache_data', $db))
  8228. {
  8229. if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))'))
  8230. {
  8231. $this->mysql = null;
  8232. }
  8233. }
  8234. if (!in_array($this->options['prefix'][0] . 'items', $db))
  8235. {
  8236. if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))'))
  8237. {
  8238. $this->mysql = null;
  8239. }
  8240. }
  8241. }
  8242. else
  8243. {
  8244. $this->mysql = null;
  8245. }
  8246. }
  8247. }
  8248. function save($data)
  8249. {
  8250. if ($this->mysql)
  8251. {
  8252. $feed_id = "'" . mysql_real_escape_string($this->id) . "'";
  8253. if (is_a($data, 'SimplePie'))
  8254. {
  8255. if (SIMPLEPIE_PHP5)
  8256. {
  8257. // This keyword needs to defy coding standards for PHP4 compatibility
  8258. $data = clone($data);
  8259. }
  8260. $prepared = $this->prepare_simplepie_object_for_cache($data);
  8261. if ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
  8262. {
  8263. if (mysql_num_rows($query))
  8264. {
  8265. $items = count($prepared[1]);
  8266. if ($items)
  8267. {
  8268. $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
  8269. }
  8270. else
  8271. {
  8272. $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
  8273. }
  8274. if (!mysql_query($sql, $this->mysql))
  8275. {
  8276. return false;
  8277. }
  8278. }
  8279. elseif (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(' . $feed_id . ', ' . count($prepared[1]) . ', \'' . mysql_real_escape_string($prepared[0]) . '\', ' . time() . ')', $this->mysql))
  8280. {
  8281. return false;
  8282. }
  8283. $ids = array_keys($prepared[1]);
  8284. if (!empty($ids))
  8285. {
  8286. foreach ($ids as $id)
  8287. {
  8288. $database_ids[] = mysql_real_escape_string($id);
  8289. }
  8290. if ($query = mysql_unbuffered_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'items` WHERE `id` = \'' . implode('\' OR `id` = \'', $database_ids) . '\' AND `feed_id` = ' . $feed_id, $this->mysql))
  8291. {
  8292. $existing_ids = array();
  8293. while ($row = mysql_fetch_row($query))
  8294. {
  8295. $existing_ids[] = $row[0];
  8296. }
  8297. $new_ids = array_diff($ids, $existing_ids);
  8298. foreach ($new_ids as $new_id)
  8299. {
  8300. if (!($date = $prepared[1][$new_id]->get_date('U')))
  8301. {
  8302. $date = time();
  8303. }
  8304. if (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(' . $feed_id . ', \'' . mysql_real_escape_string($new_id) . '\', \'' . mysql_real_escape_string(serialize($prepared[1][$new_id]->data)) . '\', ' . $date . ')', $this->mysql))
  8305. {
  8306. return false;
  8307. }
  8308. }
  8309. return true;
  8310. }
  8311. }
  8312. else
  8313. {
  8314. return true;
  8315. }
  8316. }
  8317. }
  8318. elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
  8319. {
  8320. if (mysql_num_rows($query))
  8321. {
  8322. if (mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = 0, `data` = \'' . mysql_real_escape_string(serialize($data)) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id, $this->mysql))
  8323. {
  8324. return true;
  8325. }
  8326. }
  8327. elseif (mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(\'' . mysql_real_escape_string($this->id) . '\', 0, \'' . mysql_real_escape_string(serialize($data)) . '\', ' . time() . ')', $this->mysql))
  8328. {
  8329. return true;
  8330. }
  8331. }
  8332. }
  8333. return false;
  8334. }
  8335. function load()
  8336. {
  8337. if ($this->mysql && ($query = mysql_query('SELECT `items`, `data` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
  8338. {
  8339. $data = unserialize($row[1]);
  8340. if (isset($this->options['items'][0]))
  8341. {
  8342. $items = (int) $this->options['items'][0];
  8343. }
  8344. else
  8345. {
  8346. $items = (int) $row[0];
  8347. }
  8348. if ($items !== 0)
  8349. {
  8350. if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
  8351. {
  8352. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
  8353. }
  8354. elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
  8355. {
  8356. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
  8357. }
  8358. elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
  8359. {
  8360. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
  8361. }
  8362. elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
  8363. {
  8364. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
  8365. }
  8366. else
  8367. {
  8368. $feed = null;
  8369. }
  8370. if ($feed !== null)
  8371. {
  8372. $sql = 'SELECT `data` FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . '\' ORDER BY `posted` DESC';
  8373. if ($items > 0)
  8374. {
  8375. $sql .= ' LIMIT ' . $items;
  8376. }
  8377. if ($query = mysql_unbuffered_query($sql, $this->mysql))
  8378. {
  8379. while ($row = mysql_fetch_row($query))
  8380. {
  8381. $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row[0]);
  8382. }
  8383. }
  8384. else
  8385. {
  8386. return false;
  8387. }
  8388. }
  8389. }
  8390. return $data;
  8391. }
  8392. return false;
  8393. }
  8394. function mtime()
  8395. {
  8396. if ($this->mysql && ($query = mysql_query('SELECT `mtime` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
  8397. {
  8398. return $row[0];
  8399. }
  8400. else
  8401. {
  8402. return false;
  8403. }
  8404. }
  8405. function touch()
  8406. {
  8407. if ($this->mysql && ($query = mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `mtime` = ' . time() . ' WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && mysql_affected_rows($this->mysql))
  8408. {
  8409. return true;
  8410. }
  8411. else
  8412. {
  8413. return false;
  8414. }
  8415. }
  8416. function unlink()
  8417. {
  8418. if ($this->mysql && ($query = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($query2 = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)))
  8419. {
  8420. return true;
  8421. }
  8422. else
  8423. {
  8424. return false;
  8425. }
  8426. }
  8427. }
  8428. class SimplePie_Misc
  8429. {
  8430. function time_hms($seconds)
  8431. {
  8432. $time = '';
  8433. $hours = floor($seconds / 3600);
  8434. $remainder = $seconds % 3600;
  8435. if ($hours > 0)
  8436. {
  8437. $time .= $hours.':';
  8438. }
  8439. $minutes = floor($remainder / 60);
  8440. $seconds = $remainder % 60;
  8441. if ($minutes < 10 && $hours > 0)
  8442. {
  8443. $minutes = '0' . $minutes;
  8444. }
  8445. if ($seconds < 10)
  8446. {
  8447. $seconds = '0' . $seconds;
  8448. }
  8449. $time .= $minutes.':';
  8450. $time .= $seconds;
  8451. return $time;
  8452. }
  8453. function absolutize_url($relative, $base)
  8454. {
  8455. $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);
  8456. return $iri->get_iri();
  8457. }
  8458. function remove_dot_segments($input)
  8459. {
  8460. $output = '';
  8461. while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
  8462. {
  8463. // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
  8464. if (strpos($input, '../') === 0)
  8465. {
  8466. $input = substr($input, 3);
  8467. }
  8468. elseif (strpos($input, './') === 0)
  8469. {
  8470. $input = substr($input, 2);
  8471. }
  8472. // 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,
  8473. elseif (strpos($input, '/./') === 0)
  8474. {
  8475. $input = substr_replace($input, '/', 0, 3);
  8476. }
  8477. elseif ($input === '/.')
  8478. {
  8479. $input = '/';
  8480. }
  8481. // 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,
  8482. elseif (strpos($input, '/../') === 0)
  8483. {
  8484. $input = substr_replace($input, '/', 0, 4);
  8485. $output = substr_replace($output, '', strrpos($output, '/'));
  8486. }
  8487. elseif ($input === '/..')
  8488. {
  8489. $input = '/';
  8490. $output = substr_replace($output, '', strrpos($output, '/'));
  8491. }
  8492. // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
  8493. elseif ($input === '.' || $input === '..')
  8494. {
  8495. $input = '';
  8496. }
  8497. // 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
  8498. elseif (($pos = strpos($input, '/', 1)) !== false)
  8499. {
  8500. $output .= substr($input, 0, $pos);
  8501. $input = substr_replace($input, '', 0, $pos);
  8502. }
  8503. else
  8504. {
  8505. $output .= $input;
  8506. $input = '';
  8507. }
  8508. }
  8509. return $output . $input;
  8510. }
  8511. function get_element($realname, $string)
  8512. {
  8513. $return = array();
  8514. $name = preg_quote($realname, '/');
  8515. if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
  8516. {
  8517. for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
  8518. {
  8519. $return[$i]['tag'] = $realname;
  8520. $return[$i]['full'] = $matches[$i][0][0];
  8521. $return[$i]['offset'] = $matches[$i][0][1];
  8522. if (strlen($matches[$i][3][0]) <= 2)
  8523. {
  8524. $return[$i]['self_closing'] = true;
  8525. }
  8526. else
  8527. {
  8528. $return[$i]['self_closing'] = false;
  8529. $return[$i]['content'] = $matches[$i][4][0];
  8530. }
  8531. $return[$i]['attribs'] = array();
  8532. 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))
  8533. {
  8534. for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
  8535. {
  8536. if (count($attribs[$j]) === 2)
  8537. {
  8538. $attribs[$j][2] = $attribs[$j][1];
  8539. }
  8540. $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
  8541. }
  8542. }
  8543. }
  8544. }
  8545. return $return;
  8546. }
  8547. function element_implode($element)
  8548. {
  8549. $full = "<$element[tag]";
  8550. foreach ($element['attribs'] as $key => $value)
  8551. {
  8552. $key = strtolower($key);
  8553. $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
  8554. }
  8555. if ($element['self_closing'])
  8556. {
  8557. $full .= ' />';
  8558. }
  8559. else
  8560. {
  8561. $full .= ">$element[content]</$element[tag]>";
  8562. }
  8563. return $full;
  8564. }
  8565. function error($message, $level, $file, $line)
  8566. {
  8567. if ((ini_get('error_reporting') & $level) > 0)
  8568. {
  8569. switch ($level)
  8570. {
  8571. case E_USER_ERROR:
  8572. $note = 'PHP Error';
  8573. break;
  8574. case E_USER_WARNING:
  8575. $note = 'PHP Warning';
  8576. break;
  8577. case E_USER_NOTICE:
  8578. $note = 'PHP Notice';
  8579. break;
  8580. default:
  8581. $note = 'Unknown Error';
  8582. break;
  8583. }
  8584. $log_error = true;
  8585. if (!function_exists('error_log'))
  8586. {
  8587. $log_error = false;
  8588. }
  8589. $log_file = @ini_get('error_log');
  8590. if (!empty($log_file) && ('syslog' != $log_file) && !@is_writable($log_file))
  8591. {
  8592. $log_error = false;
  8593. }
  8594. if ($log_error)
  8595. {
  8596. @error_log("$note: $message in $file on line $line", 0);
  8597. }
  8598. }
  8599. return $message;
  8600. }
  8601. /**
  8602. * If a file has been cached, retrieve and display it.
  8603. *
  8604. * This is most useful for caching images (get_favicon(), etc.),
  8605. * however it works for all cached files. This WILL NOT display ANY
  8606. * file/image/page/whatever, but rather only display what has already
  8607. * been cached by SimplePie.
  8608. *
  8609. * @access public
  8610. * @see SimplePie::get_favicon()
  8611. * @param str $identifier_url URL that is used to identify the content.
  8612. * This may or may not be the actual URL of the live content.
  8613. * @param str $cache_location Location of SimplePie's cache. Defaults
  8614. * to './cache'.
  8615. * @param str $cache_extension The file extension that the file was
  8616. * cached with. Defaults to 'spc'.
  8617. * @param str $cache_class Name of the cache-handling class being used
  8618. * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
  8619. * as-is unless you've overloaded the class.
  8620. * @param str $cache_name_function Obsolete. Exists for backwards
  8621. * compatibility reasons only.
  8622. */
  8623. function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
  8624. {
  8625. $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
  8626. if ($file = $cache->load())
  8627. {
  8628. if (isset($file['headers']['content-type']))
  8629. {
  8630. header('Content-type:' . $file['headers']['content-type']);
  8631. }
  8632. else
  8633. {
  8634. header('Content-type: application/octet-stream');
  8635. }
  8636. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  8637. echo $file['body'];
  8638. exit;
  8639. }
  8640. die('Cached file for ' . $identifier_url . ' cannot be found.');
  8641. }
  8642. function fix_protocol($url, $http = 1)
  8643. {
  8644. $url = SimplePie_Misc::normalize_url($url);
  8645. $parsed = SimplePie_Misc::parse_url($url);
  8646. if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
  8647. {
  8648. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
  8649. }
  8650. if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
  8651. {
  8652. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
  8653. }
  8654. if ($http === 2 && $parsed['scheme'] !== '')
  8655. {
  8656. return "feed:$url";
  8657. }
  8658. elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
  8659. {
  8660. return substr_replace($url, 'podcast', 0, 4);
  8661. }
  8662. elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
  8663. {
  8664. return substr_replace($url, 'itpc', 0, 4);
  8665. }
  8666. else
  8667. {
  8668. return $url;
  8669. }
  8670. }
  8671. function parse_url($url)
  8672. {
  8673. $iri =& new SimplePie_IRI($url);
  8674. return array(
  8675. 'scheme' => (string) $iri->get_scheme(),
  8676. 'authority' => (string) $iri->get_authority(),
  8677. 'path' => (string) $iri->get_path(),
  8678. 'query' => (string) $iri->get_query(),
  8679. 'fragment' => (string) $iri->get_fragment()
  8680. );
  8681. }
  8682. function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
  8683. {
  8684. $iri =& new SimplePie_IRI('');
  8685. $iri->set_scheme($scheme);
  8686. $iri->set_authority($authority);
  8687. $iri->set_path($path);
  8688. $iri->set_query($query);
  8689. $iri->set_fragment($fragment);
  8690. return $iri->get_iri();
  8691. }
  8692. function normalize_url($url)
  8693. {
  8694. $iri =& new SimplePie_IRI($url);
  8695. return $iri->get_iri();
  8696. }
  8697. function percent_encoding_normalization($match)
  8698. {
  8699. $integer = hexdec($match[1]);
  8700. if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
  8701. {
  8702. return chr($integer);
  8703. }
  8704. else
  8705. {
  8706. return strtoupper($match[0]);
  8707. }
  8708. }
  8709. /**
  8710. * Remove bad UTF-8 bytes
  8711. *
  8712. * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
  8713. * FAQ: Multilingual Forms (modified to include full ASCII range)
  8714. *
  8715. * @author Geoffrey Sneddon
  8716. * @see http://www.w3.org/International/questions/qa-forms-utf-8
  8717. * @param string $str String to remove bad UTF-8 bytes from
  8718. * @return string UTF-8 string
  8719. */
  8720. function utf8_bad_replace($str)
  8721. {
  8722. if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
  8723. {
  8724. return $return;
  8725. }
  8726. elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
  8727. {
  8728. return $return;
  8729. }
  8730. 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))
  8731. {
  8732. return implode("\xEF\xBF\xBD", $matches[0]);
  8733. }
  8734. elseif ($str !== '')
  8735. {
  8736. return "\xEF\xBF\xBD";
  8737. }
  8738. else
  8739. {
  8740. return '';
  8741. }
  8742. }
  8743. /**
  8744. * Converts a Windows-1252 encoded string to a UTF-8 encoded string
  8745. *
  8746. * @static
  8747. * @access public
  8748. * @param string $string Windows-1252 encoded string
  8749. * @return string UTF-8 encoded string
  8750. */
  8751. function windows_1252_to_utf8($string)
  8752. {
  8753. 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");
  8754. return strtr($string, $convert_table);
  8755. }
  8756. function change_encoding($data, $input, $output)
  8757. {
  8758. $input = SimplePie_Misc::encoding($input);
  8759. $output = SimplePie_Misc::encoding($output);
  8760. // We fail to fail on non US-ASCII bytes
  8761. if ($input === 'US-ASCII')
  8762. {
  8763. static $non_ascii_octects = '';
  8764. if (!$non_ascii_octects)
  8765. {
  8766. for ($i = 0x80; $i <= 0xFF; $i++)
  8767. {
  8768. $non_ascii_octects .= chr($i);
  8769. }
  8770. }
  8771. $data = substr($data, 0, strcspn($data, $non_ascii_octects));
  8772. }
  8773. // This is first, as behaviour of this is completely predictable
  8774. if ($input === 'windows-1252' && $output === 'UTF-8')
  8775. {
  8776. return SimplePie_Misc::windows_1252_to_utf8($data);
  8777. }
  8778. // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
  8779. elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && in_array($input, mb_list_encodings()) && ($return = @mb_convert_encoding($data, $output, $input)))
  8780. {
  8781. return $return;
  8782. }
  8783. // This is last, as behaviour of this varies with OS userland and PHP version
  8784. elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
  8785. {
  8786. return $return;
  8787. }
  8788. // If we can't do anything, just fail
  8789. else
  8790. {
  8791. return false;
  8792. }
  8793. }
  8794. /**
  8795. * Normalize an encoding name
  8796. *
  8797. * This is automatically generated by create.php
  8798. *
  8799. * To generate it, run `php create.php` on the command line, and copy the
  8800. * output to replace this function.
  8801. *
  8802. * @param string $charset Character set to standardise
  8803. * @return string Standardised name
  8804. */
  8805. function encoding($charset)
  8806. {
  8807. // Normalization from UTS #22
  8808. switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
  8809. {
  8810. case 'adobestandardencoding':
  8811. case 'csadobestandardencoding':
  8812. return 'Adobe-Standard-Encoding';
  8813. case 'adobesymbolencoding':
  8814. case 'cshppsmath':
  8815. return 'Adobe-Symbol-Encoding';
  8816. case 'ami1251':
  8817. case 'amiga1251':
  8818. return 'Amiga-1251';
  8819. case 'ansix31101983':
  8820. case 'csat5001983':
  8821. case 'csiso99naplps':
  8822. case 'isoir99':
  8823. case 'naplps':
  8824. return 'ANSI_X3.110-1983';
  8825. case 'arabic7':
  8826. case 'asmo449':
  8827. case 'csiso89asmo449':
  8828. case 'iso9036':
  8829. case 'isoir89':
  8830. return 'ASMO_449';
  8831. case 'big5':
  8832. case 'csbig5':
  8833. return 'Big5';
  8834. case 'big5hkscs':
  8835. return 'Big5-HKSCS';
  8836. case 'bocu1':
  8837. case 'csbocu1':
  8838. return 'BOCU-1';
  8839. case 'brf':
  8840. case 'csbrf':
  8841. return 'BRF';
  8842. case 'bs4730':
  8843. case 'csiso4unitedkingdom':
  8844. case 'gb':
  8845. case 'iso646gb':
  8846. case 'isoir4':
  8847. case 'uk':
  8848. return 'BS_4730';
  8849. case 'bsviewdata':
  8850. case 'csiso47bsviewdata':
  8851. case 'isoir47':
  8852. return 'BS_viewdata';
  8853. case 'cesu8':
  8854. case 'cscesu8':
  8855. return 'CESU-8';
  8856. case 'ca':
  8857. case 'csa71':
  8858. case 'csaz243419851':
  8859. case 'csiso121canadian1':
  8860. case 'iso646ca':
  8861. case 'isoir121':
  8862. return 'CSA_Z243.4-1985-1';
  8863. case 'csa72':
  8864. case 'csaz243419852':
  8865. case 'csiso122canadian2':
  8866. case 'iso646ca2':
  8867. case 'isoir122':
  8868. return 'CSA_Z243.4-1985-2';
  8869. case 'csaz24341985gr':
  8870. case 'csiso123csaz24341985gr':
  8871. case 'isoir123':
  8872. return 'CSA_Z243.4-1985-gr';
  8873. case 'csiso139csn369103':
  8874. case 'csn369103':
  8875. case 'isoir139':
  8876. return 'CSN_369103';
  8877. case 'csdecmcs':
  8878. case 'dec':
  8879. case 'decmcs':
  8880. return 'DEC-MCS';
  8881. case 'csiso21german':
  8882. case 'de':
  8883. case 'din66003':
  8884. case 'iso646de':
  8885. case 'isoir21':
  8886. return 'DIN_66003';
  8887. case 'csdkus':
  8888. case 'dkus':
  8889. return 'dk-us';
  8890. case 'csiso646danish':
  8891. case 'dk':
  8892. case 'ds2089':
  8893. case 'iso646dk':
  8894. return 'DS_2089';
  8895. case 'csibmebcdicatde':
  8896. case 'ebcdicatde':
  8897. return 'EBCDIC-AT-DE';
  8898. case 'csebcdicatdea':
  8899. case 'ebcdicatdea':
  8900. return 'EBCDIC-AT-DE-A';
  8901. case 'csebcdiccafr':
  8902. case 'ebcdiccafr':
  8903. return 'EBCDIC-CA-FR';
  8904. case 'csebcdicdkno':
  8905. case 'ebcdicdkno':
  8906. return 'EBCDIC-DK-NO';
  8907. case 'csebcdicdknoa':
  8908. case 'ebcdicdknoa':
  8909. return 'EBCDIC-DK-NO-A';
  8910. case 'csebcdices':
  8911. case 'ebcdices':
  8912. return 'EBCDIC-ES';
  8913. case 'csebcdicesa':
  8914. case 'ebcdicesa':
  8915. return 'EBCDIC-ES-A';
  8916. case 'csebcdicess':
  8917. case 'ebcdicess':
  8918. return 'EBCDIC-ES-S';
  8919. case 'csebcdicfise':
  8920. case 'ebcdicfise':
  8921. return 'EBCDIC-FI-SE';
  8922. case 'csebcdicfisea':
  8923. case 'ebcdicfisea':
  8924. return 'EBCDIC-FI-SE-A';
  8925. case 'csebcdicfr':
  8926. case 'ebcdicfr':
  8927. return 'EBCDIC-FR';
  8928. case 'csebcdicit':
  8929. case 'ebcdicit':
  8930. return 'EBCDIC-IT';
  8931. case 'csebcdicpt':
  8932. case 'ebcdicpt':
  8933. return 'EBCDIC-PT';
  8934. case 'csebcdicuk':
  8935. case 'ebcdicuk':
  8936. return 'EBCDIC-UK';
  8937. case 'csebcdicus':
  8938. case 'ebcdicus':
  8939. return 'EBCDIC-US';
  8940. case 'csiso111ecmacyrillic':
  8941. case 'ecmacyrillic':
  8942. case 'isoir111':
  8943. case 'koi8e':
  8944. return 'ECMA-cyrillic';
  8945. case 'csiso17spanish':
  8946. case 'es':
  8947. case 'iso646es':
  8948. case 'isoir17':
  8949. return 'ES';
  8950. case 'csiso85spanish2':
  8951. case 'es2':
  8952. case 'iso646es2':
  8953. case 'isoir85':
  8954. return 'ES2';
  8955. case 'cseucpkdfmtjapanese':
  8956. case 'eucjp':
  8957. case 'extendedunixcodepackedformatforjapanese':
  8958. return 'EUC-JP';
  8959. case 'cseucfixwidjapanese':
  8960. case 'extendedunixcodefixedwidthforjapanese':
  8961. return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
  8962. case 'gb18030':
  8963. return 'GB18030';
  8964. case 'chinese':
  8965. case 'cp936':
  8966. case 'csgb2312':
  8967. case 'csiso58gb231280':
  8968. case 'gb2312':
  8969. case 'gb231280':
  8970. case 'gbk':
  8971. case 'isoir58':
  8972. case 'ms936':
  8973. case 'windows936':
  8974. return 'GBK';
  8975. case 'cn':
  8976. case 'csiso57gb1988':
  8977. case 'gb198880':
  8978. case 'iso646cn':
  8979. case 'isoir57':
  8980. return 'GB_1988-80';
  8981. case 'csiso153gost1976874':
  8982. case 'gost1976874':
  8983. case 'isoir153':
  8984. case 'stsev35888':
  8985. return 'GOST_19768-74';
  8986. case 'csiso150':
  8987. case 'csiso150greekccitt':
  8988. case 'greekccitt':
  8989. case 'isoir150':
  8990. return 'greek-ccitt';
  8991. case 'csiso88greek7':
  8992. case 'greek7':
  8993. case 'isoir88':
  8994. return 'greek7';
  8995. case 'csiso18greek7old':
  8996. case 'greek7old':
  8997. case 'isoir18':
  8998. return 'greek7-old';
  8999. case 'cshpdesktop':
  9000. case 'hpdesktop':
  9001. return 'HP-DeskTop';
  9002. case 'cshplegal':
  9003. case 'hplegal':
  9004. return 'HP-Legal';
  9005. case 'cshpmath8':
  9006. case 'hpmath8':
  9007. return 'HP-Math8';
  9008. case 'cshppifont':
  9009. case 'hppifont':
  9010. return 'HP-Pi-font';
  9011. case 'cshproman8':
  9012. case 'hproman8':
  9013. case 'r8':
  9014. case 'roman8':
  9015. return 'hp-roman8';
  9016. case 'hzgb2312':
  9017. return 'HZ-GB-2312';
  9018. case 'csibmsymbols':
  9019. case 'ibmsymbols':
  9020. return 'IBM-Symbols';
  9021. case 'csibmthai':
  9022. case 'ibmthai':
  9023. return 'IBM-Thai';
  9024. case 'cp37':
  9025. case 'csibm37':
  9026. case 'ebcdiccpca':
  9027. case 'ebcdiccpnl':
  9028. case 'ebcdiccpus':
  9029. case 'ebcdiccpwt':
  9030. case 'ibm37':
  9031. return 'IBM037';
  9032. case 'cp38':
  9033. case 'csibm38':
  9034. case 'ebcdicint':
  9035. case 'ibm38':
  9036. return 'IBM038';
  9037. case 'cp273':
  9038. case 'csibm273':
  9039. case 'ibm273':
  9040. return 'IBM273';
  9041. case 'cp274':
  9042. case 'csibm274':
  9043. case 'ebcdicbe':
  9044. case 'ibm274':
  9045. return 'IBM274';
  9046. case 'cp275':
  9047. case 'csibm275':
  9048. case 'ebcdicbr':
  9049. case 'ibm275':
  9050. return 'IBM275';
  9051. case 'csibm277':
  9052. case 'ebcdiccpdk':
  9053. case 'ebcdiccpno':
  9054. case 'ibm277':
  9055. return 'IBM277';
  9056. case 'cp278':
  9057. case 'csibm278':
  9058. case 'ebcdiccpfi':
  9059. case 'ebcdiccpse':
  9060. case 'ibm278':
  9061. return 'IBM278';
  9062. case 'cp280':
  9063. case 'csibm280':
  9064. case 'ebcdiccpit':
  9065. case 'ibm280':
  9066. return 'IBM280';
  9067. case 'cp281':
  9068. case 'csibm281':
  9069. case 'ebcdicjpe':
  9070. case 'ibm281':
  9071. return 'IBM281';
  9072. case 'cp284':
  9073. case 'csibm284':
  9074. case 'ebcdiccpes':
  9075. case 'ibm284':
  9076. return 'IBM284';
  9077. case 'cp285':
  9078. case 'csibm285':
  9079. case 'ebcdiccpgb':
  9080. case 'ibm285':
  9081. return 'IBM285';
  9082. case 'cp290':
  9083. case 'csibm290':
  9084. case 'ebcdicjpkana':
  9085. case 'ibm290':
  9086. return 'IBM290';
  9087. case 'cp297':
  9088. case 'csibm297':
  9089. case 'ebcdiccpfr':
  9090. case 'ibm297':
  9091. return 'IBM297';
  9092. case 'cp420':
  9093. case 'csibm420':
  9094. case 'ebcdiccpar1':
  9095. case 'ibm420':
  9096. return 'IBM420';
  9097. case 'cp423':
  9098. case 'csibm423':
  9099. case 'ebcdiccpgr':
  9100. case 'ibm423':
  9101. return 'IBM423';
  9102. case 'cp424':
  9103. case 'csibm424':
  9104. case 'ebcdiccphe':
  9105. case 'ibm424':
  9106. return 'IBM424';
  9107. case '437':
  9108. case 'cp437':
  9109. case 'cspc8codepage437':
  9110. case 'ibm437':
  9111. return 'IBM437';
  9112. case 'cp500':
  9113. case 'csibm500':
  9114. case 'ebcdiccpbe':
  9115. case 'ebcdiccpch':
  9116. case 'ibm500':
  9117. return 'IBM500';
  9118. case 'cp775':
  9119. case 'cspc775baltic':
  9120. case 'ibm775':
  9121. return 'IBM775';
  9122. case '850':
  9123. case 'cp850':
  9124. case 'cspc850multilingual':
  9125. case 'ibm850':
  9126. return 'IBM850';
  9127. case '851':
  9128. case 'cp851':
  9129. case 'csibm851':
  9130. case 'ibm851':
  9131. return 'IBM851';
  9132. case '852':
  9133. case 'cp852':
  9134. case 'cspcp852':
  9135. case 'ibm852':
  9136. return 'IBM852';
  9137. case '855':
  9138. case 'cp855':
  9139. case 'csibm855':
  9140. case 'ibm855':
  9141. return 'IBM855';
  9142. case '857':
  9143. case 'cp857':
  9144. case 'csibm857':
  9145. case 'ibm857':
  9146. return 'IBM857';
  9147. case 'ccsid858':
  9148. case 'cp858':
  9149. case 'ibm858':
  9150. case 'pcmultilingual850euro':
  9151. return 'IBM00858';
  9152. case '860':
  9153. case 'cp860':
  9154. case 'csibm860':
  9155. case 'ibm860':
  9156. return 'IBM860';
  9157. case '861':
  9158. case 'cp861':
  9159. case 'cpis':
  9160. case 'csibm861':
  9161. case 'ibm861':
  9162. return 'IBM861';
  9163. case '862':
  9164. case 'cp862':
  9165. case 'cspc862latinhebrew':
  9166. case 'ibm862':
  9167. return 'IBM862';
  9168. case '863':
  9169. case 'cp863':
  9170. case 'csibm863':
  9171. case 'ibm863':
  9172. return 'IBM863';
  9173. case 'cp864':
  9174. case 'csibm864':
  9175. case 'ibm864':
  9176. return 'IBM864';
  9177. case '865':
  9178. case 'cp865':
  9179. case 'csibm865':
  9180. case 'ibm865':
  9181. return 'IBM865';
  9182. case '866':
  9183. case 'cp866':
  9184. case 'csibm866':
  9185. case 'ibm866':
  9186. return 'IBM866';
  9187. case 'cp868':
  9188. case 'cpar':
  9189. case 'csibm868':
  9190. case 'ibm868':
  9191. return 'IBM868';
  9192. case '869':
  9193. case 'cp869':
  9194. case 'cpgr':
  9195. case 'csibm869':
  9196. case 'ibm869':
  9197. return 'IBM869';
  9198. case 'cp870':
  9199. case 'csibm870':
  9200. case 'ebcdiccproece':
  9201. case 'ebcdiccpyu':
  9202. case 'ibm870':
  9203. return 'IBM870';
  9204. case 'cp871':
  9205. case 'csibm871':
  9206. case 'ebcdiccpis':
  9207. case 'ibm871':
  9208. return 'IBM871';
  9209. case 'cp880':
  9210. case 'csibm880':
  9211. case 'ebcdiccyrillic':
  9212. case 'ibm880':
  9213. return 'IBM880';
  9214. case 'cp891':
  9215. case 'csibm891':
  9216. case 'ibm891':
  9217. return 'IBM891';
  9218. case 'cp903':
  9219. case 'csibm903':
  9220. case 'ibm903':
  9221. return 'IBM903';
  9222. case '904':
  9223. case 'cp904':
  9224. case 'csibbm904':
  9225. case 'ibm904':
  9226. return 'IBM904';
  9227. case 'cp905':
  9228. case 'csibm905':
  9229. case 'ebcdiccptr':
  9230. case 'ibm905':
  9231. return 'IBM905';
  9232. case 'cp918':
  9233. case 'csibm918':
  9234. case 'ebcdiccpar2':
  9235. case 'ibm918':
  9236. return 'IBM918';
  9237. case 'ccsid924':
  9238. case 'cp924':
  9239. case 'ebcdiclatin9euro':
  9240. case 'ibm924':
  9241. return 'IBM00924';
  9242. case 'cp1026':
  9243. case 'csibm1026':
  9244. case 'ibm1026':
  9245. return 'IBM1026';
  9246. case 'ibm1047':
  9247. return 'IBM1047';
  9248. case 'ccsid1140':
  9249. case 'cp1140':
  9250. case 'ebcdicus37euro':
  9251. case 'ibm1140':
  9252. return 'IBM01140';
  9253. case 'ccsid1141':
  9254. case 'cp1141':
  9255. case 'ebcdicde273euro':
  9256. case 'ibm1141':
  9257. return 'IBM01141';
  9258. case 'ccsid1142':
  9259. case 'cp1142':
  9260. case 'ebcdicdk277euro':
  9261. case 'ebcdicno277euro':
  9262. case 'ibm1142':
  9263. return 'IBM01142';
  9264. case 'ccsid1143':
  9265. case 'cp1143':
  9266. case 'ebcdicfi278euro':
  9267. case 'ebcdicse278euro':
  9268. case 'ibm1143':
  9269. return 'IBM01143';
  9270. case 'ccsid1144':
  9271. case 'cp1144':
  9272. case 'ebcdicit280euro':
  9273. case 'ibm1144':
  9274. return 'IBM01144';
  9275. case 'ccsid1145':
  9276. case 'cp1145':
  9277. case 'ebcdices284euro':
  9278. case 'ibm1145':
  9279. return 'IBM01145';
  9280. case 'ccsid1146':
  9281. case 'cp1146':
  9282. case 'ebcdicgb285euro':
  9283. case 'ibm1146':
  9284. return 'IBM01146';
  9285. case 'ccsid1147':
  9286. case 'cp1147':
  9287. case 'ebcdicfr297euro':
  9288. case 'ibm1147':
  9289. return 'IBM01147';
  9290. case 'ccsid1148':
  9291. case 'cp1148':
  9292. case 'ebcdicinternational500euro':
  9293. case 'ibm1148':
  9294. return 'IBM01148';
  9295. case 'ccsid1149':
  9296. case 'cp1149':
  9297. case 'ebcdicis871euro':
  9298. case 'ibm1149':
  9299. return 'IBM01149';
  9300. case 'csiso143iecp271':
  9301. case 'iecp271':
  9302. case 'isoir143':
  9303. return 'IEC_P27-1';
  9304. case 'csiso49inis':
  9305. case 'inis':
  9306. case 'isoir49':
  9307. return 'INIS';
  9308. case 'csiso50inis8':
  9309. case 'inis8':
  9310. case 'isoir50':
  9311. return 'INIS-8';
  9312. case 'csiso51iniscyrillic':
  9313. case 'iniscyrillic':
  9314. case 'isoir51':
  9315. return 'INIS-cyrillic';
  9316. case 'csinvariant':
  9317. case 'invariant':
  9318. return 'INVARIANT';
  9319. case 'iso2022cn':
  9320. return 'ISO-2022-CN';
  9321. case 'iso2022cnext':
  9322. return 'ISO-2022-CN-EXT';
  9323. case 'csiso2022jp':
  9324. case 'iso2022jp':
  9325. return 'ISO-2022-JP';
  9326. case 'csiso2022jp2':
  9327. case 'iso2022jp2':
  9328. return 'ISO-2022-JP-2';
  9329. case 'csiso2022kr':
  9330. case 'iso2022kr':
  9331. return 'ISO-2022-KR';
  9332. case 'cswindows30latin1':
  9333. case 'iso88591windows30latin1':
  9334. return 'ISO-8859-1-Windows-3.0-Latin-1';
  9335. case 'cswindows31latin1':
  9336. case 'iso88591windows31latin1':
  9337. return 'ISO-8859-1-Windows-3.1-Latin-1';
  9338. case 'csisolatin2':
  9339. case 'iso88592':
  9340. case 'iso885921987':
  9341. case 'isoir101':
  9342. case 'l2':
  9343. case 'latin2':
  9344. return 'ISO-8859-2';
  9345. case 'cswindows31latin2':
  9346. case 'iso88592windowslatin2':
  9347. return 'ISO-8859-2-Windows-Latin-2';
  9348. case 'csisolatin3':
  9349. case 'iso88593':
  9350. case 'iso885931988':
  9351. case 'isoir109':
  9352. case 'l3':
  9353. case 'latin3':
  9354. return 'ISO-8859-3';
  9355. case 'csisolatin4':
  9356. case 'iso88594':
  9357. case 'iso885941988':
  9358. case 'isoir110':
  9359. case 'l4':
  9360. case 'latin4':
  9361. return 'ISO-8859-4';
  9362. case 'csisolatincyrillic':
  9363. case 'cyrillic':
  9364. case 'iso88595':
  9365. case 'iso885951988':
  9366. case 'isoir144':
  9367. return 'ISO-8859-5';
  9368. case 'arabic':
  9369. case 'asmo708':
  9370. case 'csisolatinarabic':
  9371. case 'ecma114':
  9372. case 'iso88596':
  9373. case 'iso885961987':
  9374. case 'isoir127':
  9375. return 'ISO-8859-6';
  9376. case 'csiso88596e':
  9377. case 'iso88596e':
  9378. return 'ISO-8859-6-E';
  9379. case 'csiso88596i':
  9380. case 'iso88596i':
  9381. return 'ISO-8859-6-I';
  9382. case 'csisolatingreek':
  9383. case 'ecma118':
  9384. case 'elot928':
  9385. case 'greek':
  9386. case 'greek8':
  9387. case 'iso88597':
  9388. case 'iso885971987':
  9389. case 'isoir126':
  9390. return 'ISO-8859-7';
  9391. case 'csisolatinhebrew':
  9392. case 'hebrew':
  9393. case 'iso88598':
  9394. case 'iso885981988':
  9395. case 'isoir138':
  9396. return 'ISO-8859-8';
  9397. case 'csiso88598e':
  9398. case 'iso88598e':
  9399. return 'ISO-8859-8-E';
  9400. case 'csiso88598i':
  9401. case 'iso88598i':
  9402. return 'ISO-8859-8-I';
  9403. case 'cswindows31latin5':
  9404. case 'iso88599windowslatin5':
  9405. return 'ISO-8859-9-Windows-Latin-5';
  9406. case 'csisolatin6':
  9407. case 'iso885910':
  9408. case 'iso8859101992':
  9409. case 'isoir157':
  9410. case 'l6':
  9411. case 'latin6':
  9412. return 'ISO-8859-10';
  9413. case 'iso885913':
  9414. return 'ISO-8859-13';
  9415. case 'iso885914':
  9416. case 'iso8859141998':
  9417. case 'isoceltic':
  9418. case 'isoir199':
  9419. case 'l8':
  9420. case 'latin8':
  9421. return 'ISO-8859-14';
  9422. case 'iso885915':
  9423. case 'latin9':
  9424. return 'ISO-8859-15';
  9425. case 'iso885916':
  9426. case 'iso8859162001':
  9427. case 'isoir226':
  9428. case 'l10':
  9429. case 'latin10':
  9430. return 'ISO-8859-16';
  9431. case 'iso10646j1':
  9432. return 'ISO-10646-J-1';
  9433. case 'csunicode':
  9434. case 'iso10646ucs2':
  9435. return 'ISO-10646-UCS-2';
  9436. case 'csucs4':
  9437. case 'iso10646ucs4':
  9438. return 'ISO-10646-UCS-4';
  9439. case 'csunicodeascii':
  9440. case 'iso10646ucsbasic':
  9441. return 'ISO-10646-UCS-Basic';
  9442. case 'csunicodelatin1':
  9443. case 'iso10646':
  9444. case 'iso10646unicodelatin1':
  9445. return 'ISO-10646-Unicode-Latin1';
  9446. case 'csiso10646utf1':
  9447. case 'iso10646utf1':
  9448. return 'ISO-10646-UTF-1';
  9449. case 'csiso115481':
  9450. case 'iso115481':
  9451. case 'isotr115481':
  9452. return 'ISO-11548-1';
  9453. case 'csiso90':
  9454. case 'isoir90':
  9455. return 'iso-ir-90';
  9456. case 'csunicodeibm1261':
  9457. case 'isounicodeibm1261':
  9458. return 'ISO-Unicode-IBM-1261';
  9459. case 'csunicodeibm1264':
  9460. case 'isounicodeibm1264':
  9461. return 'ISO-Unicode-IBM-1264';
  9462. case 'csunicodeibm1265':
  9463. case 'isounicodeibm1265':
  9464. return 'ISO-Unicode-IBM-1265';
  9465. case 'csunicodeibm1268':
  9466. case 'isounicodeibm1268':
  9467. return 'ISO-Unicode-IBM-1268';
  9468. case 'csunicodeibm1276':
  9469. case 'isounicodeibm1276':
  9470. return 'ISO-Unicode-IBM-1276';
  9471. case 'csiso646basic1983':
  9472. case 'iso646basic1983':
  9473. case 'ref':
  9474. return 'ISO_646.basic:1983';
  9475. case 'csiso2intlrefversion':
  9476. case 'irv':
  9477. case 'iso646irv1983':
  9478. case 'isoir2':
  9479. return 'ISO_646.irv:1983';
  9480. case 'csiso2033':
  9481. case 'e13b':
  9482. case 'iso20331983':
  9483. case 'isoir98':
  9484. return 'ISO_2033-1983';
  9485. case 'csiso5427cyrillic':
  9486. case 'iso5427':
  9487. case 'isoir37':
  9488. return 'ISO_5427';
  9489. case 'iso5427cyrillic1981':
  9490. case 'iso54271981':
  9491. case 'isoir54':
  9492. return 'ISO_5427:1981';
  9493. case 'csiso5428greek':
  9494. case 'iso54281980':
  9495. case 'isoir55':
  9496. return 'ISO_5428:1980';
  9497. case 'csiso6937add':
  9498. case 'iso6937225':
  9499. case 'isoir152':
  9500. return 'ISO_6937-2-25';
  9501. case 'csisotextcomm':
  9502. case 'iso69372add':
  9503. case 'isoir142':
  9504. return 'ISO_6937-2-add';
  9505. case 'csiso8859supp':
  9506. case 'iso8859supp':
  9507. case 'isoir154':
  9508. case 'latin125':
  9509. return 'ISO_8859-supp';
  9510. case 'csiso10367box':
  9511. case 'iso10367box':
  9512. case 'isoir155':
  9513. return 'ISO_10367-box';
  9514. case 'csiso15italian':
  9515. case 'iso646it':
  9516. case 'isoir15':
  9517. case 'it':
  9518. return 'IT';
  9519. case 'csiso13jisc6220jp':
  9520. case 'isoir13':
  9521. case 'jisc62201969':
  9522. case 'jisc62201969jp':
  9523. case 'katakana':
  9524. case 'x2017':
  9525. return 'JIS_C6220-1969-jp';
  9526. case 'csiso14jisc6220ro':
  9527. case 'iso646jp':
  9528. case 'isoir14':
  9529. case 'jisc62201969ro':
  9530. case 'jp':
  9531. return 'JIS_C6220-1969-ro';
  9532. case 'csiso42jisc62261978':
  9533. case 'isoir42':
  9534. case 'jisc62261978':
  9535. return 'JIS_C6226-1978';
  9536. case 'csiso87jisx208':
  9537. case 'isoir87':
  9538. case 'jisc62261983':
  9539. case 'jisx2081983':
  9540. case 'x208':
  9541. return 'JIS_C6226-1983';
  9542. case 'csiso91jisc62291984a':
  9543. case 'isoir91':
  9544. case 'jisc62291984a':
  9545. case 'jpocra':
  9546. return 'JIS_C6229-1984-a';
  9547. case 'csiso92jisc62991984b':
  9548. case 'iso646jpocrb':
  9549. case 'isoir92':
  9550. case 'jisc62291984b':
  9551. case 'jpocrb':
  9552. return 'JIS_C6229-1984-b';
  9553. case 'csiso93jis62291984badd':
  9554. case 'isoir93':
  9555. case 'jisc62291984badd':
  9556. case 'jpocrbadd':
  9557. return 'JIS_C6229-1984-b-add';
  9558. case 'csiso94jis62291984hand':
  9559. case 'isoir94':
  9560. case 'jisc62291984hand':
  9561. case 'jpocrhand':
  9562. return 'JIS_C6229-1984-hand';
  9563. case 'csiso95jis62291984handadd':
  9564. case 'isoir95':
  9565. case 'jisc62291984handadd':
  9566. case 'jpocrhandadd':
  9567. return 'JIS_C6229-1984-hand-add';
  9568. case 'csiso96jisc62291984kana':
  9569. case 'isoir96':
  9570. case 'jisc62291984kana':
  9571. return 'JIS_C6229-1984-kana';
  9572. case 'csjisencoding':
  9573. case 'jisencoding':
  9574. return 'JIS_Encoding';
  9575. case 'cshalfwidthkatakana':
  9576. case 'jisx201':
  9577. case 'x201':
  9578. return 'JIS_X0201';
  9579. case 'csiso159jisx2121990':
  9580. case 'isoir159':
  9581. case 'jisx2121990':
  9582. case 'x212':
  9583. return 'JIS_X0212-1990';
  9584. case 'csiso141jusib1002':
  9585. case 'iso646yu':
  9586. case 'isoir141':
  9587. case 'js':
  9588. case 'jusib1002':
  9589. case 'yu':
  9590. return 'JUS_I.B1.002';
  9591. case 'csiso147macedonian':
  9592. case 'isoir147':
  9593. case 'jusib1003mac':
  9594. case 'macedonian':
  9595. return 'JUS_I.B1.003-mac';
  9596. case 'csiso146serbian':
  9597. case 'isoir146':
  9598. case 'jusib1003serb':
  9599. case 'serbian':
  9600. return 'JUS_I.B1.003-serb';
  9601. case 'koi7switched':
  9602. return 'KOI7-switched';
  9603. case 'cskoi8r':
  9604. case 'koi8r':
  9605. return 'KOI8-R';
  9606. case 'koi8u':
  9607. return 'KOI8-U';
  9608. case 'csksc5636':
  9609. case 'iso646kr':
  9610. case 'ksc5636':
  9611. return 'KSC5636';
  9612. case 'cskz1048':
  9613. case 'kz1048':
  9614. case 'rk1048':
  9615. case 'strk10482002':
  9616. return 'KZ-1048';
  9617. case 'csiso19latingreek':
  9618. case 'isoir19':
  9619. case 'latingreek':
  9620. return 'latin-greek';
  9621. case 'csiso27latingreek1':
  9622. case 'isoir27':
  9623. case 'latingreek1':
  9624. return 'Latin-greek-1';
  9625. case 'csiso158lap':
  9626. case 'isoir158':
  9627. case 'lap':
  9628. case 'latinlap':
  9629. return 'latin-lap';
  9630. case 'csmacintosh':
  9631. case 'mac':
  9632. case 'macintosh':
  9633. return 'macintosh';
  9634. case 'csmicrosoftpublishing':
  9635. case 'microsoftpublishing':
  9636. return 'Microsoft-Publishing';
  9637. case 'csmnem':
  9638. case 'mnem':
  9639. return 'MNEM';
  9640. case 'csmnemonic':
  9641. case 'mnemonic':
  9642. return 'MNEMONIC';
  9643. case 'csiso86hungarian':
  9644. case 'hu':
  9645. case 'iso646hu':
  9646. case 'isoir86':
  9647. case 'msz77953':
  9648. return 'MSZ_7795.3';
  9649. case 'csnatsdano':
  9650. case 'isoir91':
  9651. case 'natsdano':
  9652. return 'NATS-DANO';
  9653. case 'csnatsdanoadd':
  9654. case 'isoir92':
  9655. case 'natsdanoadd':
  9656. return 'NATS-DANO-ADD';
  9657. case 'csnatssefi':
  9658. case 'isoir81':
  9659. case 'natssefi':
  9660. return 'NATS-SEFI';
  9661. case 'csnatssefiadd':
  9662. case 'isoir82':
  9663. case 'natssefiadd':
  9664. return 'NATS-SEFI-ADD';
  9665. case 'csiso151cuba':
  9666. case 'cuba':
  9667. case 'iso646cu':
  9668. case 'isoir151':
  9669. case 'ncnc1081':
  9670. return 'NC_NC00-10:81';
  9671. case 'csiso69french':
  9672. case 'fr':
  9673. case 'iso646fr':
  9674. case 'isoir69':
  9675. case 'nfz62010':
  9676. return 'NF_Z_62-010';
  9677. case 'csiso25french':
  9678. case 'iso646fr1':
  9679. case 'isoir25':
  9680. case 'nfz620101973':
  9681. return 'NF_Z_62-010_(1973)';
  9682. case 'csiso60danishnorwegian':
  9683. case 'csiso60norwegian1':
  9684. case 'iso646no':
  9685. case 'isoir60':
  9686. case 'no':
  9687. case 'ns45511':
  9688. return 'NS_4551-1';
  9689. case 'csiso61norwegian2':
  9690. case 'iso646no2':
  9691. case 'isoir61':
  9692. case 'no2':
  9693. case 'ns45512':
  9694. return 'NS_4551-2';
  9695. case 'osdebcdicdf3irv':
  9696. return 'OSD_EBCDIC_DF03_IRV';
  9697. case 'osdebcdicdf41':
  9698. return 'OSD_EBCDIC_DF04_1';
  9699. case 'osdebcdicdf415':
  9700. return 'OSD_EBCDIC_DF04_15';
  9701. case 'cspc8danishnorwegian':
  9702. case 'pc8danishnorwegian':
  9703. return 'PC8-Danish-Norwegian';
  9704. case 'cspc8turkish':
  9705. case 'pc8turkish':
  9706. return 'PC8-Turkish';
  9707. case 'csiso16portuguese':
  9708. case 'iso646pt':
  9709. case 'isoir16':
  9710. case 'pt':
  9711. return 'PT';
  9712. case 'csiso84portuguese2':
  9713. case 'iso646pt2':
  9714. case 'isoir84':
  9715. case 'pt2':
  9716. return 'PT2';
  9717. case 'cp154':
  9718. case 'csptcp154':
  9719. case 'cyrillicasian':
  9720. case 'pt154':
  9721. case 'ptcp154':
  9722. return 'PTCP154';
  9723. case 'scsu':
  9724. return 'SCSU';
  9725. case 'csiso10swedish':
  9726. case 'fi':
  9727. case 'iso646fi':
  9728. case 'iso646se':
  9729. case 'isoir10':
  9730. case 'se':
  9731. case 'sen850200b':
  9732. return 'SEN_850200_B';
  9733. case 'csiso11swedishfornames':
  9734. case 'iso646se2':
  9735. case 'isoir11':
  9736. case 'se2':
  9737. case 'sen850200c':
  9738. return 'SEN_850200_C';
  9739. case 'csiso102t617bit':
  9740. case 'isoir102':
  9741. case 't617bit':
  9742. return 'T.61-7bit';
  9743. case 'csiso103t618bit':
  9744. case 'isoir103':
  9745. case 't61':
  9746. case 't618bit':
  9747. return 'T.61-8bit';
  9748. case 'csiso128t101g2':
  9749. case 'isoir128':
  9750. case 't101g2':
  9751. return 'T.101-G2';
  9752. case 'cstscii':
  9753. case 'tscii':
  9754. return 'TSCII';
  9755. case 'csunicode11':
  9756. case 'unicode11':
  9757. return 'UNICODE-1-1';
  9758. case 'csunicode11utf7':
  9759. case 'unicode11utf7':
  9760. return 'UNICODE-1-1-UTF-7';
  9761. case 'csunknown8bit':
  9762. case 'unknown8bit':
  9763. return 'UNKNOWN-8BIT';
  9764. case 'ansix341968':
  9765. case 'ansix341986':
  9766. case 'ascii':
  9767. case 'cp367':
  9768. case 'csascii':
  9769. case 'ibm367':
  9770. case 'iso646irv1991':
  9771. case 'iso646us':
  9772. case 'isoir6':
  9773. case 'us':
  9774. case 'usascii':
  9775. return 'US-ASCII';
  9776. case 'csusdk':
  9777. case 'usdk':
  9778. return 'us-dk';
  9779. case 'utf7':
  9780. return 'UTF-7';
  9781. case 'utf8':
  9782. return 'UTF-8';
  9783. case 'utf16':
  9784. return 'UTF-16';
  9785. case 'utf16be':
  9786. return 'UTF-16BE';
  9787. case 'utf16le':
  9788. return 'UTF-16LE';
  9789. case 'utf32':
  9790. return 'UTF-32';
  9791. case 'utf32be':
  9792. return 'UTF-32BE';
  9793. case 'utf32le':
  9794. return 'UTF-32LE';
  9795. case 'csventurainternational':
  9796. case 'venturainternational':
  9797. return 'Ventura-International';
  9798. case 'csventuramath':
  9799. case 'venturamath':
  9800. return 'Ventura-Math';
  9801. case 'csventuraus':
  9802. case 'venturaus':
  9803. return 'Ventura-US';
  9804. case 'csiso70videotexsupp1':
  9805. case 'isoir70':
  9806. case 'videotexsuppl':
  9807. return 'videotex-suppl';
  9808. case 'csviqr':
  9809. case 'viqr':
  9810. return 'VIQR';
  9811. case 'csviscii':
  9812. case 'viscii':
  9813. return 'VISCII';
  9814. case 'csshiftjis':
  9815. case 'cswindows31j':
  9816. case 'mskanji':
  9817. case 'shiftjis':
  9818. case 'windows31j':
  9819. return 'Windows-31J';
  9820. case 'iso885911':
  9821. case 'tis620':
  9822. return 'windows-874';
  9823. case 'cseuckr':
  9824. case 'csksc56011987':
  9825. case 'euckr':
  9826. case 'isoir149':
  9827. case 'korean':
  9828. case 'ksc5601':
  9829. case 'ksc56011987':
  9830. case 'ksc56011989':
  9831. case 'windows949':
  9832. return 'windows-949';
  9833. case 'windows1250':
  9834. return 'windows-1250';
  9835. case 'windows1251':
  9836. return 'windows-1251';
  9837. case 'cp819':
  9838. case 'csisolatin1':
  9839. case 'ibm819':
  9840. case 'iso88591':
  9841. case 'iso885911987':
  9842. case 'isoir100':
  9843. case 'l1':
  9844. case 'latin1':
  9845. case 'windows1252':
  9846. return 'windows-1252';
  9847. case 'windows1253':
  9848. return 'windows-1253';
  9849. case 'csisolatin5':
  9850. case 'iso88599':
  9851. case 'iso885991989':
  9852. case 'isoir148':
  9853. case 'l5':
  9854. case 'latin5':
  9855. case 'windows1254':
  9856. return 'windows-1254';
  9857. case 'windows1255':
  9858. return 'windows-1255';
  9859. case 'windows1256':
  9860. return 'windows-1256';
  9861. case 'windows1257':
  9862. return 'windows-1257';
  9863. case 'windows1258':
  9864. return 'windows-1258';
  9865. default:
  9866. return $charset;
  9867. }
  9868. }
  9869. function get_curl_version()
  9870. {
  9871. if (is_array($curl = curl_version()))
  9872. {
  9873. $curl = $curl['version'];
  9874. }
  9875. elseif (substr($curl, 0, 5) === 'curl/')
  9876. {
  9877. $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
  9878. }
  9879. elseif (substr($curl, 0, 8) === 'libcurl/')
  9880. {
  9881. $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
  9882. }
  9883. else
  9884. {
  9885. $curl = 0;
  9886. }
  9887. return $curl;
  9888. }
  9889. function is_subclass_of($class1, $class2)
  9890. {
  9891. if (func_num_args() !== 2)
  9892. {
  9893. trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
  9894. }
  9895. elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
  9896. {
  9897. return is_subclass_of($class1, $class2);
  9898. }
  9899. elseif (is_string($class1) && is_string($class2))
  9900. {
  9901. if (class_exists($class1))
  9902. {
  9903. if (class_exists($class2))
  9904. {
  9905. $class2 = strtolower($class2);
  9906. while ($class1 = strtolower(get_parent_class($class1)))
  9907. {
  9908. if ($class1 === $class2)
  9909. {
  9910. return true;
  9911. }
  9912. }
  9913. }
  9914. }
  9915. else
  9916. {
  9917. trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
  9918. }
  9919. }
  9920. return false;
  9921. }
  9922. /**
  9923. * Strip HTML comments
  9924. *
  9925. * @access public
  9926. * @param string $data Data to strip comments from
  9927. * @return string Comment stripped string
  9928. */
  9929. function strip_comments($data)
  9930. {
  9931. $output = '';
  9932. while (($start = strpos($data, '<!--')) !== false)
  9933. {
  9934. $output .= substr($data, 0, $start);
  9935. if (($end = strpos($data, '-->', $start)) !== false)
  9936. {
  9937. $data = substr_replace($data, '', 0, $end + 3);
  9938. }
  9939. else
  9940. {
  9941. $data = '';
  9942. }
  9943. }
  9944. return $output . $data;
  9945. }
  9946. function parse_date($dt)
  9947. {
  9948. $parser = SimplePie_Parse_Date::get();
  9949. return $parser->parse($dt);
  9950. }
  9951. /**
  9952. * Decode HTML entities
  9953. *
  9954. * @static
  9955. * @access public
  9956. * @param string $data Input data
  9957. * @return string Output data
  9958. */
  9959. function entities_decode($data)
  9960. {
  9961. $decoder =& new SimplePie_Decode_HTML_Entities($data);
  9962. return $decoder->parse();
  9963. }
  9964. /**
  9965. * Remove RFC822 comments
  9966. *
  9967. * @access public
  9968. * @param string $data Data to strip comments from
  9969. * @return string Comment stripped string
  9970. */
  9971. function uncomment_rfc822($string)
  9972. {
  9973. $string = (string) $string;
  9974. $position = 0;
  9975. $length = strlen($string);
  9976. $depth = 0;
  9977. $output = '';
  9978. while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
  9979. {
  9980. $output .= substr($string, $position, $pos - $position);
  9981. $position = $pos + 1;
  9982. if ($string[$pos - 1] !== '\\')
  9983. {
  9984. $depth++;
  9985. while ($depth && $position < $length)
  9986. {
  9987. $position += strcspn($string, '()', $position);
  9988. if ($string[$position - 1] === '\\')
  9989. {
  9990. $position++;
  9991. continue;
  9992. }
  9993. elseif (isset($string[$position]))
  9994. {
  9995. switch ($string[$position])
  9996. {
  9997. case '(':
  9998. $depth++;
  9999. break;
  10000. case ')':
  10001. $depth--;
  10002. break;
  10003. }
  10004. $position++;
  10005. }
  10006. else
  10007. {
  10008. break;
  10009. }
  10010. }
  10011. }
  10012. else
  10013. {
  10014. $output .= '(';
  10015. }
  10016. }
  10017. $output .= substr($string, $position);
  10018. return $output;
  10019. }
  10020. function parse_mime($mime)
  10021. {
  10022. if (($pos = strpos($mime, ';')) === false)
  10023. {
  10024. return trim($mime);
  10025. }
  10026. else
  10027. {
  10028. return trim(substr($mime, 0, $pos));
  10029. }
  10030. }
  10031. function htmlspecialchars_decode($string, $quote_style)
  10032. {
  10033. if (function_exists('htmlspecialchars_decode'))
  10034. {
  10035. return htmlspecialchars_decode($string, $quote_style);
  10036. }
  10037. else
  10038. {
  10039. return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
  10040. }
  10041. }
  10042. function atom_03_construct_type($attribs)
  10043. {
  10044. if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
  10045. {
  10046. $mode = SIMPLEPIE_CONSTRUCT_BASE64;
  10047. }
  10048. else
  10049. {
  10050. $mode = SIMPLEPIE_CONSTRUCT_NONE;
  10051. }
  10052. if (isset($attribs['']['type']))
  10053. {
  10054. switch (strtolower(trim($attribs['']['type'])))
  10055. {
  10056. case 'text':
  10057. case 'text/plain':
  10058. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  10059. case 'html':
  10060. case 'text/html':
  10061. return SIMPLEPIE_CONSTRUCT_HTML | $mode;
  10062. case 'xhtml':
  10063. case 'application/xhtml+xml':
  10064. return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
  10065. default:
  10066. return SIMPLEPIE_CONSTRUCT_NONE | $mode;
  10067. }
  10068. }
  10069. else
  10070. {
  10071. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  10072. }
  10073. }
  10074. function atom_10_construct_type($attribs)
  10075. {
  10076. if (isset($attribs['']['type']))
  10077. {
  10078. switch (strtolower(trim($attribs['']['type'])))
  10079. {
  10080. case 'text':
  10081. return SIMPLEPIE_CONSTRUCT_TEXT;
  10082. case 'html':
  10083. return SIMPLEPIE_CONSTRUCT_HTML;
  10084. case 'xhtml':
  10085. return SIMPLEPIE_CONSTRUCT_XHTML;
  10086. default:
  10087. return SIMPLEPIE_CONSTRUCT_NONE;
  10088. }
  10089. }
  10090. return SIMPLEPIE_CONSTRUCT_TEXT;
  10091. }
  10092. function atom_10_content_construct_type($attribs)
  10093. {
  10094. if (isset($attribs['']['type']))
  10095. {
  10096. $type = strtolower(trim($attribs['']['type']));
  10097. switch ($type)
  10098. {
  10099. case 'text':
  10100. return SIMPLEPIE_CONSTRUCT_TEXT;
  10101. case 'html':
  10102. return SIMPLEPIE_CONSTRUCT_HTML;
  10103. case 'xhtml':
  10104. return SIMPLEPIE_CONSTRUCT_XHTML;
  10105. }
  10106. if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
  10107. {
  10108. return SIMPLEPIE_CONSTRUCT_NONE;
  10109. }
  10110. else
  10111. {
  10112. return SIMPLEPIE_CONSTRUCT_BASE64;
  10113. }
  10114. }
  10115. else
  10116. {
  10117. return SIMPLEPIE_CONSTRUCT_TEXT;
  10118. }
  10119. }
  10120. function is_isegment_nz_nc($string)
  10121. {
  10122. 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);
  10123. }
  10124. function space_seperated_tokens($string)
  10125. {
  10126. $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
  10127. $string_length = strlen($string);
  10128. $position = strspn($string, $space_characters);
  10129. $tokens = array();
  10130. while ($position < $string_length)
  10131. {
  10132. $len = strcspn($string, $space_characters, $position);
  10133. $tokens[] = substr($string, $position, $len);
  10134. $position += $len;
  10135. $position += strspn($string, $space_characters, $position);
  10136. }
  10137. return $tokens;
  10138. }
  10139. function array_unique($array)
  10140. {
  10141. if (version_compare(PHP_VERSION, '5.2', '>='))
  10142. {
  10143. return array_unique($array);
  10144. }
  10145. else
  10146. {
  10147. $array = (array) $array;
  10148. $new_array = array();
  10149. $new_array_strings = array();
  10150. foreach ($array as $key => $value)
  10151. {
  10152. if (is_object($value))
  10153. {
  10154. if (method_exists($value, '__toString'))
  10155. {
  10156. $cmp = $value->__toString();
  10157. }
  10158. else
  10159. {
  10160. trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
  10161. }
  10162. }
  10163. elseif (is_array($value))
  10164. {
  10165. $cmp = (string) reset($value);
  10166. }
  10167. else
  10168. {
  10169. $cmp = (string) $value;
  10170. }
  10171. if (!in_array($cmp, $new_array_strings))
  10172. {
  10173. $new_array[$key] = $value;
  10174. $new_array_strings[] = $cmp;
  10175. }
  10176. }
  10177. return $new_array;
  10178. }
  10179. }
  10180. /**
  10181. * Converts a unicode codepoint to a UTF-8 character
  10182. *
  10183. * @static
  10184. * @access public
  10185. * @param int $codepoint Unicode codepoint
  10186. * @return string UTF-8 character
  10187. */
  10188. function codepoint_to_utf8($codepoint)
  10189. {
  10190. $codepoint = (int) $codepoint;
  10191. if ($codepoint < 0)
  10192. {
  10193. return false;
  10194. }
  10195. else if ($codepoint <= 0x7f)
  10196. {
  10197. return chr($codepoint);
  10198. }
  10199. else if ($codepoint <= 0x7ff)
  10200. {
  10201. return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
  10202. }
  10203. else if ($codepoint <= 0xffff)
  10204. {
  10205. return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  10206. }
  10207. else if ($codepoint <= 0x10ffff)
  10208. {
  10209. return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  10210. }
  10211. else
  10212. {
  10213. // U+FFFD REPLACEMENT CHARACTER
  10214. return "\xEF\xBF\xBD";
  10215. }
  10216. }
  10217. /**
  10218. * Re-implementation of PHP 5's stripos()
  10219. *
  10220. * Returns the numeric position of the first occurrence of needle in the
  10221. * haystack string.
  10222. *
  10223. * @static
  10224. * @access string
  10225. * @param object $haystack
  10226. * @param string $needle Note that the needle may be a string of one or more
  10227. * characters. If needle is not a string, it is converted to an integer
  10228. * and applied as the ordinal value of a character.
  10229. * @param int $offset The optional offset parameter allows you to specify which
  10230. * character in haystack to start searching. The position returned is still
  10231. * relative to the beginning of haystack.
  10232. * @return bool If needle is not found, stripos() will return boolean false.
  10233. */
  10234. function stripos($haystack, $needle, $offset = 0)
  10235. {
  10236. if (function_exists('stripos'))
  10237. {
  10238. return stripos($haystack, $needle, $offset);
  10239. }
  10240. else
  10241. {
  10242. if (is_string($needle))
  10243. {
  10244. $needle = strtolower($needle);
  10245. }
  10246. elseif (is_int($needle) || is_bool($needle) || is_double($needle))
  10247. {
  10248. $needle = strtolower(chr($needle));
  10249. }
  10250. else
  10251. {
  10252. trigger_error('needle is not a string or an integer', E_USER_WARNING);
  10253. return false;
  10254. }
  10255. return strpos(strtolower($haystack), $needle, $offset);
  10256. }
  10257. }
  10258. /**
  10259. * Similar to parse_str()
  10260. *
  10261. * Returns an associative array of name/value pairs, where the value is an
  10262. * array of values that have used the same name
  10263. *
  10264. * @static
  10265. * @access string
  10266. * @param string $str The input string.
  10267. * @return array
  10268. */
  10269. function parse_str($str)
  10270. {
  10271. $return = array();
  10272. $str = explode('&', $str);
  10273. foreach ($str as $section)
  10274. {
  10275. if (strpos($section, '=') !== false)
  10276. {
  10277. list($name, $value) = explode('=', $section, 2);
  10278. $return[urldecode($name)][] = urldecode($value);
  10279. }
  10280. else
  10281. {
  10282. $return[urldecode($section)][] = null;
  10283. }
  10284. }
  10285. return $return;
  10286. }
  10287. /**
  10288. * Detect XML encoding, as per XML 1.0 Appendix F.1
  10289. *
  10290. * @todo Add support for EBCDIC
  10291. * @param string $data XML data
  10292. * @return array Possible encodings
  10293. */
  10294. function xml_encoding($data)
  10295. {
  10296. // UTF-32 Big Endian BOM
  10297. if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
  10298. {
  10299. $encoding[] = 'UTF-32BE';
  10300. }
  10301. // UTF-32 Little Endian BOM
  10302. elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
  10303. {
  10304. $encoding[] = 'UTF-32LE';
  10305. }
  10306. // UTF-16 Big Endian BOM
  10307. elseif (substr($data, 0, 2) === "\xFE\xFF")
  10308. {
  10309. $encoding[] = 'UTF-16BE';
  10310. }
  10311. // UTF-16 Little Endian BOM
  10312. elseif (substr($data, 0, 2) === "\xFF\xFE")
  10313. {
  10314. $encoding[] = 'UTF-16LE';
  10315. }
  10316. // UTF-8 BOM
  10317. elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
  10318. {
  10319. $encoding[] = 'UTF-8';
  10320. }
  10321. // UTF-32 Big Endian Without BOM
  10322. 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")
  10323. {
  10324. if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
  10325. {
  10326. $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
  10327. if ($parser->parse())
  10328. {
  10329. $encoding[] = $parser->encoding;
  10330. }
  10331. }
  10332. $encoding[] = 'UTF-32BE';
  10333. }
  10334. // UTF-32 Little Endian Without BOM
  10335. 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")
  10336. {
  10337. if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
  10338. {
  10339. $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
  10340. if ($parser->parse())
  10341. {
  10342. $encoding[] = $parser->encoding;
  10343. }
  10344. }
  10345. $encoding[] = 'UTF-32LE';
  10346. }
  10347. // UTF-16 Big Endian Without BOM
  10348. elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
  10349. {
  10350. if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
  10351. {
  10352. $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
  10353. if ($parser->parse())
  10354. {
  10355. $encoding[] = $parser->encoding;
  10356. }
  10357. }
  10358. $encoding[] = 'UTF-16BE';
  10359. }
  10360. // UTF-16 Little Endian Without BOM
  10361. elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
  10362. {
  10363. if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
  10364. {
  10365. $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
  10366. if ($parser->parse())
  10367. {
  10368. $encoding[] = $parser->encoding;
  10369. }
  10370. }
  10371. $encoding[] = 'UTF-16LE';
  10372. }
  10373. // US-ASCII (or superset)
  10374. elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
  10375. {
  10376. if ($pos = strpos($data, "\x3F\x3E"))
  10377. {
  10378. $parser =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
  10379. if ($parser->parse())
  10380. {
  10381. $encoding[] = $parser->encoding;
  10382. }
  10383. }
  10384. $encoding[] = 'UTF-8';
  10385. }
  10386. // Fallback to UTF-8
  10387. else
  10388. {
  10389. $encoding[] = 'UTF-8';
  10390. }
  10391. return $encoding;
  10392. }
  10393. function output_javascript()
  10394. {
  10395. if (function_exists('ob_gzhandler'))
  10396. {
  10397. ob_start('ob_gzhandler');
  10398. }
  10399. header('Content-type: text/javascript; charset: UTF-8');
  10400. header('Cache-Control: must-revalidate');
  10401. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  10402. ?>
  10403. function embed_odeo(link) {
  10404. 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>');
  10405. }
  10406. function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
  10407. if (placeholder != '') {
  10408. 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>');
  10409. }
  10410. else {
  10411. 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>');
  10412. }
  10413. }
  10414. function embed_flash(bgcolor, width, height, link, loop, type) {
  10415. 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>');
  10416. }
  10417. function embed_flv(width, height, link, placeholder, loop, player) {
  10418. 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>');
  10419. }
  10420. function embed_wmedia(width, height, link) {
  10421. document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
  10422. }
  10423. <?php
  10424. }
  10425. /**
  10426. * Format debugging information
  10427. */
  10428. function debug($sp)
  10429. {
  10430. $info = 'SimplePie ' . SIMPLEPIE_VERSION . ' Build ' . SIMPLEPIE_BUILD . "\n";
  10431. $info .= 'PHP ' . PHP_VERSION . "\n";
  10432. if ($sp->error() !== null)
  10433. {
  10434. $info .= 'Error occurred: ' . $sp->error() . "\n";
  10435. }
  10436. else
  10437. {
  10438. $info .= "No error found.\n";
  10439. }
  10440. $info .= "Extensions:\n";
  10441. $extensions = array('pcre', 'curl', 'zlib', 'mbstring', 'iconv', 'xmlreader', 'xml');
  10442. foreach ($extensions as $ext)
  10443. {
  10444. if (extension_loaded($ext))
  10445. {
  10446. $info .= " $ext loaded\n";
  10447. switch ($ext)
  10448. {
  10449. case 'pcre':
  10450. $info .= ' Version ' . PCRE_VERSION . "\n";
  10451. break;
  10452. case 'curl':
  10453. $version = curl_version();
  10454. $info .= ' Version ' . $version['version'] . "\n";
  10455. break;
  10456. case 'mbstring':
  10457. $info .= ' Overloading: ' . mb_get_info('func_overload') . "\n";
  10458. break;
  10459. case 'iconv':
  10460. $info .= ' Version ' . ICONV_VERSION . "\n";
  10461. break;
  10462. case 'xml':
  10463. $info .= ' Version ' . LIBXML_DOTTED_VERSION . "\n";
  10464. break;
  10465. }
  10466. }
  10467. else
  10468. {
  10469. $info .= " $ext not loaded\n";
  10470. }
  10471. }
  10472. return $info;
  10473. }
  10474. }
  10475. /**
  10476. * Decode HTML Entities
  10477. *
  10478. * This implements HTML5 as of revision 967 (2007-06-28)
  10479. *
  10480. * @package SimplePie
  10481. */
  10482. class SimplePie_Decode_HTML_Entities
  10483. {
  10484. /**
  10485. * Data to be parsed
  10486. *
  10487. * @access private
  10488. * @var string
  10489. */
  10490. var $data = '';
  10491. /**
  10492. * Currently consumed bytes
  10493. *
  10494. * @access private
  10495. * @var string
  10496. */
  10497. var $consumed = '';
  10498. /**
  10499. * Position of the current byte being parsed
  10500. *
  10501. * @access private
  10502. * @var int
  10503. */
  10504. var $position = 0;
  10505. /**
  10506. * Create an instance of the class with the input data
  10507. *
  10508. * @access public
  10509. * @param string $data Input data
  10510. */
  10511. function SimplePie_Decode_HTML_Entities($data)
  10512. {
  10513. $this->data = $data;
  10514. }
  10515. /**
  10516. * Parse the input data
  10517. *
  10518. * @access public
  10519. * @return string Output data
  10520. */
  10521. function parse()
  10522. {
  10523. while (($this->position = strpos($this->data, '&', $this->position)) !== false)
  10524. {
  10525. $this->consume();
  10526. $this->entity();
  10527. $this->consumed = '';
  10528. }
  10529. return $this->data;
  10530. }
  10531. /**
  10532. * Consume the next byte
  10533. *
  10534. * @access private
  10535. * @return mixed The next byte, or false, if there is no more data
  10536. */
  10537. function consume()
  10538. {
  10539. if (isset($this->data[$this->position]))
  10540. {
  10541. $this->consumed .= $this->data[$this->position];
  10542. return $this->data[$this->position++];
  10543. }
  10544. else
  10545. {
  10546. return false;
  10547. }
  10548. }
  10549. /**
  10550. * Consume a range of characters
  10551. *
  10552. * @access private
  10553. * @param string $chars Characters to consume
  10554. * @return mixed A series of characters that match the range, or false
  10555. */
  10556. function consume_range($chars)
  10557. {
  10558. if ($len = strspn($this->data, $chars, $this->position))
  10559. {
  10560. $data = substr($this->data, $this->position, $len);
  10561. $this->consumed .= $data;
  10562. $this->position += $len;
  10563. return $data;
  10564. }
  10565. else
  10566. {
  10567. return false;
  10568. }
  10569. }
  10570. /**
  10571. * Unconsume one byte
  10572. *
  10573. * @access private
  10574. */
  10575. function unconsume()
  10576. {
  10577. $this->consumed = substr($this->consumed, 0, -1);
  10578. $this->position--;
  10579. }
  10580. /**
  10581. * Decode an entity
  10582. *
  10583. * @access private
  10584. */
  10585. function entity()
  10586. {
  10587. switch ($this->consume())
  10588. {
  10589. case "\x09":
  10590. case "\x0A":
  10591. case "\x0B":
  10592. case "\x0B":
  10593. case "\x0C":
  10594. case "\x20":
  10595. case "\x3C":
  10596. case "\x26":
  10597. case false:
  10598. break;
  10599. case "\x23":
  10600. switch ($this->consume())
  10601. {
  10602. case "\x78":
  10603. case "\x58":
  10604. $range = '0123456789ABCDEFabcdef';
  10605. $hex = true;
  10606. break;
  10607. default:
  10608. $range = '0123456789';
  10609. $hex = false;
  10610. $this->unconsume();
  10611. break;
  10612. }
  10613. if ($codepoint = $this->consume_range($range))
  10614. {
  10615. 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");
  10616. if ($hex)
  10617. {
  10618. $codepoint = hexdec($codepoint);
  10619. }
  10620. else
  10621. {
  10622. $codepoint = intval($codepoint);
  10623. }
  10624. if (isset($windows_1252_specials[$codepoint]))
  10625. {
  10626. $replacement = $windows_1252_specials[$codepoint];
  10627. }
  10628. else
  10629. {
  10630. $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
  10631. }
  10632. if (!in_array($this->consume(), array(';', false), true))
  10633. {
  10634. $this->unconsume();
  10635. }
  10636. $consumed_length = strlen($this->consumed);
  10637. $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
  10638. $this->position += strlen($replacement) - $consumed_length;
  10639. }
  10640. break;
  10641. default:
  10642. 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");
  10643. for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
  10644. {
  10645. $consumed = substr($this->consumed, 1);
  10646. if (isset($entities[$consumed]))
  10647. {
  10648. $match = $consumed;
  10649. }
  10650. }
  10651. if ($match !== null)
  10652. {
  10653. $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
  10654. $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
  10655. }
  10656. break;
  10657. }
  10658. }
  10659. }
  10660. /**
  10661. * IRI parser/serialiser
  10662. *
  10663. * @package SimplePie
  10664. */
  10665. class SimplePie_IRI
  10666. {
  10667. /**
  10668. * Scheme
  10669. *
  10670. * @access private
  10671. * @var string
  10672. */
  10673. var $scheme;
  10674. /**
  10675. * User Information
  10676. *
  10677. * @access private
  10678. * @var string
  10679. */
  10680. var $userinfo;
  10681. /**
  10682. * Host
  10683. *
  10684. * @access private
  10685. * @var string
  10686. */
  10687. var $host;
  10688. /**
  10689. * Port
  10690. *
  10691. * @access private
  10692. * @var string
  10693. */
  10694. var $port;
  10695. /**
  10696. * Path
  10697. *
  10698. * @access private
  10699. * @var string
  10700. */
  10701. var $path;
  10702. /**
  10703. * Query
  10704. *
  10705. * @access private
  10706. * @var string
  10707. */
  10708. var $query;
  10709. /**
  10710. * Fragment
  10711. *
  10712. * @access private
  10713. * @var string
  10714. */
  10715. var $fragment;
  10716. /**
  10717. * Whether the object represents a valid IRI
  10718. *
  10719. * @access private
  10720. * @var array
  10721. */
  10722. var $valid = array();
  10723. /**
  10724. * Return the entire IRI when you try and read the object as a string
  10725. *
  10726. * @access public
  10727. * @return string
  10728. */
  10729. function __toString()
  10730. {
  10731. return $this->get_iri();
  10732. }
  10733. /**
  10734. * Create a new IRI object, from a specified string
  10735. *
  10736. * @access public
  10737. * @param string $iri
  10738. * @return SimplePie_IRI
  10739. */
  10740. function SimplePie_IRI($iri)
  10741. {
  10742. $iri = (string) $iri;
  10743. if ($iri !== '')
  10744. {
  10745. $parsed = $this->parse_iri($iri);
  10746. $this->set_scheme($parsed['scheme']);
  10747. $this->set_authority($parsed['authority']);
  10748. $this->set_path($parsed['path']);
  10749. $this->set_query($parsed['query']);
  10750. $this->set_fragment($parsed['fragment']);
  10751. }
  10752. }
  10753. /**
  10754. * Create a new IRI object by resolving a relative IRI
  10755. *
  10756. * @static
  10757. * @access public
  10758. * @param SimplePie_IRI $base Base IRI
  10759. * @param string $relative Relative IRI
  10760. * @return SimplePie_IRI
  10761. */
  10762. function absolutize($base, $relative)
  10763. {
  10764. $relative = (string) $relative;
  10765. if ($relative !== '')
  10766. {
  10767. $relative =& new SimplePie_IRI($relative);
  10768. if ($relative->get_scheme() !== null)
  10769. {
  10770. $target = $relative;
  10771. }
  10772. elseif ($base->get_iri() !== null)
  10773. {
  10774. if ($relative->get_authority() !== null)
  10775. {
  10776. $target = $relative;
  10777. $target->set_scheme($base->get_scheme());
  10778. }
  10779. else
  10780. {
  10781. $target =& new SimplePie_IRI('');
  10782. $target->set_scheme($base->get_scheme());
  10783. $target->set_userinfo($base->get_userinfo());
  10784. $target->set_host($base->get_host());
  10785. $target->set_port($base->get_port());
  10786. if ($relative->get_path() !== null)
  10787. {
  10788. if (strpos($relative->get_path(), '/') === 0)
  10789. {
  10790. $target->set_path($relative->get_path());
  10791. }
  10792. elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)
  10793. {
  10794. $target->set_path('/' . $relative->get_path());
  10795. }
  10796. elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
  10797. {
  10798. $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());
  10799. }
  10800. else
  10801. {
  10802. $target->set_path($relative->get_path());
  10803. }
  10804. $target->set_query($relative->get_query());
  10805. }
  10806. else
  10807. {
  10808. $target->set_path($base->get_path());
  10809. if ($relative->get_query() !== null)
  10810. {
  10811. $target->set_query($relative->get_query());
  10812. }
  10813. elseif ($base->get_query() !== null)
  10814. {
  10815. $target->set_query($base->get_query());
  10816. }
  10817. }
  10818. }
  10819. $target->set_fragment($relative->get_fragment());
  10820. }
  10821. else
  10822. {
  10823. // No base URL, just return the relative URL
  10824. $target = $relative;
  10825. }
  10826. }
  10827. else
  10828. {
  10829. $target = $base;
  10830. }
  10831. return $target;
  10832. }
  10833. /**
  10834. * Parse an IRI into scheme/authority/path/query/fragment segments
  10835. *
  10836. * @access private
  10837. * @param string $iri
  10838. * @return array
  10839. */
  10840. function parse_iri($iri)
  10841. {
  10842. preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
  10843. for ($i = count($match); $i <= 9; $i++)
  10844. {
  10845. $match[$i] = '';
  10846. }
  10847. return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
  10848. }
  10849. /**
  10850. * Remove dot segments from a path
  10851. *
  10852. * @access private
  10853. * @param string $input
  10854. * @return string
  10855. */
  10856. function remove_dot_segments($input)
  10857. {
  10858. $output = '';
  10859. while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
  10860. {
  10861. // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
  10862. if (strpos($input, '../') === 0)
  10863. {
  10864. $input = substr($input, 3);
  10865. }
  10866. elseif (strpos($input, './') === 0)
  10867. {
  10868. $input = substr($input, 2);
  10869. }
  10870. // 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,
  10871. elseif (strpos($input, '/./') === 0)
  10872. {
  10873. $input = substr_replace($input, '/', 0, 3);
  10874. }
  10875. elseif ($input === '/.')
  10876. {
  10877. $input = '/';
  10878. }
  10879. // 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,
  10880. elseif (strpos($input, '/../') === 0)
  10881. {
  10882. $input = substr_replace($input, '/', 0, 4);
  10883. $output = substr_replace($output, '', strrpos($output, '/'));
  10884. }
  10885. elseif ($input === '/..')
  10886. {
  10887. $input = '/';
  10888. $output = substr_replace($output, '', strrpos($output, '/'));
  10889. }
  10890. // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
  10891. elseif ($input === '.' || $input === '..')
  10892. {
  10893. $input = '';
  10894. }
  10895. // 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
  10896. elseif (($pos = strpos($input, '/', 1)) !== false)
  10897. {
  10898. $output .= substr($input, 0, $pos);
  10899. $input = substr_replace($input, '', 0, $pos);
  10900. }
  10901. else
  10902. {
  10903. $output .= $input;
  10904. $input = '';
  10905. }
  10906. }
  10907. return $output . $input;
  10908. }
  10909. /**
  10910. * Replace invalid character with percent encoding
  10911. *
  10912. * @param string $string Input string
  10913. * @param string $valid_chars Valid characters
  10914. * @param int $case Normalise case
  10915. * @return string
  10916. */
  10917. function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE, $iprivate = false)
  10918. {
  10919. // Normalize as many pct-encoded sections as possible
  10920. $string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array(&$this, 'remove_iunreserved_percent_encoded'), $string);
  10921. // Replace invalid percent characters
  10922. $string = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $string);
  10923. // Add unreserved and % to $valid_chars (the latter is safe because all
  10924. // pct-encoded sections are now valid).
  10925. $valid_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';
  10926. // Now replace any bytes that aren't allowed with their pct-encoded versions
  10927. $position = 0;
  10928. $strlen = strlen($string);
  10929. while (($position += strspn($string, $valid_chars, $position)) < $strlen)
  10930. {
  10931. $value = ord($string[$position]);
  10932. // Start position
  10933. $start = $position;
  10934. // By default we are valid
  10935. $valid = true;
  10936. // No one byte sequences are valid due to the while.
  10937. // Two byte sequence:
  10938. if (($value & 0xE0) === 0xC0)
  10939. {
  10940. $character = ($value & 0x1F) << 6;
  10941. $length = 2;
  10942. $remaining = 1;
  10943. }
  10944. // Three byte sequence:
  10945. elseif (($value & 0xF0) === 0xE0)
  10946. {
  10947. $character = ($value & 0x0F) << 12;
  10948. $length = 3;
  10949. $remaining = 2;
  10950. }
  10951. // Four byte sequence:
  10952. elseif (($value & 0xF8) === 0xF0)
  10953. {
  10954. $character = ($value & 0x07) << 18;
  10955. $length = 4;
  10956. $remaining = 3;
  10957. }
  10958. // Invalid byte:
  10959. else
  10960. {
  10961. $valid = false;
  10962. $length = 1;
  10963. $remaining = 0;
  10964. }
  10965. if ($remaining)
  10966. {
  10967. if ($position + $length <= $strlen)
  10968. {
  10969. for ($position++; $remaining; $position++)
  10970. {
  10971. $value = ord($string[$position]);
  10972. // Check that the byte is valid, then add it to the character:
  10973. if (($value & 0xC0) === 0x80)
  10974. {
  10975. $character |= ($value & 0x3F) << (--$remaining * 6);
  10976. }
  10977. // If it is invalid, count the sequence as invalid and reprocess the current byte:
  10978. else
  10979. {
  10980. $valid = false;
  10981. $position--;
  10982. break;
  10983. }
  10984. }
  10985. }
  10986. else
  10987. {
  10988. $position = $strlen - 1;
  10989. $valid = false;
  10990. }
  10991. }
  10992. // Percent encode anything invalid or not in ucschar
  10993. if (
  10994. // Invalid sequences
  10995. !$valid
  10996. // Non-shortest form sequences are invalid
  10997. || $length > 1 && $character <= 0x7F
  10998. || $length > 2 && $character <= 0x7FF
  10999. || $length > 3 && $character <= 0xFFFF
  11000. // Outside of range of ucschar codepoints
  11001. // Noncharacters
  11002. || ($character & 0xFFFE) === 0xFFFE
  11003. || $character >= 0xFDD0 && $character <= 0xFDEF
  11004. || (
  11005. // Everything else not in ucschar
  11006. $character > 0xD7FF && $character < 0xF900
  11007. || $character < 0xA0
  11008. || $character > 0xEFFFD
  11009. )
  11010. && (
  11011. // Everything not in iprivate, if it applies
  11012. !$iprivate
  11013. || $character < 0xE000
  11014. || $character > 0x10FFFD
  11015. )
  11016. )
  11017. {
  11018. // If we were a character, pretend we weren't, but rather an error.
  11019. if ($valid)
  11020. $position--;
  11021. for ($j = $start; $j <= $position; $j++)
  11022. {
  11023. $string = substr_replace($string, sprintf('%%%02X', ord($string[$j])), $j, 1);
  11024. $j += 2;
  11025. $position += 2;
  11026. $strlen += 2;
  11027. }
  11028. }
  11029. }
  11030. // Normalise case
  11031. if ($case & SIMPLEPIE_LOWERCASE)
  11032. {
  11033. $string = strtolower($string);
  11034. }
  11035. elseif ($case & SIMPLEPIE_UPPERCASE)
  11036. {
  11037. $string = strtoupper($string);
  11038. }
  11039. return $string;
  11040. }
  11041. /**
  11042. * Callback function for preg_replace_callback.
  11043. *
  11044. * Removes sequences of percent encoded bytes that represent UTF-8
  11045. * encoded characters in iunreserved
  11046. *
  11047. * @access private
  11048. * @param array $match PCRE match
  11049. * @return string Replacement
  11050. */
  11051. function remove_iunreserved_percent_encoded($match)
  11052. {
  11053. // As we just have valid percent encoded sequences we can just explode
  11054. // and ignore the first member of the returned array (an empty string).
  11055. $bytes = explode('%', $match[0]);
  11056. // Initialize the new string (this is what will be returned) and that
  11057. // there are no bytes remaining in the current sequence (unsurprising
  11058. // at the first byte!).
  11059. $string = '';
  11060. $remaining = 0;
  11061. // Loop over each and every byte, and set $value to its value
  11062. for ($i = 1, $len = count($bytes); $i < $len; $i++)
  11063. {
  11064. $value = hexdec($bytes[$i]);
  11065. // If we're the first byte of sequence:
  11066. if (!$remaining)
  11067. {
  11068. // Start position
  11069. $start = $i;
  11070. // By default we are valid
  11071. $valid = true;
  11072. // One byte sequence:
  11073. if ($value <= 0x7F)
  11074. {
  11075. $character = $value;
  11076. $length = 1;
  11077. }
  11078. // Two byte sequence:
  11079. elseif (($value & 0xE0) === 0xC0)
  11080. {
  11081. $character = ($value & 0x1F) << 6;
  11082. $length = 2;
  11083. $remaining = 1;
  11084. }
  11085. // Three byte sequence:
  11086. elseif (($value & 0xF0) === 0xE0)
  11087. {
  11088. $character = ($value & 0x0F) << 12;
  11089. $length = 3;
  11090. $remaining = 2;
  11091. }
  11092. // Four byte sequence:
  11093. elseif (($value & 0xF8) === 0xF0)
  11094. {
  11095. $character = ($value & 0x07) << 18;
  11096. $length = 4;
  11097. $remaining = 3;
  11098. }
  11099. // Invalid byte:
  11100. else
  11101. {
  11102. $valid = false;
  11103. $remaining = 0;
  11104. }
  11105. }
  11106. // Continuation byte:
  11107. else
  11108. {
  11109. // Check that the byte is valid, then add it to the character:
  11110. if (($value & 0xC0) === 0x80)
  11111. {
  11112. $remaining--;
  11113. $character |= ($value & 0x3F) << ($remaining * 6);
  11114. }
  11115. // If it is invalid, count the sequence as invalid and reprocess the current byte as the start of a sequence:
  11116. else
  11117. {
  11118. $valid = false;
  11119. $remaining = 0;
  11120. $i--;
  11121. }
  11122. }
  11123. // If we've reached the end of the current byte sequence, append it to Unicode::$data
  11124. if (!$remaining)
  11125. {
  11126. // Percent encode anything invalid or not in iunreserved
  11127. if (
  11128. // Invalid sequences
  11129. !$valid
  11130. // Non-shortest form sequences are invalid
  11131. || $length > 1 && $character <= 0x7F
  11132. || $length > 2 && $character <= 0x7FF
  11133. || $length > 3 && $character <= 0xFFFF
  11134. // Outside of range of iunreserved codepoints
  11135. || $character < 0x2D
  11136. || $character > 0xEFFFD
  11137. // Noncharacters
  11138. || ($character & 0xFFFE) === 0xFFFE
  11139. || $character >= 0xFDD0 && $character <= 0xFDEF
  11140. // Everything else not in iunreserved (this is all BMP)
  11141. || $character === 0x2F
  11142. || $character > 0x39 && $character < 0x41
  11143. || $character > 0x5A && $character < 0x61
  11144. || $character > 0x7A && $character < 0x7E
  11145. || $character > 0x7E && $character < 0xA0
  11146. || $character > 0xD7FF && $character < 0xF900
  11147. )
  11148. {
  11149. for ($j = $start; $j <= $i; $j++)
  11150. {
  11151. $string .= '%' . strtoupper($bytes[$j]);
  11152. }
  11153. }
  11154. else
  11155. {
  11156. for ($j = $start; $j <= $i; $j++)
  11157. {
  11158. $string .= chr(hexdec($bytes[$j]));
  11159. }
  11160. }
  11161. }
  11162. }
  11163. // If we have any bytes left over they are invalid (i.e., we are
  11164. // mid-way through a multi-byte sequence)
  11165. if ($remaining)
  11166. {
  11167. for ($j = $start; $j < $len; $j++)
  11168. {
  11169. $string .= '%' . strtoupper($bytes[$j]);
  11170. }
  11171. }
  11172. return $string;
  11173. }
  11174. /**
  11175. * Check if the object represents a valid IRI
  11176. *
  11177. * @access public
  11178. * @return bool
  11179. */
  11180. function is_valid()
  11181. {
  11182. return array_sum($this->valid) === count($this->valid);
  11183. }
  11184. /**
  11185. * Set the scheme. Returns true on success, false on failure (if there are
  11186. * any invalid characters).
  11187. *
  11188. * @access public
  11189. * @param string $scheme
  11190. * @return bool
  11191. */
  11192. function set_scheme($scheme)
  11193. {
  11194. if ($scheme === null || $scheme === '')
  11195. {
  11196. $this->scheme = null;
  11197. }
  11198. else
  11199. {
  11200. $len = strlen($scheme);
  11201. switch (true)
  11202. {
  11203. case $len > 1:
  11204. if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
  11205. {
  11206. $this->scheme = null;
  11207. $this->valid[__FUNCTION__] = false;
  11208. return false;
  11209. }
  11210. case $len > 0:
  11211. if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
  11212. {
  11213. $this->scheme = null;
  11214. $this->valid[__FUNCTION__] = false;
  11215. return false;
  11216. }
  11217. }
  11218. $this->scheme = strtolower($scheme);
  11219. }
  11220. $this->valid[__FUNCTION__] = true;
  11221. return true;
  11222. }
  11223. /**
  11224. * Set the authority. Returns true on success, false on failure (if there are
  11225. * any invalid characters).
  11226. *
  11227. * @access public
  11228. * @param string $authority
  11229. * @return bool
  11230. */
  11231. function set_authority($authority)
  11232. {
  11233. if (($userinfo_end = strrpos($authority, '@')) !== false)
  11234. {
  11235. $userinfo = substr($authority, 0, $userinfo_end);
  11236. $authority = substr($authority, $userinfo_end + 1);
  11237. }
  11238. else
  11239. {
  11240. $userinfo = null;
  11241. }
  11242. if (($port_start = strpos($authority, ':')) !== false)
  11243. {
  11244. $port = substr($authority, $port_start + 1);
  11245. $authority = substr($authority, 0, $port_start);
  11246. }
  11247. else
  11248. {
  11249. $port = null;
  11250. }
  11251. return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
  11252. }
  11253. /**
  11254. * Set the userinfo.
  11255. *
  11256. * @access public
  11257. * @param string $userinfo
  11258. * @return bool
  11259. */
  11260. function set_userinfo($userinfo)
  11261. {
  11262. if ($userinfo === null || $userinfo === '')
  11263. {
  11264. $this->userinfo = null;
  11265. }
  11266. else
  11267. {
  11268. $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
  11269. }
  11270. $this->valid[__FUNCTION__] = true;
  11271. return true;
  11272. }
  11273. /**
  11274. * Set the host. Returns true on success, false on failure (if there are
  11275. * any invalid characters).
  11276. *
  11277. * @access public
  11278. * @param string $host
  11279. * @return bool
  11280. */
  11281. function set_host($host)
  11282. {
  11283. if ($host === null || $host === '')
  11284. {
  11285. $this->host = null;
  11286. $this->valid[__FUNCTION__] = true;
  11287. return true;
  11288. }
  11289. elseif ($host[0] === '[' && substr($host, -1) === ']')
  11290. {
  11291. if (SimplePie_Net_IPv6::checkIPv6(substr($host, 1, -1)))
  11292. {
  11293. $this->host = $host;
  11294. $this->valid[__FUNCTION__] = true;
  11295. return true;
  11296. }
  11297. else
  11298. {
  11299. $this->host = null;
  11300. $this->valid[__FUNCTION__] = false;
  11301. return false;
  11302. }
  11303. }
  11304. else
  11305. {
  11306. $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);
  11307. $this->valid[__FUNCTION__] = true;
  11308. return true;
  11309. }
  11310. }
  11311. /**
  11312. * Set the port. Returns true on success, false on failure (if there are
  11313. * any invalid characters).
  11314. *
  11315. * @access public
  11316. * @param string $port
  11317. * @return bool
  11318. */
  11319. function set_port($port)
  11320. {
  11321. if ($port === null || $port === '')
  11322. {
  11323. $this->port = null;
  11324. $this->valid[__FUNCTION__] = true;
  11325. return true;
  11326. }
  11327. elseif (strspn($port, '0123456789') === strlen($port))
  11328. {
  11329. $this->port = (int) $port;
  11330. $this->valid[__FUNCTION__] = true;
  11331. return true;
  11332. }
  11333. else
  11334. {
  11335. $this->port = null;
  11336. $this->valid[__FUNCTION__] = false;
  11337. return false;
  11338. }
  11339. }
  11340. /**
  11341. * Set the path.
  11342. *
  11343. * @access public
  11344. * @param string $path
  11345. * @return bool
  11346. */
  11347. function set_path($path)
  11348. {
  11349. if ($path === null || $path === '')
  11350. {
  11351. $this->path = null;
  11352. $this->valid[__FUNCTION__] = true;
  11353. return true;
  11354. }
  11355. elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)
  11356. {
  11357. $this->path = null;
  11358. $this->valid[__FUNCTION__] = false;
  11359. return false;
  11360. }
  11361. else
  11362. {
  11363. $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
  11364. if ($this->scheme !== null)
  11365. {
  11366. $this->path = $this->remove_dot_segments($this->path);
  11367. }
  11368. $this->valid[__FUNCTION__] = true;
  11369. return true;
  11370. }
  11371. }
  11372. /**
  11373. * Set the query.
  11374. *
  11375. * @access public
  11376. * @param string $query
  11377. * @return bool
  11378. */
  11379. function set_query($query)
  11380. {
  11381. if ($query === null || $query === '')
  11382. {
  11383. $this->query = null;
  11384. }
  11385. else
  11386. {
  11387. $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$\'()*+,;:@/?&=');
  11388. }
  11389. $this->valid[__FUNCTION__] = true;
  11390. return true;
  11391. }
  11392. /**
  11393. * Set the fragment.
  11394. *
  11395. * @access public
  11396. * @param string $fragment
  11397. * @return bool
  11398. */
  11399. function set_fragment($fragment)
  11400. {
  11401. if ($fragment === null || $fragment === '')
  11402. {
  11403. $this->fragment = null;
  11404. }
  11405. else
  11406. {
  11407. $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
  11408. }
  11409. $this->valid[__FUNCTION__] = true;
  11410. return true;
  11411. }
  11412. /**
  11413. * Get the complete IRI
  11414. *
  11415. * @access public
  11416. * @return string
  11417. */
  11418. function get_iri()
  11419. {
  11420. $iri = '';
  11421. if ($this->scheme !== null)
  11422. {
  11423. $iri .= $this->scheme . ':';
  11424. }
  11425. if (($authority = $this->get_authority()) !== null)
  11426. {
  11427. $iri .= '//' . $authority;
  11428. }
  11429. if ($this->path !== null)
  11430. {
  11431. $iri .= $this->path;
  11432. }
  11433. if ($this->query !== null)
  11434. {
  11435. $iri .= '?' . $this->query;
  11436. }
  11437. if ($this->fragment !== null)
  11438. {
  11439. $iri .= '#' . $this->fragment;
  11440. }
  11441. if ($iri !== '')
  11442. {
  11443. return $iri;
  11444. }
  11445. else
  11446. {
  11447. return null;
  11448. }
  11449. }
  11450. /**
  11451. * Get the scheme
  11452. *
  11453. * @access public
  11454. * @return string
  11455. */
  11456. function get_scheme()
  11457. {
  11458. return $this->scheme;
  11459. }
  11460. /**
  11461. * Get the complete authority
  11462. *
  11463. * @access public
  11464. * @return string
  11465. */
  11466. function get_authority()
  11467. {
  11468. $authority = '';
  11469. if ($this->userinfo !== null)
  11470. {
  11471. $authority .= $this->userinfo . '@';
  11472. }
  11473. if ($this->host !== null)
  11474. {
  11475. $authority .= $this->host;
  11476. }
  11477. if ($this->port !== null)
  11478. {
  11479. $authority .= ':' . $this->port;
  11480. }
  11481. if ($authority !== '')
  11482. {
  11483. return $authority;
  11484. }
  11485. else
  11486. {
  11487. return null;
  11488. }
  11489. }
  11490. /**
  11491. * Get the user information
  11492. *
  11493. * @access public
  11494. * @return string
  11495. */
  11496. function get_userinfo()
  11497. {
  11498. return $this->userinfo;
  11499. }
  11500. /**
  11501. * Get the host
  11502. *
  11503. * @access public
  11504. * @return string
  11505. */
  11506. function get_host()
  11507. {
  11508. return $this->host;
  11509. }
  11510. /**
  11511. * Get the port
  11512. *
  11513. * @access public
  11514. * @return string
  11515. */
  11516. function get_port()
  11517. {
  11518. return $this->port;
  11519. }
  11520. /**
  11521. * Get the path
  11522. *
  11523. * @access public
  11524. * @return string
  11525. */
  11526. function get_path()
  11527. {
  11528. return $this->path;
  11529. }
  11530. /**
  11531. * Get the query
  11532. *
  11533. * @access public
  11534. * @return string
  11535. */
  11536. function get_query()
  11537. {
  11538. return $this->query;
  11539. }
  11540. /**
  11541. * Get the fragment
  11542. *
  11543. * @access public
  11544. * @return string
  11545. */
  11546. function get_fragment()
  11547. {
  11548. return $this->fragment;
  11549. }
  11550. }
  11551. /**
  11552. * Class to validate and to work with IPv6 addresses.
  11553. *
  11554. * @package SimplePie
  11555. * @copyright 2003-2005 The PHP Group
  11556. * @license http://www.opensource.org/licenses/bsd-license.php
  11557. * @link http://pear.php.net/package/Net_IPv6
  11558. * @author Alexander Merz <alexander.merz@web.de>
  11559. * @author elfrink at introweb dot nl
  11560. * @author Josh Peck <jmp at joshpeck dot org>
  11561. * @author Geoffrey Sneddon <geoffers@gmail.com>
  11562. */
  11563. class SimplePie_Net_IPv6
  11564. {
  11565. /**
  11566. * Removes a possible existing netmask specification of an IP address.
  11567. *
  11568. * @param string $ip the (compressed) IP as Hex representation
  11569. * @return string the IP the without netmask
  11570. * @since 1.1.0
  11571. * @access public
  11572. * @static
  11573. */
  11574. function removeNetmaskSpec($ip)
  11575. {
  11576. if (strpos($ip, '/') !== false)
  11577. {
  11578. list($addr, $nm) = explode('/', $ip);
  11579. }
  11580. else
  11581. {
  11582. $addr = $ip;
  11583. }
  11584. return $addr;
  11585. }
  11586. /**
  11587. * Uncompresses an IPv6 address
  11588. *
  11589. * RFC 2373 allows you to compress zeros in an address to '::'. This
  11590. * function expects an valid IPv6 address and expands the '::' to
  11591. * the required zeros.
  11592. *
  11593. * Example: FF01::101 -> FF01:0:0:0:0:0:0:101
  11594. * ::1 -> 0:0:0:0:0:0:0:1
  11595. *
  11596. * @access public
  11597. * @static
  11598. * @param string $ip a valid IPv6-address (hex format)
  11599. * @return string the uncompressed IPv6-address (hex format)
  11600. */
  11601. function Uncompress($ip)
  11602. {
  11603. $uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip);
  11604. $c1 = -1;
  11605. $c2 = -1;
  11606. if (strpos($ip, '::') !== false)
  11607. {
  11608. list($ip1, $ip2) = explode('::', $ip);
  11609. if ($ip1 === '')
  11610. {
  11611. $c1 = -1;
  11612. }
  11613. else
  11614. {
  11615. $pos = 0;
  11616. if (($pos = substr_count($ip1, ':')) > 0)
  11617. {
  11618. $c1 = $pos;
  11619. }
  11620. else
  11621. {
  11622. $c1 = 0;
  11623. }
  11624. }
  11625. if ($ip2 === '')
  11626. {
  11627. $c2 = -1;
  11628. }
  11629. else
  11630. {
  11631. $pos = 0;
  11632. if (($pos = substr_count($ip2, ':')) > 0)
  11633. {
  11634. $c2 = $pos;
  11635. }
  11636. else
  11637. {
  11638. $c2 = 0;
  11639. }
  11640. }
  11641. if (strstr($ip2, '.'))
  11642. {
  11643. $c2++;
  11644. }
  11645. // ::
  11646. if ($c1 === -1 && $c2 === -1)
  11647. {
  11648. $uip = '0:0:0:0:0:0:0:0';
  11649. }
  11650. // ::xxx
  11651. else if ($c1 === -1)
  11652. {
  11653. $fill = str_repeat('0:', 7 - $c2);
  11654. $uip = str_replace('::', $fill, $uip);
  11655. }
  11656. // xxx::
  11657. else if ($c2 === -1)
  11658. {
  11659. $fill = str_repeat(':0', 7 - $c1);
  11660. $uip = str_replace('::', $fill, $uip);
  11661. }
  11662. // xxx::xxx
  11663. else
  11664. {
  11665. $fill = str_repeat(':0:', 6 - $c2 - $c1);
  11666. $uip = str_replace('::', $fill, $uip);
  11667. $uip = str_replace('::', ':', $uip);
  11668. }
  11669. }
  11670. return $uip;
  11671. }
  11672. /**
  11673. * Splits an IPv6 address into the IPv6 and a possible IPv4 part
  11674. *
  11675. * RFC 2373 allows you to note the last two parts of an IPv6 address as
  11676. * an IPv4 compatible address
  11677. *
  11678. * Example: 0:0:0:0:0:0:13.1.68.3
  11679. * 0:0:0:0:0:FFFF:129.144.52.38
  11680. *
  11681. * @access public
  11682. * @static
  11683. * @param string $ip a valid IPv6-address (hex format)
  11684. * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)
  11685. */
  11686. function SplitV64($ip)
  11687. {
  11688. $ip = SimplePie_Net_IPv6::Uncompress($ip);
  11689. if (strstr($ip, '.'))
  11690. {
  11691. $pos = strrpos($ip, ':');
  11692. $ip[$pos] = '_';
  11693. $ipPart = explode('_', $ip);
  11694. return $ipPart;
  11695. }
  11696. else
  11697. {
  11698. return array($ip, '');
  11699. }
  11700. }
  11701. /**
  11702. * Checks an IPv6 address
  11703. *
  11704. * Checks if the given IP is IPv6-compatible
  11705. *
  11706. * @access public
  11707. * @static
  11708. * @param string $ip a valid IPv6-address
  11709. * @return bool true if $ip is an IPv6 address
  11710. */
  11711. function checkIPv6($ip)
  11712. {
  11713. $ipPart = SimplePie_Net_IPv6::SplitV64($ip);
  11714. $count = 0;
  11715. if (!empty($ipPart[0]))
  11716. {
  11717. $ipv6 = explode(':', $ipPart[0]);
  11718. for ($i = 0; $i < count($ipv6); $i++)
  11719. {
  11720. $dec = hexdec($ipv6[$i]);
  11721. $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));
  11722. if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))
  11723. {
  11724. $count++;
  11725. }
  11726. }
  11727. if ($count === 8)
  11728. {
  11729. return true;
  11730. }
  11731. elseif ($count === 6 && !empty($ipPart[1]))
  11732. {
  11733. $ipv4 = explode('.', $ipPart[1]);
  11734. $count = 0;
  11735. foreach ($ipv4 as $ipv4_part)
  11736. {
  11737. if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))
  11738. {
  11739. $count++;
  11740. }
  11741. }
  11742. if ($count === 4)
  11743. {
  11744. return true;
  11745. }
  11746. }
  11747. else
  11748. {
  11749. return false;
  11750. }
  11751. }
  11752. else
  11753. {
  11754. return false;
  11755. }
  11756. }
  11757. }
  11758. /**
  11759. * Date Parser
  11760. *
  11761. * @package SimplePie
  11762. */
  11763. class SimplePie_Parse_Date
  11764. {
  11765. /**
  11766. * Input data
  11767. *
  11768. * @access protected
  11769. * @var string
  11770. */
  11771. var $date;
  11772. /**
  11773. * List of days, calendar day name => ordinal day number in the week
  11774. *
  11775. * @access protected
  11776. * @var array
  11777. */
  11778. var $day = array(
  11779. // English
  11780. 'mon' => 1,
  11781. 'monday' => 1,
  11782. 'tue' => 2,
  11783. 'tuesday' => 2,
  11784. 'wed' => 3,
  11785. 'wednesday' => 3,
  11786. 'thu' => 4,
  11787. 'thursday' => 4,
  11788. 'fri' => 5,
  11789. 'friday' => 5,
  11790. 'sat' => 6,
  11791. 'saturday' => 6,
  11792. 'sun' => 7,
  11793. 'sunday' => 7,
  11794. // Dutch
  11795. 'maandag' => 1,
  11796. 'dinsdag' => 2,
  11797. 'woensdag' => 3,
  11798. 'donderdag' => 4,
  11799. 'vrijdag' => 5,
  11800. 'zaterdag' => 6,
  11801. 'zondag' => 7,
  11802. // French
  11803. 'lundi' => 1,
  11804. 'mardi' => 2,
  11805. 'mercredi' => 3,
  11806. 'jeudi' => 4,
  11807. 'vendredi' => 5,
  11808. 'samedi' => 6,
  11809. 'dimanche' => 7,
  11810. // German
  11811. 'montag' => 1,
  11812. 'dienstag' => 2,
  11813. 'mittwoch' => 3,
  11814. 'donnerstag' => 4,
  11815. 'freitag' => 5,
  11816. 'samstag' => 6,
  11817. 'sonnabend' => 6,
  11818. 'sonntag' => 7,
  11819. // Italian
  11820. 'lunedì' => 1,
  11821. 'martedì' => 2,
  11822. 'mercoledì' => 3,
  11823. 'giovedì' => 4,
  11824. 'venerdì' => 5,
  11825. 'sabato' => 6,
  11826. 'domenica' => 7,
  11827. // Spanish
  11828. 'lunes' => 1,
  11829. 'martes' => 2,
  11830. 'miércoles' => 3,
  11831. 'jueves' => 4,
  11832. 'viernes' => 5,
  11833. 'sábado' => 6,
  11834. 'domingo' => 7,
  11835. // Finnish
  11836. 'maanantai' => 1,
  11837. 'tiistai' => 2,
  11838. 'keskiviikko' => 3,
  11839. 'torstai' => 4,
  11840. 'perjantai' => 5,
  11841. 'lauantai' => 6,
  11842. 'sunnuntai' => 7,
  11843. // Hungarian
  11844. 'hétfő' => 1,
  11845. 'kedd' => 2,
  11846. 'szerda' => 3,
  11847. 'csütörtok' => 4,
  11848. 'péntek' => 5,
  11849. 'szombat' => 6,
  11850. 'vasárnap' => 7,
  11851. // Greek
  11852. 'Δευ' => 1,
  11853. 'Τρι' => 2,
  11854. 'Τετ' => 3,
  11855. 'Πεμ' => 4,
  11856. 'Παρ' => 5,
  11857. 'Σαβ' => 6,
  11858. 'Κυρ' => 7,
  11859. );
  11860. /**
  11861. * List of months, calendar month name => calendar month number
  11862. *
  11863. * @access protected
  11864. * @var array
  11865. */
  11866. var $month = array(
  11867. // English
  11868. 'jan' => 1,
  11869. 'january' => 1,
  11870. 'feb' => 2,
  11871. 'february' => 2,
  11872. 'mar' => 3,
  11873. 'march' => 3,
  11874. 'apr' => 4,
  11875. 'april' => 4,
  11876. 'may' => 5,
  11877. // No long form of May
  11878. 'jun' => 6,
  11879. 'june' => 6,
  11880. 'jul' => 7,
  11881. 'july' => 7,
  11882. 'aug' => 8,
  11883. 'august' => 8,
  11884. 'sep' => 9,
  11885. 'september' => 8,
  11886. 'oct' => 10,
  11887. 'october' => 10,
  11888. 'nov' => 11,
  11889. 'november' => 11,
  11890. 'dec' => 12,
  11891. 'december' => 12,
  11892. // Dutch
  11893. 'januari' => 1,
  11894. 'februari' => 2,
  11895. 'maart' => 3,
  11896. 'april' => 4,
  11897. 'mei' => 5,
  11898. 'juni' => 6,
  11899. 'juli' => 7,
  11900. 'augustus' => 8,
  11901. 'september' => 9,
  11902. 'oktober' => 10,
  11903. 'november' => 11,
  11904. 'december' => 12,
  11905. // French
  11906. 'janvier' => 1,
  11907. 'février' => 2,
  11908. 'mars' => 3,
  11909. 'avril' => 4,
  11910. 'mai' => 5,
  11911. 'juin' => 6,
  11912. 'juillet' => 7,
  11913. 'août' => 8,
  11914. 'septembre' => 9,
  11915. 'octobre' => 10,
  11916. 'novembre' => 11,
  11917. 'décembre' => 12,
  11918. // German
  11919. 'januar' => 1,
  11920. 'februar' => 2,
  11921. 'märz' => 3,
  11922. 'april' => 4,
  11923. 'mai' => 5,
  11924. 'juni' => 6,
  11925. 'juli' => 7,
  11926. 'august' => 8,
  11927. 'september' => 9,
  11928. 'oktober' => 10,
  11929. 'november' => 11,
  11930. 'dezember' => 12,
  11931. // Italian
  11932. 'gennaio' => 1,
  11933. 'febbraio' => 2,
  11934. 'marzo' => 3,
  11935. 'aprile' => 4,
  11936. 'maggio' => 5,
  11937. 'giugno' => 6,
  11938. 'luglio' => 7,
  11939. 'agosto' => 8,
  11940. 'settembre' => 9,
  11941. 'ottobre' => 10,
  11942. 'novembre' => 11,
  11943. 'dicembre' => 12,
  11944. // Spanish
  11945. 'enero' => 1,
  11946. 'febrero' => 2,
  11947. 'marzo' => 3,
  11948. 'abril' => 4,
  11949. 'mayo' => 5,
  11950. 'junio' => 6,
  11951. 'julio' => 7,
  11952. 'agosto' => 8,
  11953. 'septiembre' => 9,
  11954. 'setiembre' => 9,
  11955. 'octubre' => 10,
  11956. 'noviembre' => 11,
  11957. 'diciembre' => 12,
  11958. // Finnish
  11959. 'tammikuu' => 1,
  11960. 'helmikuu' => 2,
  11961. 'maaliskuu' => 3,
  11962. 'huhtikuu' => 4,
  11963. 'toukokuu' => 5,
  11964. 'kesäkuu' => 6,
  11965. 'heinäkuu' => 7,
  11966. 'elokuu' => 8,
  11967. 'suuskuu' => 9,
  11968. 'lokakuu' => 10,
  11969. 'marras' => 11,
  11970. 'joulukuu' => 12,
  11971. // Hungarian
  11972. 'január' => 1,
  11973. 'február' => 2,
  11974. 'március' => 3,
  11975. 'április' => 4,
  11976. 'május' => 5,
  11977. 'június' => 6,
  11978. 'július' => 7,
  11979. 'augusztus' => 8,
  11980. 'szeptember' => 9,
  11981. 'október' => 10,
  11982. 'november' => 11,
  11983. 'december' => 12,
  11984. // Greek
  11985. 'Ιαν' => 1,
  11986. 'Φεβ' => 2,
  11987. 'Μάώ' => 3,
  11988. 'Μαώ' => 3,
  11989. 'Απρ' => 4,
  11990. 'Μάι' => 5,
  11991. 'Μαϊ' => 5,
  11992. 'Μαι' => 5,
  11993. 'Ιούν' => 6,
  11994. 'Ιον' => 6,
  11995. 'Ιούλ' => 7,
  11996. 'Ιολ' => 7,
  11997. 'Αύγ' => 8,
  11998. 'Αυγ' => 8,
  11999. 'Σεπ' => 9,
  12000. 'Οκτ' => 10,
  12001. 'Νοέ' => 11,
  12002. 'Δεκ' => 12,
  12003. );
  12004. /**
  12005. * List of timezones, abbreviation => offset from UTC
  12006. *
  12007. * @access protected
  12008. * @var array
  12009. */
  12010. var $timezone = array(
  12011. 'ACDT' => 37800,
  12012. 'ACIT' => 28800,
  12013. 'ACST' => 34200,
  12014. 'ACT' => -18000,
  12015. 'ACWDT' => 35100,
  12016. 'ACWST' => 31500,
  12017. 'AEDT' => 39600,
  12018. 'AEST' => 36000,
  12019. 'AFT' => 16200,
  12020. 'AKDT' => -28800,
  12021. 'AKST' => -32400,
  12022. 'AMDT' => 18000,
  12023. 'AMT' => -14400,
  12024. 'ANAST' => 46800,
  12025. 'ANAT' => 43200,
  12026. 'ART' => -10800,
  12027. 'AZOST' => -3600,
  12028. 'AZST' => 18000,
  12029. 'AZT' => 14400,
  12030. 'BIOT' => 21600,
  12031. 'BIT' => -43200,
  12032. 'BOT' => -14400,
  12033. 'BRST' => -7200,
  12034. 'BRT' => -10800,
  12035. 'BST' => 3600,
  12036. 'BTT' => 21600,
  12037. 'CAST' => 18000,
  12038. 'CAT' => 7200,
  12039. 'CCT' => 23400,
  12040. 'CDT' => -18000,
  12041. 'CEDT' => 7200,
  12042. 'CET' => 3600,
  12043. 'CGST' => -7200,
  12044. 'CGT' => -10800,
  12045. 'CHADT' => 49500,
  12046. 'CHAST' => 45900,
  12047. 'CIST' => -28800,
  12048. 'CKT' => -36000,
  12049. 'CLDT' => -10800,
  12050. 'CLST' => -14400,
  12051. 'COT' => -18000,
  12052. 'CST' => -21600,
  12053. 'CVT' => -3600,
  12054. 'CXT' => 25200,
  12055. 'DAVT' => 25200,
  12056. 'DTAT' => 36000,
  12057. 'EADT' => -18000,
  12058. 'EAST' => -21600,
  12059. 'EAT' => 10800,
  12060. 'ECT' => -18000,
  12061. 'EDT' => -14400,
  12062. 'EEST' => 10800,
  12063. 'EET' => 7200,
  12064. 'EGT' => -3600,
  12065. 'EKST' => 21600,
  12066. 'EST' => -18000,
  12067. 'FJT' => 43200,
  12068. 'FKDT' => -10800,
  12069. 'FKST' => -14400,
  12070. 'FNT' => -7200,
  12071. 'GALT' => -21600,
  12072. 'GEDT' => 14400,
  12073. 'GEST' => 10800,
  12074. 'GFT' => -10800,
  12075. 'GILT' => 43200,
  12076. 'GIT' => -32400,
  12077. 'GST' => 14400,
  12078. 'GST' => -7200,
  12079. 'GYT' => -14400,
  12080. 'HAA' => -10800,
  12081. 'HAC' => -18000,
  12082. 'HADT' => -32400,
  12083. 'HAE' => -14400,
  12084. 'HAP' => -25200,
  12085. 'HAR' => -21600,
  12086. 'HAST' => -36000,
  12087. 'HAT' => -9000,
  12088. 'HAY' => -28800,
  12089. 'HKST' => 28800,
  12090. 'HMT' => 18000,
  12091. 'HNA' => -14400,
  12092. 'HNC' => -21600,
  12093. 'HNE' => -18000,
  12094. 'HNP' => -28800,
  12095. 'HNR' => -25200,
  12096. 'HNT' => -12600,
  12097. 'HNY' => -32400,
  12098. 'IRDT' => 16200,
  12099. 'IRKST' => 32400,
  12100. 'IRKT' => 28800,
  12101. 'IRST' => 12600,
  12102. 'JFDT' => -10800,
  12103. 'JFST' => -14400,
  12104. 'JST' => 32400,
  12105. 'KGST' => 21600,
  12106. 'KGT' => 18000,
  12107. 'KOST' => 39600,
  12108. 'KOVST' => 28800,
  12109. 'KOVT' => 25200,
  12110. 'KRAST' => 28800,
  12111. 'KRAT' => 25200,
  12112. 'KST' => 32400,
  12113. 'LHDT' => 39600,
  12114. 'LHST' => 37800,
  12115. 'LINT' => 50400,
  12116. 'LKT' => 21600,
  12117. 'MAGST' => 43200,
  12118. 'MAGT' => 39600,
  12119. 'MAWT' => 21600,
  12120. 'MDT' => -21600,
  12121. 'MESZ' => 7200,
  12122. 'MEZ' => 3600,
  12123. 'MHT' => 43200,
  12124. 'MIT' => -34200,
  12125. 'MNST' => 32400,
  12126. 'MSDT' => 14400,
  12127. 'MSST' => 10800,
  12128. 'MST' => -25200,
  12129. 'MUT' => 14400,
  12130. 'MVT' => 18000,
  12131. 'MYT' => 28800,
  12132. 'NCT' => 39600,
  12133. 'NDT' => -9000,
  12134. 'NFT' => 41400,
  12135. 'NMIT' => 36000,
  12136. 'NOVST' => 25200,
  12137. 'NOVT' => 21600,
  12138. 'NPT' => 20700,
  12139. 'NRT' => 43200,
  12140. 'NST' => -12600,
  12141. 'NUT' => -39600,
  12142. 'NZDT' => 46800,
  12143. 'NZST' => 43200,
  12144. 'OMSST' => 25200,
  12145. 'OMST' => 21600,
  12146. 'PDT' => -25200,
  12147. 'PET' => -18000,
  12148. 'PETST' => 46800,
  12149. 'PETT' => 43200,
  12150. 'PGT' => 36000,
  12151. 'PHOT' => 46800,
  12152. 'PHT' => 28800,
  12153. 'PKT' => 18000,
  12154. 'PMDT' => -7200,
  12155. 'PMST' => -10800,
  12156. 'PONT' => 39600,
  12157. 'PST' => -28800,
  12158. 'PWT' => 32400,
  12159. 'PYST' => -10800,
  12160. 'PYT' => -14400,
  12161. 'RET' => 14400,
  12162. 'ROTT' => -10800,
  12163. 'SAMST' => 18000,
  12164. 'SAMT' => 14400,
  12165. 'SAST' => 7200,
  12166. 'SBT' => 39600,
  12167. 'SCDT' => 46800,
  12168. 'SCST' => 43200,
  12169. 'SCT' => 14400,
  12170. 'SEST' => 3600,
  12171. 'SGT' => 28800,
  12172. 'SIT' => 28800,
  12173. 'SRT' => -10800,
  12174. 'SST' => -39600,
  12175. 'SYST' => 10800,
  12176. 'SYT' => 7200,
  12177. 'TFT' => 18000,
  12178. 'THAT' => -36000,
  12179. 'TJT' => 18000,
  12180. 'TKT' => -36000,
  12181. 'TMT' => 18000,
  12182. 'TOT' => 46800,
  12183. 'TPT' => 32400,
  12184. 'TRUT' => 36000,
  12185. 'TVT' => 43200,
  12186. 'TWT' => 28800,
  12187. 'UYST' => -7200,
  12188. 'UYT' => -10800,
  12189. 'UZT' => 18000,
  12190. 'VET' => -14400,
  12191. 'VLAST' => 39600,
  12192. 'VLAT' => 36000,
  12193. 'VOST' => 21600,
  12194. 'VUT' => 39600,
  12195. 'WAST' => 7200,
  12196. 'WAT' => 3600,
  12197. 'WDT' => 32400,
  12198. 'WEST' => 3600,
  12199. 'WFT' => 43200,
  12200. 'WIB' => 25200,
  12201. 'WIT' => 32400,
  12202. 'WITA' => 28800,
  12203. 'WKST' => 18000,
  12204. 'WST' => 28800,
  12205. 'YAKST' => 36000,
  12206. 'YAKT' => 32400,
  12207. 'YAPT' => 36000,
  12208. 'YEKST' => 21600,
  12209. 'YEKT' => 18000,
  12210. );
  12211. /**
  12212. * Cached PCRE for SimplePie_Parse_Date::$day
  12213. *
  12214. * @access protected
  12215. * @var string
  12216. */
  12217. var $day_pcre;
  12218. /**
  12219. * Cached PCRE for SimplePie_Parse_Date::$month
  12220. *
  12221. * @access protected
  12222. * @var string
  12223. */
  12224. var $month_pcre;
  12225. /**
  12226. * Array of user-added callback methods
  12227. *
  12228. * @access private
  12229. * @var array
  12230. */
  12231. var $built_in = array();
  12232. /**
  12233. * Array of user-added callback methods
  12234. *
  12235. * @access private
  12236. * @var array
  12237. */
  12238. var $user = array();
  12239. /**
  12240. * Create new SimplePie_Parse_Date object, and set self::day_pcre,
  12241. * self::month_pcre, and self::built_in
  12242. *
  12243. * @access private
  12244. */
  12245. function SimplePie_Parse_Date()
  12246. {
  12247. $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
  12248. $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
  12249. static $cache;
  12250. if (!isset($cache[get_class($this)]))
  12251. {
  12252. $all_methods = get_class_methods($this);
  12253. foreach ($all_methods as $method)
  12254. {
  12255. if (strtolower(substr($method, 0, 5)) === 'date_')
  12256. {
  12257. $cache[get_class($this)][] = $method;
  12258. }
  12259. }
  12260. }
  12261. foreach ($cache[get_class($this)] as $method)
  12262. {
  12263. $this->built_in[] = $method;
  12264. }
  12265. }
  12266. /**
  12267. * Get the object
  12268. *
  12269. * @access public
  12270. */
  12271. function get()
  12272. {
  12273. static $object;
  12274. if (!$object)
  12275. {
  12276. $object =& new SimplePie_Parse_Date;
  12277. }
  12278. return $object;
  12279. }
  12280. /**
  12281. * Parse a date
  12282. *
  12283. * @final
  12284. * @access public
  12285. * @param string $date Date to parse
  12286. * @return int Timestamp corresponding to date string, or false on failure
  12287. */
  12288. function parse($date)
  12289. {
  12290. foreach ($this->user as $method)
  12291. {
  12292. if (($returned = call_user_func($method, $date)) !== false)
  12293. {
  12294. return $returned;
  12295. }
  12296. }
  12297. foreach ($this->built_in as $method)
  12298. {
  12299. if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
  12300. {
  12301. return $returned;
  12302. }
  12303. }
  12304. return false;
  12305. }
  12306. /**
  12307. * Add a callback method to parse a date
  12308. *
  12309. * @final
  12310. * @access public
  12311. * @param callback $callback
  12312. */
  12313. function add_callback($callback)
  12314. {
  12315. if (is_callable($callback))
  12316. {
  12317. $this->user[] = $callback;
  12318. }
  12319. else
  12320. {
  12321. trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
  12322. }
  12323. }
  12324. /**
  12325. * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
  12326. * well as allowing any of upper or lower case "T", horizontal tabs, or
  12327. * spaces to be used as the time seperator (including more than one))
  12328. *
  12329. * @access protected
  12330. * @return int Timestamp
  12331. */
  12332. function date_w3cdtf($date)
  12333. {
  12334. static $pcre;
  12335. if (!$pcre)
  12336. {
  12337. $year = '([0-9]{4})';
  12338. $month = $day = $hour = $minute = $second = '([0-9]{2})';
  12339. $decimal = '([0-9]*)';
  12340. $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
  12341. $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
  12342. }
  12343. if (preg_match($pcre, $date, $match))
  12344. {
  12345. /*
  12346. Capturing subpatterns:
  12347. 1: Year
  12348. 2: Month
  12349. 3: Day
  12350. 4: Hour
  12351. 5: Minute
  12352. 6: Second
  12353. 7: Decimal fraction of a second
  12354. 8: Zulu
  12355. 9: Timezone ±
  12356. 10: Timezone hours
  12357. 11: Timezone minutes
  12358. */
  12359. // Fill in empty matches
  12360. for ($i = count($match); $i <= 3; $i++)
  12361. {
  12362. $match[$i] = '1';
  12363. }
  12364. for ($i = count($match); $i <= 7; $i++)
  12365. {
  12366. $match[$i] = '0';
  12367. }
  12368. // Numeric timezone
  12369. if (isset($match[9]) && $match[9] !== '')
  12370. {
  12371. $timezone = $match[10] * 3600;
  12372. $timezone += $match[11] * 60;
  12373. if ($match[9] === '-')
  12374. {
  12375. $timezone = 0 - $timezone;
  12376. }
  12377. }
  12378. else
  12379. {
  12380. $timezone = 0;
  12381. }
  12382. // Convert the number of seconds to an integer, taking decimals into account
  12383. $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
  12384. return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
  12385. }
  12386. else
  12387. {
  12388. return false;
  12389. }
  12390. }
  12391. /**
  12392. * Remove RFC822 comments
  12393. *
  12394. * @access protected
  12395. * @param string $data Data to strip comments from
  12396. * @return string Comment stripped string
  12397. */
  12398. function remove_rfc2822_comments($string)
  12399. {
  12400. $string = (string) $string;
  12401. $position = 0;
  12402. $length = strlen($string);
  12403. $depth = 0;
  12404. $output = '';
  12405. while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
  12406. {
  12407. $output .= substr($string, $position, $pos - $position);
  12408. $position = $pos + 1;
  12409. if ($string[$pos - 1] !== '\\')
  12410. {
  12411. $depth++;
  12412. while ($depth && $position < $length)
  12413. {
  12414. $position += strcspn($string, '()', $position);
  12415. if ($string[$position - 1] === '\\')
  12416. {
  12417. $position++;
  12418. continue;
  12419. }
  12420. elseif (isset($string[$position]))
  12421. {
  12422. switch ($string[$position])
  12423. {
  12424. case '(':
  12425. $depth++;
  12426. break;
  12427. case ')':
  12428. $depth--;
  12429. break;
  12430. }
  12431. $position++;
  12432. }
  12433. else
  12434. {
  12435. break;
  12436. }
  12437. }
  12438. }
  12439. else
  12440. {
  12441. $output .= '(';
  12442. }
  12443. }
  12444. $output .= substr($string, $position);
  12445. return $output;
  12446. }
  12447. /**
  12448. * Parse RFC2822's date format
  12449. *
  12450. * @access protected
  12451. * @return int Timestamp
  12452. */
  12453. function date_rfc2822($date)
  12454. {
  12455. static $pcre;
  12456. if (!$pcre)
  12457. {
  12458. $wsp = '[\x09\x20]';
  12459. $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
  12460. $optional_fws = $fws . '?';
  12461. $day_name = $this->day_pcre;
  12462. $month = $this->month_pcre;
  12463. $day = '([0-9]{1,2})';
  12464. $hour = $minute = $second = '([0-9]{2})';
  12465. $year = '([0-9]{2,4})';
  12466. $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
  12467. $character_zone = '([A-Z]{1,5})';
  12468. $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
  12469. $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';
  12470. }
  12471. if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
  12472. {
  12473. /*
  12474. Capturing subpatterns:
  12475. 1: Day name
  12476. 2: Day
  12477. 3: Month
  12478. 4: Year
  12479. 5: Hour
  12480. 6: Minute
  12481. 7: Second
  12482. 8: Timezone ±
  12483. 9: Timezone hours
  12484. 10: Timezone minutes
  12485. 11: Alphabetic timezone
  12486. */
  12487. // Find the month number
  12488. $month = $this->month[strtolower($match[3])];
  12489. // Numeric timezone
  12490. if ($match[8] !== '')
  12491. {
  12492. $timezone = $match[9] * 3600;
  12493. $timezone += $match[10] * 60;
  12494. if ($match[8] === '-')
  12495. {
  12496. $timezone = 0 - $timezone;
  12497. }
  12498. }
  12499. // Character timezone
  12500. elseif (isset($this->timezone[strtoupper($match[11])]))
  12501. {
  12502. $timezone = $this->timezone[strtoupper($match[11])];
  12503. }
  12504. // Assume everything else to be -0000
  12505. else
  12506. {
  12507. $timezone = 0;
  12508. }
  12509. // Deal with 2/3 digit years
  12510. if ($match[4] < 50)
  12511. {
  12512. $match[4] += 2000;
  12513. }
  12514. elseif ($match[4] < 1000)
  12515. {
  12516. $match[4] += 1900;
  12517. }
  12518. // Second is optional, if it is empty set it to zero
  12519. if ($match[7] !== '')
  12520. {
  12521. $second = $match[7];
  12522. }
  12523. else
  12524. {
  12525. $second = 0;
  12526. }
  12527. return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
  12528. }
  12529. else
  12530. {
  12531. return false;
  12532. }
  12533. }
  12534. /**
  12535. * Parse RFC850's date format
  12536. *
  12537. * @access protected
  12538. * @return int Timestamp
  12539. */
  12540. function date_rfc850($date)
  12541. {
  12542. static $pcre;
  12543. if (!$pcre)
  12544. {
  12545. $space = '[\x09\x20]+';
  12546. $day_name = $this->day_pcre;
  12547. $month = $this->month_pcre;
  12548. $day = '([0-9]{1,2})';
  12549. $year = $hour = $minute = $second = '([0-9]{2})';
  12550. $zone = '([A-Z]{1,5})';
  12551. $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
  12552. }
  12553. if (preg_match($pcre, $date, $match))
  12554. {
  12555. /*
  12556. Capturing subpatterns:
  12557. 1: Day name
  12558. 2: Day
  12559. 3: Month
  12560. 4: Year
  12561. 5: Hour
  12562. 6: Minute
  12563. 7: Second
  12564. 8: Timezone
  12565. */
  12566. // Month
  12567. $month = $this->month[strtolower($match[3])];
  12568. // Character timezone
  12569. if (isset($this->timezone[strtoupper($match[8])]))
  12570. {
  12571. $timezone = $this->timezone[strtoupper($match[8])];
  12572. }
  12573. // Assume everything else to be -0000
  12574. else
  12575. {
  12576. $timezone = 0;
  12577. }
  12578. // Deal with 2 digit year
  12579. if ($match[4] < 50)
  12580. {
  12581. $match[4] += 2000;
  12582. }
  12583. else
  12584. {
  12585. $match[4] += 1900;
  12586. }
  12587. return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
  12588. }
  12589. else
  12590. {
  12591. return false;
  12592. }
  12593. }
  12594. /**
  12595. * Parse C99's asctime()'s date format
  12596. *
  12597. * @access protected
  12598. * @return int Timestamp
  12599. */
  12600. function date_asctime($date)
  12601. {
  12602. static $pcre;
  12603. if (!$pcre)
  12604. {
  12605. $space = '[\x09\x20]+';
  12606. $wday_name = $this->day_pcre;
  12607. $mon_name = $this->month_pcre;
  12608. $day = '([0-9]{1,2})';
  12609. $hour = $sec = $min = '([0-9]{2})';
  12610. $year = '([0-9]{4})';
  12611. $terminator = '\x0A?\x00?';
  12612. $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
  12613. }
  12614. if (preg_match($pcre, $date, $match))
  12615. {
  12616. /*
  12617. Capturing subpatterns:
  12618. 1: Day name
  12619. 2: Month
  12620. 3: Day
  12621. 4: Hour
  12622. 5: Minute
  12623. 6: Second
  12624. 7: Year
  12625. */
  12626. $month = $this->month[strtolower($match[2])];
  12627. return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
  12628. }
  12629. else
  12630. {
  12631. return false;
  12632. }
  12633. }
  12634. /**
  12635. * Parse dates using strtotime()
  12636. *
  12637. * @access protected
  12638. * @return int Timestamp
  12639. */
  12640. function date_strtotime($date)
  12641. {
  12642. $strtotime = strtotime($date);
  12643. if ($strtotime === -1 || $strtotime === false)
  12644. {
  12645. return false;
  12646. }
  12647. else
  12648. {
  12649. return $strtotime;
  12650. }
  12651. }
  12652. }
  12653. /**
  12654. * Content-type sniffing
  12655. *
  12656. * @package SimplePie
  12657. */
  12658. class SimplePie_Content_Type_Sniffer
  12659. {
  12660. /**
  12661. * File object
  12662. *
  12663. * @var SimplePie_File
  12664. * @access private
  12665. */
  12666. var $file;
  12667. /**
  12668. * Create an instance of the class with the input file
  12669. *
  12670. * @access public
  12671. * @param SimplePie_Content_Type_Sniffer $file Input file
  12672. */
  12673. function SimplePie_Content_Type_Sniffer($file)
  12674. {
  12675. $this->file = $file;
  12676. }
  12677. /**
  12678. * Get the Content-Type of the specified file
  12679. *
  12680. * @access public
  12681. * @return string Actual Content-Type
  12682. */
  12683. function get_type()
  12684. {
  12685. if (isset($this->file->headers['content-type']))
  12686. {
  12687. if (!isset($this->file->headers['content-encoding'])
  12688. && ($this->file->headers['content-type'] === 'text/plain'
  12689. || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
  12690. || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
  12691. {
  12692. return $this->text_or_binary();
  12693. }
  12694. if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
  12695. {
  12696. $official = substr($this->file->headers['content-type'], 0, $pos);
  12697. }
  12698. else
  12699. {
  12700. $official = $this->file->headers['content-type'];
  12701. }
  12702. $official = strtolower($official);
  12703. if ($official === 'unknown/unknown'
  12704. || $official === 'application/unknown')
  12705. {
  12706. return $this->unknown();
  12707. }
  12708. elseif (substr($official, -4) === '+xml'
  12709. || $official === 'text/xml'
  12710. || $official === 'application/xml')
  12711. {
  12712. return $official;
  12713. }
  12714. elseif (substr($official, 0, 6) === 'image/')
  12715. {
  12716. if ($return = $this->image())
  12717. {
  12718. return $return;
  12719. }
  12720. else
  12721. {
  12722. return $official;
  12723. }
  12724. }
  12725. elseif ($official === 'text/html')
  12726. {
  12727. return $this->feed_or_html();
  12728. }
  12729. else
  12730. {
  12731. return $official;
  12732. }
  12733. }
  12734. else
  12735. {
  12736. return $this->unknown();
  12737. }
  12738. }
  12739. /**
  12740. * Sniff text or binary
  12741. *
  12742. * @access private
  12743. * @return string Actual Content-Type
  12744. */
  12745. function text_or_binary()
  12746. {
  12747. if (substr($this->file->body, 0, 2) === "\xFE\xFF"
  12748. || substr($this->file->body, 0, 2) === "\xFF\xFE"
  12749. || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
  12750. || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
  12751. {
  12752. return 'text/plain';
  12753. }
  12754. elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
  12755. {
  12756. return 'application/octect-stream';
  12757. }
  12758. else
  12759. {
  12760. return 'text/plain';
  12761. }
  12762. }
  12763. /**
  12764. * Sniff unknown
  12765. *
  12766. * @access private
  12767. * @return string Actual Content-Type
  12768. */
  12769. function unknown()
  12770. {
  12771. $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
  12772. if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
  12773. || strtolower(substr($this->file->body, $ws, 5)) === '<html'
  12774. || strtolower(substr($this->file->body, $ws, 7)) === '<script')
  12775. {
  12776. return 'text/html';
  12777. }
  12778. elseif (substr($this->file->body, 0, 5) === '%PDF-')
  12779. {
  12780. return 'application/pdf';
  12781. }
  12782. elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
  12783. {
  12784. return 'application/postscript';
  12785. }
  12786. elseif (substr($this->file->body, 0, 6) === 'GIF87a'
  12787. || substr($this->file->body, 0, 6) === 'GIF89a')
  12788. {
  12789. return 'image/gif';
  12790. }
  12791. elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
  12792. {
  12793. return 'image/png';
  12794. }
  12795. elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
  12796. {
  12797. return 'image/jpeg';
  12798. }
  12799. elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
  12800. {
  12801. return 'image/bmp';
  12802. }
  12803. else
  12804. {
  12805. return $this->text_or_binary();
  12806. }
  12807. }
  12808. /**
  12809. * Sniff images
  12810. *
  12811. * @access private
  12812. * @return string Actual Content-Type
  12813. */
  12814. function image()
  12815. {
  12816. if (substr($this->file->body, 0, 6) === 'GIF87a'
  12817. || substr($this->file->body, 0, 6) === 'GIF89a')
  12818. {
  12819. return 'image/gif';
  12820. }
  12821. elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
  12822. {
  12823. return 'image/png';
  12824. }
  12825. elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
  12826. {
  12827. return 'image/jpeg';
  12828. }
  12829. elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
  12830. {
  12831. return 'image/bmp';
  12832. }
  12833. else
  12834. {
  12835. return false;
  12836. }
  12837. }
  12838. /**
  12839. * Sniff HTML
  12840. *
  12841. * @access private
  12842. * @return string Actual Content-Type
  12843. */
  12844. function feed_or_html()
  12845. {
  12846. $len = strlen($this->file->body);
  12847. $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
  12848. while ($pos < $len)
  12849. {
  12850. switch ($this->file->body[$pos])
  12851. {
  12852. case "\x09":
  12853. case "\x0A":
  12854. case "\x0D":
  12855. case "\x20":
  12856. $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
  12857. continue 2;
  12858. case '<':
  12859. $pos++;
  12860. break;
  12861. default:
  12862. return 'text/html';
  12863. }
  12864. if (substr($this->file->body, $pos, 3) === '!--')
  12865. {
  12866. $pos += 3;
  12867. if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
  12868. {
  12869. $pos += 3;
  12870. }
  12871. else
  12872. {
  12873. return 'text/html';
  12874. }
  12875. }
  12876. elseif (substr($this->file->body, $pos, 1) === '!')
  12877. {
  12878. if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
  12879. {
  12880. $pos++;
  12881. }
  12882. else
  12883. {
  12884. return 'text/html';
  12885. }
  12886. }
  12887. elseif (substr($this->file->body, $pos, 1) === '?')
  12888. {
  12889. if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
  12890. {
  12891. $pos += 2;
  12892. }
  12893. else
  12894. {
  12895. return 'text/html';
  12896. }
  12897. }
  12898. elseif (substr($this->file->body, $pos, 3) === 'rss'
  12899. || substr($this->file->body, $pos, 7) === 'rdf:RDF')
  12900. {
  12901. return 'application/rss+xml';
  12902. }
  12903. elseif (substr($this->file->body, $pos, 4) === 'feed')
  12904. {
  12905. return 'application/atom+xml';
  12906. }
  12907. else
  12908. {
  12909. return 'text/html';
  12910. }
  12911. }
  12912. return 'text/html';
  12913. }
  12914. }
  12915. /**
  12916. * Parses the XML Declaration
  12917. *
  12918. * @package SimplePie
  12919. */
  12920. class SimplePie_XML_Declaration_Parser
  12921. {
  12922. /**
  12923. * XML Version
  12924. *
  12925. * @access public
  12926. * @var string
  12927. */
  12928. var $version = '1.0';
  12929. /**
  12930. * Encoding
  12931. *
  12932. * @access public
  12933. * @var string
  12934. */
  12935. var $encoding = 'UTF-8';
  12936. /**
  12937. * Standalone
  12938. *
  12939. * @access public
  12940. * @var bool
  12941. */
  12942. var $standalone = false;
  12943. /**
  12944. * Current state of the state machine
  12945. *
  12946. * @access private
  12947. * @var string
  12948. */
  12949. var $state = 'before_version_name';
  12950. /**
  12951. * Input data
  12952. *
  12953. * @access private
  12954. * @var string
  12955. */
  12956. var $data = '';
  12957. /**
  12958. * Input data length (to avoid calling strlen() everytime this is needed)
  12959. *
  12960. * @access private
  12961. * @var int
  12962. */
  12963. var $data_length = 0;
  12964. /**
  12965. * Current position of the pointer
  12966. *
  12967. * @var int
  12968. * @access private
  12969. */
  12970. var $position = 0;
  12971. /**
  12972. * Create an instance of the class with the input data
  12973. *
  12974. * @access public
  12975. * @param string $data Input data
  12976. */
  12977. function SimplePie_XML_Declaration_Parser($data)
  12978. {
  12979. $this->data = $data;
  12980. $this->data_length = strlen($this->data);
  12981. }
  12982. /**
  12983. * Parse the input data
  12984. *
  12985. * @access public
  12986. * @return bool true on success, false on failure
  12987. */
  12988. function parse()
  12989. {
  12990. while ($this->state && $this->state !== 'emit' && $this->has_data())
  12991. {
  12992. $state = $this->state;
  12993. $this->$state();
  12994. }
  12995. $this->data = '';
  12996. if ($this->state === 'emit')
  12997. {
  12998. return true;
  12999. }
  13000. else
  13001. {
  13002. $this->version = '';
  13003. $this->encoding = '';
  13004. $this->standalone = '';
  13005. return false;
  13006. }
  13007. }
  13008. /**
  13009. * Check whether there is data beyond the pointer
  13010. *
  13011. * @access private
  13012. * @return bool true if there is further data, false if not
  13013. */
  13014. function has_data()
  13015. {
  13016. return (bool) ($this->position < $this->data_length);
  13017. }
  13018. /**
  13019. * Advance past any whitespace
  13020. *
  13021. * @return int Number of whitespace characters passed
  13022. */
  13023. function skip_whitespace()
  13024. {
  13025. $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
  13026. $this->position += $whitespace;
  13027. return $whitespace;
  13028. }
  13029. /**
  13030. * Read value
  13031. */
  13032. function get_value()
  13033. {
  13034. $quote = substr($this->data, $this->position, 1);
  13035. if ($quote === '"' || $quote === "'")
  13036. {
  13037. $this->position++;
  13038. $len = strcspn($this->data, $quote, $this->position);
  13039. if ($this->has_data())
  13040. {
  13041. $value = substr($this->data, $this->position, $len);
  13042. $this->position += $len + 1;
  13043. return $value;
  13044. }
  13045. }
  13046. return false;
  13047. }
  13048. function before_version_name()
  13049. {
  13050. if ($this->skip_whitespace())
  13051. {
  13052. $this->state = 'version_name';
  13053. }
  13054. else
  13055. {
  13056. $this->state = false;
  13057. }
  13058. }
  13059. function version_name()
  13060. {
  13061. if (substr($this->data, $this->position, 7) === 'version')
  13062. {
  13063. $this->position += 7;
  13064. $this->skip_whitespace();
  13065. $this->state = 'version_equals';
  13066. }
  13067. else
  13068. {
  13069. $this->state = false;
  13070. }
  13071. }
  13072. function version_equals()
  13073. {
  13074. if (substr($this->data, $this->position, 1) === '=')
  13075. {
  13076. $this->position++;
  13077. $this->skip_whitespace();
  13078. $this->state = 'version_value';
  13079. }
  13080. else
  13081. {
  13082. $this->state = false;
  13083. }
  13084. }
  13085. function version_value()
  13086. {
  13087. if ($this->version = $this->get_value())
  13088. {
  13089. $this->skip_whitespace();
  13090. if ($this->has_data())
  13091. {
  13092. $this->state = 'encoding_name';
  13093. }
  13094. else
  13095. {
  13096. $this->state = 'emit';
  13097. }
  13098. }
  13099. else
  13100. {
  13101. $this->state = false;
  13102. }
  13103. }
  13104. function encoding_name()
  13105. {
  13106. if (substr($this->data, $this->position, 8) === 'encoding')
  13107. {
  13108. $this->position += 8;
  13109. $this->skip_whitespace();
  13110. $this->state = 'encoding_equals';
  13111. }
  13112. else
  13113. {
  13114. $this->state = 'standalone_name';
  13115. }
  13116. }
  13117. function encoding_equals()
  13118. {
  13119. if (substr($this->data, $this->position, 1) === '=')
  13120. {
  13121. $this->position++;
  13122. $this->skip_whitespace();
  13123. $this->state = 'encoding_value';
  13124. }
  13125. else
  13126. {
  13127. $this->state = false;
  13128. }
  13129. }
  13130. function encoding_value()
  13131. {
  13132. if ($this->encoding = $this->get_value())
  13133. {
  13134. $this->skip_whitespace();
  13135. if ($this->has_data())
  13136. {
  13137. $this->state = 'standalone_name';
  13138. }
  13139. else
  13140. {
  13141. $this->state = 'emit';
  13142. }
  13143. }
  13144. else
  13145. {
  13146. $this->state = false;
  13147. }
  13148. }
  13149. function standalone_name()
  13150. {
  13151. if (substr($this->data, $this->position, 10) === 'standalone')
  13152. {
  13153. $this->position += 10;
  13154. $this->skip_whitespace();
  13155. $this->state = 'standalone_equals';
  13156. }
  13157. else
  13158. {
  13159. $this->state = false;
  13160. }
  13161. }
  13162. function standalone_equals()
  13163. {
  13164. if (substr($this->data, $this->position, 1) === '=')
  13165. {
  13166. $this->position++;
  13167. $this->skip_whitespace();
  13168. $this->state = 'standalone_value';
  13169. }
  13170. else
  13171. {
  13172. $this->state = false;
  13173. }
  13174. }
  13175. function standalone_value()
  13176. {
  13177. if ($standalone = $this->get_value())
  13178. {
  13179. switch ($standalone)
  13180. {
  13181. case 'yes':
  13182. $this->standalone = true;
  13183. break;
  13184. case 'no':
  13185. $this->standalone = false;
  13186. break;
  13187. default:
  13188. $this->state = false;
  13189. return;
  13190. }
  13191. $this->skip_whitespace();
  13192. if ($this->has_data())
  13193. {
  13194. $this->state = false;
  13195. }
  13196. else
  13197. {
  13198. $this->state = 'emit';
  13199. }
  13200. }
  13201. else
  13202. {
  13203. $this->state = false;
  13204. }
  13205. }
  13206. }
  13207. class SimplePie_Locator
  13208. {
  13209. var $useragent;
  13210. var $timeout;
  13211. var $file;
  13212. var $local = array();
  13213. var $elsewhere = array();
  13214. var $file_class = 'SimplePie_File';
  13215. var $cached_entities = array();
  13216. var $http_base;
  13217. var $base;
  13218. var $base_location = 0;
  13219. var $checked_feeds = 0;
  13220. var $max_checked_feeds = 10;
  13221. var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
  13222. function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
  13223. {
  13224. $this->file =& $file;
  13225. $this->file_class = $file_class;
  13226. $this->useragent = $useragent;
  13227. $this->timeout = $timeout;
  13228. $this->max_checked_feeds = $max_checked_feeds;
  13229. $this->content_type_sniffer_class = $content_type_sniffer_class;
  13230. }
  13231. function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
  13232. {
  13233. if ($this->is_feed($this->file))
  13234. {
  13235. return $this->file;
  13236. }
  13237. if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
  13238. {
  13239. $sniffer =& new $this->content_type_sniffer_class($this->file);
  13240. if ($sniffer->get_type() !== 'text/html')
  13241. {
  13242. return null;
  13243. }
  13244. }
  13245. if ($type & ~SIMPLEPIE_LOCATOR_NONE)
  13246. {
  13247. $this->get_base();
  13248. }
  13249. if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
  13250. {
  13251. return $working[0];
  13252. }
  13253. if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
  13254. {
  13255. if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
  13256. {
  13257. return $working;
  13258. }
  13259. if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
  13260. {
  13261. return $working;
  13262. }
  13263. if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
  13264. {
  13265. return $working;
  13266. }
  13267. if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
  13268. {
  13269. return $working;
  13270. }
  13271. }
  13272. return null;
  13273. }
  13274. function is_feed(&$file)
  13275. {
  13276. if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
  13277. {
  13278. $sniffer =& new $this->content_type_sniffer_class($file);
  13279. $sniffed = $sniffer->get_type();
  13280. if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
  13281. {
  13282. return true;
  13283. }
  13284. else
  13285. {
  13286. return false;
  13287. }
  13288. }
  13289. elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
  13290. {
  13291. return true;
  13292. }
  13293. else
  13294. {
  13295. return false;
  13296. }
  13297. }
  13298. function get_base()
  13299. {
  13300. $this->http_base = $this->file->url;
  13301. $this->base = $this->http_base;
  13302. $elements = SimplePie_Misc::get_element('base', $this->file->body);
  13303. foreach ($elements as $element)
  13304. {
  13305. if ($element['attribs']['href']['data'] !== '')
  13306. {
  13307. $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
  13308. $this->base_location = $element['offset'];
  13309. break;
  13310. }
  13311. }
  13312. }
  13313. function autodiscovery()
  13314. {
  13315. $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));
  13316. $done = array();
  13317. $feeds = array();
  13318. foreach ($links as $link)
  13319. {
  13320. if ($this->checked_feeds === $this->max_checked_feeds)
  13321. {
  13322. break;
  13323. }
  13324. if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
  13325. {
  13326. $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
  13327. if ($this->base_location < $link['offset'])
  13328. {
  13329. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
  13330. }
  13331. else
  13332. {
  13333. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
  13334. }
  13335. if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href]))
  13336. {
  13337. $this->checked_feeds++;
  13338. $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
  13339. if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
  13340. {
  13341. $feeds[$href] = $feed;
  13342. }
  13343. }
  13344. $done[] = $href;
  13345. }
  13346. }
  13347. if (!empty($feeds))
  13348. {
  13349. return array_values($feeds);
  13350. }
  13351. else {
  13352. return null;
  13353. }
  13354. }
  13355. function get_links()
  13356. {
  13357. $links = SimplePie_Misc::get_element('a', $this->file->body);
  13358. foreach ($links as $link)
  13359. {
  13360. if (isset($link['attribs']['href']['data']))
  13361. {
  13362. $href = trim($link['attribs']['href']['data']);
  13363. $parsed = SimplePie_Misc::parse_url($href);
  13364. if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
  13365. {
  13366. if ($this->base_location < $link['offset'])
  13367. {
  13368. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
  13369. }
  13370. else
  13371. {
  13372. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
  13373. }
  13374. $current = SimplePie_Misc::parse_url($this->file->url);
  13375. if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
  13376. {
  13377. $this->local[] = $href;
  13378. }
  13379. else
  13380. {
  13381. $this->elsewhere[] = $href;
  13382. }
  13383. }
  13384. }
  13385. }
  13386. $this->local = array_unique($this->local);
  13387. $this->elsewhere = array_unique($this->elsewhere);
  13388. if (!empty($this->local) || !empty($this->elsewhere))
  13389. {
  13390. return true;
  13391. }
  13392. return null;
  13393. }
  13394. function extension(&$array)
  13395. {
  13396. foreach ($array as $key => $value)
  13397. {
  13398. if ($this->checked_feeds === $this->max_checked_feeds)
  13399. {
  13400. break;
  13401. }
  13402. if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
  13403. {
  13404. $this->checked_feeds++;
  13405. $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
  13406. if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
  13407. {
  13408. return $feed;
  13409. }
  13410. else
  13411. {
  13412. unset($array[$key]);
  13413. }
  13414. }
  13415. }
  13416. return null;
  13417. }
  13418. function body(&$array)
  13419. {
  13420. foreach ($array as $key => $value)
  13421. {
  13422. if ($this->checked_feeds === $this->max_checked_feeds)
  13423. {
  13424. break;
  13425. }
  13426. if (preg_match('/(rss|rdf|atom|xml)/i', $value))
  13427. {
  13428. $this->checked_feeds++;
  13429. $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
  13430. if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
  13431. {
  13432. return $feed;
  13433. }
  13434. else
  13435. {
  13436. unset($array[$key]);
  13437. }
  13438. }
  13439. }
  13440. return null;
  13441. }
  13442. }
  13443. class SimplePie_Parser
  13444. {
  13445. var $error_code;
  13446. var $error_string;
  13447. var $current_line;
  13448. var $current_column;
  13449. var $current_byte;
  13450. var $separator = ' ';
  13451. var $namespace = array('');
  13452. var $element = array('');
  13453. var $xml_base = array('');
  13454. var $xml_base_explicit = array(false);
  13455. var $xml_lang = array('');
  13456. var $data = array();
  13457. var $datas = array(array());
  13458. var $current_xhtml_construct = -1;
  13459. var $encoding;
  13460. function parse(&$data, $encoding)
  13461. {
  13462. // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
  13463. if (strtoupper($encoding) === 'US-ASCII')
  13464. {
  13465. $this->encoding = 'UTF-8';
  13466. }
  13467. else
  13468. {
  13469. $this->encoding = $encoding;
  13470. }
  13471. // Strip BOM:
  13472. // UTF-32 Big Endian BOM
  13473. if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
  13474. {
  13475. $data = substr($data, 4);
  13476. }
  13477. // UTF-32 Little Endian BOM
  13478. elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
  13479. {
  13480. $data = substr($data, 4);
  13481. }
  13482. // UTF-16 Big Endian BOM
  13483. elseif (substr($data, 0, 2) === "\xFE\xFF")
  13484. {
  13485. $data = substr($data, 2);
  13486. }
  13487. // UTF-16 Little Endian BOM
  13488. elseif (substr($data, 0, 2) === "\xFF\xFE")
  13489. {
  13490. $data = substr($data, 2);
  13491. }
  13492. // UTF-8 BOM
  13493. elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
  13494. {
  13495. $data = substr($data, 3);
  13496. }
  13497. if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
  13498. {
  13499. $declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
  13500. if ($declaration->parse())
  13501. {
  13502. $data = substr($data, $pos + 2);
  13503. $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
  13504. }
  13505. else
  13506. {
  13507. $this->error_string = 'SimplePie bug! Please report this!';
  13508. return false;
  13509. }
  13510. }
  13511. $return = true;
  13512. static $xml_is_sane = null;
  13513. if ($xml_is_sane === null)
  13514. {
  13515. $parser_check = xml_parser_create();
  13516. xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
  13517. xml_parser_free($parser_check);
  13518. $xml_is_sane = isset($values[0]['value']);
  13519. }
  13520. // Create the parser
  13521. if ($xml_is_sane)
  13522. {
  13523. $xml = xml_parser_create_ns($this->encoding, $this->separator);
  13524. xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
  13525. xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
  13526. xml_set_object($xml, $this);
  13527. xml_set_character_data_handler($xml, 'cdata');
  13528. xml_set_element_handler($xml, 'tag_open', 'tag_close');
  13529. // Parse!
  13530. if (!xml_parse($xml, $data, true))
  13531. {
  13532. $this->error_code = xml_get_error_code($xml);
  13533. $this->error_string = xml_error_string($this->error_code);
  13534. $return = false;
  13535. }
  13536. $this->current_line = xml_get_current_line_number($xml);
  13537. $this->current_column = xml_get_current_column_number($xml);
  13538. $this->current_byte = xml_get_current_byte_index($xml);
  13539. xml_parser_free($xml);
  13540. return $return;
  13541. }
  13542. else
  13543. {
  13544. libxml_clear_errors();
  13545. $xml =& new XMLReader();
  13546. $xml->xml($data);
  13547. while (@$xml->read())
  13548. {
  13549. switch ($xml->nodeType)
  13550. {
  13551. case constant('XMLReader::END_ELEMENT'):
  13552. if ($xml->namespaceURI !== '')
  13553. {
  13554. $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
  13555. }
  13556. else
  13557. {
  13558. $tagName = $xml->localName;
  13559. }
  13560. $this->tag_close(null, $tagName);
  13561. break;
  13562. case constant('XMLReader::ELEMENT'):
  13563. $empty = $xml->isEmptyElement;
  13564. if ($xml->namespaceURI !== '')
  13565. {
  13566. $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
  13567. }
  13568. else
  13569. {
  13570. $tagName = $xml->localName;
  13571. }
  13572. $attributes = array();
  13573. while ($xml->moveToNextAttribute())
  13574. {
  13575. if ($xml->namespaceURI !== '')
  13576. {
  13577. $attrName = $xml->namespaceURI . $this->separator . $xml->localName;
  13578. }
  13579. else
  13580. {
  13581. $attrName = $xml->localName;
  13582. }
  13583. $attributes[$attrName] = $xml->value;
  13584. }
  13585. $this->tag_open(null, $tagName, $attributes);
  13586. if ($empty)
  13587. {
  13588. $this->tag_close(null, $tagName);
  13589. }
  13590. break;
  13591. case constant('XMLReader::TEXT'):
  13592. case constant('XMLReader::CDATA'):
  13593. $this->cdata(null, $xml->value);
  13594. break;
  13595. }
  13596. }
  13597. if ($error = libxml_get_last_error())
  13598. {
  13599. $this->error_code = $error->code;
  13600. $this->error_string = $error->message;
  13601. $this->current_line = $error->line;
  13602. $this->current_column = $error->column;
  13603. return false;
  13604. }
  13605. else
  13606. {
  13607. return true;
  13608. }
  13609. }
  13610. }
  13611. function get_error_code()
  13612. {
  13613. return $this->error_code;
  13614. }
  13615. function get_error_string()
  13616. {
  13617. return $this->error_string;
  13618. }
  13619. function get_current_line()
  13620. {
  13621. return $this->current_line;
  13622. }
  13623. function get_current_column()
  13624. {
  13625. return $this->current_column;
  13626. }
  13627. function get_current_byte()
  13628. {
  13629. return $this->current_byte;
  13630. }
  13631. function get_data()
  13632. {
  13633. return $this->data;
  13634. }
  13635. function tag_open($parser, $tag, $attributes)
  13636. {
  13637. list($this->namespace[], $this->element[]) = $this->split_ns($tag);
  13638. $attribs = array();
  13639. foreach ($attributes as $name => $value)
  13640. {
  13641. list($attrib_namespace, $attribute) = $this->split_ns($name);
  13642. $attribs[$attrib_namespace][$attribute] = $value;
  13643. }
  13644. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
  13645. {
  13646. $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
  13647. $this->xml_base_explicit[] = true;
  13648. }
  13649. else
  13650. {
  13651. $this->xml_base[] = end($this->xml_base);
  13652. $this->xml_base_explicit[] = end($this->xml_base_explicit);
  13653. }
  13654. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
  13655. {
  13656. $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
  13657. }
  13658. else
  13659. {
  13660. $this->xml_lang[] = end($this->xml_lang);
  13661. }
  13662. if ($this->current_xhtml_construct >= 0)
  13663. {
  13664. $this->current_xhtml_construct++;
  13665. if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
  13666. {
  13667. $this->data['data'] .= '<' . end($this->element);
  13668. if (isset($attribs['']))
  13669. {
  13670. foreach ($attribs[''] as $name => $value)
  13671. {
  13672. $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
  13673. }
  13674. }
  13675. $this->data['data'] .= '>';
  13676. }
  13677. }
  13678. else
  13679. {
  13680. $this->datas[] =& $this->data;
  13681. $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
  13682. $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));
  13683. 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')
  13684. || (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'))
  13685. {
  13686. $this->current_xhtml_construct = 0;
  13687. }
  13688. }
  13689. }
  13690. function cdata($parser, $cdata)
  13691. {
  13692. if ($this->current_xhtml_construct >= 0)
  13693. {
  13694. $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
  13695. }
  13696. else
  13697. {
  13698. $this->data['data'] .= $cdata;
  13699. }
  13700. }
  13701. function tag_close($parser, $tag)
  13702. {
  13703. if ($this->current_xhtml_construct >= 0)
  13704. {
  13705. $this->current_xhtml_construct--;
  13706. 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')))
  13707. {
  13708. $this->data['data'] .= '</' . end($this->element) . '>';
  13709. }
  13710. }
  13711. if ($this->current_xhtml_construct === -1)
  13712. {
  13713. $this->data =& $this->datas[count($this->datas) - 1];
  13714. array_pop($this->datas);
  13715. }
  13716. array_pop($this->element);
  13717. array_pop($this->namespace);
  13718. array_pop($this->xml_base);
  13719. array_pop($this->xml_base_explicit);
  13720. array_pop($this->xml_lang);
  13721. }
  13722. function split_ns($string)
  13723. {
  13724. static $cache = array();
  13725. if (!isset($cache[$string]))
  13726. {
  13727. if ($pos = strpos($string, $this->separator))
  13728. {
  13729. static $separator_length;
  13730. if (!$separator_length)
  13731. {
  13732. $separator_length = strlen($this->separator);
  13733. }
  13734. $namespace = substr($string, 0, $pos);
  13735. $local_name = substr($string, $pos + $separator_length);
  13736. if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
  13737. {
  13738. $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
  13739. }
  13740. // Normalize the Media RSS namespaces
  13741. if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
  13742. {
  13743. $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
  13744. }
  13745. $cache[$string] = array($namespace, $local_name);
  13746. }
  13747. else
  13748. {
  13749. $cache[$string] = array('', $string);
  13750. }
  13751. }
  13752. return $cache[$string];
  13753. }
  13754. }
  13755. /**
  13756. * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags
  13757. */
  13758. class SimplePie_Sanitize
  13759. {
  13760. // Private vars
  13761. var $base;
  13762. // Options
  13763. var $remove_div = true;
  13764. var $image_handler = '';
  13765. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  13766. var $encode_instead_of_strip = false;
  13767. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  13768. var $strip_comments = false;
  13769. var $output_encoding = 'UTF-8';
  13770. var $enable_cache = true;
  13771. var $cache_location = './cache';
  13772. var $cache_name_function = 'md5';
  13773. var $cache_class = 'SimplePie_Cache';
  13774. var $file_class = 'SimplePie_File';
  13775. var $timeout = 10;
  13776. var $useragent = '';
  13777. var $force_fsockopen = false;
  13778. var $replace_url_attributes = array(
  13779. 'a' => 'href',
  13780. 'area' => 'href',
  13781. 'blockquote' => 'cite',
  13782. 'del' => 'cite',
  13783. 'form' => 'action',
  13784. 'img' => array('longdesc', 'src'),
  13785. 'input' => 'src',
  13786. 'ins' => 'cite',
  13787. 'q' => 'cite'
  13788. );
  13789. function remove_div($enable = true)
  13790. {
  13791. $this->remove_div = (bool) $enable;
  13792. }
  13793. function set_image_handler($page = false)
  13794. {
  13795. if ($page)
  13796. {
  13797. $this->image_handler = (string) $page;
  13798. }
  13799. else
  13800. {
  13801. $this->image_handler = false;
  13802. }
  13803. }
  13804. function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
  13805. {
  13806. if (isset($enable_cache))
  13807. {
  13808. $this->enable_cache = (bool) $enable_cache;
  13809. }
  13810. if ($cache_location)
  13811. {
  13812. $this->cache_location = (string) $cache_location;
  13813. }
  13814. if ($cache_name_function)
  13815. {
  13816. $this->cache_name_function = (string) $cache_name_function;
  13817. }
  13818. if ($cache_class)
  13819. {
  13820. $this->cache_class = (string) $cache_class;
  13821. }
  13822. }
  13823. function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
  13824. {
  13825. if ($file_class)
  13826. {
  13827. $this->file_class = (string) $file_class;
  13828. }
  13829. if ($timeout)
  13830. {
  13831. $this->timeout = (string) $timeout;
  13832. }
  13833. if ($useragent)
  13834. {
  13835. $this->useragent = (string) $useragent;
  13836. }
  13837. if ($force_fsockopen)
  13838. {
  13839. $this->force_fsockopen = (string) $force_fsockopen;
  13840. }
  13841. }
  13842. function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
  13843. {
  13844. if ($tags)
  13845. {
  13846. if (is_array($tags))
  13847. {
  13848. $this->strip_htmltags = $tags;
  13849. }
  13850. else
  13851. {
  13852. $this->strip_htmltags = explode(',', $tags);
  13853. }
  13854. }
  13855. else
  13856. {
  13857. $this->strip_htmltags = false;
  13858. }
  13859. }
  13860. function encode_instead_of_strip($encode = false)
  13861. {
  13862. $this->encode_instead_of_strip = (bool) $encode;
  13863. }
  13864. function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
  13865. {
  13866. if ($attribs)
  13867. {
  13868. if (is_array($attribs))
  13869. {
  13870. $this->strip_attributes = $attribs;
  13871. }
  13872. else
  13873. {
  13874. $this->strip_attributes = explode(',', $attribs);
  13875. }
  13876. }
  13877. else
  13878. {
  13879. $this->strip_attributes = false;
  13880. }
  13881. }
  13882. function strip_comments($strip = false)
  13883. {
  13884. $this->strip_comments = (bool) $strip;
  13885. }
  13886. function set_output_encoding($encoding = 'UTF-8')
  13887. {
  13888. $this->output_encoding = (string) $encoding;
  13889. }
  13890. /**
  13891. * Set element/attribute key/value pairs of HTML attributes
  13892. * containing URLs that need to be resolved relative to the feed
  13893. *
  13894. * @access public
  13895. * @since 1.0
  13896. * @param array $element_attribute Element/attribute key/value pairs
  13897. */
  13898. 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'))
  13899. {
  13900. $this->replace_url_attributes = (array) $element_attribute;
  13901. }
  13902. function sanitize($data, $type, $base = '')
  13903. {
  13904. $data = trim($data);
  13905. if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
  13906. {
  13907. if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
  13908. {
  13909. 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))
  13910. {
  13911. $type |= SIMPLEPIE_CONSTRUCT_HTML;
  13912. }
  13913. else
  13914. {
  13915. $type |= SIMPLEPIE_CONSTRUCT_TEXT;
  13916. }
  13917. }
  13918. if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
  13919. {
  13920. $data = base64_decode($data);
  13921. }
  13922. if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
  13923. {
  13924. if ($this->remove_div)
  13925. {
  13926. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
  13927. $data = preg_replace('/<\/div>$/', '', $data);
  13928. }
  13929. else
  13930. {
  13931. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
  13932. }
  13933. }
  13934. if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
  13935. {
  13936. // Strip comments
  13937. if ($this->strip_comments)
  13938. {
  13939. $data = SimplePie_Misc::strip_comments($data);
  13940. }
  13941. // Strip out HTML tags and attributes that might cause various security problems.
  13942. // Based on recommendations by Mark Pilgrim at:
  13943. // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
  13944. if ($this->strip_htmltags)
  13945. {
  13946. foreach ($this->strip_htmltags as $tag)
  13947. {
  13948. $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
  13949. while (preg_match($pcre, $data))
  13950. {
  13951. $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
  13952. }
  13953. }
  13954. }
  13955. if ($this->strip_attributes)
  13956. {
  13957. foreach ($this->strip_attributes as $attrib)
  13958. {
  13959. $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);
  13960. }
  13961. }
  13962. // Replace relative URLs
  13963. $this->base = $base;
  13964. foreach ($this->replace_url_attributes as $element => $attributes)
  13965. {
  13966. $data = $this->replace_urls($data, $element, $attributes);
  13967. }
  13968. // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
  13969. if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
  13970. {
  13971. $images = SimplePie_Misc::get_element('img', $data);
  13972. foreach ($images as $img)
  13973. {
  13974. if (isset($img['attribs']['src']['data']))
  13975. {
  13976. $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
  13977. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
  13978. if ($cache->load())
  13979. {
  13980. $img['attribs']['src']['data'] = $this->image_handler . $image_url;
  13981. $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
  13982. }
  13983. else
  13984. {
  13985. $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
  13986. $headers = $file->headers;
  13987. if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
  13988. {
  13989. if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  13990. {
  13991. $img['attribs']['src']['data'] = $this->image_handler . $image_url;
  13992. $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
  13993. }
  13994. else
  13995. {
  13996. trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
  13997. }
  13998. }
  13999. }
  14000. }
  14001. }
  14002. }
  14003. // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
  14004. $data = trim($data);
  14005. }
  14006. if ($type & SIMPLEPIE_CONSTRUCT_IRI)
  14007. {
  14008. $data = SimplePie_Misc::absolutize_url($data, $base);
  14009. }
  14010. if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
  14011. {
  14012. $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
  14013. }
  14014. if ($this->output_encoding !== 'UTF-8')
  14015. {
  14016. $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
  14017. }
  14018. }
  14019. return $data;
  14020. }
  14021. function replace_urls($data, $tag, $attributes)
  14022. {
  14023. if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
  14024. {
  14025. $elements = SimplePie_Misc::get_element($tag, $data);
  14026. foreach ($elements as $element)
  14027. {
  14028. if (is_array($attributes))
  14029. {
  14030. foreach ($attributes as $attribute)
  14031. {
  14032. if (isset($element['attribs'][$attribute]['data']))
  14033. {
  14034. $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
  14035. $new_element = SimplePie_Misc::element_implode($element);
  14036. $data = str_replace($element['full'], $new_element, $data);
  14037. $element['full'] = $new_element;
  14038. }
  14039. }
  14040. }
  14041. elseif (isset($element['attribs'][$attributes]['data']))
  14042. {
  14043. $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
  14044. $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
  14045. }
  14046. }
  14047. }
  14048. return $data;
  14049. }
  14050. function do_strip_htmltags($match)
  14051. {
  14052. if ($this->encode_instead_of_strip)
  14053. {
  14054. if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  14055. {
  14056. $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
  14057. $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
  14058. return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
  14059. }
  14060. else
  14061. {
  14062. return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
  14063. }
  14064. }
  14065. elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  14066. {
  14067. return $match[4];
  14068. }
  14069. else
  14070. {
  14071. return '';
  14072. }
  14073. }
  14074. }
  14075. endif;
  14076. ?>