PageRenderTime 848ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 1ms

/libraries/simplepie/simplepie.php

https://bitbucket.org/asosso/joomla25
PHP | 15001 lines | 11791 code | 1089 blank | 2121 comment | 1153 complexity | d1c8a277f0cc128b5610db721c70eabd MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * SimplePie
  4. *
  5. * A PHP-Based RSS and Atom Feed Framework.
  6. * Takes the hard work out of managing a complete RSS/Atom solution.
  7. *
  8. * Copyright (c) 2004-2009, Ryan Parman and Geoffrey Sneddon
  9. * All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without modification, are
  12. * permitted provided that the following conditions are met:
  13. *
  14. * * Redistributions of source code must retain the above copyright notice, this list of
  15. * conditions and the following disclaimer.
  16. *
  17. * * Redistributions in binary form must reproduce the above copyright notice, this list
  18. * of conditions and the following disclaimer in the documentation and/or other materials
  19. * provided with the distribution.
  20. *
  21. * * Neither the name of the SimplePie Team nor the names of its contributors may be used
  22. * to endorse or promote products derived from this software without specific prior
  23. * written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  26. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  27. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
  28. * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  30. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  32. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. *
  35. * @package SimplePie
  36. * @version 1.2
  37. * @copyright 2004-2009 Ryan Parman, Geoffrey Sneddon
  38. * @author Ryan Parman
  39. * @author Geoffrey Sneddon
  40. * @link http://simplepie.org/ SimplePie
  41. * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
  42. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  43. * @todo phpDoc comments
  44. */
  45. /**
  46. * SimplePie Name
  47. */
  48. define('SIMPLEPIE_NAME', 'SimplePie');
  49. /**
  50. * SimplePie Version
  51. */
  52. define('SIMPLEPIE_VERSION', '1.2');
  53. /**
  54. * SimplePie Build
  55. */
  56. define('SIMPLEPIE_BUILD', '20090627192103');
  57. /**
  58. * SimplePie Website URL
  59. */
  60. define('SIMPLEPIE_URL', 'http://simplepie.org');
  61. /**
  62. * SimplePie Useragent
  63. * @see SimplePie::set_useragent()
  64. */
  65. define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
  66. /**
  67. * SimplePie Linkback
  68. */
  69. define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
  70. /**
  71. * No Autodiscovery
  72. * @see SimplePie::set_autodiscovery_level()
  73. */
  74. define('SIMPLEPIE_LOCATOR_NONE', 0);
  75. /**
  76. * Feed Link Element Autodiscovery
  77. * @see SimplePie::set_autodiscovery_level()
  78. */
  79. define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
  80. /**
  81. * Local Feed Extension Autodiscovery
  82. * @see SimplePie::set_autodiscovery_level()
  83. */
  84. define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
  85. /**
  86. * Local Feed Body Autodiscovery
  87. * @see SimplePie::set_autodiscovery_level()
  88. */
  89. define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
  90. /**
  91. * Remote Feed Extension Autodiscovery
  92. * @see SimplePie::set_autodiscovery_level()
  93. */
  94. define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
  95. /**
  96. * Remote Feed Body Autodiscovery
  97. * @see SimplePie::set_autodiscovery_level()
  98. */
  99. define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
  100. /**
  101. * All Feed Autodiscovery
  102. * @see SimplePie::set_autodiscovery_level()
  103. */
  104. define('SIMPLEPIE_LOCATOR_ALL', 31);
  105. /**
  106. * No known feed type
  107. */
  108. define('SIMPLEPIE_TYPE_NONE', 0);
  109. /**
  110. * RSS 0.90
  111. */
  112. define('SIMPLEPIE_TYPE_RSS_090', 1);
  113. /**
  114. * RSS 0.91 (Netscape)
  115. */
  116. define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
  117. /**
  118. * RSS 0.91 (Userland)
  119. */
  120. define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
  121. /**
  122. * RSS 0.91 (both Netscape and Userland)
  123. */
  124. define('SIMPLEPIE_TYPE_RSS_091', 6);
  125. /**
  126. * RSS 0.92
  127. */
  128. define('SIMPLEPIE_TYPE_RSS_092', 8);
  129. /**
  130. * RSS 0.93
  131. */
  132. define('SIMPLEPIE_TYPE_RSS_093', 16);
  133. /**
  134. * RSS 0.94
  135. */
  136. define('SIMPLEPIE_TYPE_RSS_094', 32);
  137. /**
  138. * RSS 1.0
  139. */
  140. define('SIMPLEPIE_TYPE_RSS_10', 64);
  141. /**
  142. * RSS 2.0
  143. */
  144. define('SIMPLEPIE_TYPE_RSS_20', 128);
  145. /**
  146. * RDF-based RSS
  147. */
  148. define('SIMPLEPIE_TYPE_RSS_RDF', 65);
  149. /**
  150. * Non-RDF-based RSS (truly intended as syndication format)
  151. */
  152. define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
  153. /**
  154. * All RSS
  155. */
  156. define('SIMPLEPIE_TYPE_RSS_ALL', 255);
  157. /**
  158. * Atom 0.3
  159. */
  160. define('SIMPLEPIE_TYPE_ATOM_03', 256);
  161. /**
  162. * Atom 1.0
  163. */
  164. define('SIMPLEPIE_TYPE_ATOM_10', 512);
  165. /**
  166. * All Atom
  167. */
  168. define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
  169. /**
  170. * All feed types
  171. */
  172. define('SIMPLEPIE_TYPE_ALL', 1023);
  173. /**
  174. * No construct
  175. */
  176. define('SIMPLEPIE_CONSTRUCT_NONE', 0);
  177. /**
  178. * Text construct
  179. */
  180. define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
  181. /**
  182. * HTML construct
  183. */
  184. define('SIMPLEPIE_CONSTRUCT_HTML', 2);
  185. /**
  186. * XHTML construct
  187. */
  188. define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
  189. /**
  190. * base64-encoded construct
  191. */
  192. define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
  193. /**
  194. * IRI construct
  195. */
  196. define('SIMPLEPIE_CONSTRUCT_IRI', 16);
  197. /**
  198. * A construct that might be HTML
  199. */
  200. define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
  201. /**
  202. * All constructs
  203. */
  204. define('SIMPLEPIE_CONSTRUCT_ALL', 63);
  205. /**
  206. * Don't change case
  207. */
  208. define('SIMPLEPIE_SAME_CASE', 1);
  209. /**
  210. * Change to lowercase
  211. */
  212. define('SIMPLEPIE_LOWERCASE', 2);
  213. /**
  214. * Change to uppercase
  215. */
  216. define('SIMPLEPIE_UPPERCASE', 4);
  217. /**
  218. * PCRE for HTML attributes
  219. */
  220. 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]*');
  221. /**
  222. * PCRE for XML attributes
  223. */
  224. define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
  225. /**
  226. * XML Namespace
  227. */
  228. define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
  229. /**
  230. * Atom 1.0 Namespace
  231. */
  232. define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
  233. /**
  234. * Atom 0.3 Namespace
  235. */
  236. define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
  237. /**
  238. * RDF Namespace
  239. */
  240. define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
  241. /**
  242. * RSS 0.90 Namespace
  243. */
  244. define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
  245. /**
  246. * RSS 1.0 Namespace
  247. */
  248. define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
  249. /**
  250. * RSS 1.0 Content Module Namespace
  251. */
  252. define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
  253. /**
  254. * RSS 2.0 Namespace
  255. * (Stupid, I know, but I'm certain it will confuse people less with support.)
  256. */
  257. define('SIMPLEPIE_NAMESPACE_RSS_20', '');
  258. /**
  259. * DC 1.0 Namespace
  260. */
  261. define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
  262. /**
  263. * DC 1.1 Namespace
  264. */
  265. define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
  266. /**
  267. * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
  268. */
  269. define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
  270. /**
  271. * GeoRSS Namespace
  272. */
  273. define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
  274. /**
  275. * Media RSS Namespace
  276. */
  277. define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
  278. /**
  279. * Wrong Media RSS Namespace
  280. */
  281. define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
  282. /**
  283. * iTunes RSS Namespace
  284. */
  285. define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
  286. /**
  287. * XHTML Namespace
  288. */
  289. define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
  290. /**
  291. * IANA Link Relations Registry
  292. */
  293. define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
  294. /**
  295. * Whether we're running on PHP5
  296. */
  297. define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
  298. /**
  299. * No file source
  300. */
  301. define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
  302. /**
  303. * Remote file source
  304. */
  305. define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
  306. /**
  307. * Local file source
  308. */
  309. define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
  310. /**
  311. * fsockopen() file source
  312. */
  313. define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
  314. /**
  315. * cURL file source
  316. */
  317. define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
  318. /**
  319. * file_get_contents() file source
  320. */
  321. define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
  322. /**
  323. * SimplePie
  324. *
  325. * @package SimplePie
  326. */
  327. class SimplePie
  328. {
  329. /**
  330. * @var array Raw data
  331. * @access private
  332. */
  333. var $data = array();
  334. /**
  335. * @var mixed Error string
  336. * @access private
  337. */
  338. var $error;
  339. /**
  340. * @var object Instance of SimplePie_Sanitize (or other class)
  341. * @see SimplePie::set_sanitize_class()
  342. * @access private
  343. */
  344. var $sanitize;
  345. /**
  346. * @var string SimplePie Useragent
  347. * @see SimplePie::set_useragent()
  348. * @access private
  349. */
  350. var $useragent = SIMPLEPIE_USERAGENT;
  351. /**
  352. * @var string Feed URL
  353. * @see SimplePie::set_feed_url()
  354. * @access private
  355. */
  356. var $feed_url;
  357. /**
  358. * @var object Instance of SimplePie_File to use as a feed
  359. * @see SimplePie::set_file()
  360. * @access private
  361. */
  362. var $file;
  363. /**
  364. * @var string Raw feed data
  365. * @see SimplePie::set_raw_data()
  366. * @access private
  367. */
  368. var $raw_data;
  369. /**
  370. * @var int Timeout for fetching remote files
  371. * @see SimplePie::set_timeout()
  372. * @access private
  373. */
  374. var $timeout = 10;
  375. /**
  376. * @var bool Forces fsockopen() to be used for remote files instead
  377. * of cURL, even if a new enough version is installed
  378. * @see SimplePie::force_fsockopen()
  379. * @access private
  380. */
  381. var $force_fsockopen = false;
  382. /**
  383. * @var bool Force the given data/URL to be treated as a feed no matter what
  384. * it appears like
  385. * @see SimplePie::force_feed()
  386. * @access private
  387. */
  388. var $force_feed = false;
  389. /**
  390. * @var bool Enable/Disable XML dump
  391. * @see SimplePie::enable_xml_dump()
  392. * @access private
  393. */
  394. var $xml_dump = false;
  395. /**
  396. * @var bool Enable/Disable Caching
  397. * @see SimplePie::enable_cache()
  398. * @access private
  399. */
  400. var $cache = true;
  401. /**
  402. * @var int Cache duration (in seconds)
  403. * @see SimplePie::set_cache_duration()
  404. * @access private
  405. */
  406. var $cache_duration = 3600;
  407. /**
  408. * @var int Auto-discovery cache duration (in seconds)
  409. * @see SimplePie::set_autodiscovery_cache_duration()
  410. * @access private
  411. */
  412. var $autodiscovery_cache_duration = 604800; // 7 Days.
  413. /**
  414. * @var string Cache location (relative to executing script)
  415. * @see SimplePie::set_cache_location()
  416. * @access private
  417. */
  418. var $cache_location = './cache';
  419. /**
  420. * @var string Function that creates the cache filename
  421. * @see SimplePie::set_cache_name_function()
  422. * @access private
  423. */
  424. var $cache_name_function = 'md5';
  425. /**
  426. * @var bool Reorder feed by date descending
  427. * @see SimplePie::enable_order_by_date()
  428. * @access private
  429. */
  430. var $order_by_date = true;
  431. /**
  432. * @var mixed Force input encoding to be set to the follow value
  433. * (false, or anything type-cast to false, disables this feature)
  434. * @see SimplePie::set_input_encoding()
  435. * @access private
  436. */
  437. var $input_encoding = false;
  438. /**
  439. * @var int Feed Autodiscovery Level
  440. * @see SimplePie::set_autodiscovery_level()
  441. * @access private
  442. */
  443. var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
  444. /**
  445. * @var string Class used for caching feeds
  446. * @see SimplePie::set_cache_class()
  447. * @access private
  448. */
  449. var $cache_class = 'SimplePie_Cache';
  450. /**
  451. * @var string Class used for locating feeds
  452. * @see SimplePie::set_locator_class()
  453. * @access private
  454. */
  455. var $locator_class = 'SimplePie_Locator';
  456. /**
  457. * @var string Class used for parsing feeds
  458. * @see SimplePie::set_parser_class()
  459. * @access private
  460. */
  461. var $parser_class = 'SimplePie_Parser';
  462. /**
  463. * @var string Class used for fetching feeds
  464. * @see SimplePie::set_file_class()
  465. * @access private
  466. */
  467. var $file_class = 'SimplePie_File';
  468. /**
  469. * @var string Class used for items
  470. * @see SimplePie::set_item_class()
  471. * @access private
  472. */
  473. var $item_class = 'SimplePie_Item';
  474. /**
  475. * @var string Class used for authors
  476. * @see SimplePie::set_author_class()
  477. * @access private
  478. */
  479. var $author_class = 'SimplePie_Author';
  480. /**
  481. * @var string Class used for categories
  482. * @see SimplePie::set_category_class()
  483. * @access private
  484. */
  485. var $category_class = 'SimplePie_Category';
  486. /**
  487. * @var string Class used for enclosures
  488. * @see SimplePie::set_enclosures_class()
  489. * @access private
  490. */
  491. var $enclosure_class = 'SimplePie_Enclosure';
  492. /**
  493. * @var string Class used for Media RSS <media:text> captions
  494. * @see SimplePie::set_caption_class()
  495. * @access private
  496. */
  497. var $caption_class = 'SimplePie_Caption';
  498. /**
  499. * @var string Class used for Media RSS <media:copyright>
  500. * @see SimplePie::set_copyright_class()
  501. * @access private
  502. */
  503. var $copyright_class = 'SimplePie_Copyright';
  504. /**
  505. * @var string Class used for Media RSS <media:credit>
  506. * @see SimplePie::set_credit_class()
  507. * @access private
  508. */
  509. var $credit_class = 'SimplePie_Credit';
  510. /**
  511. * @var string Class used for Media RSS <media:rating>
  512. * @see SimplePie::set_rating_class()
  513. * @access private
  514. */
  515. var $rating_class = 'SimplePie_Rating';
  516. /**
  517. * @var string Class used for Media RSS <media:restriction>
  518. * @see SimplePie::set_restriction_class()
  519. * @access private
  520. */
  521. var $restriction_class = 'SimplePie_Restriction';
  522. /**
  523. * @var string Class used for content-type sniffing
  524. * @see SimplePie::set_content_type_sniffer_class()
  525. * @access private
  526. */
  527. var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
  528. /**
  529. * @var string Class used for item sources.
  530. * @see SimplePie::set_source_class()
  531. * @access private
  532. */
  533. var $source_class = 'SimplePie_Source';
  534. /**
  535. * @var mixed Set javascript query string parameter (false, or
  536. * anything type-cast to false, disables this feature)
  537. * @see SimplePie::set_javascript()
  538. * @access private
  539. */
  540. var $javascript = 'js';
  541. /**
  542. * @var int Maximum number of feeds to check with autodiscovery
  543. * @see SimplePie::set_max_checked_feeds()
  544. * @access private
  545. */
  546. var $max_checked_feeds = 10;
  547. /**
  548. * @var array All the feeds found during the autodiscovery process
  549. * @see SimplePie::get_all_discovered_feeds()
  550. * @access private
  551. */
  552. var $all_discovered_feeds = array();
  553. /**
  554. * @var string Web-accessible path to the handler_favicon.php file.
  555. * @see SimplePie::set_favicon_handler()
  556. * @access private
  557. */
  558. var $favicon_handler = '';
  559. /**
  560. * @var string Web-accessible path to the handler_image.php file.
  561. * @see SimplePie::set_image_handler()
  562. * @access private
  563. */
  564. var $image_handler = '';
  565. /**
  566. * @var array Stores the URLs when multiple feeds are being initialized.
  567. * @see SimplePie::set_feed_url()
  568. * @access private
  569. */
  570. var $multifeed_url = array();
  571. /**
  572. * @var array Stores SimplePie objects when multiple feeds initialized.
  573. * @access private
  574. */
  575. var $multifeed_objects = array();
  576. /**
  577. * @var array Stores the get_object_vars() array for use with multifeeds.
  578. * @see SimplePie::set_feed_url()
  579. * @access private
  580. */
  581. var $config_settings = null;
  582. /**
  583. * @var integer Stores the number of items to return per-feed with multifeeds.
  584. * @see SimplePie::set_item_limit()
  585. * @access private
  586. */
  587. var $item_limit = 0;
  588. /**
  589. * @var array Stores the default attributes to be stripped by strip_attributes().
  590. * @see SimplePie::strip_attributes()
  591. * @access private
  592. */
  593. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  594. /**
  595. * @var array Stores the default tags to be stripped by strip_htmltags().
  596. * @see SimplePie::strip_htmltags()
  597. * @access private
  598. */
  599. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  600. /**
  601. * The SimplePie class contains feed level data and options
  602. *
  603. * There are two ways that you can create a new SimplePie object. The first
  604. * is by passing a feed URL as a parameter to the SimplePie constructor
  605. * (as well as optionally setting the cache location and cache expiry). This
  606. * will initialise the whole feed with all of the default settings, and you
  607. * can begin accessing methods and properties immediately.
  608. *
  609. * The second way is to create the SimplePie object with no parameters
  610. * at all. This will enable you to set configuration options. After setting
  611. * them, you must initialise the feed using $feed->init(). At that point the
  612. * object's methods and properties will be available to you. This format is
  613. * what is used throughout this documentation.
  614. *
  615. * @access public
  616. * @since 1.0 Preview Release
  617. * @param string $feed_url This is the URL you want to parse.
  618. * @param string $cache_location This is where you want the cache to be stored.
  619. * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
  620. */
  621. function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
  622. {
  623. // Other objects, instances created here so we can set options on them
  624. $this->sanitize = new SimplePie_Sanitize;
  625. // Set options if they're passed to the constructor
  626. if ($cache_location !== null)
  627. {
  628. $this->set_cache_location($cache_location);
  629. }
  630. if ($cache_duration !== null)
  631. {
  632. $this->set_cache_duration($cache_duration);
  633. }
  634. // Only init the script if we're passed a feed URL
  635. if ($feed_url !== null)
  636. {
  637. $this->set_feed_url($feed_url);
  638. $this->init();
  639. }
  640. }
  641. /**
  642. * Used for converting object to a string
  643. */
  644. function __toString()
  645. {
  646. return md5(serialize($this->data));
  647. }
  648. /**
  649. * Remove items that link back to this before destroying this object
  650. */
  651. function __destruct()
  652. {
  653. if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
  654. {
  655. if (!empty($this->data['items']))
  656. {
  657. foreach ($this->data['items'] as $item)
  658. {
  659. $item->__destruct();
  660. }
  661. unset($item, $this->data['items']);
  662. }
  663. if (!empty($this->data['ordered_items']))
  664. {
  665. foreach ($this->data['ordered_items'] as $item)
  666. {
  667. $item->__destruct();
  668. }
  669. unset($item, $this->data['ordered_items']);
  670. }
  671. }
  672. }
  673. /**
  674. * Force the given data/URL to be treated as a feed no matter what it
  675. * appears like
  676. *
  677. * @access public
  678. * @since 1.1
  679. * @param bool $enable Force the given data/URL to be treated as a feed
  680. */
  681. function force_feed($enable = false)
  682. {
  683. $this->force_feed = (bool) $enable;
  684. }
  685. /**
  686. * This is the URL of the feed you want to parse.
  687. *
  688. * This allows you to enter the URL of the feed you want to parse, or the
  689. * website you want to try to use auto-discovery on. This takes priority
  690. * over any set raw data.
  691. *
  692. * You can set multiple feeds to mash together by passing an array instead
  693. * of a string for the $url. Remember that with each additional feed comes
  694. * additional processing and resources.
  695. *
  696. * @access public
  697. * @since 1.0 Preview Release
  698. * @param mixed $url This is the URL (or array of URLs) that you want to parse.
  699. * @see SimplePie::set_raw_data()
  700. */
  701. function set_feed_url($url)
  702. {
  703. if (is_array($url))
  704. {
  705. $this->multifeed_url = array();
  706. foreach ($url as $value)
  707. {
  708. $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
  709. }
  710. }
  711. else
  712. {
  713. $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
  714. }
  715. }
  716. /**
  717. * Provides an instance of SimplePie_File to use as a feed
  718. *
  719. * @access public
  720. * @param object &$file Instance of SimplePie_File (or subclass)
  721. * @return bool True on success, false on failure
  722. */
  723. function set_file(&$file)
  724. {
  725. if (is_a($file, 'SimplePie_File'))
  726. {
  727. $this->feed_url = $file->url;
  728. $this->file =& $file;
  729. return true;
  730. }
  731. return false;
  732. }
  733. /**
  734. * Allows you to use a string of RSS/Atom data instead of a remote feed.
  735. *
  736. * If you have a feed available as a string in PHP, you can tell SimplePie
  737. * to parse that data string instead of a remote feed. Any set feed URL
  738. * takes precedence.
  739. *
  740. * @access public
  741. * @since 1.0 Beta 3
  742. * @param string $data RSS or Atom data as a string.
  743. * @see SimplePie::set_feed_url()
  744. */
  745. function set_raw_data($data)
  746. {
  747. $this->raw_data = $data;
  748. }
  749. /**
  750. * Allows you to override the default timeout for fetching remote feeds.
  751. *
  752. * This allows you to change the maximum time the feed's server to respond
  753. * and send the feed back.
  754. *
  755. * @access public
  756. * @since 1.0 Beta 3
  757. * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
  758. */
  759. function set_timeout($timeout = 10)
  760. {
  761. $this->timeout = (int) $timeout;
  762. }
  763. /**
  764. * Forces SimplePie to use fsockopen() instead of the preferred cURL
  765. * functions.
  766. *
  767. * @access public
  768. * @since 1.0 Beta 3
  769. * @param bool $enable Force fsockopen() to be used
  770. */
  771. function force_fsockopen($enable = false)
  772. {
  773. $this->force_fsockopen = (bool) $enable;
  774. }
  775. /**
  776. * Outputs the raw XML content of the feed, after it has gone through
  777. * SimplePie's filters.
  778. *
  779. * Used only for debugging, this function will output the XML content as
  780. * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
  781. * before trying to parse it. Many parts of the feed are re-written in
  782. * memory, and in the end, you have a parsable feed. XML dump shows you the
  783. * actual XML that SimplePie tries to parse, which may or may not be very
  784. * different from the original feed.
  785. *
  786. * @access public
  787. * @since 1.0 Preview Release
  788. * @param bool $enable Enable XML dump
  789. */
  790. function enable_xml_dump($enable = false)
  791. {
  792. $this->xml_dump = (bool) $enable;
  793. }
  794. /**
  795. * Enables/disables caching in SimplePie.
  796. *
  797. * This option allows you to disable caching all-together in SimplePie.
  798. * However, disabling the cache can lead to longer load times.
  799. *
  800. * @access public
  801. * @since 1.0 Preview Release
  802. * @param bool $enable Enable caching
  803. */
  804. function enable_cache($enable = true)
  805. {
  806. $this->cache = (bool) $enable;
  807. }
  808. /**
  809. * Set the length of time (in seconds) that the contents of a feed
  810. * will be cached.
  811. *
  812. * @access public
  813. * @param int $seconds The feed content cache duration.
  814. */
  815. function set_cache_duration($seconds = 3600)
  816. {
  817. $this->cache_duration = (int) $seconds;
  818. }
  819. /**
  820. * Set the length of time (in seconds) that the autodiscovered feed
  821. * URL will be cached.
  822. *
  823. * @access public
  824. * @param int $seconds The autodiscovered feed URL cache duration.
  825. */
  826. function set_autodiscovery_cache_duration($seconds = 604800)
  827. {
  828. $this->autodiscovery_cache_duration = (int) $seconds;
  829. }
  830. /**
  831. * Set the file system location where the cached files should be stored.
  832. *
  833. * @access public
  834. * @param string $location The file system location.
  835. */
  836. function set_cache_location($location = './cache')
  837. {
  838. $this->cache_location = (string) $location;
  839. }
  840. /**
  841. * Determines whether feed items should be sorted into reverse chronological order.
  842. *
  843. * @access public
  844. * @param bool $enable Sort as reverse chronological order.
  845. */
  846. function enable_order_by_date($enable = true)
  847. {
  848. $this->order_by_date = (bool) $enable;
  849. }
  850. /**
  851. * Allows you to override the character encoding reported by the feed.
  852. *
  853. * @access public
  854. * @param string $encoding Character encoding.
  855. */
  856. function set_input_encoding($encoding = false)
  857. {
  858. if ($encoding)
  859. {
  860. $this->input_encoding = (string) $encoding;
  861. }
  862. else
  863. {
  864. $this->input_encoding = false;
  865. }
  866. }
  867. /**
  868. * Set how much feed autodiscovery to do
  869. *
  870. * @access public
  871. * @see SIMPLEPIE_LOCATOR_NONE
  872. * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
  873. * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
  874. * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
  875. * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
  876. * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
  877. * @see SIMPLEPIE_LOCATOR_ALL
  878. * @param int $level Feed Autodiscovery Level (level can be a
  879. * combination of the above constants, see bitwise OR operator)
  880. */
  881. function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
  882. {
  883. $this->autodiscovery = (int) $level;
  884. }
  885. /**
  886. * Allows you to change which class SimplePie uses for caching.
  887. * Useful when you are overloading or extending SimplePie's default classes.
  888. *
  889. * @access public
  890. * @param string $class Name of custom class.
  891. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  892. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  893. */
  894. function set_cache_class($class = 'SimplePie_Cache')
  895. {
  896. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
  897. {
  898. $this->cache_class = $class;
  899. return true;
  900. }
  901. return false;
  902. }
  903. /**
  904. * Allows you to change which class SimplePie uses for auto-discovery.
  905. * Useful when you are overloading or extending SimplePie's default classes.
  906. *
  907. * @access public
  908. * @param string $class Name of custom class.
  909. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  910. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  911. */
  912. function set_locator_class($class = 'SimplePie_Locator')
  913. {
  914. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
  915. {
  916. $this->locator_class = $class;
  917. return true;
  918. }
  919. return false;
  920. }
  921. /**
  922. * Allows you to change which class SimplePie uses for XML parsing.
  923. * Useful when you are overloading or extending SimplePie's default classes.
  924. *
  925. * @access public
  926. * @param string $class Name of custom class.
  927. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  928. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  929. */
  930. function set_parser_class($class = 'SimplePie_Parser')
  931. {
  932. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
  933. {
  934. $this->parser_class = $class;
  935. return true;
  936. }
  937. return false;
  938. }
  939. /**
  940. * Allows you to change which class SimplePie uses for remote file fetching.
  941. * Useful when you are overloading or extending SimplePie's default classes.
  942. *
  943. * @access public
  944. * @param string $class Name of custom class.
  945. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  946. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  947. */
  948. function set_file_class($class = 'SimplePie_File')
  949. {
  950. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
  951. {
  952. $this->file_class = $class;
  953. return true;
  954. }
  955. return false;
  956. }
  957. /**
  958. * Allows you to change which class SimplePie uses for data sanitization.
  959. * Useful when you are overloading or extending SimplePie's default classes.
  960. *
  961. * @access public
  962. * @param string $class Name of custom class.
  963. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  964. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  965. */
  966. function set_sanitize_class($class = 'SimplePie_Sanitize')
  967. {
  968. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
  969. {
  970. $this->sanitize = new $class;
  971. return true;
  972. }
  973. return false;
  974. }
  975. /**
  976. * Allows you to change which class SimplePie uses for handling feed items.
  977. * Useful when you are overloading or extending SimplePie's default classes.
  978. *
  979. * @access public
  980. * @param string $class Name of custom class.
  981. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  982. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  983. */
  984. function set_item_class($class = 'SimplePie_Item')
  985. {
  986. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
  987. {
  988. $this->item_class = $class;
  989. return true;
  990. }
  991. return false;
  992. }
  993. /**
  994. * Allows you to change which class SimplePie uses for handling author data.
  995. * Useful when you are overloading or extending SimplePie's default classes.
  996. *
  997. * @access public
  998. * @param string $class Name of custom class.
  999. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1000. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1001. */
  1002. function set_author_class($class = 'SimplePie_Author')
  1003. {
  1004. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
  1005. {
  1006. $this->author_class = $class;
  1007. return true;
  1008. }
  1009. return false;
  1010. }
  1011. /**
  1012. * Allows you to change which class SimplePie uses for handling category data.
  1013. * Useful when you are overloading or extending SimplePie's default classes.
  1014. *
  1015. * @access public
  1016. * @param string $class Name of custom class.
  1017. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1018. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1019. */
  1020. function set_category_class($class = 'SimplePie_Category')
  1021. {
  1022. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
  1023. {
  1024. $this->category_class = $class;
  1025. return true;
  1026. }
  1027. return false;
  1028. }
  1029. /**
  1030. * Allows you to change which class SimplePie uses for feed enclosures.
  1031. * Useful when you are overloading or extending SimplePie's default classes.
  1032. *
  1033. * @access public
  1034. * @param string $class Name of custom class.
  1035. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1036. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1037. */
  1038. function set_enclosure_class($class = 'SimplePie_Enclosure')
  1039. {
  1040. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
  1041. {
  1042. $this->enclosure_class = $class;
  1043. return true;
  1044. }
  1045. return false;
  1046. }
  1047. /**
  1048. * Allows you to change which class SimplePie uses for <media:text> captions
  1049. * Useful when you are overloading or extending SimplePie's default classes.
  1050. *
  1051. * @access public
  1052. * @param string $class Name of custom class.
  1053. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1054. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1055. */
  1056. function set_caption_class($class = 'SimplePie_Caption')
  1057. {
  1058. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
  1059. {
  1060. $this->caption_class = $class;
  1061. return true;
  1062. }
  1063. return false;
  1064. }
  1065. /**
  1066. * Allows you to change which class SimplePie uses for <media:copyright>
  1067. * Useful when you are overloading or extending SimplePie's default classes.
  1068. *
  1069. * @access public
  1070. * @param string $class Name of custom class.
  1071. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1072. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1073. */
  1074. function set_copyright_class($class = 'SimplePie_Copyright')
  1075. {
  1076. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
  1077. {
  1078. $this->copyright_class = $class;
  1079. return true;
  1080. }
  1081. return false;
  1082. }
  1083. /**
  1084. * Allows you to change which class SimplePie uses for <media:credit>
  1085. * Useful when you are overloading or extending SimplePie's default classes.
  1086. *
  1087. * @access public
  1088. * @param string $class Name of custom class.
  1089. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1090. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1091. */
  1092. function set_credit_class($class = 'SimplePie_Credit')
  1093. {
  1094. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
  1095. {
  1096. $this->credit_class = $class;
  1097. return true;
  1098. }
  1099. return false;
  1100. }
  1101. /**
  1102. * Allows you to change which class SimplePie uses for <media:rating>
  1103. * Useful when you are overloading or extending SimplePie's default classes.
  1104. *
  1105. * @access public
  1106. * @param string $class Name of custom class.
  1107. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1108. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1109. */
  1110. function set_rating_class($class = 'SimplePie_Rating')
  1111. {
  1112. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
  1113. {
  1114. $this->rating_class = $class;
  1115. return true;
  1116. }
  1117. return false;
  1118. }
  1119. /**
  1120. * Allows you to change which class SimplePie uses for <media:restriction>
  1121. * Useful when you are overloading or extending SimplePie's default classes.
  1122. *
  1123. * @access public
  1124. * @param string $class Name of custom class.
  1125. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1126. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1127. */
  1128. function set_restriction_class($class = 'SimplePie_Restriction')
  1129. {
  1130. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
  1131. {
  1132. $this->restriction_class = $class;
  1133. return true;
  1134. }
  1135. return false;
  1136. }
  1137. /**
  1138. * Allows you to change which class SimplePie uses for content-type sniffing.
  1139. * Useful when you are overloading or extending SimplePie's default classes.
  1140. *
  1141. * @access public
  1142. * @param string $class Name of custom class.
  1143. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1144. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1145. */
  1146. function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
  1147. {
  1148. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
  1149. {
  1150. $this->content_type_sniffer_class = $class;
  1151. return true;
  1152. }
  1153. return false;
  1154. }
  1155. /**
  1156. * Allows you to change which class SimplePie uses item sources.
  1157. * Useful when you are overloading or extending SimplePie's default classes.
  1158. *
  1159. * @access public
  1160. * @param string $class Name of custom class.
  1161. * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
  1162. * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
  1163. */
  1164. function set_source_class($class = 'SimplePie_Source')
  1165. {
  1166. if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
  1167. {
  1168. $this->source_class = $class;
  1169. return true;
  1170. }
  1171. return false;
  1172. }
  1173. /**
  1174. * Allows you to override the default user agent string.
  1175. *
  1176. * @access public
  1177. * @param string $ua New user agent string.
  1178. */
  1179. function set_useragent($ua = SIMPLEPIE_USERAGENT)
  1180. {
  1181. $this->useragent = (string) $ua;
  1182. }
  1183. /**
  1184. * Set callback function to create cache filename with
  1185. *
  1186. * @access public
  1187. * @param mixed $function Callback function
  1188. */
  1189. function set_cache_name_function($function = 'md5')
  1190. {
  1191. if (is_callable($function))
  1192. {
  1193. $this->cache_name_function = $function;
  1194. }
  1195. }
  1196. /**
  1197. * Set javascript query string parameter
  1198. *
  1199. * @access public
  1200. * @param mixed $get Javascript query string parameter
  1201. */
  1202. function set_javascript($get = 'js')
  1203. {
  1204. if ($get)
  1205. {
  1206. $this->javascript = (string) $get;
  1207. }
  1208. else
  1209. {
  1210. $this->javascript = false;
  1211. }
  1212. }
  1213. /**
  1214. * Set options to make SP as fast as possible. Forgoes a
  1215. * substantial amount of data sanitization in favor of speed.
  1216. *
  1217. * @access public
  1218. * @param bool $set Whether to set them or not
  1219. */
  1220. function set_stupidly_fast($set = false)
  1221. {
  1222. if ($set)
  1223. {
  1224. $this->enable_order_by_date(false);
  1225. $this->remove_div(false);
  1226. $this->strip_comments(false);
  1227. $this->strip_htmltags(false);
  1228. $this->strip_attributes(false);
  1229. $this->set_image_handler(false);
  1230. }
  1231. }
  1232. /**
  1233. * Set maximum number of feeds to check with autodiscovery
  1234. *
  1235. * @access public
  1236. * @param int $max Maximum number of feeds to check
  1237. */
  1238. function set_max_checked_feeds($max = 10)
  1239. {
  1240. $this->max_checked_feeds = (int) $max;
  1241. }
  1242. function remove_div($enable = true)
  1243. {
  1244. $this->sanitize->remove_div($enable);
  1245. }
  1246. function strip_htmltags($tags = '', $encode = null)
  1247. {
  1248. if ($tags === '')
  1249. {
  1250. $tags = $this->strip_htmltags;
  1251. }
  1252. $this->sanitize->strip_htmltags($tags);
  1253. if ($encode !== null)
  1254. {
  1255. $this->sanitize->encode_instead_of_strip($tags);
  1256. }
  1257. }
  1258. function encode_instead_of_strip($enable = true)
  1259. {
  1260. $this->sanitize->encode_instead_of_strip($enable);
  1261. }
  1262. function strip_attributes($attribs = '')
  1263. {
  1264. if ($attribs === '')
  1265. {
  1266. $attribs = $this->strip_attributes;
  1267. }
  1268. $this->sanitize->strip_attributes($attribs);
  1269. }
  1270. function set_output_encoding($encoding = 'UTF-8')
  1271. {
  1272. $this->sanitize->set_output_encoding($encoding);
  1273. }
  1274. function strip_comments($strip = false)
  1275. {
  1276. $this->sanitize->strip_comments($strip);
  1277. }
  1278. /**
  1279. * Set element/attribute key/value pairs of HTML attributes
  1280. * containing URLs that need to be resolved relative to the feed
  1281. *
  1282. * @access public
  1283. * @since 1.0
  1284. * @param array $element_attribute Element/attribute key/value pairs
  1285. */
  1286. 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'))
  1287. {
  1288. $this->sanitize->set_url_replacements($element_attribute);
  1289. }
  1290. /**
  1291. * Set the handler to enable the display of cached favicons.
  1292. *
  1293. * @access public
  1294. * @param str $page Web-accessible path to the handler_favicon.php file.
  1295. * @param str $qs The query string that the value should be passed to.
  1296. */
  1297. function set_favicon_handler($page = false, $qs = 'i')
  1298. {
  1299. if ($page !== false)
  1300. {
  1301. $this->favicon_handler = $page . '?' . $qs . '=';
  1302. }
  1303. else
  1304. {
  1305. $this->favicon_handler = '';
  1306. }
  1307. }
  1308. /**
  1309. * Set the handler to enable the display of cached images.
  1310. *
  1311. * @access public
  1312. * @param str $page Web-accessible path to the handler_image.php file.
  1313. * @param str $qs The query string that the value should be passed to.
  1314. */
  1315. function set_image_handler($page = false, $qs = 'i')
  1316. {
  1317. if ($page !== false)
  1318. {
  1319. $this->sanitize->set_image_handler($page . '?' . $qs . '=');
  1320. }
  1321. else
  1322. {
  1323. $this->image_handler = '';
  1324. }
  1325. }
  1326. /**
  1327. * Set the limit for items returned per-feed with multifeeds.
  1328. *
  1329. * @access public
  1330. * @param integer $limit The maximum number of items to return.
  1331. */
  1332. function set_item_limit($limit = 0)
  1333. {
  1334. $this->item_limit = (int) $limit;
  1335. }
  1336. function init()
  1337. {
  1338. // Check absolute bare minimum requirements.
  1339. if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
  1340. {
  1341. return false;
  1342. }
  1343. // 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.
  1344. elseif (!extension_loaded('xmlreader'))
  1345. {
  1346. static $xml_is_sane = null;
  1347. if ($xml_is_sane === null)
  1348. {
  1349. $parser_check = xml_parser_create();
  1350. xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
  1351. xml_parser_free($parser_check);
  1352. $xml_is_sane = isset($values[0]['value']);
  1353. }
  1354. if (!$xml_is_sane)
  1355. {
  1356. return false;
  1357. }
  1358. }
  1359. if (isset($_GET[$this->javascript]))
  1360. {
  1361. SimplePie_Misc::output_javascript();
  1362. exit;
  1363. }
  1364. // Pass whatever was set with config options over to the sanitizer.
  1365. $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
  1366. $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
  1367. if ($this->feed_url !== null || $this->raw_data !== null)
  1368. {
  1369. $this->data = array();
  1370. $this->multifeed_objects = array();
  1371. $cache = false;
  1372. if ($this->feed_url !== null)
  1373. {
  1374. $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
  1375. // Decide whether to enable caching
  1376. if ($this->cache && $parsed_feed_url['scheme'] !== '')
  1377. {
  1378. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
  1379. }
  1380. // If it's enabled and we don't want an XML dump, use the cache
  1381. if ($cache && !$this->xml_dump)
  1382. {
  1383. // Load the Cache
  1384. $this->data = $cache->load();
  1385. if (!empty($this->data))
  1386. {
  1387. // If the cache is for an outdated build of SimplePie
  1388. if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
  1389. {
  1390. $cache->unlink();
  1391. $this->data = array();
  1392. }
  1393. // If we've hit a collision just rerun it with caching disabled
  1394. elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
  1395. {
  1396. $cache = false;
  1397. $this->data = array();
  1398. }
  1399. // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
  1400. elseif (isset($this->data['feed_url']))
  1401. {
  1402. // If the autodiscovery cache is still valid use it.
  1403. if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
  1404. {
  1405. // Do not need to do feed autodiscovery yet.
  1406. if ($this->data['feed_url'] === $this->data['url'])
  1407. {
  1408. $cache->unlink();
  1409. $this->data = array();
  1410. }
  1411. else
  1412. {
  1413. $this->set_feed_url($this->data['feed_url']);
  1414. return $this->init();
  1415. }
  1416. }
  1417. }
  1418. // Check if the cache has been updated
  1419. elseif ($cache->mtime() + $this->cache_duration < time())
  1420. {
  1421. // If we have last-modified and/or etag set
  1422. if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
  1423. {
  1424. $headers = array();
  1425. if (isset($this->data['headers']['last-modified']))
  1426. {
  1427. $headers['if-modified-since'] = $this->data['headers']['last-modified'];
  1428. }
  1429. if (isset($this->data['headers']['etag']))
  1430. {
  1431. $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
  1432. }
  1433. $file = new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
  1434. if ($file->success)
  1435. {
  1436. if ($file->status_code === 304)
  1437. {
  1438. $cache->touch();
  1439. return true;
  1440. }
  1441. else
  1442. {
  1443. $headers = $file->headers;
  1444. }
  1445. }
  1446. else
  1447. {
  1448. unset($file);
  1449. }
  1450. }
  1451. }
  1452. // If the cache is still valid, just return true
  1453. else
  1454. {
  1455. return true;
  1456. }
  1457. }
  1458. // If the cache is empty, delete it
  1459. else
  1460. {
  1461. $cache->unlink();
  1462. $this->data = array();
  1463. }
  1464. }
  1465. // 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.
  1466. if (!isset($file))
  1467. {
  1468. if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url)
  1469. {
  1470. $file =& $this->file;
  1471. }
  1472. else
  1473. {
  1474. $file = new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
  1475. }
  1476. }
  1477. // If the file connection has an error, set SimplePie::error to that and quit
  1478. if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
  1479. {
  1480. $this->error = $file->error;
  1481. if (!empty($this->data))
  1482. {
  1483. return true;
  1484. }
  1485. else
  1486. {
  1487. return false;
  1488. }
  1489. }
  1490. if (!$this->force_feed)
  1491. {
  1492. // Check if the supplied URL is a feed, if it isn't, look for it.
  1493. $locate = new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
  1494. if (!$locate->is_feed($file))
  1495. {
  1496. // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
  1497. unset($file);
  1498. if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))
  1499. {
  1500. if ($cache)
  1501. {
  1502. $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
  1503. if (!$cache->save($this))
  1504. {
  1505. trigger_error("$this->cache_location is not writeable", E_USER_WARNING);
  1506. }
  1507. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
  1508. }
  1509. $this->feed_url = $file->url;
  1510. }
  1511. else
  1512. {
  1513. $this->error = "A feed could not be found at $this->feed_url";
  1514. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1515. return false;
  1516. }
  1517. }
  1518. $locate = null;
  1519. }
  1520. $headers = $file->headers;
  1521. $data = $file->body;
  1522. $sniffer = new $this->content_type_sniffer_class($file);
  1523. $sniffed = $sniffer->get_type();
  1524. }
  1525. else
  1526. {
  1527. $data = $this->raw_data;
  1528. }
  1529. // Set up array of possible encodings
  1530. $encodings = array();
  1531. // First check to see if input has been overridden.
  1532. if ($this->input_encoding !== false)
  1533. {
  1534. $encodings[] = $this->input_encoding;
  1535. }
  1536. $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
  1537. $text_types = array('text/xml', 'text/xml-external-parsed-entity');
  1538. // RFC 3023 (only applies to sniffed content)
  1539. if (isset($sniffed))
  1540. {
  1541. if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
  1542. {
  1543. if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  1544. {
  1545. $encodings[] = strtoupper($charset[1]);
  1546. }
  1547. $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
  1548. $encodings[] = 'UTF-8';
  1549. }
  1550. elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
  1551. {
  1552. if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  1553. {
  1554. $encodings[] = $charset[1];
  1555. }
  1556. $encodings[] = 'US-ASCII';
  1557. }
  1558. // Text MIME-type default
  1559. elseif (substr($sniffed, 0, 5) === 'text/')
  1560. {
  1561. $encodings[] = 'US-ASCII';
  1562. }
  1563. }
  1564. // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
  1565. $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
  1566. $encodings[] = 'UTF-8';
  1567. $encodings[] = 'ISO-8859-1';
  1568. // There's no point in trying an encoding twice
  1569. $encodings = array_unique($encodings);
  1570. // If we want the XML, just output that with the most likely encoding and quit
  1571. if ($this->xml_dump)
  1572. {
  1573. header('Content-type: text/xml; charset=' . $encodings[0]);
  1574. echo $data;
  1575. exit;
  1576. }
  1577. // Loop through each possible encoding, till we return something, or run out of possibilities
  1578. foreach ($encodings as $encoding)
  1579. {
  1580. // Change the encoding to UTF-8 (as we always use UTF-8 internally)
  1581. if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
  1582. {
  1583. // Create new parser
  1584. $parser = new $this->parser_class();
  1585. // If it's parsed fine
  1586. if ($parser->parse($utf8_data, 'UTF-8'))
  1587. {
  1588. $this->data = $parser->get_data();
  1589. if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
  1590. {
  1591. if (isset($headers))
  1592. {
  1593. $this->data['headers'] = $headers;
  1594. }
  1595. $this->data['build'] = SIMPLEPIE_BUILD;
  1596. // Cache the file if caching is enabled
  1597. if ($cache && !$cache->save($this))
  1598. {
  1599. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1600. }
  1601. return true;
  1602. }
  1603. else
  1604. {
  1605. $this->error = "A feed could not be found at $this->feed_url";
  1606. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1607. return false;
  1608. }
  1609. }
  1610. }
  1611. }
  1612. if(isset($parser))
  1613. {
  1614. // We have an error, just set SimplePie_Misc::error to it and quit
  1615. $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
  1616. }
  1617. else
  1618. {
  1619. $this->error = 'The data could not be converted to UTF-8';
  1620. }
  1621. SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
  1622. return false;
  1623. }
  1624. elseif (!empty($this->multifeed_url))
  1625. {
  1626. $i = 0;
  1627. $success = 0;
  1628. $this->multifeed_objects = array();
  1629. foreach ($this->multifeed_url as $url)
  1630. {
  1631. if (SIMPLEPIE_PHP5)
  1632. {
  1633. // This keyword needs to defy coding standards for PHP4 compatibility
  1634. $this->multifeed_objects[$i] = clone($this);
  1635. }
  1636. else
  1637. {
  1638. $this->multifeed_objects[$i] = $this;
  1639. }
  1640. $this->multifeed_objects[$i]->set_feed_url($url);
  1641. $success |= $this->multifeed_objects[$i]->init();
  1642. $i++;
  1643. }
  1644. return (bool) $success;
  1645. }
  1646. else
  1647. {
  1648. return false;
  1649. }
  1650. }
  1651. /**
  1652. * Return the error message for the occured error
  1653. *
  1654. * @access public
  1655. * @return string Error message
  1656. */
  1657. function error()
  1658. {
  1659. return $this->error;
  1660. }
  1661. function get_encoding()
  1662. {
  1663. return $this->sanitize->output_encoding;
  1664. }
  1665. function handle_content_type($mime = 'text/html')
  1666. {
  1667. if (!headers_sent())
  1668. {
  1669. $header = "Content-type: $mime;";
  1670. if ($this->get_encoding())
  1671. {
  1672. $header .= ' charset=' . $this->get_encoding();
  1673. }
  1674. else
  1675. {
  1676. $header .= ' charset=UTF-8';
  1677. }
  1678. header($header);
  1679. }
  1680. }
  1681. function get_type()
  1682. {
  1683. if (!isset($this->data['type']))
  1684. {
  1685. $this->data['type'] = SIMPLEPIE_TYPE_ALL;
  1686. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
  1687. {
  1688. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
  1689. }
  1690. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
  1691. {
  1692. $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
  1693. }
  1694. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
  1695. {
  1696. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
  1697. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
  1698. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
  1699. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
  1700. {
  1701. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
  1702. }
  1703. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
  1704. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
  1705. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
  1706. || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
  1707. {
  1708. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
  1709. }
  1710. }
  1711. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
  1712. {
  1713. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
  1714. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
  1715. {
  1716. switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
  1717. {
  1718. case '0.91':
  1719. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
  1720. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
  1721. {
  1722. switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
  1723. {
  1724. case '0':
  1725. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
  1726. break;
  1727. case '24':
  1728. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
  1729. break;
  1730. }
  1731. }
  1732. break;
  1733. case '0.92':
  1734. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
  1735. break;
  1736. case '0.93':
  1737. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
  1738. break;
  1739. case '0.94':
  1740. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
  1741. break;
  1742. case '2.0':
  1743. $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
  1744. break;
  1745. }
  1746. }
  1747. }
  1748. else
  1749. {
  1750. $this->data['type'] = SIMPLEPIE_TYPE_NONE;
  1751. }
  1752. }
  1753. return $this->data['type'];
  1754. }
  1755. /**
  1756. * Returns the URL for the favicon of the feed's website.
  1757. *
  1758. * @todo Cache atom:icon
  1759. * @access public
  1760. * @since 1.0
  1761. */
  1762. function get_favicon()
  1763. {
  1764. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  1765. {
  1766. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  1767. }
  1768. elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
  1769. {
  1770. $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
  1771. if ($this->cache && $this->favicon_handler)
  1772. {
  1773. $favicon_filename = call_user_func($this->cache_name_function, $favicon);
  1774. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
  1775. if ($cache->load())
  1776. {
  1777. return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
  1778. }
  1779. else
  1780. {
  1781. $file = new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
  1782. 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)
  1783. {
  1784. $sniffer = new $this->content_type_sniffer_class($file);
  1785. if (substr($sniffer->get_type(), 0, 6) === 'image/')
  1786. {
  1787. if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  1788. {
  1789. return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
  1790. }
  1791. else
  1792. {
  1793. trigger_error("$cache->name is not writeable", E_USER_WARNING);
  1794. return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
  1795. }
  1796. }
  1797. // not an image
  1798. else
  1799. {
  1800. return false;
  1801. }
  1802. }
  1803. }
  1804. }
  1805. else
  1806. {
  1807. return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
  1808. }
  1809. }
  1810. return false;
  1811. }
  1812. /**
  1813. * @todo If we have a perm redirect we should return the new URL
  1814. * @todo When we make the above change, let's support <itunes:new-feed-url> as well
  1815. * @todo Also, |atom:link|@rel=self
  1816. */
  1817. function subscribe_url()
  1818. {
  1819. if ($this->feed_url !== null)
  1820. {
  1821. return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
  1822. }
  1823. else
  1824. {
  1825. return null;
  1826. }
  1827. }
  1828. function subscribe_feed()
  1829. {
  1830. if ($this->feed_url !== null)
  1831. {
  1832. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
  1833. }
  1834. else
  1835. {
  1836. return null;
  1837. }
  1838. }
  1839. function subscribe_outlook()
  1840. {
  1841. if ($this->feed_url !== null)
  1842. {
  1843. return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
  1844. }
  1845. else
  1846. {
  1847. return null;
  1848. }
  1849. }
  1850. function subscribe_podcast()
  1851. {
  1852. if ($this->feed_url !== null)
  1853. {
  1854. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
  1855. }
  1856. else
  1857. {
  1858. return null;
  1859. }
  1860. }
  1861. function subscribe_itunes()
  1862. {
  1863. if ($this->feed_url !== null)
  1864. {
  1865. return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
  1866. }
  1867. else
  1868. {
  1869. return null;
  1870. }
  1871. }
  1872. /**
  1873. * Creates the subscribe_* methods' return data
  1874. *
  1875. * @access private
  1876. * @param string $feed_url String to prefix to the feed URL
  1877. * @param string $site_url String to prefix to the site URL (and
  1878. * suffix to the feed URL)
  1879. * @return mixed URL if feed exists, false otherwise
  1880. */
  1881. function subscribe_service($feed_url, $site_url = null)
  1882. {
  1883. if ($this->subscribe_url())
  1884. {
  1885. $return = $feed_url . rawurlencode($this->feed_url);
  1886. if ($site_url !== null && $this->get_link() !== null)
  1887. {
  1888. $return .= $site_url . rawurlencode($this->get_link());
  1889. }
  1890. return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
  1891. }
  1892. else
  1893. {
  1894. return null;
  1895. }
  1896. }
  1897. function subscribe_aol()
  1898. {
  1899. return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
  1900. }
  1901. function subscribe_bloglines()
  1902. {
  1903. return $this->subscribe_service('http://www.bloglines.com/sub/');
  1904. }
  1905. function subscribe_eskobo()
  1906. {
  1907. return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
  1908. }
  1909. function subscribe_feedfeeds()
  1910. {
  1911. return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
  1912. }
  1913. function subscribe_feedster()
  1914. {
  1915. return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
  1916. }
  1917. function subscribe_google()
  1918. {
  1919. return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
  1920. }
  1921. function subscribe_gritwire()
  1922. {
  1923. return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
  1924. }
  1925. function subscribe_msn()
  1926. {
  1927. return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
  1928. }
  1929. function subscribe_netvibes()
  1930. {
  1931. return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
  1932. }
  1933. function subscribe_newsburst()
  1934. {
  1935. return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
  1936. }
  1937. function subscribe_newsgator()
  1938. {
  1939. return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
  1940. }
  1941. function subscribe_odeo()
  1942. {
  1943. return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
  1944. }
  1945. function subscribe_podnova()
  1946. {
  1947. return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
  1948. }
  1949. function subscribe_rojo()
  1950. {
  1951. return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
  1952. }
  1953. function subscribe_yahoo()
  1954. {
  1955. return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
  1956. }
  1957. function get_feed_tags($namespace, $tag)
  1958. {
  1959. $type = $this->get_type();
  1960. if ($type & SIMPLEPIE_TYPE_ATOM_10)
  1961. {
  1962. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
  1963. {
  1964. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
  1965. }
  1966. }
  1967. if ($type & SIMPLEPIE_TYPE_ATOM_03)
  1968. {
  1969. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
  1970. {
  1971. return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
  1972. }
  1973. }
  1974. if ($type & SIMPLEPIE_TYPE_RSS_RDF)
  1975. {
  1976. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
  1977. {
  1978. return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
  1979. }
  1980. }
  1981. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  1982. {
  1983. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
  1984. {
  1985. return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
  1986. }
  1987. }
  1988. return null;
  1989. }
  1990. function get_channel_tags($namespace, $tag)
  1991. {
  1992. $type = $this->get_type();
  1993. if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
  1994. {
  1995. if ($return = $this->get_feed_tags($namespace, $tag))
  1996. {
  1997. return $return;
  1998. }
  1999. }
  2000. if ($type & SIMPLEPIE_TYPE_RSS_10)
  2001. {
  2002. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
  2003. {
  2004. if (isset($channel[0]['child'][$namespace][$tag]))
  2005. {
  2006. return $channel[0]['child'][$namespace][$tag];
  2007. }
  2008. }
  2009. }
  2010. if ($type & SIMPLEPIE_TYPE_RSS_090)
  2011. {
  2012. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
  2013. {
  2014. if (isset($channel[0]['child'][$namespace][$tag]))
  2015. {
  2016. return $channel[0]['child'][$namespace][$tag];
  2017. }
  2018. }
  2019. }
  2020. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  2021. {
  2022. if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
  2023. {
  2024. if (isset($channel[0]['child'][$namespace][$tag]))
  2025. {
  2026. return $channel[0]['child'][$namespace][$tag];
  2027. }
  2028. }
  2029. }
  2030. return null;
  2031. }
  2032. function get_image_tags($namespace, $tag)
  2033. {
  2034. $type = $this->get_type();
  2035. if ($type & SIMPLEPIE_TYPE_RSS_10)
  2036. {
  2037. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
  2038. {
  2039. if (isset($image[0]['child'][$namespace][$tag]))
  2040. {
  2041. return $image[0]['child'][$namespace][$tag];
  2042. }
  2043. }
  2044. }
  2045. if ($type & SIMPLEPIE_TYPE_RSS_090)
  2046. {
  2047. if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
  2048. {
  2049. if (isset($image[0]['child'][$namespace][$tag]))
  2050. {
  2051. return $image[0]['child'][$namespace][$tag];
  2052. }
  2053. }
  2054. }
  2055. if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
  2056. {
  2057. if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
  2058. {
  2059. if (isset($image[0]['child'][$namespace][$tag]))
  2060. {
  2061. return $image[0]['child'][$namespace][$tag];
  2062. }
  2063. }
  2064. }
  2065. return null;
  2066. }
  2067. function get_base($element = array())
  2068. {
  2069. if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
  2070. {
  2071. return $element['xml_base'];
  2072. }
  2073. elseif ($this->get_link() !== null)
  2074. {
  2075. return $this->get_link();
  2076. }
  2077. else
  2078. {
  2079. return $this->subscribe_url();
  2080. }
  2081. }
  2082. function sanitize($data, $type, $base = '')
  2083. {
  2084. return $this->sanitize->sanitize($data, $type, $base);
  2085. }
  2086. function get_title()
  2087. {
  2088. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  2089. {
  2090. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2091. }
  2092. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  2093. {
  2094. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2095. }
  2096. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2097. {
  2098. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2099. }
  2100. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2101. {
  2102. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2103. }
  2104. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  2105. {
  2106. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2107. }
  2108. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2109. {
  2110. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2111. }
  2112. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2113. {
  2114. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2115. }
  2116. else
  2117. {
  2118. return null;
  2119. }
  2120. }
  2121. function get_category($key = 0)
  2122. {
  2123. $categories = $this->get_categories();
  2124. if (isset($categories[$key]))
  2125. {
  2126. return $categories[$key];
  2127. }
  2128. else
  2129. {
  2130. return null;
  2131. }
  2132. }
  2133. function get_categories()
  2134. {
  2135. $categories = array();
  2136. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  2137. {
  2138. $term = null;
  2139. $scheme = null;
  2140. $label = null;
  2141. if (isset($category['attribs']['']['term']))
  2142. {
  2143. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  2144. }
  2145. if (isset($category['attribs']['']['scheme']))
  2146. {
  2147. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  2148. }
  2149. if (isset($category['attribs']['']['label']))
  2150. {
  2151. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  2152. }
  2153. $categories[] = new $this->category_class($term, $scheme, $label);
  2154. }
  2155. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
  2156. {
  2157. // This is really the label, but keep this as the term also for BC.
  2158. // Label will also work on retrieving because that falls back to term.
  2159. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2160. if (isset($category['attribs']['']['domain']))
  2161. {
  2162. $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
  2163. }
  2164. else
  2165. {
  2166. $scheme = null;
  2167. }
  2168. $categories[] = new $this->category_class($term, $scheme, null);
  2169. }
  2170. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  2171. {
  2172. $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2173. }
  2174. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  2175. {
  2176. $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2177. }
  2178. if (!empty($categories))
  2179. {
  2180. return SimplePie_Misc::array_unique($categories);
  2181. }
  2182. else
  2183. {
  2184. return null;
  2185. }
  2186. }
  2187. function get_author($key = 0)
  2188. {
  2189. $authors = $this->get_authors();
  2190. if (isset($authors[$key]))
  2191. {
  2192. return $authors[$key];
  2193. }
  2194. else
  2195. {
  2196. return null;
  2197. }
  2198. }
  2199. function get_authors()
  2200. {
  2201. $authors = array();
  2202. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  2203. {
  2204. $name = null;
  2205. $uri = null;
  2206. $email = null;
  2207. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  2208. {
  2209. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2210. }
  2211. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  2212. {
  2213. $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]));
  2214. }
  2215. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  2216. {
  2217. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2218. }
  2219. if ($name !== null || $email !== null || $uri !== null)
  2220. {
  2221. $authors[] = new $this->author_class($name, $uri, $email);
  2222. }
  2223. }
  2224. if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  2225. {
  2226. $name = null;
  2227. $url = null;
  2228. $email = null;
  2229. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  2230. {
  2231. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2232. }
  2233. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  2234. {
  2235. $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]));
  2236. }
  2237. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  2238. {
  2239. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2240. }
  2241. if ($name !== null || $email !== null || $url !== null)
  2242. {
  2243. $authors[] = new $this->author_class($name, $url, $email);
  2244. }
  2245. }
  2246. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  2247. {
  2248. $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2249. }
  2250. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  2251. {
  2252. $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2253. }
  2254. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  2255. {
  2256. $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  2257. }
  2258. if (!empty($authors))
  2259. {
  2260. return SimplePie_Misc::array_unique($authors);
  2261. }
  2262. else
  2263. {
  2264. return null;
  2265. }
  2266. }
  2267. function get_contributor($key = 0)
  2268. {
  2269. $contributors = $this->get_contributors();
  2270. if (isset($contributors[$key]))
  2271. {
  2272. return $contributors[$key];
  2273. }
  2274. else
  2275. {
  2276. return null;
  2277. }
  2278. }
  2279. function get_contributors()
  2280. {
  2281. $contributors = array();
  2282. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  2283. {
  2284. $name = null;
  2285. $uri = null;
  2286. $email = null;
  2287. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  2288. {
  2289. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2290. }
  2291. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  2292. {
  2293. $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]));
  2294. }
  2295. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  2296. {
  2297. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2298. }
  2299. if ($name !== null || $email !== null || $uri !== null)
  2300. {
  2301. $contributors[] = new $this->author_class($name, $uri, $email);
  2302. }
  2303. }
  2304. foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  2305. {
  2306. $name = null;
  2307. $url = null;
  2308. $email = null;
  2309. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  2310. {
  2311. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2312. }
  2313. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  2314. {
  2315. $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]));
  2316. }
  2317. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  2318. {
  2319. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2320. }
  2321. if ($name !== null || $email !== null || $url !== null)
  2322. {
  2323. $contributors[] = new $this->author_class($name, $url, $email);
  2324. }
  2325. }
  2326. if (!empty($contributors))
  2327. {
  2328. return SimplePie_Misc::array_unique($contributors);
  2329. }
  2330. else
  2331. {
  2332. return null;
  2333. }
  2334. }
  2335. function get_link($key = 0, $rel = 'alternate')
  2336. {
  2337. $links = $this->get_links($rel);
  2338. if (isset($links[$key]))
  2339. {
  2340. return $links[$key];
  2341. }
  2342. else
  2343. {
  2344. return null;
  2345. }
  2346. }
  2347. /**
  2348. * Added for parity between the parent-level and the item/entry-level.
  2349. */
  2350. function get_permalink()
  2351. {
  2352. return $this->get_link(0);
  2353. }
  2354. function get_links($rel = 'alternate')
  2355. {
  2356. if (!isset($this->data['links']))
  2357. {
  2358. $this->data['links'] = array();
  2359. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  2360. {
  2361. foreach ($links as $link)
  2362. {
  2363. if (isset($link['attribs']['']['href']))
  2364. {
  2365. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2366. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2367. }
  2368. }
  2369. }
  2370. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  2371. {
  2372. foreach ($links as $link)
  2373. {
  2374. if (isset($link['attribs']['']['href']))
  2375. {
  2376. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  2377. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  2378. }
  2379. }
  2380. }
  2381. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2382. {
  2383. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2384. }
  2385. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2386. {
  2387. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2388. }
  2389. if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  2390. {
  2391. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  2392. }
  2393. $keys = array_keys($this->data['links']);
  2394. foreach ($keys as $key)
  2395. {
  2396. if (SimplePie_Misc::is_isegment_nz_nc($key))
  2397. {
  2398. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  2399. {
  2400. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  2401. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  2402. }
  2403. else
  2404. {
  2405. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  2406. }
  2407. }
  2408. elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  2409. {
  2410. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  2411. }
  2412. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  2413. }
  2414. }
  2415. if (isset($this->data['links'][$rel]))
  2416. {
  2417. return $this->data['links'][$rel];
  2418. }
  2419. else
  2420. {
  2421. return null;
  2422. }
  2423. }
  2424. function get_all_discovered_feeds()
  2425. {
  2426. return $this->all_discovered_feeds;
  2427. }
  2428. function get_description()
  2429. {
  2430. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  2431. {
  2432. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2433. }
  2434. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  2435. {
  2436. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2437. }
  2438. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  2439. {
  2440. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2441. }
  2442. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  2443. {
  2444. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2445. }
  2446. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
  2447. {
  2448. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2449. }
  2450. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  2451. {
  2452. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2453. }
  2454. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  2455. {
  2456. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2457. }
  2458. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  2459. {
  2460. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2461. }
  2462. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  2463. {
  2464. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2465. }
  2466. else
  2467. {
  2468. return null;
  2469. }
  2470. }
  2471. function get_copyright()
  2472. {
  2473. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  2474. {
  2475. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2476. }
  2477. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
  2478. {
  2479. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2480. }
  2481. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
  2482. {
  2483. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2484. }
  2485. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  2486. {
  2487. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2488. }
  2489. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  2490. {
  2491. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2492. }
  2493. else
  2494. {
  2495. return null;
  2496. }
  2497. }
  2498. function get_language()
  2499. {
  2500. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
  2501. {
  2502. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2503. }
  2504. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  2505. {
  2506. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2507. }
  2508. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  2509. {
  2510. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2511. }
  2512. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
  2513. {
  2514. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2515. }
  2516. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
  2517. {
  2518. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2519. }
  2520. elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
  2521. {
  2522. return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  2523. }
  2524. elseif (isset($this->data['headers']['content-language']))
  2525. {
  2526. return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
  2527. }
  2528. else
  2529. {
  2530. return null;
  2531. }
  2532. }
  2533. function get_latitude()
  2534. {
  2535. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  2536. {
  2537. return (float) $return[0]['data'];
  2538. }
  2539. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  2540. {
  2541. return (float) $match[1];
  2542. }
  2543. else
  2544. {
  2545. return null;
  2546. }
  2547. }
  2548. function get_longitude()
  2549. {
  2550. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  2551. {
  2552. return (float) $return[0]['data'];
  2553. }
  2554. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  2555. {
  2556. return (float) $return[0]['data'];
  2557. }
  2558. elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  2559. {
  2560. return (float) $match[2];
  2561. }
  2562. else
  2563. {
  2564. return null;
  2565. }
  2566. }
  2567. function get_image_title()
  2568. {
  2569. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2570. {
  2571. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2572. }
  2573. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2574. {
  2575. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2576. }
  2577. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  2578. {
  2579. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2580. }
  2581. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2582. {
  2583. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2584. }
  2585. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2586. {
  2587. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2588. }
  2589. else
  2590. {
  2591. return null;
  2592. }
  2593. }
  2594. function get_image_url()
  2595. {
  2596. if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  2597. {
  2598. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  2599. }
  2600. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  2601. {
  2602. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2603. }
  2604. elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  2605. {
  2606. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2607. }
  2608. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
  2609. {
  2610. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2611. }
  2612. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
  2613. {
  2614. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2615. }
  2616. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2617. {
  2618. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2619. }
  2620. else
  2621. {
  2622. return null;
  2623. }
  2624. }
  2625. function get_image_link()
  2626. {
  2627. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  2628. {
  2629. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2630. }
  2631. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  2632. {
  2633. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2634. }
  2635. elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  2636. {
  2637. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2638. }
  2639. else
  2640. {
  2641. return null;
  2642. }
  2643. }
  2644. function get_image_width()
  2645. {
  2646. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
  2647. {
  2648. return round($return[0]['data']);
  2649. }
  2650. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2651. {
  2652. return 88.0;
  2653. }
  2654. else
  2655. {
  2656. return null;
  2657. }
  2658. }
  2659. function get_image_height()
  2660. {
  2661. if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
  2662. {
  2663. return round($return[0]['data']);
  2664. }
  2665. elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2666. {
  2667. return 31.0;
  2668. }
  2669. else
  2670. {
  2671. return null;
  2672. }
  2673. }
  2674. function get_item_quantity($max = 0)
  2675. {
  2676. $max = (int) $max;
  2677. $qty = count($this->get_items());
  2678. if ($max === 0)
  2679. {
  2680. return $qty;
  2681. }
  2682. else
  2683. {
  2684. return ($qty > $max) ? $max : $qty;
  2685. }
  2686. }
  2687. function get_item($key = 0)
  2688. {
  2689. $items = $this->get_items();
  2690. if (isset($items[$key]))
  2691. {
  2692. return $items[$key];
  2693. }
  2694. else
  2695. {
  2696. return null;
  2697. }
  2698. }
  2699. function get_items($start = 0, $end = 0)
  2700. {
  2701. if (!isset($this->data['items']))
  2702. {
  2703. if (!empty($this->multifeed_objects))
  2704. {
  2705. $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
  2706. }
  2707. else
  2708. {
  2709. $this->data['items'] = array();
  2710. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
  2711. {
  2712. $keys = array_keys($items);
  2713. foreach ($keys as $key)
  2714. {
  2715. $this->data['items'][] = new $this->item_class($this, $items[$key]);
  2716. }
  2717. }
  2718. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
  2719. {
  2720. $keys = array_keys($items);
  2721. foreach ($keys as $key)
  2722. {
  2723. $this->data['items'][] = new $this->item_class($this, $items[$key]);
  2724. }
  2725. }
  2726. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
  2727. {
  2728. $keys = array_keys($items);
  2729. foreach ($keys as $key)
  2730. {
  2731. $this->data['items'][] = new $this->item_class($this, $items[$key]);
  2732. }
  2733. }
  2734. if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
  2735. {
  2736. $keys = array_keys($items);
  2737. foreach ($keys as $key)
  2738. {
  2739. $this->data['items'][] = new $this->item_class($this, $items[$key]);
  2740. }
  2741. }
  2742. if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
  2743. {
  2744. $keys = array_keys($items);
  2745. foreach ($keys as $key)
  2746. {
  2747. $this->data['items'][] = new $this->item_class($this, $items[$key]);
  2748. }
  2749. }
  2750. }
  2751. }
  2752. if (!empty($this->data['items']))
  2753. {
  2754. // If we want to order it by date, check if all items have a date, and then sort it
  2755. if ($this->order_by_date && empty($this->multifeed_objects))
  2756. {
  2757. if (!isset($this->data['ordered_items']))
  2758. {
  2759. $do_sort = true;
  2760. foreach ($this->data['items'] as $item)
  2761. {
  2762. if (!$item->get_date('U'))
  2763. {
  2764. $do_sort = false;
  2765. break;
  2766. }
  2767. }
  2768. $item = null;
  2769. $this->data['ordered_items'] = $this->data['items'];
  2770. if ($do_sort)
  2771. {
  2772. usort($this->data['ordered_items'], array(&$this, 'sort_items'));
  2773. }
  2774. }
  2775. $items = $this->data['ordered_items'];
  2776. }
  2777. else
  2778. {
  2779. $items = $this->data['items'];
  2780. }
  2781. // Slice the data as desired
  2782. if ($end === 0)
  2783. {
  2784. return array_slice($items, $start);
  2785. }
  2786. else
  2787. {
  2788. return array_slice($items, $start, $end);
  2789. }
  2790. }
  2791. else
  2792. {
  2793. return array();
  2794. }
  2795. }
  2796. /**
  2797. * @static
  2798. */
  2799. function sort_items($a, $b)
  2800. {
  2801. return $a->get_date('U') <= $b->get_date('U');
  2802. }
  2803. /**
  2804. * @static
  2805. */
  2806. function merge_items($urls, $start = 0, $end = 0, $limit = 0)
  2807. {
  2808. if (is_array($urls) && sizeof($urls) > 0)
  2809. {
  2810. $items = array();
  2811. foreach ($urls as $arg)
  2812. {
  2813. if (is_a($arg, 'SimplePie'))
  2814. {
  2815. $items = array_merge($items, $arg->get_items(0, $limit));
  2816. }
  2817. else
  2818. {
  2819. trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
  2820. }
  2821. }
  2822. $do_sort = true;
  2823. foreach ($items as $item)
  2824. {
  2825. if (!$item->get_date('U'))
  2826. {
  2827. $do_sort = false;
  2828. break;
  2829. }
  2830. }
  2831. $item = null;
  2832. if ($do_sort)
  2833. {
  2834. usort($items, array('SimplePie', 'sort_items'));
  2835. }
  2836. if ($end === 0)
  2837. {
  2838. return array_slice($items, $start);
  2839. }
  2840. else
  2841. {
  2842. return array_slice($items, $start, $end);
  2843. }
  2844. }
  2845. else
  2846. {
  2847. trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
  2848. return array();
  2849. }
  2850. }
  2851. }
  2852. class SimplePie_Item
  2853. {
  2854. var $feed;
  2855. var $data = array();
  2856. function SimplePie_Item($feed, $data)
  2857. {
  2858. $this->feed = $feed;
  2859. $this->data = $data;
  2860. }
  2861. function __toString()
  2862. {
  2863. return md5(serialize($this->data));
  2864. }
  2865. /**
  2866. * Remove items that link back to this before destroying this object
  2867. */
  2868. function __destruct()
  2869. {
  2870. if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
  2871. {
  2872. unset($this->feed);
  2873. }
  2874. }
  2875. function get_item_tags($namespace, $tag)
  2876. {
  2877. if (isset($this->data['child'][$namespace][$tag]))
  2878. {
  2879. return $this->data['child'][$namespace][$tag];
  2880. }
  2881. else
  2882. {
  2883. return null;
  2884. }
  2885. }
  2886. function get_base($element = array())
  2887. {
  2888. return $this->feed->get_base($element);
  2889. }
  2890. function sanitize($data, $type, $base = '')
  2891. {
  2892. return $this->feed->sanitize($data, $type, $base);
  2893. }
  2894. function get_feed()
  2895. {
  2896. return $this->feed;
  2897. }
  2898. function get_id($hash = false)
  2899. {
  2900. if (!$hash)
  2901. {
  2902. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
  2903. {
  2904. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2905. }
  2906. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
  2907. {
  2908. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2909. }
  2910. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
  2911. {
  2912. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2913. }
  2914. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
  2915. {
  2916. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2917. }
  2918. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
  2919. {
  2920. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2921. }
  2922. elseif (($return = $this->get_permalink()) !== null)
  2923. {
  2924. return $return;
  2925. }
  2926. elseif (($return = $this->get_title()) !== null)
  2927. {
  2928. return $return;
  2929. }
  2930. }
  2931. if ($this->get_permalink() !== null || $this->get_title() !== null)
  2932. {
  2933. return md5($this->get_permalink() . $this->get_title());
  2934. }
  2935. else
  2936. {
  2937. return md5(serialize($this->data));
  2938. }
  2939. }
  2940. function get_title()
  2941. {
  2942. if (!isset($this->data['title']))
  2943. {
  2944. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  2945. {
  2946. $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2947. }
  2948. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  2949. {
  2950. $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2951. }
  2952. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  2953. {
  2954. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2955. }
  2956. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  2957. {
  2958. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2959. }
  2960. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  2961. {
  2962. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2963. }
  2964. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  2965. {
  2966. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2967. }
  2968. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2969. {
  2970. $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2971. }
  2972. else
  2973. {
  2974. $this->data['title'] = null;
  2975. }
  2976. }
  2977. return $this->data['title'];
  2978. }
  2979. function get_description($description_only = false)
  2980. {
  2981. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
  2982. {
  2983. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2984. }
  2985. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
  2986. {
  2987. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  2988. }
  2989. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  2990. {
  2991. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  2992. }
  2993. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
  2994. {
  2995. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2996. }
  2997. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  2998. {
  2999. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3000. }
  3001. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  3002. {
  3003. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3004. }
  3005. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  3006. {
  3007. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  3008. }
  3009. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  3010. {
  3011. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3012. }
  3013. elseif (!$description_only)
  3014. {
  3015. return $this->get_content(true);
  3016. }
  3017. else
  3018. {
  3019. return null;
  3020. }
  3021. }
  3022. function get_content($content_only = false)
  3023. {
  3024. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
  3025. {
  3026. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  3027. }
  3028. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
  3029. {
  3030. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  3031. }
  3032. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
  3033. {
  3034. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  3035. }
  3036. elseif (!$content_only)
  3037. {
  3038. return $this->get_description(true);
  3039. }
  3040. else
  3041. {
  3042. return null;
  3043. }
  3044. }
  3045. function get_category($key = 0)
  3046. {
  3047. $categories = $this->get_categories();
  3048. if (isset($categories[$key]))
  3049. {
  3050. return $categories[$key];
  3051. }
  3052. else
  3053. {
  3054. return null;
  3055. }
  3056. }
  3057. function get_categories()
  3058. {
  3059. $categories = array();
  3060. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  3061. {
  3062. $term = null;
  3063. $scheme = null;
  3064. $label = null;
  3065. if (isset($category['attribs']['']['term']))
  3066. {
  3067. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  3068. }
  3069. if (isset($category['attribs']['']['scheme']))
  3070. {
  3071. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3072. }
  3073. if (isset($category['attribs']['']['label']))
  3074. {
  3075. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3076. }
  3077. $categories[] = new $this->feed->category_class($term, $scheme, $label);
  3078. }
  3079. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
  3080. {
  3081. // This is really the label, but keep this as the term also for BC.
  3082. // Label will also work on retrieving because that falls back to term.
  3083. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3084. if (isset($category['attribs']['']['domain']))
  3085. {
  3086. $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
  3087. }
  3088. else
  3089. {
  3090. $scheme = null;
  3091. }
  3092. $categories[] = new $this->feed->category_class($term, $scheme, null);
  3093. }
  3094. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  3095. {
  3096. $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3097. }
  3098. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  3099. {
  3100. $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3101. }
  3102. if (!empty($categories))
  3103. {
  3104. return SimplePie_Misc::array_unique($categories);
  3105. }
  3106. else
  3107. {
  3108. return null;
  3109. }
  3110. }
  3111. function get_author($key = 0)
  3112. {
  3113. $authors = $this->get_authors();
  3114. if (isset($authors[$key]))
  3115. {
  3116. return $authors[$key];
  3117. }
  3118. else
  3119. {
  3120. return null;
  3121. }
  3122. }
  3123. function get_contributor($key = 0)
  3124. {
  3125. $contributors = $this->get_contributors();
  3126. if (isset($contributors[$key]))
  3127. {
  3128. return $contributors[$key];
  3129. }
  3130. else
  3131. {
  3132. return null;
  3133. }
  3134. }
  3135. function get_contributors()
  3136. {
  3137. $contributors = array();
  3138. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  3139. {
  3140. $name = null;
  3141. $uri = null;
  3142. $email = null;
  3143. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  3144. {
  3145. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3146. }
  3147. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  3148. {
  3149. $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]));
  3150. }
  3151. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  3152. {
  3153. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3154. }
  3155. if ($name !== null || $email !== null || $uri !== null)
  3156. {
  3157. $contributors[] = new $this->feed->author_class($name, $uri, $email);
  3158. }
  3159. }
  3160. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  3161. {
  3162. $name = null;
  3163. $url = null;
  3164. $email = null;
  3165. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  3166. {
  3167. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3168. }
  3169. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  3170. {
  3171. $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]));
  3172. }
  3173. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  3174. {
  3175. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3176. }
  3177. if ($name !== null || $email !== null || $url !== null)
  3178. {
  3179. $contributors[] = new $this->feed->author_class($name, $url, $email);
  3180. }
  3181. }
  3182. if (!empty($contributors))
  3183. {
  3184. return SimplePie_Misc::array_unique($contributors);
  3185. }
  3186. else
  3187. {
  3188. return null;
  3189. }
  3190. }
  3191. function get_authors()
  3192. {
  3193. $authors = array();
  3194. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  3195. {
  3196. $name = null;
  3197. $uri = null;
  3198. $email = null;
  3199. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  3200. {
  3201. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3202. }
  3203. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  3204. {
  3205. $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]));
  3206. }
  3207. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  3208. {
  3209. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3210. }
  3211. if ($name !== null || $email !== null || $uri !== null)
  3212. {
  3213. $authors[] = new $this->feed->author_class($name, $uri, $email);
  3214. }
  3215. }
  3216. if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  3217. {
  3218. $name = null;
  3219. $url = null;
  3220. $email = null;
  3221. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  3222. {
  3223. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3224. }
  3225. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  3226. {
  3227. $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]));
  3228. }
  3229. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  3230. {
  3231. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3232. }
  3233. if ($name !== null || $email !== null || $url !== null)
  3234. {
  3235. $authors[] = new $this->feed->author_class($name, $url, $email);
  3236. }
  3237. }
  3238. if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
  3239. {
  3240. $authors[] = new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3241. }
  3242. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  3243. {
  3244. $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3245. }
  3246. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  3247. {
  3248. $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3249. }
  3250. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  3251. {
  3252. $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  3253. }
  3254. if (!empty($authors))
  3255. {
  3256. return SimplePie_Misc::array_unique($authors);
  3257. }
  3258. elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
  3259. {
  3260. return $authors;
  3261. }
  3262. elseif ($authors = $this->feed->get_authors())
  3263. {
  3264. return $authors;
  3265. }
  3266. else
  3267. {
  3268. return null;
  3269. }
  3270. }
  3271. function get_copyright()
  3272. {
  3273. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  3274. {
  3275. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  3276. }
  3277. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  3278. {
  3279. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3280. }
  3281. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  3282. {
  3283. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3284. }
  3285. else
  3286. {
  3287. return null;
  3288. }
  3289. }
  3290. function get_date($date_format = 'j F Y, g:i a')
  3291. {
  3292. if (!isset($this->data['date']))
  3293. {
  3294. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
  3295. {
  3296. $this->data['date']['raw'] = $return[0]['data'];
  3297. }
  3298. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
  3299. {
  3300. $this->data['date']['raw'] = $return[0]['data'];
  3301. }
  3302. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
  3303. {
  3304. $this->data['date']['raw'] = $return[0]['data'];
  3305. }
  3306. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
  3307. {
  3308. $this->data['date']['raw'] = $return[0]['data'];
  3309. }
  3310. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
  3311. {
  3312. $this->data['date']['raw'] = $return[0]['data'];
  3313. }
  3314. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
  3315. {
  3316. $this->data['date']['raw'] = $return[0]['data'];
  3317. }
  3318. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
  3319. {
  3320. $this->data['date']['raw'] = $return[0]['data'];
  3321. }
  3322. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
  3323. {
  3324. $this->data['date']['raw'] = $return[0]['data'];
  3325. }
  3326. if (!empty($this->data['date']['raw']))
  3327. {
  3328. $parser = SimplePie_Parse_Date::get();
  3329. $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
  3330. }
  3331. else
  3332. {
  3333. $this->data['date'] = null;
  3334. }
  3335. }
  3336. if ($this->data['date'])
  3337. {
  3338. $date_format = (string) $date_format;
  3339. switch ($date_format)
  3340. {
  3341. case '':
  3342. return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
  3343. case 'U':
  3344. return $this->data['date']['parsed'];
  3345. default:
  3346. return date($date_format, $this->data['date']['parsed']);
  3347. }
  3348. }
  3349. else
  3350. {
  3351. return null;
  3352. }
  3353. }
  3354. function get_local_date($date_format = '%c')
  3355. {
  3356. if (!$date_format)
  3357. {
  3358. return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
  3359. }
  3360. elseif (($date = $this->get_date('U')) !== null)
  3361. {
  3362. return strftime($date_format, $date);
  3363. }
  3364. else
  3365. {
  3366. return null;
  3367. }
  3368. }
  3369. function get_permalink()
  3370. {
  3371. $link = $this->get_link();
  3372. $enclosure = $this->get_enclosure(0);
  3373. if ($link !== null)
  3374. {
  3375. return $link;
  3376. }
  3377. elseif ($enclosure !== null)
  3378. {
  3379. return $enclosure->get_link();
  3380. }
  3381. else
  3382. {
  3383. return null;
  3384. }
  3385. }
  3386. function get_link($key = 0, $rel = 'alternate')
  3387. {
  3388. $links = $this->get_links($rel);
  3389. if ($links[$key] !== null)
  3390. {
  3391. return $links[$key];
  3392. }
  3393. else
  3394. {
  3395. return null;
  3396. }
  3397. }
  3398. function get_links($rel = 'alternate')
  3399. {
  3400. if (!isset($this->data['links']))
  3401. {
  3402. $this->data['links'] = array();
  3403. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  3404. {
  3405. if (isset($link['attribs']['']['href']))
  3406. {
  3407. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  3408. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  3409. }
  3410. }
  3411. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  3412. {
  3413. if (isset($link['attribs']['']['href']))
  3414. {
  3415. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  3416. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  3417. }
  3418. }
  3419. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  3420. {
  3421. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3422. }
  3423. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  3424. {
  3425. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3426. }
  3427. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  3428. {
  3429. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3430. }
  3431. if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
  3432. {
  3433. if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')
  3434. {
  3435. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  3436. }
  3437. }
  3438. $keys = array_keys($this->data['links']);
  3439. foreach ($keys as $key)
  3440. {
  3441. if (SimplePie_Misc::is_isegment_nz_nc($key))
  3442. {
  3443. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  3444. {
  3445. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  3446. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  3447. }
  3448. else
  3449. {
  3450. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  3451. }
  3452. }
  3453. elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  3454. {
  3455. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  3456. }
  3457. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  3458. }
  3459. }
  3460. if (isset($this->data['links'][$rel]))
  3461. {
  3462. return $this->data['links'][$rel];
  3463. }
  3464. else
  3465. {
  3466. return null;
  3467. }
  3468. }
  3469. /**
  3470. * @todo Add ability to prefer one type of content over another (in a media group).
  3471. */
  3472. function get_enclosure($key = 0, $prefer = null)
  3473. {
  3474. $enclosures = $this->get_enclosures();
  3475. if (isset($enclosures[$key]))
  3476. {
  3477. return $enclosures[$key];
  3478. }
  3479. else
  3480. {
  3481. return null;
  3482. }
  3483. }
  3484. /**
  3485. * Grabs all available enclosures (podcasts, etc.)
  3486. *
  3487. * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
  3488. *
  3489. * 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.
  3490. *
  3491. * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
  3492. * @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).
  3493. */
  3494. function get_enclosures()
  3495. {
  3496. if (!isset($this->data['enclosures']))
  3497. {
  3498. $this->data['enclosures'] = array();
  3499. // Elements
  3500. $captions_parent = null;
  3501. $categories_parent = null;
  3502. $copyrights_parent = null;
  3503. $credits_parent = null;
  3504. $description_parent = null;
  3505. $duration_parent = null;
  3506. $hashes_parent = null;
  3507. $keywords_parent = null;
  3508. $player_parent = null;
  3509. $ratings_parent = null;
  3510. $restrictions_parent = null;
  3511. $thumbnails_parent = null;
  3512. $title_parent = null;
  3513. // Let's do the channel and item-level ones first, and just re-use them if we need to.
  3514. $parent = $this->get_feed();
  3515. // CAPTIONS
  3516. if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  3517. {
  3518. foreach ($captions as $caption)
  3519. {
  3520. $caption_type = null;
  3521. $caption_lang = null;
  3522. $caption_startTime = null;
  3523. $caption_endTime = null;
  3524. $caption_text = null;
  3525. if (isset($caption['attribs']['']['type']))
  3526. {
  3527. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3528. }
  3529. if (isset($caption['attribs']['']['lang']))
  3530. {
  3531. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3532. }
  3533. if (isset($caption['attribs']['']['start']))
  3534. {
  3535. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3536. }
  3537. if (isset($caption['attribs']['']['end']))
  3538. {
  3539. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3540. }
  3541. if (isset($caption['data']))
  3542. {
  3543. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3544. }
  3545. $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3546. }
  3547. }
  3548. elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
  3549. {
  3550. foreach ($captions as $caption)
  3551. {
  3552. $caption_type = null;
  3553. $caption_lang = null;
  3554. $caption_startTime = null;
  3555. $caption_endTime = null;
  3556. $caption_text = null;
  3557. if (isset($caption['attribs']['']['type']))
  3558. {
  3559. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3560. }
  3561. if (isset($caption['attribs']['']['lang']))
  3562. {
  3563. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  3564. }
  3565. if (isset($caption['attribs']['']['start']))
  3566. {
  3567. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  3568. }
  3569. if (isset($caption['attribs']['']['end']))
  3570. {
  3571. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  3572. }
  3573. if (isset($caption['data']))
  3574. {
  3575. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3576. }
  3577. $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  3578. }
  3579. }
  3580. if (is_array($captions_parent))
  3581. {
  3582. $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
  3583. }
  3584. // CATEGORIES
  3585. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  3586. {
  3587. $term = null;
  3588. $scheme = null;
  3589. $label = null;
  3590. if (isset($category['data']))
  3591. {
  3592. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3593. }
  3594. if (isset($category['attribs']['']['scheme']))
  3595. {
  3596. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3597. }
  3598. else
  3599. {
  3600. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3601. }
  3602. if (isset($category['attribs']['']['label']))
  3603. {
  3604. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3605. }
  3606. $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
  3607. }
  3608. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
  3609. {
  3610. $term = null;
  3611. $scheme = null;
  3612. $label = null;
  3613. if (isset($category['data']))
  3614. {
  3615. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3616. }
  3617. if (isset($category['attribs']['']['scheme']))
  3618. {
  3619. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3620. }
  3621. else
  3622. {
  3623. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  3624. }
  3625. if (isset($category['attribs']['']['label']))
  3626. {
  3627. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  3628. }
  3629. $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
  3630. }
  3631. foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
  3632. {
  3633. $term = null;
  3634. $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
  3635. $label = null;
  3636. if (isset($category['attribs']['']['text']))
  3637. {
  3638. $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  3639. }
  3640. $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
  3641. if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
  3642. {
  3643. foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
  3644. {
  3645. if (isset($subcategory['attribs']['']['text']))
  3646. {
  3647. $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
  3648. }
  3649. $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
  3650. }
  3651. }
  3652. }
  3653. if (is_array($categories_parent))
  3654. {
  3655. $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
  3656. }
  3657. // COPYRIGHT
  3658. if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  3659. {
  3660. $copyright_url = null;
  3661. $copyright_label = null;
  3662. if (isset($copyright[0]['attribs']['']['url']))
  3663. {
  3664. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3665. }
  3666. if (isset($copyright[0]['data']))
  3667. {
  3668. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3669. }
  3670. $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label);
  3671. }
  3672. elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
  3673. {
  3674. $copyright_url = null;
  3675. $copyright_label = null;
  3676. if (isset($copyright[0]['attribs']['']['url']))
  3677. {
  3678. $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  3679. }
  3680. if (isset($copyright[0]['data']))
  3681. {
  3682. $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3683. }
  3684. $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label);
  3685. }
  3686. // CREDITS
  3687. if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  3688. {
  3689. foreach ($credits as $credit)
  3690. {
  3691. $credit_role = null;
  3692. $credit_scheme = null;
  3693. $credit_name = null;
  3694. if (isset($credit['attribs']['']['role']))
  3695. {
  3696. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3697. }
  3698. if (isset($credit['attribs']['']['scheme']))
  3699. {
  3700. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3701. }
  3702. else
  3703. {
  3704. $credit_scheme = 'urn:ebu';
  3705. }
  3706. if (isset($credit['data']))
  3707. {
  3708. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3709. }
  3710. $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3711. }
  3712. }
  3713. elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
  3714. {
  3715. foreach ($credits as $credit)
  3716. {
  3717. $credit_role = null;
  3718. $credit_scheme = null;
  3719. $credit_name = null;
  3720. if (isset($credit['attribs']['']['role']))
  3721. {
  3722. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  3723. }
  3724. if (isset($credit['attribs']['']['scheme']))
  3725. {
  3726. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3727. }
  3728. else
  3729. {
  3730. $credit_scheme = 'urn:ebu';
  3731. }
  3732. if (isset($credit['data']))
  3733. {
  3734. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3735. }
  3736. $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  3737. }
  3738. }
  3739. if (is_array($credits_parent))
  3740. {
  3741. $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
  3742. }
  3743. // DESCRIPTION
  3744. if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  3745. {
  3746. if (isset($description_parent[0]['data']))
  3747. {
  3748. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3749. }
  3750. }
  3751. elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
  3752. {
  3753. if (isset($description_parent[0]['data']))
  3754. {
  3755. $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3756. }
  3757. }
  3758. // DURATION
  3759. if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
  3760. {
  3761. $seconds = null;
  3762. $minutes = null;
  3763. $hours = null;
  3764. if (isset($duration_parent[0]['data']))
  3765. {
  3766. $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3767. if (sizeof($temp) > 0)
  3768. {
  3769. (int) $seconds = array_pop($temp);
  3770. }
  3771. if (sizeof($temp) > 0)
  3772. {
  3773. (int) $minutes = array_pop($temp);
  3774. $seconds += $minutes * 60;
  3775. }
  3776. if (sizeof($temp) > 0)
  3777. {
  3778. (int) $hours = array_pop($temp);
  3779. $seconds += $hours * 3600;
  3780. }
  3781. unset($temp);
  3782. $duration_parent = $seconds;
  3783. }
  3784. }
  3785. // HASHES
  3786. if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  3787. {
  3788. foreach ($hashes_iterator as $hash)
  3789. {
  3790. $value = null;
  3791. $algo = null;
  3792. if (isset($hash['data']))
  3793. {
  3794. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3795. }
  3796. if (isset($hash['attribs']['']['algo']))
  3797. {
  3798. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3799. }
  3800. else
  3801. {
  3802. $algo = 'md5';
  3803. }
  3804. $hashes_parent[] = $algo.':'.$value;
  3805. }
  3806. }
  3807. elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
  3808. {
  3809. foreach ($hashes_iterator as $hash)
  3810. {
  3811. $value = null;
  3812. $algo = null;
  3813. if (isset($hash['data']))
  3814. {
  3815. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3816. }
  3817. if (isset($hash['attribs']['']['algo']))
  3818. {
  3819. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  3820. }
  3821. else
  3822. {
  3823. $algo = 'md5';
  3824. }
  3825. $hashes_parent[] = $algo.':'.$value;
  3826. }
  3827. }
  3828. if (is_array($hashes_parent))
  3829. {
  3830. $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
  3831. }
  3832. // KEYWORDS
  3833. if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  3834. {
  3835. if (isset($keywords[0]['data']))
  3836. {
  3837. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3838. foreach ($temp as $word)
  3839. {
  3840. $keywords_parent[] = trim($word);
  3841. }
  3842. }
  3843. unset($temp);
  3844. }
  3845. elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  3846. {
  3847. if (isset($keywords[0]['data']))
  3848. {
  3849. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3850. foreach ($temp as $word)
  3851. {
  3852. $keywords_parent[] = trim($word);
  3853. }
  3854. }
  3855. unset($temp);
  3856. }
  3857. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
  3858. {
  3859. if (isset($keywords[0]['data']))
  3860. {
  3861. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3862. foreach ($temp as $word)
  3863. {
  3864. $keywords_parent[] = trim($word);
  3865. }
  3866. }
  3867. unset($temp);
  3868. }
  3869. elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
  3870. {
  3871. if (isset($keywords[0]['data']))
  3872. {
  3873. $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  3874. foreach ($temp as $word)
  3875. {
  3876. $keywords_parent[] = trim($word);
  3877. }
  3878. }
  3879. unset($temp);
  3880. }
  3881. if (is_array($keywords_parent))
  3882. {
  3883. $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
  3884. }
  3885. // PLAYER
  3886. if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  3887. {
  3888. if (isset($player_parent[0]['attribs']['']['url']))
  3889. {
  3890. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3891. }
  3892. }
  3893. elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
  3894. {
  3895. if (isset($player_parent[0]['attribs']['']['url']))
  3896. {
  3897. $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  3898. }
  3899. }
  3900. // RATINGS
  3901. if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  3902. {
  3903. foreach ($ratings as $rating)
  3904. {
  3905. $rating_scheme = null;
  3906. $rating_value = null;
  3907. if (isset($rating['attribs']['']['scheme']))
  3908. {
  3909. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3910. }
  3911. else
  3912. {
  3913. $rating_scheme = 'urn:simple';
  3914. }
  3915. if (isset($rating['data']))
  3916. {
  3917. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3918. }
  3919. $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
  3920. }
  3921. }
  3922. elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  3923. {
  3924. foreach ($ratings as $rating)
  3925. {
  3926. $rating_scheme = 'urn:itunes';
  3927. $rating_value = null;
  3928. if (isset($rating['data']))
  3929. {
  3930. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3931. }
  3932. $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
  3933. }
  3934. }
  3935. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
  3936. {
  3937. foreach ($ratings as $rating)
  3938. {
  3939. $rating_scheme = null;
  3940. $rating_value = null;
  3941. if (isset($rating['attribs']['']['scheme']))
  3942. {
  3943. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  3944. }
  3945. else
  3946. {
  3947. $rating_scheme = 'urn:simple';
  3948. }
  3949. if (isset($rating['data']))
  3950. {
  3951. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3952. }
  3953. $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
  3954. }
  3955. }
  3956. elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
  3957. {
  3958. foreach ($ratings as $rating)
  3959. {
  3960. $rating_scheme = 'urn:itunes';
  3961. $rating_value = null;
  3962. if (isset($rating['data']))
  3963. {
  3964. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3965. }
  3966. $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
  3967. }
  3968. }
  3969. if (is_array($ratings_parent))
  3970. {
  3971. $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
  3972. }
  3973. // RESTRICTIONS
  3974. if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  3975. {
  3976. foreach ($restrictions as $restriction)
  3977. {
  3978. $restriction_relationship = null;
  3979. $restriction_type = null;
  3980. $restriction_value = null;
  3981. if (isset($restriction['attribs']['']['relationship']))
  3982. {
  3983. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  3984. }
  3985. if (isset($restriction['attribs']['']['type']))
  3986. {
  3987. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  3988. }
  3989. if (isset($restriction['data']))
  3990. {
  3991. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  3992. }
  3993. $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  3994. }
  3995. }
  3996. elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  3997. {
  3998. foreach ($restrictions as $restriction)
  3999. {
  4000. $restriction_relationship = 'allow';
  4001. $restriction_type = null;
  4002. $restriction_value = 'itunes';
  4003. if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
  4004. {
  4005. $restriction_relationship = 'deny';
  4006. }
  4007. $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4008. }
  4009. }
  4010. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
  4011. {
  4012. foreach ($restrictions as $restriction)
  4013. {
  4014. $restriction_relationship = null;
  4015. $restriction_type = null;
  4016. $restriction_value = null;
  4017. if (isset($restriction['attribs']['']['relationship']))
  4018. {
  4019. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4020. }
  4021. if (isset($restriction['attribs']['']['type']))
  4022. {
  4023. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4024. }
  4025. if (isset($restriction['data']))
  4026. {
  4027. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4028. }
  4029. $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4030. }
  4031. }
  4032. elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
  4033. {
  4034. foreach ($restrictions as $restriction)
  4035. {
  4036. $restriction_relationship = 'allow';
  4037. $restriction_type = null;
  4038. $restriction_value = 'itunes';
  4039. if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
  4040. {
  4041. $restriction_relationship = 'deny';
  4042. }
  4043. $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4044. }
  4045. }
  4046. if (is_array($restrictions_parent))
  4047. {
  4048. $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
  4049. }
  4050. // THUMBNAILS
  4051. if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  4052. {
  4053. foreach ($thumbnails as $thumbnail)
  4054. {
  4055. if (isset($thumbnail['attribs']['']['url']))
  4056. {
  4057. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4058. }
  4059. }
  4060. }
  4061. elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
  4062. {
  4063. foreach ($thumbnails as $thumbnail)
  4064. {
  4065. if (isset($thumbnail['attribs']['']['url']))
  4066. {
  4067. $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4068. }
  4069. }
  4070. }
  4071. // TITLES
  4072. if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  4073. {
  4074. if (isset($title_parent[0]['data']))
  4075. {
  4076. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4077. }
  4078. }
  4079. elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
  4080. {
  4081. if (isset($title_parent[0]['data']))
  4082. {
  4083. $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4084. }
  4085. }
  4086. // Clear the memory
  4087. unset($parent);
  4088. // Attributes
  4089. $bitrate = null;
  4090. $channels = null;
  4091. $duration = null;
  4092. $expression = null;
  4093. $framerate = null;
  4094. $height = null;
  4095. $javascript = null;
  4096. $lang = null;
  4097. $length = null;
  4098. $medium = null;
  4099. $samplingrate = null;
  4100. $type = null;
  4101. $url = null;
  4102. $width = null;
  4103. // Elements
  4104. $captions = null;
  4105. $categories = null;
  4106. $copyrights = null;
  4107. $credits = null;
  4108. $description = null;
  4109. $hashes = null;
  4110. $keywords = null;
  4111. $player = null;
  4112. $ratings = null;
  4113. $restrictions = null;
  4114. $thumbnails = null;
  4115. $title = null;
  4116. // If we have media:group tags, loop through them.
  4117. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
  4118. {
  4119. // If we have media:content tags, loop through them.
  4120. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  4121. {
  4122. if (isset($content['attribs']['']['url']))
  4123. {
  4124. // Attributes
  4125. $bitrate = null;
  4126. $channels = null;
  4127. $duration = null;
  4128. $expression = null;
  4129. $framerate = null;
  4130. $height = null;
  4131. $javascript = null;
  4132. $lang = null;
  4133. $length = null;
  4134. $medium = null;
  4135. $samplingrate = null;
  4136. $type = null;
  4137. $url = null;
  4138. $width = null;
  4139. // Elements
  4140. $captions = null;
  4141. $categories = null;
  4142. $copyrights = null;
  4143. $credits = null;
  4144. $description = null;
  4145. $hashes = null;
  4146. $keywords = null;
  4147. $player = null;
  4148. $ratings = null;
  4149. $restrictions = null;
  4150. $thumbnails = null;
  4151. $title = null;
  4152. // Start checking the attributes of media:content
  4153. if (isset($content['attribs']['']['bitrate']))
  4154. {
  4155. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4156. }
  4157. if (isset($content['attribs']['']['channels']))
  4158. {
  4159. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  4160. }
  4161. if (isset($content['attribs']['']['duration']))
  4162. {
  4163. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  4164. }
  4165. else
  4166. {
  4167. $duration = $duration_parent;
  4168. }
  4169. if (isset($content['attribs']['']['expression']))
  4170. {
  4171. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  4172. }
  4173. if (isset($content['attribs']['']['framerate']))
  4174. {
  4175. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4176. }
  4177. if (isset($content['attribs']['']['height']))
  4178. {
  4179. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  4180. }
  4181. if (isset($content['attribs']['']['lang']))
  4182. {
  4183. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4184. }
  4185. if (isset($content['attribs']['']['fileSize']))
  4186. {
  4187. $length = ceil($content['attribs']['']['fileSize']);
  4188. }
  4189. if (isset($content['attribs']['']['medium']))
  4190. {
  4191. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  4192. }
  4193. if (isset($content['attribs']['']['samplingrate']))
  4194. {
  4195. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4196. }
  4197. if (isset($content['attribs']['']['type']))
  4198. {
  4199. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4200. }
  4201. if (isset($content['attribs']['']['width']))
  4202. {
  4203. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  4204. }
  4205. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4206. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  4207. // CAPTIONS
  4208. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4209. {
  4210. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4211. {
  4212. $caption_type = null;
  4213. $caption_lang = null;
  4214. $caption_startTime = null;
  4215. $caption_endTime = null;
  4216. $caption_text = null;
  4217. if (isset($caption['attribs']['']['type']))
  4218. {
  4219. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4220. }
  4221. if (isset($caption['attribs']['']['lang']))
  4222. {
  4223. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4224. }
  4225. if (isset($caption['attribs']['']['start']))
  4226. {
  4227. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4228. }
  4229. if (isset($caption['attribs']['']['end']))
  4230. {
  4231. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4232. }
  4233. if (isset($caption['data']))
  4234. {
  4235. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4236. }
  4237. $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4238. }
  4239. if (is_array($captions))
  4240. {
  4241. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4242. }
  4243. }
  4244. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4245. {
  4246. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4247. {
  4248. $caption_type = null;
  4249. $caption_lang = null;
  4250. $caption_startTime = null;
  4251. $caption_endTime = null;
  4252. $caption_text = null;
  4253. if (isset($caption['attribs']['']['type']))
  4254. {
  4255. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4256. }
  4257. if (isset($caption['attribs']['']['lang']))
  4258. {
  4259. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4260. }
  4261. if (isset($caption['attribs']['']['start']))
  4262. {
  4263. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4264. }
  4265. if (isset($caption['attribs']['']['end']))
  4266. {
  4267. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4268. }
  4269. if (isset($caption['data']))
  4270. {
  4271. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4272. }
  4273. $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4274. }
  4275. if (is_array($captions))
  4276. {
  4277. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4278. }
  4279. }
  4280. else
  4281. {
  4282. $captions = $captions_parent;
  4283. }
  4284. // CATEGORIES
  4285. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4286. {
  4287. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4288. {
  4289. $term = null;
  4290. $scheme = null;
  4291. $label = null;
  4292. if (isset($category['data']))
  4293. {
  4294. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4295. }
  4296. if (isset($category['attribs']['']['scheme']))
  4297. {
  4298. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4299. }
  4300. else
  4301. {
  4302. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4303. }
  4304. if (isset($category['attribs']['']['label']))
  4305. {
  4306. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4307. }
  4308. $categories[] = new $this->feed->category_class($term, $scheme, $label);
  4309. }
  4310. }
  4311. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4312. {
  4313. foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4314. {
  4315. $term = null;
  4316. $scheme = null;
  4317. $label = null;
  4318. if (isset($category['data']))
  4319. {
  4320. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4321. }
  4322. if (isset($category['attribs']['']['scheme']))
  4323. {
  4324. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4325. }
  4326. else
  4327. {
  4328. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4329. }
  4330. if (isset($category['attribs']['']['label']))
  4331. {
  4332. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4333. }
  4334. $categories[] = new $this->feed->category_class($term, $scheme, $label);
  4335. }
  4336. }
  4337. if (is_array($categories) && is_array($categories_parent))
  4338. {
  4339. $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
  4340. }
  4341. elseif (is_array($categories))
  4342. {
  4343. $categories = array_values(SimplePie_Misc::array_unique($categories));
  4344. }
  4345. elseif (is_array($categories_parent))
  4346. {
  4347. $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
  4348. }
  4349. // COPYRIGHTS
  4350. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4351. {
  4352. $copyright_url = null;
  4353. $copyright_label = null;
  4354. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4355. {
  4356. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4357. }
  4358. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4359. {
  4360. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4361. }
  4362. $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
  4363. }
  4364. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4365. {
  4366. $copyright_url = null;
  4367. $copyright_label = null;
  4368. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4369. {
  4370. $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4371. }
  4372. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4373. {
  4374. $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4375. }
  4376. $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
  4377. }
  4378. else
  4379. {
  4380. $copyrights = $copyrights_parent;
  4381. }
  4382. // CREDITS
  4383. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4384. {
  4385. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4386. {
  4387. $credit_role = null;
  4388. $credit_scheme = null;
  4389. $credit_name = null;
  4390. if (isset($credit['attribs']['']['role']))
  4391. {
  4392. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4393. }
  4394. if (isset($credit['attribs']['']['scheme']))
  4395. {
  4396. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4397. }
  4398. else
  4399. {
  4400. $credit_scheme = 'urn:ebu';
  4401. }
  4402. if (isset($credit['data']))
  4403. {
  4404. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4405. }
  4406. $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4407. }
  4408. if (is_array($credits))
  4409. {
  4410. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4411. }
  4412. }
  4413. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4414. {
  4415. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4416. {
  4417. $credit_role = null;
  4418. $credit_scheme = null;
  4419. $credit_name = null;
  4420. if (isset($credit['attribs']['']['role']))
  4421. {
  4422. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4423. }
  4424. if (isset($credit['attribs']['']['scheme']))
  4425. {
  4426. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4427. }
  4428. else
  4429. {
  4430. $credit_scheme = 'urn:ebu';
  4431. }
  4432. if (isset($credit['data']))
  4433. {
  4434. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4435. }
  4436. $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4437. }
  4438. if (is_array($credits))
  4439. {
  4440. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4441. }
  4442. }
  4443. else
  4444. {
  4445. $credits = $credits_parent;
  4446. }
  4447. // DESCRIPTION
  4448. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4449. {
  4450. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4451. }
  4452. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4453. {
  4454. $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4455. }
  4456. else
  4457. {
  4458. $description = $description_parent;
  4459. }
  4460. // HASHES
  4461. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4462. {
  4463. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4464. {
  4465. $value = null;
  4466. $algo = null;
  4467. if (isset($hash['data']))
  4468. {
  4469. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4470. }
  4471. if (isset($hash['attribs']['']['algo']))
  4472. {
  4473. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4474. }
  4475. else
  4476. {
  4477. $algo = 'md5';
  4478. }
  4479. $hashes[] = $algo.':'.$value;
  4480. }
  4481. if (is_array($hashes))
  4482. {
  4483. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4484. }
  4485. }
  4486. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4487. {
  4488. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4489. {
  4490. $value = null;
  4491. $algo = null;
  4492. if (isset($hash['data']))
  4493. {
  4494. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4495. }
  4496. if (isset($hash['attribs']['']['algo']))
  4497. {
  4498. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4499. }
  4500. else
  4501. {
  4502. $algo = 'md5';
  4503. }
  4504. $hashes[] = $algo.':'.$value;
  4505. }
  4506. if (is_array($hashes))
  4507. {
  4508. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4509. }
  4510. }
  4511. else
  4512. {
  4513. $hashes = $hashes_parent;
  4514. }
  4515. // KEYWORDS
  4516. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4517. {
  4518. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4519. {
  4520. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4521. foreach ($temp as $word)
  4522. {
  4523. $keywords[] = trim($word);
  4524. }
  4525. unset($temp);
  4526. }
  4527. if (is_array($keywords))
  4528. {
  4529. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4530. }
  4531. }
  4532. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4533. {
  4534. if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4535. {
  4536. $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4537. foreach ($temp as $word)
  4538. {
  4539. $keywords[] = trim($word);
  4540. }
  4541. unset($temp);
  4542. }
  4543. if (is_array($keywords))
  4544. {
  4545. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  4546. }
  4547. }
  4548. else
  4549. {
  4550. $keywords = $keywords_parent;
  4551. }
  4552. // PLAYER
  4553. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4554. {
  4555. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4556. }
  4557. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  4558. {
  4559. $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4560. }
  4561. else
  4562. {
  4563. $player = $player_parent;
  4564. }
  4565. // RATINGS
  4566. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4567. {
  4568. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4569. {
  4570. $rating_scheme = null;
  4571. $rating_value = null;
  4572. if (isset($rating['attribs']['']['scheme']))
  4573. {
  4574. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4575. }
  4576. else
  4577. {
  4578. $rating_scheme = 'urn:simple';
  4579. }
  4580. if (isset($rating['data']))
  4581. {
  4582. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4583. }
  4584. $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
  4585. }
  4586. if (is_array($ratings))
  4587. {
  4588. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4589. }
  4590. }
  4591. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  4592. {
  4593. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  4594. {
  4595. $rating_scheme = null;
  4596. $rating_value = null;
  4597. if (isset($rating['attribs']['']['scheme']))
  4598. {
  4599. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4600. }
  4601. else
  4602. {
  4603. $rating_scheme = 'urn:simple';
  4604. }
  4605. if (isset($rating['data']))
  4606. {
  4607. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4608. }
  4609. $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
  4610. }
  4611. if (is_array($ratings))
  4612. {
  4613. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  4614. }
  4615. }
  4616. else
  4617. {
  4618. $ratings = $ratings_parent;
  4619. }
  4620. // RESTRICTIONS
  4621. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4622. {
  4623. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4624. {
  4625. $restriction_relationship = null;
  4626. $restriction_type = null;
  4627. $restriction_value = null;
  4628. if (isset($restriction['attribs']['']['relationship']))
  4629. {
  4630. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4631. }
  4632. if (isset($restriction['attribs']['']['type']))
  4633. {
  4634. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4635. }
  4636. if (isset($restriction['data']))
  4637. {
  4638. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4639. }
  4640. $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4641. }
  4642. if (is_array($restrictions))
  4643. {
  4644. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4645. }
  4646. }
  4647. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  4648. {
  4649. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  4650. {
  4651. $restriction_relationship = null;
  4652. $restriction_type = null;
  4653. $restriction_value = null;
  4654. if (isset($restriction['attribs']['']['relationship']))
  4655. {
  4656. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  4657. }
  4658. if (isset($restriction['attribs']['']['type']))
  4659. {
  4660. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4661. }
  4662. if (isset($restriction['data']))
  4663. {
  4664. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4665. }
  4666. $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  4667. }
  4668. if (is_array($restrictions))
  4669. {
  4670. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  4671. }
  4672. }
  4673. else
  4674. {
  4675. $restrictions = $restrictions_parent;
  4676. }
  4677. // THUMBNAILS
  4678. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4679. {
  4680. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4681. {
  4682. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4683. }
  4684. if (is_array($thumbnails))
  4685. {
  4686. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4687. }
  4688. }
  4689. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  4690. {
  4691. foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  4692. {
  4693. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4694. }
  4695. if (is_array($thumbnails))
  4696. {
  4697. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  4698. }
  4699. }
  4700. else
  4701. {
  4702. $thumbnails = $thumbnails_parent;
  4703. }
  4704. // TITLES
  4705. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4706. {
  4707. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4708. }
  4709. elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  4710. {
  4711. $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4712. }
  4713. else
  4714. {
  4715. $title = $title_parent;
  4716. }
  4717. $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);
  4718. }
  4719. }
  4720. }
  4721. // If we have standalone media:content tags, loop through them.
  4722. if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
  4723. {
  4724. foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
  4725. {
  4726. if (isset($content['attribs']['']['url']))
  4727. {
  4728. // Attributes
  4729. $bitrate = null;
  4730. $channels = null;
  4731. $duration = null;
  4732. $expression = null;
  4733. $framerate = null;
  4734. $height = null;
  4735. $javascript = null;
  4736. $lang = null;
  4737. $length = null;
  4738. $medium = null;
  4739. $samplingrate = null;
  4740. $type = null;
  4741. $url = null;
  4742. $width = null;
  4743. // Elements
  4744. $captions = null;
  4745. $categories = null;
  4746. $copyrights = null;
  4747. $credits = null;
  4748. $description = null;
  4749. $hashes = null;
  4750. $keywords = null;
  4751. $player = null;
  4752. $ratings = null;
  4753. $restrictions = null;
  4754. $thumbnails = null;
  4755. $title = null;
  4756. // Start checking the attributes of media:content
  4757. if (isset($content['attribs']['']['bitrate']))
  4758. {
  4759. $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4760. }
  4761. if (isset($content['attribs']['']['channels']))
  4762. {
  4763. $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
  4764. }
  4765. if (isset($content['attribs']['']['duration']))
  4766. {
  4767. $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
  4768. }
  4769. else
  4770. {
  4771. $duration = $duration_parent;
  4772. }
  4773. if (isset($content['attribs']['']['expression']))
  4774. {
  4775. $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
  4776. }
  4777. if (isset($content['attribs']['']['framerate']))
  4778. {
  4779. $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4780. }
  4781. if (isset($content['attribs']['']['height']))
  4782. {
  4783. $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
  4784. }
  4785. if (isset($content['attribs']['']['lang']))
  4786. {
  4787. $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4788. }
  4789. if (isset($content['attribs']['']['fileSize']))
  4790. {
  4791. $length = ceil($content['attribs']['']['fileSize']);
  4792. }
  4793. if (isset($content['attribs']['']['medium']))
  4794. {
  4795. $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
  4796. }
  4797. if (isset($content['attribs']['']['samplingrate']))
  4798. {
  4799. $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
  4800. }
  4801. if (isset($content['attribs']['']['type']))
  4802. {
  4803. $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4804. }
  4805. if (isset($content['attribs']['']['width']))
  4806. {
  4807. $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
  4808. }
  4809. $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  4810. // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
  4811. // CAPTIONS
  4812. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
  4813. {
  4814. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
  4815. {
  4816. $caption_type = null;
  4817. $caption_lang = null;
  4818. $caption_startTime = null;
  4819. $caption_endTime = null;
  4820. $caption_text = null;
  4821. if (isset($caption['attribs']['']['type']))
  4822. {
  4823. $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  4824. }
  4825. if (isset($caption['attribs']['']['lang']))
  4826. {
  4827. $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  4828. }
  4829. if (isset($caption['attribs']['']['start']))
  4830. {
  4831. $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
  4832. }
  4833. if (isset($caption['attribs']['']['end']))
  4834. {
  4835. $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
  4836. }
  4837. if (isset($caption['data']))
  4838. {
  4839. $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4840. }
  4841. $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
  4842. }
  4843. if (is_array($captions))
  4844. {
  4845. $captions = array_values(SimplePie_Misc::array_unique($captions));
  4846. }
  4847. }
  4848. else
  4849. {
  4850. $captions = $captions_parent;
  4851. }
  4852. // CATEGORIES
  4853. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
  4854. {
  4855. foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
  4856. {
  4857. $term = null;
  4858. $scheme = null;
  4859. $label = null;
  4860. if (isset($category['data']))
  4861. {
  4862. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4863. }
  4864. if (isset($category['attribs']['']['scheme']))
  4865. {
  4866. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4867. }
  4868. else
  4869. {
  4870. $scheme = 'http://search.yahoo.com/mrss/category_schema';
  4871. }
  4872. if (isset($category['attribs']['']['label']))
  4873. {
  4874. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  4875. }
  4876. $categories[] = new $this->feed->category_class($term, $scheme, $label);
  4877. }
  4878. }
  4879. if (is_array($categories) && is_array($categories_parent))
  4880. {
  4881. $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
  4882. }
  4883. elseif (is_array($categories))
  4884. {
  4885. $categories = array_values(SimplePie_Misc::array_unique($categories));
  4886. }
  4887. elseif (is_array($categories_parent))
  4888. {
  4889. $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
  4890. }
  4891. else
  4892. {
  4893. $categories = null;
  4894. }
  4895. // COPYRIGHTS
  4896. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
  4897. {
  4898. $copyright_url = null;
  4899. $copyright_label = null;
  4900. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
  4901. {
  4902. $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
  4903. }
  4904. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
  4905. {
  4906. $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4907. }
  4908. $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
  4909. }
  4910. else
  4911. {
  4912. $copyrights = $copyrights_parent;
  4913. }
  4914. // CREDITS
  4915. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
  4916. {
  4917. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
  4918. {
  4919. $credit_role = null;
  4920. $credit_scheme = null;
  4921. $credit_name = null;
  4922. if (isset($credit['attribs']['']['role']))
  4923. {
  4924. $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
  4925. }
  4926. if (isset($credit['attribs']['']['scheme']))
  4927. {
  4928. $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  4929. }
  4930. else
  4931. {
  4932. $credit_scheme = 'urn:ebu';
  4933. }
  4934. if (isset($credit['data']))
  4935. {
  4936. $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4937. }
  4938. $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
  4939. }
  4940. if (is_array($credits))
  4941. {
  4942. $credits = array_values(SimplePie_Misc::array_unique($credits));
  4943. }
  4944. }
  4945. else
  4946. {
  4947. $credits = $credits_parent;
  4948. }
  4949. // DESCRIPTION
  4950. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
  4951. {
  4952. $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4953. }
  4954. else
  4955. {
  4956. $description = $description_parent;
  4957. }
  4958. // HASHES
  4959. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
  4960. {
  4961. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
  4962. {
  4963. $value = null;
  4964. $algo = null;
  4965. if (isset($hash['data']))
  4966. {
  4967. $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  4968. }
  4969. if (isset($hash['attribs']['']['algo']))
  4970. {
  4971. $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
  4972. }
  4973. else
  4974. {
  4975. $algo = 'md5';
  4976. }
  4977. $hashes[] = $algo.':'.$value;
  4978. }
  4979. if (is_array($hashes))
  4980. {
  4981. $hashes = array_values(SimplePie_Misc::array_unique($hashes));
  4982. }
  4983. }
  4984. else
  4985. {
  4986. $hashes = $hashes_parent;
  4987. }
  4988. // KEYWORDS
  4989. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
  4990. {
  4991. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
  4992. {
  4993. $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
  4994. foreach ($temp as $word)
  4995. {
  4996. $keywords[] = trim($word);
  4997. }
  4998. unset($temp);
  4999. }
  5000. if (is_array($keywords))
  5001. {
  5002. $keywords = array_values(SimplePie_Misc::array_unique($keywords));
  5003. }
  5004. }
  5005. else
  5006. {
  5007. $keywords = $keywords_parent;
  5008. }
  5009. // PLAYER
  5010. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  5011. {
  5012. $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  5013. }
  5014. else
  5015. {
  5016. $player = $player_parent;
  5017. }
  5018. // RATINGS
  5019. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
  5020. {
  5021. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
  5022. {
  5023. $rating_scheme = null;
  5024. $rating_value = null;
  5025. if (isset($rating['attribs']['']['scheme']))
  5026. {
  5027. $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  5028. }
  5029. else
  5030. {
  5031. $rating_scheme = 'urn:simple';
  5032. }
  5033. if (isset($rating['data']))
  5034. {
  5035. $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5036. }
  5037. $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
  5038. }
  5039. if (is_array($ratings))
  5040. {
  5041. $ratings = array_values(SimplePie_Misc::array_unique($ratings));
  5042. }
  5043. }
  5044. else
  5045. {
  5046. $ratings = $ratings_parent;
  5047. }
  5048. // RESTRICTIONS
  5049. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
  5050. {
  5051. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
  5052. {
  5053. $restriction_relationship = null;
  5054. $restriction_type = null;
  5055. $restriction_value = null;
  5056. if (isset($restriction['attribs']['']['relationship']))
  5057. {
  5058. $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
  5059. }
  5060. if (isset($restriction['attribs']['']['type']))
  5061. {
  5062. $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5063. }
  5064. if (isset($restriction['data']))
  5065. {
  5066. $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5067. }
  5068. $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
  5069. }
  5070. if (is_array($restrictions))
  5071. {
  5072. $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
  5073. }
  5074. }
  5075. else
  5076. {
  5077. $restrictions = $restrictions_parent;
  5078. }
  5079. // THUMBNAILS
  5080. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  5081. {
  5082. foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  5083. {
  5084. $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  5085. }
  5086. if (is_array($thumbnails))
  5087. {
  5088. $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
  5089. }
  5090. }
  5091. else
  5092. {
  5093. $thumbnails = $thumbnails_parent;
  5094. }
  5095. // TITLES
  5096. if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
  5097. {
  5098. $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5099. }
  5100. else
  5101. {
  5102. $title = $title_parent;
  5103. }
  5104. $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);
  5105. }
  5106. }
  5107. }
  5108. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
  5109. {
  5110. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
  5111. {
  5112. // Attributes
  5113. $bitrate = null;
  5114. $channels = null;
  5115. $duration = null;
  5116. $expression = null;
  5117. $framerate = null;
  5118. $height = null;
  5119. $javascript = null;
  5120. $lang = null;
  5121. $length = null;
  5122. $medium = null;
  5123. $samplingrate = null;
  5124. $type = null;
  5125. $url = null;
  5126. $width = null;
  5127. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5128. if (isset($link['attribs']['']['type']))
  5129. {
  5130. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5131. }
  5132. if (isset($link['attribs']['']['length']))
  5133. {
  5134. $length = ceil($link['attribs']['']['length']);
  5135. }
  5136. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5137. $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);
  5138. }
  5139. }
  5140. foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  5141. {
  5142. if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
  5143. {
  5144. // Attributes
  5145. $bitrate = null;
  5146. $channels = null;
  5147. $duration = null;
  5148. $expression = null;
  5149. $framerate = null;
  5150. $height = null;
  5151. $javascript = null;
  5152. $lang = null;
  5153. $length = null;
  5154. $medium = null;
  5155. $samplingrate = null;
  5156. $type = null;
  5157. $url = null;
  5158. $width = null;
  5159. $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5160. if (isset($link['attribs']['']['type']))
  5161. {
  5162. $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5163. }
  5164. if (isset($link['attribs']['']['length']))
  5165. {
  5166. $length = ceil($link['attribs']['']['length']);
  5167. }
  5168. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5169. $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);
  5170. }
  5171. }
  5172. if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure'))
  5173. {
  5174. if (isset($enclosure[0]['attribs']['']['url']))
  5175. {
  5176. // Attributes
  5177. $bitrate = null;
  5178. $channels = null;
  5179. $duration = null;
  5180. $expression = null;
  5181. $framerate = null;
  5182. $height = null;
  5183. $javascript = null;
  5184. $lang = null;
  5185. $length = null;
  5186. $medium = null;
  5187. $samplingrate = null;
  5188. $type = null;
  5189. $url = null;
  5190. $width = null;
  5191. $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
  5192. if (isset($enclosure[0]['attribs']['']['type']))
  5193. {
  5194. $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
  5195. }
  5196. if (isset($enclosure[0]['attribs']['']['length']))
  5197. {
  5198. $length = ceil($enclosure[0]['attribs']['']['length']);
  5199. }
  5200. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5201. $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);
  5202. }
  5203. }
  5204. 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))
  5205. {
  5206. // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  5207. $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);
  5208. }
  5209. $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
  5210. }
  5211. if (!empty($this->data['enclosures']))
  5212. {
  5213. return $this->data['enclosures'];
  5214. }
  5215. else
  5216. {
  5217. return null;
  5218. }
  5219. }
  5220. function get_latitude()
  5221. {
  5222. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  5223. {
  5224. return (float) $return[0]['data'];
  5225. }
  5226. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5227. {
  5228. return (float) $match[1];
  5229. }
  5230. else
  5231. {
  5232. return null;
  5233. }
  5234. }
  5235. function get_longitude()
  5236. {
  5237. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  5238. {
  5239. return (float) $return[0]['data'];
  5240. }
  5241. elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  5242. {
  5243. return (float) $return[0]['data'];
  5244. }
  5245. elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5246. {
  5247. return (float) $match[2];
  5248. }
  5249. else
  5250. {
  5251. return null;
  5252. }
  5253. }
  5254. function get_source()
  5255. {
  5256. if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
  5257. {
  5258. return new $this->feed->source_class($this, $return[0]);
  5259. }
  5260. else
  5261. {
  5262. return null;
  5263. }
  5264. }
  5265. /**
  5266. * Creates the add_to_* methods' return data
  5267. *
  5268. * @access private
  5269. * @param string $item_url String to prefix to the item permalink
  5270. * @param string $title_url String to prefix to the item title
  5271. * (and suffix to the item permalink)
  5272. * @return mixed URL if feed exists, false otherwise
  5273. */
  5274. function add_to_service($item_url, $title_url = null, $summary_url = null)
  5275. {
  5276. if ($this->get_permalink() !== null)
  5277. {
  5278. $return = $item_url . rawurlencode($this->get_permalink());
  5279. if ($title_url !== null && $this->get_title() !== null)
  5280. {
  5281. $return .= $title_url . rawurlencode($this->get_title());
  5282. }
  5283. if ($summary_url !== null && $this->get_description() !== null)
  5284. {
  5285. $return .= $summary_url . rawurlencode($this->get_description());
  5286. }
  5287. return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
  5288. }
  5289. else
  5290. {
  5291. return null;
  5292. }
  5293. }
  5294. function add_to_blinklist()
  5295. {
  5296. return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
  5297. }
  5298. function add_to_blogmarks()
  5299. {
  5300. return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
  5301. }
  5302. function add_to_delicious()
  5303. {
  5304. return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
  5305. }
  5306. function add_to_digg()
  5307. {
  5308. return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
  5309. }
  5310. function add_to_furl()
  5311. {
  5312. return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
  5313. }
  5314. function add_to_magnolia()
  5315. {
  5316. return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
  5317. }
  5318. function add_to_myweb20()
  5319. {
  5320. return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
  5321. }
  5322. function add_to_newsvine()
  5323. {
  5324. return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
  5325. }
  5326. function add_to_reddit()
  5327. {
  5328. return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
  5329. }
  5330. function add_to_segnalo()
  5331. {
  5332. return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
  5333. }
  5334. function add_to_simpy()
  5335. {
  5336. return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
  5337. }
  5338. function add_to_spurl()
  5339. {
  5340. return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
  5341. }
  5342. function add_to_wists()
  5343. {
  5344. return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
  5345. }
  5346. function search_technorati()
  5347. {
  5348. return $this->add_to_service('http://www.technorati.com/search/');
  5349. }
  5350. }
  5351. class SimplePie_Source
  5352. {
  5353. var $item;
  5354. var $data = array();
  5355. function SimplePie_Source($item, $data)
  5356. {
  5357. $this->item = $item;
  5358. $this->data = $data;
  5359. }
  5360. function __toString()
  5361. {
  5362. return md5(serialize($this->data));
  5363. }
  5364. function get_source_tags($namespace, $tag)
  5365. {
  5366. if (isset($this->data['child'][$namespace][$tag]))
  5367. {
  5368. return $this->data['child'][$namespace][$tag];
  5369. }
  5370. else
  5371. {
  5372. return null;
  5373. }
  5374. }
  5375. function get_base($element = array())
  5376. {
  5377. return $this->item->get_base($element);
  5378. }
  5379. function sanitize($data, $type, $base = '')
  5380. {
  5381. return $this->item->sanitize($data, $type, $base);
  5382. }
  5383. function get_item()
  5384. {
  5385. return $this->item;
  5386. }
  5387. function get_title()
  5388. {
  5389. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
  5390. {
  5391. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5392. }
  5393. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
  5394. {
  5395. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5396. }
  5397. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
  5398. {
  5399. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5400. }
  5401. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
  5402. {
  5403. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5404. }
  5405. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
  5406. {
  5407. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5408. }
  5409. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
  5410. {
  5411. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5412. }
  5413. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  5414. {
  5415. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5416. }
  5417. else
  5418. {
  5419. return null;
  5420. }
  5421. }
  5422. function get_category($key = 0)
  5423. {
  5424. $categories = $this->get_categories();
  5425. if (isset($categories[$key]))
  5426. {
  5427. return $categories[$key];
  5428. }
  5429. else
  5430. {
  5431. return null;
  5432. }
  5433. }
  5434. function get_categories()
  5435. {
  5436. $categories = array();
  5437. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
  5438. {
  5439. $term = null;
  5440. $scheme = null;
  5441. $label = null;
  5442. if (isset($category['attribs']['']['term']))
  5443. {
  5444. $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
  5445. }
  5446. if (isset($category['attribs']['']['scheme']))
  5447. {
  5448. $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
  5449. }
  5450. if (isset($category['attribs']['']['label']))
  5451. {
  5452. $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
  5453. }
  5454. $categories[] = new $this->item->feed->category_class($term, $scheme, $label);
  5455. }
  5456. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
  5457. {
  5458. // This is really the label, but keep this as the term also for BC.
  5459. // Label will also work on retrieving because that falls back to term.
  5460. $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5461. if (isset($category['attribs']['']['domain']))
  5462. {
  5463. $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
  5464. }
  5465. else
  5466. {
  5467. $scheme = null;
  5468. }
  5469. $categories[] = new $this->item->feed->category_class($term, $scheme, null);
  5470. }
  5471. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
  5472. {
  5473. $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5474. }
  5475. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
  5476. {
  5477. $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5478. }
  5479. if (!empty($categories))
  5480. {
  5481. return SimplePie_Misc::array_unique($categories);
  5482. }
  5483. else
  5484. {
  5485. return null;
  5486. }
  5487. }
  5488. function get_author($key = 0)
  5489. {
  5490. $authors = $this->get_authors();
  5491. if (isset($authors[$key]))
  5492. {
  5493. return $authors[$key];
  5494. }
  5495. else
  5496. {
  5497. return null;
  5498. }
  5499. }
  5500. function get_authors()
  5501. {
  5502. $authors = array();
  5503. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
  5504. {
  5505. $name = null;
  5506. $uri = null;
  5507. $email = null;
  5508. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  5509. {
  5510. $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5511. }
  5512. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  5513. {
  5514. $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]));
  5515. }
  5516. if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  5517. {
  5518. $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5519. }
  5520. if ($name !== null || $email !== null || $uri !== null)
  5521. {
  5522. $authors[] = new $this->item->feed->author_class($name, $uri, $email);
  5523. }
  5524. }
  5525. if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
  5526. {
  5527. $name = null;
  5528. $url = null;
  5529. $email = null;
  5530. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  5531. {
  5532. $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5533. }
  5534. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  5535. {
  5536. $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]));
  5537. }
  5538. if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  5539. {
  5540. $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5541. }
  5542. if ($name !== null || $email !== null || $url !== null)
  5543. {
  5544. $authors[] = new $this->item->feed->author_class($name, $url, $email);
  5545. }
  5546. }
  5547. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
  5548. {
  5549. $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5550. }
  5551. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
  5552. {
  5553. $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5554. }
  5555. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
  5556. {
  5557. $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
  5558. }
  5559. if (!empty($authors))
  5560. {
  5561. return SimplePie_Misc::array_unique($authors);
  5562. }
  5563. else
  5564. {
  5565. return null;
  5566. }
  5567. }
  5568. function get_contributor($key = 0)
  5569. {
  5570. $contributors = $this->get_contributors();
  5571. if (isset($contributors[$key]))
  5572. {
  5573. return $contributors[$key];
  5574. }
  5575. else
  5576. {
  5577. return null;
  5578. }
  5579. }
  5580. function get_contributors()
  5581. {
  5582. $contributors = array();
  5583. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
  5584. {
  5585. $name = null;
  5586. $uri = null;
  5587. $email = null;
  5588. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
  5589. {
  5590. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5591. }
  5592. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
  5593. {
  5594. $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]));
  5595. }
  5596. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
  5597. {
  5598. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5599. }
  5600. if ($name !== null || $email !== null || $uri !== null)
  5601. {
  5602. $contributors[] = new $this->item->feed->author_class($name, $uri, $email);
  5603. }
  5604. }
  5605. foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
  5606. {
  5607. $name = null;
  5608. $url = null;
  5609. $email = null;
  5610. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
  5611. {
  5612. $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5613. }
  5614. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
  5615. {
  5616. $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]));
  5617. }
  5618. if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
  5619. {
  5620. $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5621. }
  5622. if ($name !== null || $email !== null || $url !== null)
  5623. {
  5624. $contributors[] = new $this->item->feed->author_class($name, $url, $email);
  5625. }
  5626. }
  5627. if (!empty($contributors))
  5628. {
  5629. return SimplePie_Misc::array_unique($contributors);
  5630. }
  5631. else
  5632. {
  5633. return null;
  5634. }
  5635. }
  5636. function get_link($key = 0, $rel = 'alternate')
  5637. {
  5638. $links = $this->get_links($rel);
  5639. if (isset($links[$key]))
  5640. {
  5641. return $links[$key];
  5642. }
  5643. else
  5644. {
  5645. return null;
  5646. }
  5647. }
  5648. /**
  5649. * Added for parity between the parent-level and the item/entry-level.
  5650. */
  5651. function get_permalink()
  5652. {
  5653. return $this->get_link(0);
  5654. }
  5655. function get_links($rel = 'alternate')
  5656. {
  5657. if (!isset($this->data['links']))
  5658. {
  5659. $this->data['links'] = array();
  5660. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
  5661. {
  5662. foreach ($links as $link)
  5663. {
  5664. if (isset($link['attribs']['']['href']))
  5665. {
  5666. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  5667. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5668. }
  5669. }
  5670. }
  5671. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
  5672. {
  5673. foreach ($links as $link)
  5674. {
  5675. if (isset($link['attribs']['']['href']))
  5676. {
  5677. $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
  5678. $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
  5679. }
  5680. }
  5681. }
  5682. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
  5683. {
  5684. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5685. }
  5686. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
  5687. {
  5688. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5689. }
  5690. if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  5691. {
  5692. $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
  5693. }
  5694. $keys = array_keys($this->data['links']);
  5695. foreach ($keys as $key)
  5696. {
  5697. if (SimplePie_Misc::is_isegment_nz_nc($key))
  5698. {
  5699. if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
  5700. {
  5701. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
  5702. $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
  5703. }
  5704. else
  5705. {
  5706. $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
  5707. }
  5708. }
  5709. elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
  5710. {
  5711. $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
  5712. }
  5713. $this->data['links'][$key] = array_unique($this->data['links'][$key]);
  5714. }
  5715. }
  5716. if (isset($this->data['links'][$rel]))
  5717. {
  5718. return $this->data['links'][$rel];
  5719. }
  5720. else
  5721. {
  5722. return null;
  5723. }
  5724. }
  5725. function get_description()
  5726. {
  5727. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
  5728. {
  5729. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5730. }
  5731. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
  5732. {
  5733. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5734. }
  5735. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
  5736. {
  5737. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5738. }
  5739. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
  5740. {
  5741. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5742. }
  5743. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
  5744. {
  5745. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
  5746. }
  5747. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
  5748. {
  5749. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5750. }
  5751. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
  5752. {
  5753. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5754. }
  5755. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
  5756. {
  5757. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5758. }
  5759. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  5760. {
  5761. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  5762. }
  5763. else
  5764. {
  5765. return null;
  5766. }
  5767. }
  5768. function get_copyright()
  5769. {
  5770. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
  5771. {
  5772. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5773. }
  5774. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
  5775. {
  5776. return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
  5777. }
  5778. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
  5779. {
  5780. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5781. }
  5782. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
  5783. {
  5784. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5785. }
  5786. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  5787. {
  5788. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5789. }
  5790. else
  5791. {
  5792. return null;
  5793. }
  5794. }
  5795. function get_language()
  5796. {
  5797. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
  5798. {
  5799. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5800. }
  5801. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
  5802. {
  5803. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5804. }
  5805. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
  5806. {
  5807. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  5808. }
  5809. elseif (isset($this->data['xml_lang']))
  5810. {
  5811. return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
  5812. }
  5813. else
  5814. {
  5815. return null;
  5816. }
  5817. }
  5818. function get_latitude()
  5819. {
  5820. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
  5821. {
  5822. return (float) $return[0]['data'];
  5823. }
  5824. elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5825. {
  5826. return (float) $match[1];
  5827. }
  5828. else
  5829. {
  5830. return null;
  5831. }
  5832. }
  5833. function get_longitude()
  5834. {
  5835. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
  5836. {
  5837. return (float) $return[0]['data'];
  5838. }
  5839. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
  5840. {
  5841. return (float) $return[0]['data'];
  5842. }
  5843. elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
  5844. {
  5845. return (float) $match[2];
  5846. }
  5847. else
  5848. {
  5849. return null;
  5850. }
  5851. }
  5852. function get_image_url()
  5853. {
  5854. if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
  5855. {
  5856. return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
  5857. }
  5858. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
  5859. {
  5860. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  5861. }
  5862. elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
  5863. {
  5864. return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  5865. }
  5866. else
  5867. {
  5868. return null;
  5869. }
  5870. }
  5871. }
  5872. class SimplePie_Author
  5873. {
  5874. var $name;
  5875. var $link;
  5876. var $email;
  5877. // Constructor, used to input the data
  5878. function SimplePie_Author($name = null, $link = null, $email = null)
  5879. {
  5880. $this->name = $name;
  5881. $this->link = $link;
  5882. $this->email = $email;
  5883. }
  5884. function __toString()
  5885. {
  5886. // There is no $this->data here
  5887. return md5(serialize($this));
  5888. }
  5889. function get_name()
  5890. {
  5891. if ($this->name !== null)
  5892. {
  5893. return $this->name;
  5894. }
  5895. else
  5896. {
  5897. return null;
  5898. }
  5899. }
  5900. function get_link()
  5901. {
  5902. if ($this->link !== null)
  5903. {
  5904. return $this->link;
  5905. }
  5906. else
  5907. {
  5908. return null;
  5909. }
  5910. }
  5911. function get_email()
  5912. {
  5913. if ($this->email !== null)
  5914. {
  5915. return $this->email;
  5916. }
  5917. else
  5918. {
  5919. return null;
  5920. }
  5921. }
  5922. }
  5923. class SimplePie_Category
  5924. {
  5925. var $term;
  5926. var $scheme;
  5927. var $label;
  5928. // Constructor, used to input the data
  5929. function SimplePie_Category($term = null, $scheme = null, $label = null)
  5930. {
  5931. $this->term = $term;
  5932. $this->scheme = $scheme;
  5933. $this->label = $label;
  5934. }
  5935. function __toString()
  5936. {
  5937. // There is no $this->data here
  5938. return md5(serialize($this));
  5939. }
  5940. function get_term()
  5941. {
  5942. if ($this->term !== null)
  5943. {
  5944. return $this->term;
  5945. }
  5946. else
  5947. {
  5948. return null;
  5949. }
  5950. }
  5951. function get_scheme()
  5952. {
  5953. if ($this->scheme !== null)
  5954. {
  5955. return $this->scheme;
  5956. }
  5957. else
  5958. {
  5959. return null;
  5960. }
  5961. }
  5962. function get_label()
  5963. {
  5964. if ($this->label !== null)
  5965. {
  5966. return $this->label;
  5967. }
  5968. else
  5969. {
  5970. return $this->get_term();
  5971. }
  5972. }
  5973. }
  5974. class SimplePie_Enclosure
  5975. {
  5976. var $bitrate;
  5977. var $captions;
  5978. var $categories;
  5979. var $channels;
  5980. var $copyright;
  5981. var $credits;
  5982. var $description;
  5983. var $duration;
  5984. var $expression;
  5985. var $framerate;
  5986. var $handler;
  5987. var $hashes;
  5988. var $height;
  5989. var $javascript;
  5990. var $keywords;
  5991. var $lang;
  5992. var $length;
  5993. var $link;
  5994. var $medium;
  5995. var $player;
  5996. var $ratings;
  5997. var $restrictions;
  5998. var $samplingrate;
  5999. var $thumbnails;
  6000. var $title;
  6001. var $type;
  6002. var $width;
  6003. // Constructor, used to input the data
  6004. 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)
  6005. {
  6006. $this->bitrate = $bitrate;
  6007. $this->captions = $captions;
  6008. $this->categories = $categories;
  6009. $this->channels = $channels;
  6010. $this->copyright = $copyright;
  6011. $this->credits = $credits;
  6012. $this->description = $description;
  6013. $this->duration = $duration;
  6014. $this->expression = $expression;
  6015. $this->framerate = $framerate;
  6016. $this->hashes = $hashes;
  6017. $this->height = $height;
  6018. $this->javascript = $javascript;
  6019. $this->keywords = $keywords;
  6020. $this->lang = $lang;
  6021. $this->length = $length;
  6022. $this->link = $link;
  6023. $this->medium = $medium;
  6024. $this->player = $player;
  6025. $this->ratings = $ratings;
  6026. $this->restrictions = $restrictions;
  6027. $this->samplingrate = $samplingrate;
  6028. $this->thumbnails = $thumbnails;
  6029. $this->title = $title;
  6030. $this->type = $type;
  6031. $this->width = $width;
  6032. if (class_exists('idna_convert'))
  6033. {
  6034. $idn = new idna_convert;
  6035. $parsed = SimplePie_Misc::parse_url($link);
  6036. $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  6037. }
  6038. $this->handler = $this->get_handler(); // Needs to load last
  6039. }
  6040. function __toString()
  6041. {
  6042. // There is no $this->data here
  6043. return md5(serialize($this));
  6044. }
  6045. function get_bitrate()
  6046. {
  6047. if ($this->bitrate !== null)
  6048. {
  6049. return $this->bitrate;
  6050. }
  6051. else
  6052. {
  6053. return null;
  6054. }
  6055. }
  6056. function get_caption($key = 0)
  6057. {
  6058. $captions = $this->get_captions();
  6059. if (isset($captions[$key]))
  6060. {
  6061. return $captions[$key];
  6062. }
  6063. else
  6064. {
  6065. return null;
  6066. }
  6067. }
  6068. function get_captions()
  6069. {
  6070. if ($this->captions !== null)
  6071. {
  6072. return $this->captions;
  6073. }
  6074. else
  6075. {
  6076. return null;
  6077. }
  6078. }
  6079. function get_category($key = 0)
  6080. {
  6081. $categories = $this->get_categories();
  6082. if (isset($categories[$key]))
  6083. {
  6084. return $categories[$key];
  6085. }
  6086. else
  6087. {
  6088. return null;
  6089. }
  6090. }
  6091. function get_categories()
  6092. {
  6093. if ($this->categories !== null)
  6094. {
  6095. return $this->categories;
  6096. }
  6097. else
  6098. {
  6099. return null;
  6100. }
  6101. }
  6102. function get_channels()
  6103. {
  6104. if ($this->channels !== null)
  6105. {
  6106. return $this->channels;
  6107. }
  6108. else
  6109. {
  6110. return null;
  6111. }
  6112. }
  6113. function get_copyright()
  6114. {
  6115. if ($this->copyright !== null)
  6116. {
  6117. return $this->copyright;
  6118. }
  6119. else
  6120. {
  6121. return null;
  6122. }
  6123. }
  6124. function get_credit($key = 0)
  6125. {
  6126. $credits = $this->get_credits();
  6127. if (isset($credits[$key]))
  6128. {
  6129. return $credits[$key];
  6130. }
  6131. else
  6132. {
  6133. return null;
  6134. }
  6135. }
  6136. function get_credits()
  6137. {
  6138. if ($this->credits !== null)
  6139. {
  6140. return $this->credits;
  6141. }
  6142. else
  6143. {
  6144. return null;
  6145. }
  6146. }
  6147. function get_description()
  6148. {
  6149. if ($this->description !== null)
  6150. {
  6151. return $this->description;
  6152. }
  6153. else
  6154. {
  6155. return null;
  6156. }
  6157. }
  6158. function get_duration($convert = false)
  6159. {
  6160. if ($this->duration !== null)
  6161. {
  6162. if ($convert)
  6163. {
  6164. $time = SimplePie_Misc::time_hms($this->duration);
  6165. return $time;
  6166. }
  6167. else
  6168. {
  6169. return $this->duration;
  6170. }
  6171. }
  6172. else
  6173. {
  6174. return null;
  6175. }
  6176. }
  6177. function get_expression()
  6178. {
  6179. if ($this->expression !== null)
  6180. {
  6181. return $this->expression;
  6182. }
  6183. else
  6184. {
  6185. return 'full';
  6186. }
  6187. }
  6188. function get_extension()
  6189. {
  6190. if ($this->link !== null)
  6191. {
  6192. $url = SimplePie_Misc::parse_url($this->link);
  6193. if ($url['path'] !== '')
  6194. {
  6195. return pathinfo($url['path'], PATHINFO_EXTENSION);
  6196. }
  6197. }
  6198. return null;
  6199. }
  6200. function get_framerate()
  6201. {
  6202. if ($this->framerate !== null)
  6203. {
  6204. return $this->framerate;
  6205. }
  6206. else
  6207. {
  6208. return null;
  6209. }
  6210. }
  6211. function get_handler()
  6212. {
  6213. return $this->get_real_type(true);
  6214. }
  6215. function get_hash($key = 0)
  6216. {
  6217. $hashes = $this->get_hashes();
  6218. if (isset($hashes[$key]))
  6219. {
  6220. return $hashes[$key];
  6221. }
  6222. else
  6223. {
  6224. return null;
  6225. }
  6226. }
  6227. function get_hashes()
  6228. {
  6229. if ($this->hashes !== null)
  6230. {
  6231. return $this->hashes;
  6232. }
  6233. else
  6234. {
  6235. return null;
  6236. }
  6237. }
  6238. function get_height()
  6239. {
  6240. if ($this->height !== null)
  6241. {
  6242. return $this->height;
  6243. }
  6244. else
  6245. {
  6246. return null;
  6247. }
  6248. }
  6249. function get_language()
  6250. {
  6251. if ($this->lang !== null)
  6252. {
  6253. return $this->lang;
  6254. }
  6255. else
  6256. {
  6257. return null;
  6258. }
  6259. }
  6260. function get_keyword($key = 0)
  6261. {
  6262. $keywords = $this->get_keywords();
  6263. if (isset($keywords[$key]))
  6264. {
  6265. return $keywords[$key];
  6266. }
  6267. else
  6268. {
  6269. return null;
  6270. }
  6271. }
  6272. function get_keywords()
  6273. {
  6274. if ($this->keywords !== null)
  6275. {
  6276. return $this->keywords;
  6277. }
  6278. else
  6279. {
  6280. return null;
  6281. }
  6282. }
  6283. function get_length()
  6284. {
  6285. if ($this->length !== null)
  6286. {
  6287. return $this->length;
  6288. }
  6289. else
  6290. {
  6291. return null;
  6292. }
  6293. }
  6294. function get_link()
  6295. {
  6296. if ($this->link !== null)
  6297. {
  6298. return urldecode($this->link);
  6299. }
  6300. else
  6301. {
  6302. return null;
  6303. }
  6304. }
  6305. function get_medium()
  6306. {
  6307. if ($this->medium !== null)
  6308. {
  6309. return $this->medium;
  6310. }
  6311. else
  6312. {
  6313. return null;
  6314. }
  6315. }
  6316. function get_player()
  6317. {
  6318. if ($this->player !== null)
  6319. {
  6320. return $this->player;
  6321. }
  6322. else
  6323. {
  6324. return null;
  6325. }
  6326. }
  6327. function get_rating($key = 0)
  6328. {
  6329. $ratings = $this->get_ratings();
  6330. if (isset($ratings[$key]))
  6331. {
  6332. return $ratings[$key];
  6333. }
  6334. else
  6335. {
  6336. return null;
  6337. }
  6338. }
  6339. function get_ratings()
  6340. {
  6341. if ($this->ratings !== null)
  6342. {
  6343. return $this->ratings;
  6344. }
  6345. else
  6346. {
  6347. return null;
  6348. }
  6349. }
  6350. function get_restriction($key = 0)
  6351. {
  6352. $restrictions = $this->get_restrictions();
  6353. if (isset($restrictions[$key]))
  6354. {
  6355. return $restrictions[$key];
  6356. }
  6357. else
  6358. {
  6359. return null;
  6360. }
  6361. }
  6362. function get_restrictions()
  6363. {
  6364. if ($this->restrictions !== null)
  6365. {
  6366. return $this->restrictions;
  6367. }
  6368. else
  6369. {
  6370. return null;
  6371. }
  6372. }
  6373. function get_sampling_rate()
  6374. {
  6375. if ($this->samplingrate !== null)
  6376. {
  6377. return $this->samplingrate;
  6378. }
  6379. else
  6380. {
  6381. return null;
  6382. }
  6383. }
  6384. function get_size()
  6385. {
  6386. $length = $this->get_length();
  6387. if ($length !== null)
  6388. {
  6389. return round($length/1048576, 2);
  6390. }
  6391. else
  6392. {
  6393. return null;
  6394. }
  6395. }
  6396. function get_thumbnail($key = 0)
  6397. {
  6398. $thumbnails = $this->get_thumbnails();
  6399. if (isset($thumbnails[$key]))
  6400. {
  6401. return $thumbnails[$key];
  6402. }
  6403. else
  6404. {
  6405. return null;
  6406. }
  6407. }
  6408. function get_thumbnails()
  6409. {
  6410. if ($this->thumbnails !== null)
  6411. {
  6412. return $this->thumbnails;
  6413. }
  6414. else
  6415. {
  6416. return null;
  6417. }
  6418. }
  6419. function get_title()
  6420. {
  6421. if ($this->title !== null)
  6422. {
  6423. return $this->title;
  6424. }
  6425. else
  6426. {
  6427. return null;
  6428. }
  6429. }
  6430. function get_type()
  6431. {
  6432. if ($this->type !== null)
  6433. {
  6434. return $this->type;
  6435. }
  6436. else
  6437. {
  6438. return null;
  6439. }
  6440. }
  6441. function get_width()
  6442. {
  6443. if ($this->width !== null)
  6444. {
  6445. return $this->width;
  6446. }
  6447. else
  6448. {
  6449. return null;
  6450. }
  6451. }
  6452. function native_embed($options='')
  6453. {
  6454. return $this->embed($options, true);
  6455. }
  6456. /**
  6457. * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
  6458. */
  6459. function embed($options = '', $native = false)
  6460. {
  6461. // Set up defaults
  6462. $audio = '';
  6463. $video = '';
  6464. $alt = '';
  6465. $altclass = '';
  6466. $loop = 'false';
  6467. $width = 'auto';
  6468. $height = 'auto';
  6469. $bgcolor = '#ffffff';
  6470. $mediaplayer = '';
  6471. $widescreen = false;
  6472. $handler = $this->get_handler();
  6473. $type = $this->get_real_type();
  6474. // Process options and reassign values as necessary
  6475. if (is_array($options))
  6476. {
  6477. extract($options);
  6478. }
  6479. else
  6480. {
  6481. $options = explode(',', $options);
  6482. foreach($options as $option)
  6483. {
  6484. $opt = explode(':', $option, 2);
  6485. if (isset($opt[0], $opt[1]))
  6486. {
  6487. $opt[0] = trim($opt[0]);
  6488. $opt[1] = trim($opt[1]);
  6489. switch ($opt[0])
  6490. {
  6491. case 'audio':
  6492. $audio = $opt[1];
  6493. break;
  6494. case 'video':
  6495. $video = $opt[1];
  6496. break;
  6497. case 'alt':
  6498. $alt = $opt[1];
  6499. break;
  6500. case 'altclass':
  6501. $altclass = $opt[1];
  6502. break;
  6503. case 'loop':
  6504. $loop = $opt[1];
  6505. break;
  6506. case 'width':
  6507. $width = $opt[1];
  6508. break;
  6509. case 'height':
  6510. $height = $opt[1];
  6511. break;
  6512. case 'bgcolor':
  6513. $bgcolor = $opt[1];
  6514. break;
  6515. case 'mediaplayer':
  6516. $mediaplayer = $opt[1];
  6517. break;
  6518. case 'widescreen':
  6519. $widescreen = $opt[1];
  6520. break;
  6521. }
  6522. }
  6523. }
  6524. }
  6525. $mime = explode('/', $type, 2);
  6526. $mime = $mime[0];
  6527. // Process values for 'auto'
  6528. if ($width === 'auto')
  6529. {
  6530. if ($mime === 'video')
  6531. {
  6532. if ($height === 'auto')
  6533. {
  6534. $width = 480;
  6535. }
  6536. elseif ($widescreen)
  6537. {
  6538. $width = round((intval($height)/9)*16);
  6539. }
  6540. else
  6541. {
  6542. $width = round((intval($height)/3)*4);
  6543. }
  6544. }
  6545. else
  6546. {
  6547. $width = '100%';
  6548. }
  6549. }
  6550. if ($height === 'auto')
  6551. {
  6552. if ($mime === 'audio')
  6553. {
  6554. $height = 0;
  6555. }
  6556. elseif ($mime === 'video')
  6557. {
  6558. if ($width === 'auto')
  6559. {
  6560. if ($widescreen)
  6561. {
  6562. $height = 270;
  6563. }
  6564. else
  6565. {
  6566. $height = 360;
  6567. }
  6568. }
  6569. elseif ($widescreen)
  6570. {
  6571. $height = round((intval($width)/16)*9);
  6572. }
  6573. else
  6574. {
  6575. $height = round((intval($width)/4)*3);
  6576. }
  6577. }
  6578. else
  6579. {
  6580. $height = 376;
  6581. }
  6582. }
  6583. elseif ($mime === 'audio')
  6584. {
  6585. $height = 0;
  6586. }
  6587. // Set proper placeholder value
  6588. if ($mime === 'audio')
  6589. {
  6590. $placeholder = $audio;
  6591. }
  6592. elseif ($mime === 'video')
  6593. {
  6594. $placeholder = $video;
  6595. }
  6596. $embed = '';
  6597. // Make sure the JS library is included
  6598. if (!$native)
  6599. {
  6600. static $javascript_outputted = null;
  6601. if (!$javascript_outputted && $this->javascript)
  6602. {
  6603. $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
  6604. $javascript_outputted = true;
  6605. }
  6606. }
  6607. // Odeo Feed MP3's
  6608. if ($handler === 'odeo')
  6609. {
  6610. if ($native)
  6611. {
  6612. $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>';
  6613. }
  6614. else
  6615. {
  6616. $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
  6617. }
  6618. }
  6619. // Flash
  6620. elseif ($handler === 'flash')
  6621. {
  6622. if ($native)
  6623. {
  6624. $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>";
  6625. }
  6626. else
  6627. {
  6628. $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
  6629. }
  6630. }
  6631. // Flash Media Player file types.
  6632. // Preferred handler for MP3 file types.
  6633. elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
  6634. {
  6635. $height += 20;
  6636. if ($native)
  6637. {
  6638. $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>";
  6639. }
  6640. else
  6641. {
  6642. $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
  6643. }
  6644. }
  6645. // QuickTime 7 file types. Need to test with QuickTime 6.
  6646. // Only handle MP3's if the Flash Media Player is not present.
  6647. elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
  6648. {
  6649. $height += 16;
  6650. if ($native)
  6651. {
  6652. if ($placeholder !== '')
  6653. {
  6654. $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>";
  6655. }
  6656. else
  6657. {
  6658. $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>";
  6659. }
  6660. }
  6661. else
  6662. {
  6663. $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
  6664. }
  6665. }
  6666. // Windows Media
  6667. elseif ($handler === 'wmedia')
  6668. {
  6669. $height += 45;
  6670. if ($native)
  6671. {
  6672. $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>";
  6673. }
  6674. else
  6675. {
  6676. $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
  6677. }
  6678. }
  6679. // Everything else
  6680. else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
  6681. return $embed;
  6682. }
  6683. function get_real_type($find_handler = false)
  6684. {
  6685. // If it's Odeo, let's get it out of the way.
  6686. if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')
  6687. {
  6688. return 'odeo';
  6689. }
  6690. // Mime-types by handler.
  6691. $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
  6692. $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
  6693. $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
  6694. $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
  6695. $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
  6696. if ($this->get_type() !== null)
  6697. {
  6698. $type = strtolower($this->type);
  6699. }
  6700. else
  6701. {
  6702. $type = null;
  6703. }
  6704. // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
  6705. if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
  6706. {
  6707. switch (strtolower($this->get_extension()))
  6708. {
  6709. // Audio mime-types
  6710. case 'aac':
  6711. case 'adts':
  6712. $type = 'audio/acc';
  6713. break;
  6714. case 'aif':
  6715. case 'aifc':
  6716. case 'aiff':
  6717. case 'cdda':
  6718. $type = 'audio/aiff';
  6719. break;
  6720. case 'bwf':
  6721. $type = 'audio/wav';
  6722. break;
  6723. case 'kar':
  6724. case 'mid':
  6725. case 'midi':
  6726. case 'smf':
  6727. $type = 'audio/midi';
  6728. break;
  6729. case 'm4a':
  6730. $type = 'audio/x-m4a';
  6731. break;
  6732. case 'mp3':
  6733. case 'swa':
  6734. $type = 'audio/mp3';
  6735. break;
  6736. case 'wav':
  6737. $type = 'audio/wav';
  6738. break;
  6739. case 'wax':
  6740. $type = 'audio/x-ms-wax';
  6741. break;
  6742. case 'wma':
  6743. $type = 'audio/x-ms-wma';
  6744. break;
  6745. // Video mime-types
  6746. case '3gp':
  6747. case '3gpp':
  6748. $type = 'video/3gpp';
  6749. break;
  6750. case '3g2':
  6751. case '3gp2':
  6752. $type = 'video/3gpp2';
  6753. break;
  6754. case 'asf':
  6755. $type = 'video/x-ms-asf';
  6756. break;
  6757. case 'flv':
  6758. $type = 'video/x-flv';
  6759. break;
  6760. case 'm1a':
  6761. case 'm1s':
  6762. case 'm1v':
  6763. case 'm15':
  6764. case 'm75':
  6765. case 'mp2':
  6766. case 'mpa':
  6767. case 'mpeg':
  6768. case 'mpg':
  6769. case 'mpm':
  6770. case 'mpv':
  6771. $type = 'video/mpeg';
  6772. break;
  6773. case 'm4v':
  6774. $type = 'video/x-m4v';
  6775. break;
  6776. case 'mov':
  6777. case 'qt':
  6778. $type = 'video/quicktime';
  6779. break;
  6780. case 'mp4':
  6781. case 'mpg4':
  6782. $type = 'video/mp4';
  6783. break;
  6784. case 'sdv':
  6785. $type = 'video/sd-video';
  6786. break;
  6787. case 'wm':
  6788. $type = 'video/x-ms-wm';
  6789. break;
  6790. case 'wmv':
  6791. $type = 'video/x-ms-wmv';
  6792. break;
  6793. case 'wvx':
  6794. $type = 'video/x-ms-wvx';
  6795. break;
  6796. // Flash mime-types
  6797. case 'spl':
  6798. $type = 'application/futuresplash';
  6799. break;
  6800. case 'swf':
  6801. $type = 'application/x-shockwave-flash';
  6802. break;
  6803. }
  6804. }
  6805. if ($find_handler)
  6806. {
  6807. if (in_array($type, $types_flash))
  6808. {
  6809. return 'flash';
  6810. }
  6811. elseif (in_array($type, $types_fmedia))
  6812. {
  6813. return 'fmedia';
  6814. }
  6815. elseif (in_array($type, $types_quicktime))
  6816. {
  6817. return 'quicktime';
  6818. }
  6819. elseif (in_array($type, $types_wmedia))
  6820. {
  6821. return 'wmedia';
  6822. }
  6823. elseif (in_array($type, $types_mp3))
  6824. {
  6825. return 'mp3';
  6826. }
  6827. else
  6828. {
  6829. return null;
  6830. }
  6831. }
  6832. else
  6833. {
  6834. return $type;
  6835. }
  6836. }
  6837. }
  6838. class SimplePie_Caption
  6839. {
  6840. var $type;
  6841. var $lang;
  6842. var $startTime;
  6843. var $endTime;
  6844. var $text;
  6845. // Constructor, used to input the data
  6846. function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
  6847. {
  6848. $this->type = $type;
  6849. $this->lang = $lang;
  6850. $this->startTime = $startTime;
  6851. $this->endTime = $endTime;
  6852. $this->text = $text;
  6853. }
  6854. function __toString()
  6855. {
  6856. // There is no $this->data here
  6857. return md5(serialize($this));
  6858. }
  6859. function get_endtime()
  6860. {
  6861. if ($this->endTime !== null)
  6862. {
  6863. return $this->endTime;
  6864. }
  6865. else
  6866. {
  6867. return null;
  6868. }
  6869. }
  6870. function get_language()
  6871. {
  6872. if ($this->lang !== null)
  6873. {
  6874. return $this->lang;
  6875. }
  6876. else
  6877. {
  6878. return null;
  6879. }
  6880. }
  6881. function get_starttime()
  6882. {
  6883. if ($this->startTime !== null)
  6884. {
  6885. return $this->startTime;
  6886. }
  6887. else
  6888. {
  6889. return null;
  6890. }
  6891. }
  6892. function get_text()
  6893. {
  6894. if ($this->text !== null)
  6895. {
  6896. return $this->text;
  6897. }
  6898. else
  6899. {
  6900. return null;
  6901. }
  6902. }
  6903. function get_type()
  6904. {
  6905. if ($this->type !== null)
  6906. {
  6907. return $this->type;
  6908. }
  6909. else
  6910. {
  6911. return null;
  6912. }
  6913. }
  6914. }
  6915. class SimplePie_Credit
  6916. {
  6917. var $role;
  6918. var $scheme;
  6919. var $name;
  6920. // Constructor, used to input the data
  6921. function SimplePie_Credit($role = null, $scheme = null, $name = null)
  6922. {
  6923. $this->role = $role;
  6924. $this->scheme = $scheme;
  6925. $this->name = $name;
  6926. }
  6927. function __toString()
  6928. {
  6929. // There is no $this->data here
  6930. return md5(serialize($this));
  6931. }
  6932. function get_role()
  6933. {
  6934. if ($this->role !== null)
  6935. {
  6936. return $this->role;
  6937. }
  6938. else
  6939. {
  6940. return null;
  6941. }
  6942. }
  6943. function get_scheme()
  6944. {
  6945. if ($this->scheme !== null)
  6946. {
  6947. return $this->scheme;
  6948. }
  6949. else
  6950. {
  6951. return null;
  6952. }
  6953. }
  6954. function get_name()
  6955. {
  6956. if ($this->name !== null)
  6957. {
  6958. return $this->name;
  6959. }
  6960. else
  6961. {
  6962. return null;
  6963. }
  6964. }
  6965. }
  6966. class SimplePie_Copyright
  6967. {
  6968. var $url;
  6969. var $label;
  6970. // Constructor, used to input the data
  6971. function SimplePie_Copyright($url = null, $label = null)
  6972. {
  6973. $this->url = $url;
  6974. $this->label = $label;
  6975. }
  6976. function __toString()
  6977. {
  6978. // There is no $this->data here
  6979. return md5(serialize($this));
  6980. }
  6981. function get_url()
  6982. {
  6983. if ($this->url !== null)
  6984. {
  6985. return $this->url;
  6986. }
  6987. else
  6988. {
  6989. return null;
  6990. }
  6991. }
  6992. function get_attribution()
  6993. {
  6994. if ($this->label !== null)
  6995. {
  6996. return $this->label;
  6997. }
  6998. else
  6999. {
  7000. return null;
  7001. }
  7002. }
  7003. }
  7004. class SimplePie_Rating
  7005. {
  7006. var $scheme;
  7007. var $value;
  7008. // Constructor, used to input the data
  7009. function SimplePie_Rating($scheme = null, $value = null)
  7010. {
  7011. $this->scheme = $scheme;
  7012. $this->value = $value;
  7013. }
  7014. function __toString()
  7015. {
  7016. // There is no $this->data here
  7017. return md5(serialize($this));
  7018. }
  7019. function get_scheme()
  7020. {
  7021. if ($this->scheme !== null)
  7022. {
  7023. return $this->scheme;
  7024. }
  7025. else
  7026. {
  7027. return null;
  7028. }
  7029. }
  7030. function get_value()
  7031. {
  7032. if ($this->value !== null)
  7033. {
  7034. return $this->value;
  7035. }
  7036. else
  7037. {
  7038. return null;
  7039. }
  7040. }
  7041. }
  7042. class SimplePie_Restriction
  7043. {
  7044. var $relationship;
  7045. var $type;
  7046. var $value;
  7047. // Constructor, used to input the data
  7048. function SimplePie_Restriction($relationship = null, $type = null, $value = null)
  7049. {
  7050. $this->relationship = $relationship;
  7051. $this->type = $type;
  7052. $this->value = $value;
  7053. }
  7054. function __toString()
  7055. {
  7056. // There is no $this->data here
  7057. return md5(serialize($this));
  7058. }
  7059. function get_relationship()
  7060. {
  7061. if ($this->relationship !== null)
  7062. {
  7063. return $this->relationship;
  7064. }
  7065. else
  7066. {
  7067. return null;
  7068. }
  7069. }
  7070. function get_type()
  7071. {
  7072. if ($this->type !== null)
  7073. {
  7074. return $this->type;
  7075. }
  7076. else
  7077. {
  7078. return null;
  7079. }
  7080. }
  7081. function get_value()
  7082. {
  7083. if ($this->value !== null)
  7084. {
  7085. return $this->value;
  7086. }
  7087. else
  7088. {
  7089. return null;
  7090. }
  7091. }
  7092. }
  7093. /**
  7094. * @todo Move to properly supporting RFC2616 (HTTP/1.1)
  7095. */
  7096. class SimplePie_File
  7097. {
  7098. var $url;
  7099. var $useragent;
  7100. var $success = true;
  7101. var $headers = array();
  7102. var $body;
  7103. var $status_code;
  7104. var $redirects = 0;
  7105. var $error;
  7106. var $method = SIMPLEPIE_FILE_SOURCE_NONE;
  7107. function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
  7108. {
  7109. if (class_exists('idna_convert'))
  7110. {
  7111. $idn = new idna_convert;
  7112. $parsed = SimplePie_Misc::parse_url($url);
  7113. $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  7114. }
  7115. $this->url = $url;
  7116. $this->useragent = $useragent;
  7117. if (preg_match('/^http(s)?:\/\//i', $url))
  7118. {
  7119. if ($useragent === null)
  7120. {
  7121. $useragent = ini_get('user_agent');
  7122. $this->useragent = $useragent;
  7123. }
  7124. if (!is_array($headers))
  7125. {
  7126. $headers = array();
  7127. }
  7128. if (!$force_fsockopen && function_exists('curl_exec'))
  7129. {
  7130. $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
  7131. $fp = curl_init();
  7132. $headers2 = array();
  7133. foreach ($headers as $key => $value)
  7134. {
  7135. $headers2[] = "$key: $value";
  7136. }
  7137. if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
  7138. {
  7139. curl_setopt($fp, CURLOPT_ENCODING, '');
  7140. }
  7141. curl_setopt($fp, CURLOPT_URL, $url);
  7142. curl_setopt($fp, CURLOPT_HEADER, 1);
  7143. curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
  7144. curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
  7145. curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
  7146. curl_setopt($fp, CURLOPT_REFERER, $url);
  7147. curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
  7148. curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
  7149. if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
  7150. {
  7151. curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
  7152. curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
  7153. }
  7154. $this->headers = curl_exec($fp);
  7155. if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
  7156. {
  7157. curl_setopt($fp, CURLOPT_ENCODING, 'none');
  7158. $this->headers = curl_exec($fp);
  7159. }
  7160. if (curl_errno($fp))
  7161. {
  7162. $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
  7163. $this->success = false;
  7164. }
  7165. else
  7166. {
  7167. $info = curl_getinfo($fp);
  7168. curl_close($fp);
  7169. $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
  7170. $this->headers = array_pop($this->headers);
  7171. $parser = new SimplePie_HTTP_Parser($this->headers);
  7172. if ($parser->parse())
  7173. {
  7174. $this->headers = $parser->headers;
  7175. $this->body = $parser->body;
  7176. $this->status_code = $parser->status_code;
  7177. 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)
  7178. {
  7179. $this->redirects++;
  7180. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  7181. return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  7182. }
  7183. }
  7184. }
  7185. }
  7186. else
  7187. {
  7188. $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
  7189. $url_parts = parse_url($url);
  7190. if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
  7191. {
  7192. $url_parts['host'] = "ssl://$url_parts[host]";
  7193. $url_parts['port'] = 443;
  7194. }
  7195. if (!isset($url_parts['port']))
  7196. {
  7197. $url_parts['port'] = 80;
  7198. }
  7199. $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
  7200. if (!$fp)
  7201. {
  7202. $this->error = 'fsockopen error: ' . $errstr;
  7203. $this->success = false;
  7204. }
  7205. else
  7206. {
  7207. stream_set_timeout($fp, $timeout);
  7208. if (isset($url_parts['path']))
  7209. {
  7210. if (isset($url_parts['query']))
  7211. {
  7212. $get = "$url_parts[path]?$url_parts[query]";
  7213. }
  7214. else
  7215. {
  7216. $get = $url_parts['path'];
  7217. }
  7218. }
  7219. else
  7220. {
  7221. $get = '/';
  7222. }
  7223. $out = "GET $get HTTP/1.0\r\n";
  7224. $out .= "Host: $url_parts[host]\r\n";
  7225. $out .= "User-Agent: $useragent\r\n";
  7226. if (extension_loaded('zlib'))
  7227. {
  7228. $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
  7229. }
  7230. if (isset($url_parts['user']) && isset($url_parts['pass']))
  7231. {
  7232. $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
  7233. }
  7234. foreach ($headers as $key => $value)
  7235. {
  7236. $out .= "$key: $value\r\n";
  7237. }
  7238. $out .= "Connection: Close\r\n\r\n";
  7239. fwrite($fp, $out);
  7240. $info = stream_get_meta_data($fp);
  7241. $this->headers = '';
  7242. while (!$info['eof'] && !$info['timed_out'])
  7243. {
  7244. $this->headers .= fread($fp, 1160);
  7245. $info = stream_get_meta_data($fp);
  7246. }
  7247. if (!$info['timed_out'])
  7248. {
  7249. $parser = new SimplePie_HTTP_Parser($this->headers);
  7250. if ($parser->parse())
  7251. {
  7252. $this->headers = $parser->headers;
  7253. $this->body = $parser->body;
  7254. $this->status_code = $parser->status_code;
  7255. 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)
  7256. {
  7257. $this->redirects++;
  7258. $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  7259. return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  7260. }
  7261. if (isset($this->headers['content-encoding']))
  7262. {
  7263. // Hey, we act dumb elsewhere, so let's do that here too
  7264. switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
  7265. {
  7266. case 'gzip':
  7267. case 'x-gzip':
  7268. $decoder = new SimplePie_gzdecode($this->body);
  7269. if (!$decoder->parse())
  7270. {
  7271. $this->error = 'Unable to decode HTTP "gzip" stream';
  7272. $this->success = false;
  7273. }
  7274. else
  7275. {
  7276. $this->body = $decoder->data;
  7277. }
  7278. break;
  7279. case 'deflate':
  7280. if (($body = gzuncompress($this->body)) === false)
  7281. {
  7282. if (($body = gzinflate($this->body)) === false)
  7283. {
  7284. $this->error = 'Unable to decode HTTP "deflate" stream';
  7285. $this->success = false;
  7286. }
  7287. }
  7288. $this->body = $body;
  7289. break;
  7290. default:
  7291. $this->error = 'Unknown content coding';
  7292. $this->success = false;
  7293. }
  7294. }
  7295. }
  7296. }
  7297. else
  7298. {
  7299. $this->error = 'fsocket timed out';
  7300. $this->success = false;
  7301. }
  7302. fclose($fp);
  7303. }
  7304. }
  7305. }
  7306. else
  7307. {
  7308. $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
  7309. if (!$this->body = file_get_contents($url))
  7310. {
  7311. $this->error = 'file_get_contents could not read the file';
  7312. $this->success = false;
  7313. }
  7314. }
  7315. }
  7316. }
  7317. /**
  7318. * HTTP Response Parser
  7319. *
  7320. * @package SimplePie
  7321. */
  7322. class SimplePie_HTTP_Parser
  7323. {
  7324. /**
  7325. * HTTP Version
  7326. *
  7327. * @access public
  7328. * @var float
  7329. */
  7330. var $http_version = 0.0;
  7331. /**
  7332. * Status code
  7333. *
  7334. * @access public
  7335. * @var int
  7336. */
  7337. var $status_code = 0;
  7338. /**
  7339. * Reason phrase
  7340. *
  7341. * @access public
  7342. * @var string
  7343. */
  7344. var $reason = '';
  7345. /**
  7346. * Key/value pairs of the headers
  7347. *
  7348. * @access public
  7349. * @var array
  7350. */
  7351. var $headers = array();
  7352. /**
  7353. * Body of the response
  7354. *
  7355. * @access public
  7356. * @var string
  7357. */
  7358. var $body = '';
  7359. /**
  7360. * Current state of the state machine
  7361. *
  7362. * @access private
  7363. * @var string
  7364. */
  7365. var $state = 'http_version';
  7366. /**
  7367. * Input data
  7368. *
  7369. * @access private
  7370. * @var string
  7371. */
  7372. var $data = '';
  7373. /**
  7374. * Input data length (to avoid calling strlen() everytime this is needed)
  7375. *
  7376. * @access private
  7377. * @var int
  7378. */
  7379. var $data_length = 0;
  7380. /**
  7381. * Current position of the pointer
  7382. *
  7383. * @var int
  7384. * @access private
  7385. */
  7386. var $position = 0;
  7387. /**
  7388. * Name of the hedaer currently being parsed
  7389. *
  7390. * @access private
  7391. * @var string
  7392. */
  7393. var $name = '';
  7394. /**
  7395. * Value of the hedaer currently being parsed
  7396. *
  7397. * @access private
  7398. * @var string
  7399. */
  7400. var $value = '';
  7401. /**
  7402. * Create an instance of the class with the input data
  7403. *
  7404. * @access public
  7405. * @param string $data Input data
  7406. */
  7407. function SimplePie_HTTP_Parser($data)
  7408. {
  7409. $this->data = $data;
  7410. $this->data_length = strlen($this->data);
  7411. }
  7412. /**
  7413. * Parse the input data
  7414. *
  7415. * @access public
  7416. * @return bool true on success, false on failure
  7417. */
  7418. function parse()
  7419. {
  7420. while ($this->state && $this->state !== 'emit' && $this->has_data())
  7421. {
  7422. $state = $this->state;
  7423. $this->$state();
  7424. }
  7425. $this->data = '';
  7426. if ($this->state === 'emit' || $this->state === 'body')
  7427. {
  7428. return true;
  7429. }
  7430. else
  7431. {
  7432. $this->http_version = '';
  7433. $this->status_code = '';
  7434. $this->reason = '';
  7435. $this->headers = array();
  7436. $this->body = '';
  7437. return false;
  7438. }
  7439. }
  7440. /**
  7441. * Check whether there is data beyond the pointer
  7442. *
  7443. * @access private
  7444. * @return bool true if there is further data, false if not
  7445. */
  7446. function has_data()
  7447. {
  7448. return (bool) ($this->position < $this->data_length);
  7449. }
  7450. /**
  7451. * See if the next character is LWS
  7452. *
  7453. * @access private
  7454. * @return bool true if the next character is LWS, false if not
  7455. */
  7456. function is_linear_whitespace()
  7457. {
  7458. return (bool) ($this->data[$this->position] === "\x09"
  7459. || $this->data[$this->position] === "\x20"
  7460. || ($this->data[$this->position] === "\x0A"
  7461. && isset($this->data[$this->position + 1])
  7462. && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
  7463. }
  7464. /**
  7465. * Parse the HTTP version
  7466. *
  7467. * @access private
  7468. */
  7469. function http_version()
  7470. {
  7471. if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
  7472. {
  7473. $len = strspn($this->data, '0123456789.', 5);
  7474. $this->http_version = substr($this->data, 5, $len);
  7475. $this->position += 5 + $len;
  7476. if (substr_count($this->http_version, '.') <= 1)
  7477. {
  7478. $this->http_version = (float) $this->http_version;
  7479. $this->position += strspn($this->data, "\x09\x20", $this->position);
  7480. $this->state = 'status';
  7481. }
  7482. else
  7483. {
  7484. $this->state = false;
  7485. }
  7486. }
  7487. else
  7488. {
  7489. $this->state = false;
  7490. }
  7491. }
  7492. /**
  7493. * Parse the status code
  7494. *
  7495. * @access private
  7496. */
  7497. function status()
  7498. {
  7499. if ($len = strspn($this->data, '0123456789', $this->position))
  7500. {
  7501. $this->status_code = (int) substr($this->data, $this->position, $len);
  7502. $this->position += $len;
  7503. $this->state = 'reason';
  7504. }
  7505. else
  7506. {
  7507. $this->state = false;
  7508. }
  7509. }
  7510. /**
  7511. * Parse the reason phrase
  7512. *
  7513. * @access private
  7514. */
  7515. function reason()
  7516. {
  7517. $len = strcspn($this->data, "\x0A", $this->position);
  7518. $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
  7519. $this->position += $len + 1;
  7520. $this->state = 'new_line';
  7521. }
  7522. /**
  7523. * Deal with a new line, shifting data around as needed
  7524. *
  7525. * @access private
  7526. */
  7527. function new_line()
  7528. {
  7529. $this->value = trim($this->value, "\x0D\x20");
  7530. if ($this->name !== '' && $this->value !== '')
  7531. {
  7532. $this->name = strtolower($this->name);
  7533. if (isset($this->headers[$this->name]))
  7534. {
  7535. $this->headers[$this->name] .= ', ' . $this->value;
  7536. }
  7537. else
  7538. {
  7539. $this->headers[$this->name] = $this->value;
  7540. }
  7541. }
  7542. $this->name = '';
  7543. $this->value = '';
  7544. if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
  7545. {
  7546. $this->position += 2;
  7547. $this->state = 'body';
  7548. }
  7549. elseif ($this->data[$this->position] === "\x0A")
  7550. {
  7551. $this->position++;
  7552. $this->state = 'body';
  7553. }
  7554. else
  7555. {
  7556. $this->state = 'name';
  7557. }
  7558. }
  7559. /**
  7560. * Parse a header name
  7561. *
  7562. * @access private
  7563. */
  7564. function name()
  7565. {
  7566. $len = strcspn($this->data, "\x0A:", $this->position);
  7567. if (isset($this->data[$this->position + $len]))
  7568. {
  7569. if ($this->data[$this->position + $len] === "\x0A")
  7570. {
  7571. $this->position += $len;
  7572. $this->state = 'new_line';
  7573. }
  7574. else
  7575. {
  7576. $this->name = substr($this->data, $this->position, $len);
  7577. $this->position += $len + 1;
  7578. $this->state = 'value';
  7579. }
  7580. }
  7581. else
  7582. {
  7583. $this->state = false;
  7584. }
  7585. }
  7586. /**
  7587. * Parse LWS, replacing consecutive LWS characters with a single space
  7588. *
  7589. * @access private
  7590. */
  7591. function linear_whitespace()
  7592. {
  7593. do
  7594. {
  7595. if (substr($this->data, $this->position, 2) === "\x0D\x0A")
  7596. {
  7597. $this->position += 2;
  7598. }
  7599. elseif ($this->data[$this->position] === "\x0A")
  7600. {
  7601. $this->position++;
  7602. }
  7603. $this->position += strspn($this->data, "\x09\x20", $this->position);
  7604. } while ($this->has_data() && $this->is_linear_whitespace());
  7605. $this->value .= "\x20";
  7606. }
  7607. /**
  7608. * See what state to move to while within non-quoted header values
  7609. *
  7610. * @access private
  7611. */
  7612. function value()
  7613. {
  7614. if ($this->is_linear_whitespace())
  7615. {
  7616. $this->linear_whitespace();
  7617. }
  7618. else
  7619. {
  7620. switch ($this->data[$this->position])
  7621. {
  7622. case '"':
  7623. $this->position++;
  7624. $this->state = 'quote';
  7625. break;
  7626. case "\x0A":
  7627. $this->position++;
  7628. $this->state = 'new_line';
  7629. break;
  7630. default:
  7631. $this->state = 'value_char';
  7632. break;
  7633. }
  7634. }
  7635. }
  7636. /**
  7637. * Parse a header value while outside quotes
  7638. *
  7639. * @access private
  7640. */
  7641. function value_char()
  7642. {
  7643. $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
  7644. $this->value .= substr($this->data, $this->position, $len);
  7645. $this->position += $len;
  7646. $this->state = 'value';
  7647. }
  7648. /**
  7649. * See what state to move to while within quoted header values
  7650. *
  7651. * @access private
  7652. */
  7653. function quote()
  7654. {
  7655. if ($this->is_linear_whitespace())
  7656. {
  7657. $this->linear_whitespace();
  7658. }
  7659. else
  7660. {
  7661. switch ($this->data[$this->position])
  7662. {
  7663. case '"':
  7664. $this->position++;
  7665. $this->state = 'value';
  7666. break;
  7667. case "\x0A":
  7668. $this->position++;
  7669. $this->state = 'new_line';
  7670. break;
  7671. case '\\':
  7672. $this->position++;
  7673. $this->state = 'quote_escaped';
  7674. break;
  7675. default:
  7676. $this->state = 'quote_char';
  7677. break;
  7678. }
  7679. }
  7680. }
  7681. /**
  7682. * Parse a header value while within quotes
  7683. *
  7684. * @access private
  7685. */
  7686. function quote_char()
  7687. {
  7688. $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
  7689. $this->value .= substr($this->data, $this->position, $len);
  7690. $this->position += $len;
  7691. $this->state = 'value';
  7692. }
  7693. /**
  7694. * Parse an escaped character within quotes
  7695. *
  7696. * @access private
  7697. */
  7698. function quote_escaped()
  7699. {
  7700. $this->value .= $this->data[$this->position];
  7701. $this->position++;
  7702. $this->state = 'quote';
  7703. }
  7704. /**
  7705. * Parse the body
  7706. *
  7707. * @access private
  7708. */
  7709. function body()
  7710. {
  7711. $this->body = substr($this->data, $this->position);
  7712. $this->state = 'emit';
  7713. }
  7714. }
  7715. /**
  7716. * gzdecode
  7717. *
  7718. * @package SimplePie
  7719. */
  7720. class SimplePie_gzdecode
  7721. {
  7722. /**
  7723. * Compressed data
  7724. *
  7725. * @access private
  7726. * @see gzdecode::$data
  7727. */
  7728. var $compressed_data;
  7729. /**
  7730. * Size of compressed data
  7731. *
  7732. * @access private
  7733. */
  7734. var $compressed_size;
  7735. /**
  7736. * Minimum size of a valid gzip string
  7737. *
  7738. * @access private
  7739. */
  7740. var $min_compressed_size = 18;
  7741. /**
  7742. * Current position of pointer
  7743. *
  7744. * @access private
  7745. */
  7746. var $position = 0;
  7747. /**
  7748. * Flags (FLG)
  7749. *
  7750. * @access private
  7751. */
  7752. var $flags;
  7753. /**
  7754. * Uncompressed data
  7755. *
  7756. * @access public
  7757. * @see gzdecode::$compressed_data
  7758. */
  7759. var $data;
  7760. /**
  7761. * Modified time
  7762. *
  7763. * @access public
  7764. */
  7765. var $MTIME;
  7766. /**
  7767. * Extra Flags
  7768. *
  7769. * @access public
  7770. */
  7771. var $XFL;
  7772. /**
  7773. * Operating System
  7774. *
  7775. * @access public
  7776. */
  7777. var $OS;
  7778. /**
  7779. * Subfield ID 1
  7780. *
  7781. * @access public
  7782. * @see gzdecode::$extra_field
  7783. * @see gzdecode::$SI2
  7784. */
  7785. var $SI1;
  7786. /**
  7787. * Subfield ID 2
  7788. *
  7789. * @access public
  7790. * @see gzdecode::$extra_field
  7791. * @see gzdecode::$SI1
  7792. */
  7793. var $SI2;
  7794. /**
  7795. * Extra field content
  7796. *
  7797. * @access public
  7798. * @see gzdecode::$SI1
  7799. * @see gzdecode::$SI2
  7800. */
  7801. var $extra_field;
  7802. /**
  7803. * Original filename
  7804. *
  7805. * @access public
  7806. */
  7807. var $filename;
  7808. /**
  7809. * Human readable comment
  7810. *
  7811. * @access public
  7812. */
  7813. var $comment;
  7814. /**
  7815. * Don't allow anything to be set
  7816. *
  7817. * @access public
  7818. */
  7819. function __set($name, $value)
  7820. {
  7821. trigger_error("Cannot write property $name", E_USER_ERROR);
  7822. }
  7823. /**
  7824. * Set the compressed string and related properties
  7825. *
  7826. * @access public
  7827. */
  7828. function SimplePie_gzdecode($data)
  7829. {
  7830. $this->compressed_data = $data;
  7831. $this->compressed_size = strlen($data);
  7832. }
  7833. /**
  7834. * Decode the GZIP stream
  7835. *
  7836. * @access public
  7837. */
  7838. function parse()
  7839. {
  7840. if ($this->compressed_size >= $this->min_compressed_size)
  7841. {
  7842. // Check ID1, ID2, and CM
  7843. if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
  7844. {
  7845. return false;
  7846. }
  7847. // Get the FLG (FLaGs)
  7848. $this->flags = ord($this->compressed_data[3]);
  7849. // FLG bits above (1 << 4) are reserved
  7850. if ($this->flags > 0x1F)
  7851. {
  7852. return false;
  7853. }
  7854. // Advance the pointer after the above
  7855. $this->position += 4;
  7856. // MTIME
  7857. $mtime = substr($this->compressed_data, $this->position, 4);
  7858. // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
  7859. if (current(unpack('S', "\x00\x01")) === 1)
  7860. {
  7861. $mtime = strrev($mtime);
  7862. }
  7863. $this->MTIME = current(unpack('l', $mtime));
  7864. $this->position += 4;
  7865. // Get the XFL (eXtra FLags)
  7866. $this->XFL = ord($this->compressed_data[$this->position++]);
  7867. // Get the OS (Operating System)
  7868. $this->OS = ord($this->compressed_data[$this->position++]);
  7869. // Parse the FEXTRA
  7870. if ($this->flags & 4)
  7871. {
  7872. // Read subfield IDs
  7873. $this->SI1 = $this->compressed_data[$this->position++];
  7874. $this->SI2 = $this->compressed_data[$this->position++];
  7875. // SI2 set to zero is reserved for future use
  7876. if ($this->SI2 === "\x00")
  7877. {
  7878. return false;
  7879. }
  7880. // Get the length of the extra field
  7881. $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
  7882. $position += 2;
  7883. // Check the length of the string is still valid
  7884. $this->min_compressed_size += $len + 4;
  7885. if ($this->compressed_size >= $this->min_compressed_size)
  7886. {
  7887. // Set the extra field to the given data
  7888. $this->extra_field = substr($this->compressed_data, $this->position, $len);
  7889. $this->position += $len;
  7890. }
  7891. else
  7892. {
  7893. return false;
  7894. }
  7895. }
  7896. // Parse the FNAME
  7897. if ($this->flags & 8)
  7898. {
  7899. // Get the length of the filename
  7900. $len = strcspn($this->compressed_data, "\x00", $this->position);
  7901. // Check the length of the string is still valid
  7902. $this->min_compressed_size += $len + 1;
  7903. if ($this->compressed_size >= $this->min_compressed_size)
  7904. {
  7905. // Set the original filename to the given string
  7906. $this->filename = substr($this->compressed_data, $this->position, $len);
  7907. $this->position += $len + 1;
  7908. }
  7909. else
  7910. {
  7911. return false;
  7912. }
  7913. }
  7914. // Parse the FCOMMENT
  7915. if ($this->flags & 16)
  7916. {
  7917. // Get the length of the comment
  7918. $len = strcspn($this->compressed_data, "\x00", $this->position);
  7919. // Check the length of the string is still valid
  7920. $this->min_compressed_size += $len + 1;
  7921. if ($this->compressed_size >= $this->min_compressed_size)
  7922. {
  7923. // Set the original comment to the given string
  7924. $this->comment = substr($this->compressed_data, $this->position, $len);
  7925. $this->position += $len + 1;
  7926. }
  7927. else
  7928. {
  7929. return false;
  7930. }
  7931. }
  7932. // Parse the FHCRC
  7933. if ($this->flags & 2)
  7934. {
  7935. // Check the length of the string is still valid
  7936. $this->min_compressed_size += $len + 2;
  7937. if ($this->compressed_size >= $this->min_compressed_size)
  7938. {
  7939. // Read the CRC
  7940. $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
  7941. // Check the CRC matches
  7942. if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
  7943. {
  7944. $this->position += 2;
  7945. }
  7946. else
  7947. {
  7948. return false;
  7949. }
  7950. }
  7951. else
  7952. {
  7953. return false;
  7954. }
  7955. }
  7956. // Decompress the actual data
  7957. if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
  7958. {
  7959. return false;
  7960. }
  7961. else
  7962. {
  7963. $this->position = $this->compressed_size - 8;
  7964. }
  7965. // Check CRC of data
  7966. $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
  7967. $this->position += 4;
  7968. /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
  7969. {
  7970. return false;
  7971. }*/
  7972. // Check ISIZE of data
  7973. $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
  7974. $this->position += 4;
  7975. if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
  7976. {
  7977. return false;
  7978. }
  7979. // Wow, against all odds, we've actually got a valid gzip string
  7980. return true;
  7981. }
  7982. else
  7983. {
  7984. return false;
  7985. }
  7986. }
  7987. }
  7988. class SimplePie_Cache
  7989. {
  7990. /**
  7991. * Don't call the constructor. Please.
  7992. *
  7993. * @access private
  7994. */
  7995. function SimplePie_Cache()
  7996. {
  7997. trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
  7998. }
  7999. /**
  8000. * Create a new SimplePie_Cache object
  8001. *
  8002. * @static
  8003. * @access public
  8004. */
  8005. function create($location, $filename, $extension)
  8006. {
  8007. $location_iri = new SimplePie_IRI($location);
  8008. switch ($location_iri->get_scheme())
  8009. {
  8010. case 'mysql':
  8011. if (extension_loaded('mysql'))
  8012. {
  8013. return new SimplePie_Cache_MySQL($location_iri, $filename, $extension);
  8014. }
  8015. break;
  8016. default:
  8017. return new SimplePie_Cache_File($location, $filename, $extension);
  8018. }
  8019. }
  8020. }
  8021. class SimplePie_Cache_File
  8022. {
  8023. var $location;
  8024. var $filename;
  8025. var $extension;
  8026. var $name;
  8027. function SimplePie_Cache_File($location, $filename, $extension)
  8028. {
  8029. $this->location = $location;
  8030. $this->filename = $filename;
  8031. $this->extension = $extension;
  8032. $this->name = "$this->location/$this->filename.$this->extension";
  8033. }
  8034. function save($data)
  8035. {
  8036. if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
  8037. {
  8038. if (is_a($data, 'SimplePie'))
  8039. {
  8040. $data = $data->data;
  8041. }
  8042. $data = serialize($data);
  8043. if (function_exists('file_put_contents'))
  8044. {
  8045. return (bool) file_put_contents($this->name, $data);
  8046. }
  8047. else
  8048. {
  8049. $fp = fopen($this->name, 'wb');
  8050. if ($fp)
  8051. {
  8052. fwrite($fp, $data);
  8053. fclose($fp);
  8054. return true;
  8055. }
  8056. }
  8057. }
  8058. return false;
  8059. }
  8060. function load()
  8061. {
  8062. if (file_exists($this->name) && is_readable($this->name))
  8063. {
  8064. return unserialize(file_get_contents($this->name));
  8065. }
  8066. return false;
  8067. }
  8068. function mtime()
  8069. {
  8070. if (file_exists($this->name))
  8071. {
  8072. return filemtime($this->name);
  8073. }
  8074. return false;
  8075. }
  8076. function touch()
  8077. {
  8078. if (file_exists($this->name))
  8079. {
  8080. return touch($this->name);
  8081. }
  8082. return false;
  8083. }
  8084. function unlink()
  8085. {
  8086. if (file_exists($this->name))
  8087. {
  8088. return unlink($this->name);
  8089. }
  8090. return false;
  8091. }
  8092. }
  8093. class SimplePie_Cache_DB
  8094. {
  8095. function prepare_simplepie_object_for_cache($data)
  8096. {
  8097. $items = $data->get_items();
  8098. $items_by_id = array();
  8099. if (!empty($items))
  8100. {
  8101. foreach ($items as $item)
  8102. {
  8103. $items_by_id[$item->get_id()] = $item;
  8104. }
  8105. if (count($items_by_id) !== count($items))
  8106. {
  8107. $items_by_id = array();
  8108. foreach ($items as $item)
  8109. {
  8110. $items_by_id[$item->get_id(true)] = $item;
  8111. }
  8112. }
  8113. if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
  8114. {
  8115. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
  8116. }
  8117. elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
  8118. {
  8119. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
  8120. }
  8121. elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
  8122. {
  8123. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
  8124. }
  8125. elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
  8126. {
  8127. $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
  8128. }
  8129. else
  8130. {
  8131. $channel = null;
  8132. }
  8133. if ($channel !== null)
  8134. {
  8135. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
  8136. {
  8137. unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
  8138. }
  8139. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
  8140. {
  8141. unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
  8142. }
  8143. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
  8144. {
  8145. unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
  8146. }
  8147. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
  8148. {
  8149. unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
  8150. }
  8151. if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
  8152. {
  8153. unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
  8154. }
  8155. }
  8156. if (isset($data->data['items']))
  8157. {
  8158. unset($data->data['items']);
  8159. }
  8160. if (isset($data->data['ordered_items']))
  8161. {
  8162. unset($data->data['ordered_items']);
  8163. }
  8164. }
  8165. return array(serialize($data->data), $items_by_id);
  8166. }
  8167. }
  8168. class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
  8169. {
  8170. var $mysql;
  8171. var $options;
  8172. var $id;
  8173. function SimplePie_Cache_MySQL($mysql_location, $name, $extension)
  8174. {
  8175. $host = $mysql_location->get_host();
  8176. if (SimplePie_Misc::stripos($host, 'unix(') === 0 && substr($host, -1) === ')')
  8177. {
  8178. $server = ':' . substr($host, 5, -1);
  8179. }
  8180. else
  8181. {
  8182. $server = $host;
  8183. if ($mysql_location->get_port() !== null)
  8184. {
  8185. $server .= ':' . $mysql_location->get_port();
  8186. }
  8187. }
  8188. if (strpos($mysql_location->get_userinfo(), ':') !== false)
  8189. {
  8190. list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2);
  8191. }
  8192. else
  8193. {
  8194. $username = $mysql_location->get_userinfo();
  8195. $password = null;
  8196. }
  8197. if ($this->mysql = mysql_connect($server, $username, $password))
  8198. {
  8199. $this->id = $name . $extension;
  8200. $this->options = SimplePie_Misc::parse_str($mysql_location->get_query());
  8201. if (!isset($this->options['prefix'][0]))
  8202. {
  8203. $this->options['prefix'][0] = '';
  8204. }
  8205. if (mysql_select_db(ltrim($mysql_location->get_path(), '/'))
  8206. && mysql_query('SET NAMES utf8')
  8207. && ($query = mysql_unbuffered_query('SHOW TABLES')))
  8208. {
  8209. $db = array();
  8210. while ($row = mysql_fetch_row($query))
  8211. {
  8212. $db[] = $row[0];
  8213. }
  8214. if (!in_array($this->options['prefix'][0] . 'cache_data', $db))
  8215. {
  8216. 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)))'))
  8217. {
  8218. $this->mysql = null;
  8219. }
  8220. }
  8221. if (!in_array($this->options['prefix'][0] . 'items', $db))
  8222. {
  8223. 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)))'))
  8224. {
  8225. $this->mysql = null;
  8226. }
  8227. }
  8228. }
  8229. else
  8230. {
  8231. $this->mysql = null;
  8232. }
  8233. }
  8234. }
  8235. function save($data)
  8236. {
  8237. if ($this->mysql)
  8238. {
  8239. $feed_id = "'" . mysql_real_escape_string($this->id) . "'";
  8240. if (is_a($data, 'SimplePie'))
  8241. {
  8242. if (SIMPLEPIE_PHP5)
  8243. {
  8244. // This keyword needs to defy coding standards for PHP4 compatibility
  8245. $data = clone($data);
  8246. }
  8247. $prepared = $this->prepare_simplepie_object_for_cache($data);
  8248. if ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
  8249. {
  8250. if (mysql_num_rows($query))
  8251. {
  8252. $items = count($prepared[1]);
  8253. if ($items)
  8254. {
  8255. $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
  8256. }
  8257. else
  8258. {
  8259. $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
  8260. }
  8261. if (!mysql_query($sql, $this->mysql))
  8262. {
  8263. return false;
  8264. }
  8265. }
  8266. 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))
  8267. {
  8268. return false;
  8269. }
  8270. $ids = array_keys($prepared[1]);
  8271. if (!empty($ids))
  8272. {
  8273. foreach ($ids as $id)
  8274. {
  8275. $database_ids[] = mysql_real_escape_string($id);
  8276. }
  8277. 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))
  8278. {
  8279. $existing_ids = array();
  8280. while ($row = mysql_fetch_row($query))
  8281. {
  8282. $existing_ids[] = $row[0];
  8283. }
  8284. $new_ids = array_diff($ids, $existing_ids);
  8285. foreach ($new_ids as $new_id)
  8286. {
  8287. if (!($date = $prepared[1][$new_id]->get_date('U')))
  8288. {
  8289. $date = time();
  8290. }
  8291. 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))
  8292. {
  8293. return false;
  8294. }
  8295. }
  8296. return true;
  8297. }
  8298. }
  8299. else
  8300. {
  8301. return true;
  8302. }
  8303. }
  8304. }
  8305. elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
  8306. {
  8307. if (mysql_num_rows($query))
  8308. {
  8309. 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))
  8310. {
  8311. return true;
  8312. }
  8313. }
  8314. 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))
  8315. {
  8316. return true;
  8317. }
  8318. }
  8319. }
  8320. return false;
  8321. }
  8322. function load()
  8323. {
  8324. 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)))
  8325. {
  8326. $data = unserialize($row[1]);
  8327. if (isset($this->options['items'][0]))
  8328. {
  8329. $items = (int) $this->options['items'][0];
  8330. }
  8331. else
  8332. {
  8333. $items = (int) $row[0];
  8334. }
  8335. if ($items !== 0)
  8336. {
  8337. if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
  8338. {
  8339. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
  8340. }
  8341. elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
  8342. {
  8343. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
  8344. }
  8345. elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
  8346. {
  8347. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
  8348. }
  8349. elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
  8350. {
  8351. $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
  8352. }
  8353. else
  8354. {
  8355. $feed = null;
  8356. }
  8357. if ($feed !== null)
  8358. {
  8359. $sql = 'SELECT `data` FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . '\' ORDER BY `posted` DESC';
  8360. if ($items > 0)
  8361. {
  8362. $sql .= ' LIMIT ' . $items;
  8363. }
  8364. if ($query = mysql_unbuffered_query($sql, $this->mysql))
  8365. {
  8366. while ($row = mysql_fetch_row($query))
  8367. {
  8368. $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row[0]);
  8369. }
  8370. }
  8371. else
  8372. {
  8373. return false;
  8374. }
  8375. }
  8376. }
  8377. return $data;
  8378. }
  8379. return false;
  8380. }
  8381. function mtime()
  8382. {
  8383. 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)))
  8384. {
  8385. return $row[0];
  8386. }
  8387. else
  8388. {
  8389. return false;
  8390. }
  8391. }
  8392. function touch()
  8393. {
  8394. 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))
  8395. {
  8396. return true;
  8397. }
  8398. else
  8399. {
  8400. return false;
  8401. }
  8402. }
  8403. function unlink()
  8404. {
  8405. 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)))
  8406. {
  8407. return true;
  8408. }
  8409. else
  8410. {
  8411. return false;
  8412. }
  8413. }
  8414. }
  8415. class SimplePie_Misc
  8416. {
  8417. function time_hms($seconds)
  8418. {
  8419. $time = '';
  8420. $hours = floor($seconds / 3600);
  8421. $remainder = $seconds % 3600;
  8422. if ($hours > 0)
  8423. {
  8424. $time .= $hours.':';
  8425. }
  8426. $minutes = floor($remainder / 60);
  8427. $seconds = $remainder % 60;
  8428. if ($minutes < 10 && $hours > 0)
  8429. {
  8430. $minutes = '0' . $minutes;
  8431. }
  8432. if ($seconds < 10)
  8433. {
  8434. $seconds = '0' . $seconds;
  8435. }
  8436. $time .= $minutes.':';
  8437. $time .= $seconds;
  8438. return $time;
  8439. }
  8440. function absolutize_url($relative, $base)
  8441. {
  8442. $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);
  8443. return $iri->get_iri();
  8444. }
  8445. function remove_dot_segments($input)
  8446. {
  8447. $output = '';
  8448. while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
  8449. {
  8450. // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
  8451. if (strpos($input, '../') === 0)
  8452. {
  8453. $input = substr($input, 3);
  8454. }
  8455. elseif (strpos($input, './') === 0)
  8456. {
  8457. $input = substr($input, 2);
  8458. }
  8459. // 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,
  8460. elseif (strpos($input, '/./') === 0)
  8461. {
  8462. $input = substr_replace($input, '/', 0, 3);
  8463. }
  8464. elseif ($input === '/.')
  8465. {
  8466. $input = '/';
  8467. }
  8468. // 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,
  8469. elseif (strpos($input, '/../') === 0)
  8470. {
  8471. $input = substr_replace($input, '/', 0, 4);
  8472. $output = substr_replace($output, '', strrpos($output, '/'));
  8473. }
  8474. elseif ($input === '/..')
  8475. {
  8476. $input = '/';
  8477. $output = substr_replace($output, '', strrpos($output, '/'));
  8478. }
  8479. // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
  8480. elseif ($input === '.' || $input === '..')
  8481. {
  8482. $input = '';
  8483. }
  8484. // 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
  8485. elseif (($pos = strpos($input, '/', 1)) !== false)
  8486. {
  8487. $output .= substr($input, 0, $pos);
  8488. $input = substr_replace($input, '', 0, $pos);
  8489. }
  8490. else
  8491. {
  8492. $output .= $input;
  8493. $input = '';
  8494. }
  8495. }
  8496. return $output . $input;
  8497. }
  8498. function get_element($realname, $string)
  8499. {
  8500. $return = array();
  8501. $name = preg_quote($realname, '/');
  8502. if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
  8503. {
  8504. for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
  8505. {
  8506. $return[$i]['tag'] = $realname;
  8507. $return[$i]['full'] = $matches[$i][0][0];
  8508. $return[$i]['offset'] = $matches[$i][0][1];
  8509. if (strlen($matches[$i][3][0]) <= 2)
  8510. {
  8511. $return[$i]['self_closing'] = true;
  8512. }
  8513. else
  8514. {
  8515. $return[$i]['self_closing'] = false;
  8516. $return[$i]['content'] = $matches[$i][4][0];
  8517. }
  8518. $return[$i]['attribs'] = array();
  8519. 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))
  8520. {
  8521. for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
  8522. {
  8523. if (count($attribs[$j]) === 2)
  8524. {
  8525. $attribs[$j][2] = $attribs[$j][1];
  8526. }
  8527. $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
  8528. }
  8529. }
  8530. }
  8531. }
  8532. return $return;
  8533. }
  8534. function element_implode($element)
  8535. {
  8536. $full = "<$element[tag]";
  8537. foreach ($element['attribs'] as $key => $value)
  8538. {
  8539. $key = strtolower($key);
  8540. $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
  8541. }
  8542. if ($element['self_closing'])
  8543. {
  8544. $full .= ' />';
  8545. }
  8546. else
  8547. {
  8548. $full .= ">$element[content]</$element[tag]>";
  8549. }
  8550. return $full;
  8551. }
  8552. function error($message, $level, $file, $line)
  8553. {
  8554. if ((ini_get('error_reporting') & $level) > 0)
  8555. {
  8556. switch ($level)
  8557. {
  8558. case E_USER_ERROR:
  8559. $note = 'PHP Error';
  8560. break;
  8561. case E_USER_WARNING:
  8562. $note = 'PHP Warning';
  8563. break;
  8564. case E_USER_NOTICE:
  8565. $note = 'PHP Notice';
  8566. break;
  8567. default:
  8568. $note = 'Unknown Error';
  8569. break;
  8570. }
  8571. error_log("$note: $message in $file on line $line", 0);
  8572. }
  8573. return $message;
  8574. }
  8575. /**
  8576. * If a file has been cached, retrieve and display it.
  8577. *
  8578. * This is most useful for caching images (get_favicon(), etc.),
  8579. * however it works for all cached files. This WILL NOT display ANY
  8580. * file/image/page/whatever, but rather only display what has already
  8581. * been cached by SimplePie.
  8582. *
  8583. * @access public
  8584. * @see SimplePie::get_favicon()
  8585. * @param str $identifier_url URL that is used to identify the content.
  8586. * This may or may not be the actual URL of the live content.
  8587. * @param str $cache_location Location of SimplePie's cache. Defaults
  8588. * to './cache'.
  8589. * @param str $cache_extension The file extension that the file was
  8590. * cached with. Defaults to 'spc'.
  8591. * @param str $cache_class Name of the cache-handling class being used
  8592. * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
  8593. * as-is unless you've overloaded the class.
  8594. * @param str $cache_name_function Obsolete. Exists for backwards
  8595. * compatibility reasons only.
  8596. */
  8597. function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
  8598. {
  8599. $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
  8600. if ($file = $cache->load())
  8601. {
  8602. if (isset($file['headers']['content-type']))
  8603. {
  8604. header('Content-type:' . $file['headers']['content-type']);
  8605. }
  8606. else
  8607. {
  8608. header('Content-type: application/octet-stream');
  8609. }
  8610. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  8611. echo $file['body'];
  8612. exit;
  8613. }
  8614. die('Cached file for ' . $identifier_url . ' cannot be found.');
  8615. }
  8616. function fix_protocol($url, $http = 1)
  8617. {
  8618. $url = SimplePie_Misc::normalize_url($url);
  8619. $parsed = SimplePie_Misc::parse_url($url);
  8620. if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
  8621. {
  8622. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
  8623. }
  8624. if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
  8625. {
  8626. return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
  8627. }
  8628. if ($http === 2 && $parsed['scheme'] !== '')
  8629. {
  8630. return "feed:$url";
  8631. }
  8632. elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
  8633. {
  8634. return substr_replace($url, 'podcast', 0, 4);
  8635. }
  8636. elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
  8637. {
  8638. return substr_replace($url, 'itpc', 0, 4);
  8639. }
  8640. else
  8641. {
  8642. return $url;
  8643. }
  8644. }
  8645. function parse_url($url)
  8646. {
  8647. $iri = new SimplePie_IRI($url);
  8648. return array(
  8649. 'scheme' => (string) $iri->get_scheme(),
  8650. 'authority' => (string) $iri->get_authority(),
  8651. 'path' => (string) $iri->get_path(),
  8652. 'query' => (string) $iri->get_query(),
  8653. 'fragment' => (string) $iri->get_fragment()
  8654. );
  8655. }
  8656. function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
  8657. {
  8658. $iri = new SimplePie_IRI('');
  8659. $iri->set_scheme($scheme);
  8660. $iri->set_authority($authority);
  8661. $iri->set_path($path);
  8662. $iri->set_query($query);
  8663. $iri->set_fragment($fragment);
  8664. return $iri->get_iri();
  8665. }
  8666. function normalize_url($url)
  8667. {
  8668. $iri = new SimplePie_IRI($url);
  8669. return $iri->get_iri();
  8670. }
  8671. function percent_encoding_normalization($match)
  8672. {
  8673. $integer = hexdec($match[1]);
  8674. if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
  8675. {
  8676. return chr($integer);
  8677. }
  8678. else
  8679. {
  8680. return strtoupper($match[0]);
  8681. }
  8682. }
  8683. /**
  8684. * Remove bad UTF-8 bytes
  8685. *
  8686. * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
  8687. * FAQ: Multilingual Forms (modified to include full ASCII range)
  8688. *
  8689. * @author Geoffrey Sneddon
  8690. * @see http://www.w3.org/International/questions/qa-forms-utf-8
  8691. * @param string $str String to remove bad UTF-8 bytes from
  8692. * @return string UTF-8 string
  8693. */
  8694. function utf8_bad_replace($str)
  8695. {
  8696. if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
  8697. {
  8698. return $return;
  8699. }
  8700. elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
  8701. {
  8702. return $return;
  8703. }
  8704. 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))
  8705. {
  8706. return implode("\xEF\xBF\xBD", $matches[0]);
  8707. }
  8708. elseif ($str !== '')
  8709. {
  8710. return "\xEF\xBF\xBD";
  8711. }
  8712. else
  8713. {
  8714. return '';
  8715. }
  8716. }
  8717. /**
  8718. * Converts a Windows-1252 encoded string to a UTF-8 encoded string
  8719. *
  8720. * @static
  8721. * @access public
  8722. * @param string $string Windows-1252 encoded string
  8723. * @return string UTF-8 encoded string
  8724. */
  8725. function windows_1252_to_utf8($string)
  8726. {
  8727. 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");
  8728. return strtr($string, $convert_table);
  8729. }
  8730. function change_encoding($data, $input, $output)
  8731. {
  8732. $input = SimplePie_Misc::encoding($input);
  8733. $output = SimplePie_Misc::encoding($output);
  8734. // We fail to fail on non US-ASCII bytes
  8735. if ($input === 'US-ASCII')
  8736. {
  8737. static $non_ascii_octects = '';
  8738. if (!$non_ascii_octects)
  8739. {
  8740. for ($i = 0x80; $i <= 0xFF; $i++)
  8741. {
  8742. $non_ascii_octects .= chr($i);
  8743. }
  8744. }
  8745. $data = substr($data, 0, strcspn($data, $non_ascii_octects));
  8746. }
  8747. // This is first, as behaviour of this is completely predictable
  8748. if ($input === 'Windows-1252' && $output === 'UTF-8')
  8749. {
  8750. return SimplePie_Misc::windows_1252_to_utf8($data);
  8751. }
  8752. // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
  8753. elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && ($return = @mb_convert_encoding($data, $output, $input)))
  8754. {
  8755. return $return;
  8756. }
  8757. // This is last, as behaviour of this varies with OS userland and PHP version
  8758. elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
  8759. {
  8760. return $return;
  8761. }
  8762. // If we can't do anything, just fail
  8763. else
  8764. {
  8765. return false;
  8766. }
  8767. }
  8768. function encoding($charset)
  8769. {
  8770. // Normalization from UTS #22
  8771. switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
  8772. {
  8773. case 'adobestandardencoding':
  8774. case 'csadobestandardencoding':
  8775. return 'Adobe-Standard-Encoding';
  8776. case 'adobesymbolencoding':
  8777. case 'cshppsmath':
  8778. return 'Adobe-Symbol-Encoding';
  8779. case 'ami1251':
  8780. case 'amiga1251':
  8781. return 'Amiga-1251';
  8782. case 'ansix31101983':
  8783. case 'csat5001983':
  8784. case 'csiso99naplps':
  8785. case 'isoir99':
  8786. case 'naplps':
  8787. return 'ANSI_X3.110-1983';
  8788. case 'arabic7':
  8789. case 'asmo449':
  8790. case 'csiso89asmo449':
  8791. case 'iso9036':
  8792. case 'isoir89':
  8793. return 'ASMO_449';
  8794. case 'big5':
  8795. case 'csbig5':
  8796. case 'xxbig5':
  8797. return 'Big5';
  8798. case 'big5hkscs':
  8799. return 'Big5-HKSCS';
  8800. case 'bocu1':
  8801. case 'csbocu1':
  8802. return 'BOCU-1';
  8803. case 'brf':
  8804. case 'csbrf':
  8805. return 'BRF';
  8806. case 'bs4730':
  8807. case 'csiso4unitedkingdom':
  8808. case 'gb':
  8809. case 'iso646gb':
  8810. case 'isoir4':
  8811. case 'uk':
  8812. return 'BS_4730';
  8813. case 'bsviewdata':
  8814. case 'csiso47bsviewdata':
  8815. case 'isoir47':
  8816. return 'BS_viewdata';
  8817. case 'cesu8':
  8818. case 'cscesu8':
  8819. return 'CESU-8';
  8820. case 'ca':
  8821. case 'csa71':
  8822. case 'csaz243419851':
  8823. case 'csiso121canadian1':
  8824. case 'iso646ca':
  8825. case 'isoir121':
  8826. return 'CSA_Z243.4-1985-1';
  8827. case 'csa72':
  8828. case 'csaz243419852':
  8829. case 'csiso122canadian2':
  8830. case 'iso646ca2':
  8831. case 'isoir122':
  8832. return 'CSA_Z243.4-1985-2';
  8833. case 'csaz24341985gr':
  8834. case 'csiso123csaz24341985gr':
  8835. case 'isoir123':
  8836. return 'CSA_Z243.4-1985-gr';
  8837. case 'csiso139csn369103':
  8838. case 'csn369103':
  8839. case 'isoir139':
  8840. return 'CSN_369103';
  8841. case 'csdecmcs':
  8842. case 'dec':
  8843. case 'decmcs':
  8844. return 'DEC-MCS';
  8845. case 'csiso21german':
  8846. case 'de':
  8847. case 'din66003':
  8848. case 'iso646de':
  8849. case 'isoir21':
  8850. return 'DIN_66003';
  8851. case 'csdkus':
  8852. case 'dkus':
  8853. return 'dk-us';
  8854. case 'csiso646danish':
  8855. case 'dk':
  8856. case 'ds2089':
  8857. case 'iso646dk':
  8858. return 'DS_2089';
  8859. case 'csibmebcdicatde':
  8860. case 'ebcdicatde':
  8861. return 'EBCDIC-AT-DE';
  8862. case 'csebcdicatdea':
  8863. case 'ebcdicatdea':
  8864. return 'EBCDIC-AT-DE-A';
  8865. case 'csebcdiccafr':
  8866. case 'ebcdiccafr':
  8867. return 'EBCDIC-CA-FR';
  8868. case 'csebcdicdkno':
  8869. case 'ebcdicdkno':
  8870. return 'EBCDIC-DK-NO';
  8871. case 'csebcdicdknoa':
  8872. case 'ebcdicdknoa':
  8873. return 'EBCDIC-DK-NO-A';
  8874. case 'csebcdices':
  8875. case 'ebcdices':
  8876. return 'EBCDIC-ES';
  8877. case 'csebcdicesa':
  8878. case 'ebcdicesa':
  8879. return 'EBCDIC-ES-A';
  8880. case 'csebcdicess':
  8881. case 'ebcdicess':
  8882. return 'EBCDIC-ES-S';
  8883. case 'csebcdicfise':
  8884. case 'ebcdicfise':
  8885. return 'EBCDIC-FI-SE';
  8886. case 'csebcdicfisea':
  8887. case 'ebcdicfisea':
  8888. return 'EBCDIC-FI-SE-A';
  8889. case 'csebcdicfr':
  8890. case 'ebcdicfr':
  8891. return 'EBCDIC-FR';
  8892. case 'csebcdicit':
  8893. case 'ebcdicit':
  8894. return 'EBCDIC-IT';
  8895. case 'csebcdicpt':
  8896. case 'ebcdicpt':
  8897. return 'EBCDIC-PT';
  8898. case 'csebcdicuk':
  8899. case 'ebcdicuk':
  8900. return 'EBCDIC-UK';
  8901. case 'csebcdicus':
  8902. case 'ebcdicus':
  8903. return 'EBCDIC-US';
  8904. case 'csiso111ecmacyrillic':
  8905. case 'ecmacyrillic':
  8906. case 'isoir111':
  8907. case 'koi8e':
  8908. return 'ECMA-cyrillic';
  8909. case 'csiso17spanish':
  8910. case 'es':
  8911. case 'iso646es':
  8912. case 'isoir17':
  8913. return 'ES';
  8914. case 'csiso85spanish2':
  8915. case 'es2':
  8916. case 'iso646es2':
  8917. case 'isoir85':
  8918. return 'ES2';
  8919. case 'cseucfixwidjapanese':
  8920. case 'extendedunixcodefixedwidthforjapanese':
  8921. return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
  8922. case 'cseucpkdfmtjapanese':
  8923. case 'eucjp':
  8924. case 'extendedunixcodepackedformatforjapanese':
  8925. return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
  8926. case 'gb18030':
  8927. return 'GB18030';
  8928. case 'chinese':
  8929. case 'cp936':
  8930. case 'csgb2312':
  8931. case 'csiso58gb231280':
  8932. case 'gb2312':
  8933. case 'gb231280':
  8934. case 'gbk':
  8935. case 'isoir58':
  8936. case 'ms936':
  8937. case 'windows936':
  8938. return 'GBK';
  8939. case 'cn':
  8940. case 'csiso57gb1988':
  8941. case 'gb198880':
  8942. case 'iso646cn':
  8943. case 'isoir57':
  8944. return 'GB_1988-80';
  8945. case 'csiso153gost1976874':
  8946. case 'gost1976874':
  8947. case 'isoir153':
  8948. case 'stsev35888':
  8949. return 'GOST_19768-74';
  8950. case 'csiso150':
  8951. case 'csiso150greekccitt':
  8952. case 'greekccitt':
  8953. case 'isoir150':
  8954. return 'greek-ccitt';
  8955. case 'csiso88greek7':
  8956. case 'greek7':
  8957. case 'isoir88':
  8958. return 'greek7';
  8959. case 'csiso18greek7old':
  8960. case 'greek7old':
  8961. case 'isoir18':
  8962. return 'greek7-old';
  8963. case 'cshpdesktop':
  8964. case 'hpdesktop':
  8965. return 'HP-DeskTop';
  8966. case 'cshplegal':
  8967. case 'hplegal':
  8968. return 'HP-Legal';
  8969. case 'cshpmath8':
  8970. case 'hpmath8':
  8971. return 'HP-Math8';
  8972. case 'cshppifont':
  8973. case 'hppifont':
  8974. return 'HP-Pi-font';
  8975. case 'cshproman8':
  8976. case 'hproman8':
  8977. case 'r8':
  8978. case 'roman8':
  8979. return 'hp-roman8';
  8980. case 'hzgb2312':
  8981. return 'HZ-GB-2312';
  8982. case 'csibmsymbols':
  8983. case 'ibmsymbols':
  8984. return 'IBM-Symbols';
  8985. case 'csibmthai':
  8986. case 'ibmthai':
  8987. return 'IBM-Thai';
  8988. case 'ccsid858':
  8989. case 'cp858':
  8990. case 'ibm858':
  8991. case 'pcmultilingual850euro':
  8992. return 'IBM00858';
  8993. case 'ccsid924':
  8994. case 'cp924':
  8995. case 'ebcdiclatin9euro':
  8996. case 'ibm924':
  8997. return 'IBM00924';
  8998. case 'ccsid1140':
  8999. case 'cp1140':
  9000. case 'ebcdicus37euro':
  9001. case 'ibm1140':
  9002. return 'IBM01140';
  9003. case 'ccsid1141':
  9004. case 'cp1141':
  9005. case 'ebcdicde273euro':
  9006. case 'ibm1141':
  9007. return 'IBM01141';
  9008. case 'ccsid1142':
  9009. case 'cp1142':
  9010. case 'ebcdicdk277euro':
  9011. case 'ebcdicno277euro':
  9012. case 'ibm1142':
  9013. return 'IBM01142';
  9014. case 'ccsid1143':
  9015. case 'cp1143':
  9016. case 'ebcdicfi278euro':
  9017. case 'ebcdicse278euro':
  9018. case 'ibm1143':
  9019. return 'IBM01143';
  9020. case 'ccsid1144':
  9021. case 'cp1144':
  9022. case 'ebcdicit280euro':
  9023. case 'ibm1144':
  9024. return 'IBM01144';
  9025. case 'ccsid1145':
  9026. case 'cp1145':
  9027. case 'ebcdices284euro':
  9028. case 'ibm1145':
  9029. return 'IBM01145';
  9030. case 'ccsid1146':
  9031. case 'cp1146':
  9032. case 'ebcdicgb285euro':
  9033. case 'ibm1146':
  9034. return 'IBM01146';
  9035. case 'ccsid1147':
  9036. case 'cp1147':
  9037. case 'ebcdicfr297euro':
  9038. case 'ibm1147':
  9039. return 'IBM01147';
  9040. case 'ccsid1148':
  9041. case 'cp1148':
  9042. case 'ebcdicinternational500euro':
  9043. case 'ibm1148':
  9044. return 'IBM01148';
  9045. case 'ccsid1149':
  9046. case 'cp1149':
  9047. case 'ebcdicis871euro':
  9048. case 'ibm1149':
  9049. return 'IBM01149';
  9050. case 'cp37':
  9051. case 'csibm37':
  9052. case 'ebcdiccpca':
  9053. case 'ebcdiccpnl':
  9054. case 'ebcdiccpus':
  9055. case 'ebcdiccpwt':
  9056. case 'ibm37':
  9057. return 'IBM037';
  9058. case 'cp38':
  9059. case 'csibm38':
  9060. case 'ebcdicint':
  9061. case 'ibm38':
  9062. return 'IBM038';
  9063. case 'cp273':
  9064. case 'csibm273':
  9065. case 'ibm273':
  9066. return 'IBM273';
  9067. case 'cp274':
  9068. case 'csibm274':
  9069. case 'ebcdicbe':
  9070. case 'ibm274':
  9071. return 'IBM274';
  9072. case 'cp275':
  9073. case 'csibm275':
  9074. case 'ebcdicbr':
  9075. case 'ibm275':
  9076. return 'IBM275';
  9077. case 'csibm277':
  9078. case 'ebcdiccpdk':
  9079. case 'ebcdiccpno':
  9080. case 'ibm277':
  9081. return 'IBM277';
  9082. case 'cp278':
  9083. case 'csibm278':
  9084. case 'ebcdiccpfi':
  9085. case 'ebcdiccpse':
  9086. case 'ibm278':
  9087. return 'IBM278';
  9088. case 'cp280':
  9089. case 'csibm280':
  9090. case 'ebcdiccpit':
  9091. case 'ibm280':
  9092. return 'IBM280';
  9093. case 'cp281':
  9094. case 'csibm281':
  9095. case 'ebcdicjpe':
  9096. case 'ibm281':
  9097. return 'IBM281';
  9098. case 'cp284':
  9099. case 'csibm284':
  9100. case 'ebcdiccpes':
  9101. case 'ibm284':
  9102. return 'IBM284';
  9103. case 'cp285':
  9104. case 'csibm285':
  9105. case 'ebcdiccpgb':
  9106. case 'ibm285':
  9107. return 'IBM285';
  9108. case 'cp290':
  9109. case 'csibm290':
  9110. case 'ebcdicjpkana':
  9111. case 'ibm290':
  9112. return 'IBM290';
  9113. case 'cp297':
  9114. case 'csibm297':
  9115. case 'ebcdiccpfr':
  9116. case 'ibm297':
  9117. return 'IBM297';
  9118. case 'cp420':
  9119. case 'csibm420':
  9120. case 'ebcdiccpar1':
  9121. case 'ibm420':
  9122. return 'IBM420';
  9123. case 'cp423':
  9124. case 'csibm423':
  9125. case 'ebcdiccpgr':
  9126. case 'ibm423':
  9127. return 'IBM423';
  9128. case 'cp424':
  9129. case 'csibm424':
  9130. case 'ebcdiccphe':
  9131. case 'ibm424':
  9132. return 'IBM424';
  9133. case '437':
  9134. case 'cp437':
  9135. case 'cspc8codepage437':
  9136. case 'ibm437':
  9137. return 'IBM437';
  9138. case 'cp500':
  9139. case 'csibm500':
  9140. case 'ebcdiccpbe':
  9141. case 'ebcdiccpch':
  9142. case 'ibm500':
  9143. return 'IBM500';
  9144. case 'cp775':
  9145. case 'cspc775baltic':
  9146. case 'ibm775':
  9147. return 'IBM775';
  9148. case '850':
  9149. case 'cp850':
  9150. case 'cspc850multilingual':
  9151. case 'ibm850':
  9152. return 'IBM850';
  9153. case '851':
  9154. case 'cp851':
  9155. case 'csibm851':
  9156. case 'ibm851':
  9157. return 'IBM851';
  9158. case '852':
  9159. case 'cp852':
  9160. case 'cspcp852':
  9161. case 'ibm852':
  9162. return 'IBM852';
  9163. case '855':
  9164. case 'cp855':
  9165. case 'csibm855':
  9166. case 'ibm855':
  9167. return 'IBM855';
  9168. case '857':
  9169. case 'cp857':
  9170. case 'csibm857':
  9171. case 'ibm857':
  9172. return 'IBM857';
  9173. case '860':
  9174. case 'cp860':
  9175. case 'csibm860':
  9176. case 'ibm860':
  9177. return 'IBM860';
  9178. case '861':
  9179. case 'cp861':
  9180. case 'cpis':
  9181. case 'csibm861':
  9182. case 'ibm861':
  9183. return 'IBM861';
  9184. case '862':
  9185. case 'cp862':
  9186. case 'cspc862latinhebrew':
  9187. case 'ibm862':
  9188. return 'IBM862';
  9189. case '863':
  9190. case 'cp863':
  9191. case 'csibm863':
  9192. case 'ibm863':
  9193. return 'IBM863';
  9194. case 'cp864':
  9195. case 'csibm864':
  9196. case 'ibm864':
  9197. return 'IBM864';
  9198. case '865':
  9199. case 'cp865':
  9200. case 'csibm865':
  9201. case 'ibm865':
  9202. return 'IBM865';
  9203. case '866':
  9204. case 'cp866':
  9205. case 'csibm866':
  9206. case 'ibm866':
  9207. return 'IBM866';
  9208. case 'cp868':
  9209. case 'cpar':
  9210. case 'csibm868':
  9211. case 'ibm868':
  9212. return 'IBM868';
  9213. case '869':
  9214. case 'cp869':
  9215. case 'cpgr':
  9216. case 'csibm869':
  9217. case 'ibm869':
  9218. return 'IBM869';
  9219. case 'cp870':
  9220. case 'csibm870':
  9221. case 'ebcdiccproece':
  9222. case 'ebcdiccpyu':
  9223. case 'ibm870':
  9224. return 'IBM870';
  9225. case 'cp871':
  9226. case 'csibm871':
  9227. case 'ebcdiccpis':
  9228. case 'ibm871':
  9229. return 'IBM871';
  9230. case 'cp880':
  9231. case 'csibm880':
  9232. case 'ebcdiccyrillic':
  9233. case 'ibm880':
  9234. return 'IBM880';
  9235. case 'cp891':
  9236. case 'csibm891':
  9237. case 'ibm891':
  9238. return 'IBM891';
  9239. case 'cp903':
  9240. case 'csibm903':
  9241. case 'ibm903':
  9242. return 'IBM903';
  9243. case '904':
  9244. case 'cp904':
  9245. case 'csibbm904':
  9246. case 'ibm904':
  9247. return 'IBM904';
  9248. case 'cp905':
  9249. case 'csibm905':
  9250. case 'ebcdiccptr':
  9251. case 'ibm905':
  9252. return 'IBM905';
  9253. case 'cp918':
  9254. case 'csibm918':
  9255. case 'ebcdiccpar2':
  9256. case 'ibm918':
  9257. return 'IBM918';
  9258. case 'cp1026':
  9259. case 'csibm1026':
  9260. case 'ibm1026':
  9261. return 'IBM1026';
  9262. case 'ibm1047':
  9263. return 'IBM1047';
  9264. case 'csiso143iecp271':
  9265. case 'iecp271':
  9266. case 'isoir143':
  9267. return 'IEC_P27-1';
  9268. case 'csiso49inis':
  9269. case 'inis':
  9270. case 'isoir49':
  9271. return 'INIS';
  9272. case 'csiso50inis8':
  9273. case 'inis8':
  9274. case 'isoir50':
  9275. return 'INIS-8';
  9276. case 'csiso51iniscyrillic':
  9277. case 'iniscyrillic':
  9278. case 'isoir51':
  9279. return 'INIS-cyrillic';
  9280. case 'csinvariant':
  9281. case 'invariant':
  9282. return 'INVARIANT';
  9283. case 'iso2022cn':
  9284. return 'ISO-2022-CN';
  9285. case 'iso2022cnext':
  9286. return 'ISO-2022-CN-EXT';
  9287. case 'csiso2022jp':
  9288. case 'iso2022jp':
  9289. return 'ISO-2022-JP';
  9290. case 'csiso2022jp2':
  9291. case 'iso2022jp2':
  9292. return 'ISO-2022-JP-2';
  9293. case 'csiso2022kr':
  9294. case 'iso2022kr':
  9295. return 'ISO-2022-KR';
  9296. case 'cswindows30latin1':
  9297. case 'iso88591windows30latin1':
  9298. return 'ISO-8859-1-Windows-3.0-Latin-1';
  9299. case 'cswindows31latin1':
  9300. case 'iso88591windows31latin1':
  9301. return 'ISO-8859-1-Windows-3.1-Latin-1';
  9302. case 'csisolatin2':
  9303. case 'iso88592':
  9304. case 'iso885921987':
  9305. case 'isoir101':
  9306. case 'l2':
  9307. case 'latin2':
  9308. return 'ISO-8859-2';
  9309. case 'cswindows31latin2':
  9310. case 'iso88592windowslatin2':
  9311. return 'ISO-8859-2-Windows-Latin-2';
  9312. case 'csisolatin3':
  9313. case 'iso88593':
  9314. case 'iso885931988':
  9315. case 'isoir109':
  9316. case 'l3':
  9317. case 'latin3':
  9318. return 'ISO-8859-3';
  9319. case 'csisolatin4':
  9320. case 'iso88594':
  9321. case 'iso885941988':
  9322. case 'isoir110':
  9323. case 'l4':
  9324. case 'latin4':
  9325. return 'ISO-8859-4';
  9326. case 'csisolatincyrillic':
  9327. case 'cyrillic':
  9328. case 'iso88595':
  9329. case 'iso885951988':
  9330. case 'isoir144':
  9331. return 'ISO-8859-5';
  9332. case 'arabic':
  9333. case 'asmo708':
  9334. case 'csisolatinarabic':
  9335. case 'ecma114':
  9336. case 'iso88596':
  9337. case 'iso885961987':
  9338. case 'isoir127':
  9339. return 'ISO-8859-6';
  9340. case 'csiso88596e':
  9341. case 'iso88596e':
  9342. return 'ISO-8859-6-E';
  9343. case 'csiso88596i':
  9344. case 'iso88596i':
  9345. return 'ISO-8859-6-I';
  9346. case 'csisolatingreek':
  9347. case 'ecma118':
  9348. case 'elot928':
  9349. case 'greek':
  9350. case 'greek8':
  9351. case 'iso88597':
  9352. case 'iso885971987':
  9353. case 'isoir126':
  9354. return 'ISO-8859-7';
  9355. case 'csisolatinhebrew':
  9356. case 'hebrew':
  9357. case 'iso88598':
  9358. case 'iso885981988':
  9359. case 'isoir138':
  9360. return 'ISO-8859-8';
  9361. case 'csiso88598e':
  9362. case 'iso88598e':
  9363. return 'ISO-8859-8-E';
  9364. case 'csiso88598i':
  9365. case 'iso88598i':
  9366. return 'ISO-8859-8-I';
  9367. case 'cswindows31latin5':
  9368. case 'iso88599windowslatin5':
  9369. return 'ISO-8859-9-Windows-Latin-5';
  9370. case 'csisolatin6':
  9371. case 'iso885910':
  9372. case 'iso8859101992':
  9373. case 'isoir157':
  9374. case 'l6':
  9375. case 'latin6':
  9376. return 'ISO-8859-10';
  9377. case 'iso885913':
  9378. return 'ISO-8859-13';
  9379. case 'iso885914':
  9380. case 'iso8859141998':
  9381. case 'isoceltic':
  9382. case 'isoir199':
  9383. case 'l8':
  9384. case 'latin8':
  9385. return 'ISO-8859-14';
  9386. case 'iso885915':
  9387. case 'latin9':
  9388. return 'ISO-8859-15';
  9389. case 'iso885916':
  9390. case 'iso8859162001':
  9391. case 'isoir226':
  9392. case 'l10':
  9393. case 'latin10':
  9394. return 'ISO-8859-16';
  9395. case 'iso10646j1':
  9396. return 'ISO-10646-J-1';
  9397. case 'csunicode':
  9398. case 'iso10646ucs2':
  9399. return 'ISO-10646-UCS-2';
  9400. case 'csucs4':
  9401. case 'iso10646ucs4':
  9402. return 'ISO-10646-UCS-4';
  9403. case 'csunicodeascii':
  9404. case 'iso10646ucsbasic':
  9405. return 'ISO-10646-UCS-Basic';
  9406. case 'csunicodelatin1':
  9407. case 'iso10646':
  9408. case 'iso10646unicodelatin1':
  9409. return 'ISO-10646-Unicode-Latin1';
  9410. case 'csiso10646utf1':
  9411. case 'iso10646utf1':
  9412. return 'ISO-10646-UTF-1';
  9413. case 'csiso115481':
  9414. case 'iso115481':
  9415. case 'isotr115481':
  9416. return 'ISO-11548-1';
  9417. case 'csiso90':
  9418. case 'isoir90':
  9419. return 'iso-ir-90';
  9420. case 'csunicodeibm1261':
  9421. case 'isounicodeibm1261':
  9422. return 'ISO-Unicode-IBM-1261';
  9423. case 'csunicodeibm1264':
  9424. case 'isounicodeibm1264':
  9425. return 'ISO-Unicode-IBM-1264';
  9426. case 'csunicodeibm1265':
  9427. case 'isounicodeibm1265':
  9428. return 'ISO-Unicode-IBM-1265';
  9429. case 'csunicodeibm1268':
  9430. case 'isounicodeibm1268':
  9431. return 'ISO-Unicode-IBM-1268';
  9432. case 'csunicodeibm1276':
  9433. case 'isounicodeibm1276':
  9434. return 'ISO-Unicode-IBM-1276';
  9435. case 'csiso646basic1983':
  9436. case 'iso646basic1983':
  9437. case 'ref':
  9438. return 'ISO_646.basic:1983';
  9439. case 'csiso2intlrefversion':
  9440. case 'irv':
  9441. case 'iso646irv1983':
  9442. case 'isoir2':
  9443. return 'ISO_646.irv:1983';
  9444. case 'csiso2033':
  9445. case 'e13b':
  9446. case 'iso20331983':
  9447. case 'isoir98':
  9448. return 'ISO_2033-1983';
  9449. case 'csiso5427cyrillic':
  9450. case 'iso5427':
  9451. case 'isoir37':
  9452. return 'ISO_5427';
  9453. case 'iso5427cyrillic1981':
  9454. case 'iso54271981':
  9455. case 'isoir54':
  9456. return 'ISO_5427:1981';
  9457. case 'csiso5428greek':
  9458. case 'iso54281980':
  9459. case 'isoir55':
  9460. return 'ISO_5428:1980';
  9461. case 'csiso6937add':
  9462. case 'iso6937225':
  9463. case 'isoir152':
  9464. return 'ISO_6937-2-25';
  9465. case 'csisotextcomm':
  9466. case 'iso69372add':
  9467. case 'isoir142':
  9468. return 'ISO_6937-2-add';
  9469. case 'csiso8859supp':
  9470. case 'iso8859supp':
  9471. case 'isoir154':
  9472. case 'latin125':
  9473. return 'ISO_8859-supp';
  9474. case 'csiso10367box':
  9475. case 'iso10367box':
  9476. case 'isoir155':
  9477. return 'ISO_10367-box';
  9478. case 'csiso15italian':
  9479. case 'iso646it':
  9480. case 'isoir15':
  9481. case 'it':
  9482. return 'IT';
  9483. case 'csiso13jisc6220jp':
  9484. case 'isoir13':
  9485. case 'jisc62201969':
  9486. case 'jisc62201969jp':
  9487. case 'katakana':
  9488. case 'x2017':
  9489. return 'JIS_C6220-1969-jp';
  9490. case 'csiso14jisc6220ro':
  9491. case 'iso646jp':
  9492. case 'isoir14':
  9493. case 'jisc62201969ro':
  9494. case 'jp':
  9495. return 'JIS_C6220-1969-ro';
  9496. case 'csiso42jisc62261978':
  9497. case 'isoir42':
  9498. case 'jisc62261978':
  9499. return 'JIS_C6226-1978';
  9500. case 'csiso87jisx208':
  9501. case 'isoir87':
  9502. case 'jisc62261983':
  9503. case 'jisx2081983':
  9504. case 'x208':
  9505. return 'JIS_C6226-1983';
  9506. case 'csiso91jisc62291984a':
  9507. case 'isoir91':
  9508. case 'jisc62291984a':
  9509. case 'jpocra':
  9510. return 'JIS_C6229-1984-a';
  9511. case 'csiso92jisc62991984b':
  9512. case 'iso646jpocrb':
  9513. case 'isoir92':
  9514. case 'jisc62291984b':
  9515. case 'jpocrb':
  9516. return 'JIS_C6229-1984-b';
  9517. case 'csiso93jis62291984badd':
  9518. case 'isoir93':
  9519. case 'jisc62291984badd':
  9520. case 'jpocrbadd':
  9521. return 'JIS_C6229-1984-b-add';
  9522. case 'csiso94jis62291984hand':
  9523. case 'isoir94':
  9524. case 'jisc62291984hand':
  9525. case 'jpocrhand':
  9526. return 'JIS_C6229-1984-hand';
  9527. case 'csiso95jis62291984handadd':
  9528. case 'isoir95':
  9529. case 'jisc62291984handadd':
  9530. case 'jpocrhandadd':
  9531. return 'JIS_C6229-1984-hand-add';
  9532. case 'csiso96jisc62291984kana':
  9533. case 'isoir96':
  9534. case 'jisc62291984kana':
  9535. return 'JIS_C6229-1984-kana';
  9536. case 'csjisencoding':
  9537. case 'jisencoding':
  9538. return 'JIS_Encoding';
  9539. case 'cshalfwidthkatakana':
  9540. case 'jisx201':
  9541. case 'x201':
  9542. return 'JIS_X0201';
  9543. case 'csiso159jisx2121990':
  9544. case 'isoir159':
  9545. case 'jisx2121990':
  9546. case 'x212':
  9547. return 'JIS_X0212-1990';
  9548. case 'csiso141jusib1002':
  9549. case 'iso646yu':
  9550. case 'isoir141':
  9551. case 'js':
  9552. case 'jusib1002':
  9553. case 'yu':
  9554. return 'JUS_I.B1.002';
  9555. case 'csiso147macedonian':
  9556. case 'isoir147':
  9557. case 'jusib1003mac':
  9558. case 'macedonian':
  9559. return 'JUS_I.B1.003-mac';
  9560. case 'csiso146serbian':
  9561. case 'isoir146':
  9562. case 'jusib1003serb':
  9563. case 'serbian':
  9564. return 'JUS_I.B1.003-serb';
  9565. case 'koi7switched':
  9566. return 'KOI7-switched';
  9567. case 'cskoi8r':
  9568. case 'koi8r':
  9569. return 'KOI8-R';
  9570. case 'koi8u':
  9571. return 'KOI8-U';
  9572. case 'csksc5636':
  9573. case 'iso646kr':
  9574. case 'ksc5636':
  9575. return 'KSC5636';
  9576. case 'cskz1048':
  9577. case 'kz1048':
  9578. case 'rk1048':
  9579. case 'strk10482002':
  9580. return 'KZ-1048';
  9581. case 'csiso19latingreek':
  9582. case 'isoir19':
  9583. case 'latingreek':
  9584. return 'latin-greek';
  9585. case 'csiso27latingreek1':
  9586. case 'isoir27':
  9587. case 'latingreek1':
  9588. return 'Latin-greek-1';
  9589. case 'csiso158lap':
  9590. case 'isoir158':
  9591. case 'lap':
  9592. case 'latinlap':
  9593. return 'latin-lap';
  9594. case 'csmacintosh':
  9595. case 'mac':
  9596. case 'macintosh':
  9597. return 'macintosh';
  9598. case 'csmicrosoftpublishing':
  9599. case 'microsoftpublishing':
  9600. return 'Microsoft-Publishing';
  9601. case 'csmnem':
  9602. case 'mnem':
  9603. return 'MNEM';
  9604. case 'csmnemonic':
  9605. case 'mnemonic':
  9606. return 'MNEMONIC';
  9607. case 'csiso86hungarian':
  9608. case 'hu':
  9609. case 'iso646hu':
  9610. case 'isoir86':
  9611. case 'msz77953':
  9612. return 'MSZ_7795.3';
  9613. case 'csnatsdano':
  9614. case 'isoir91':
  9615. case 'natsdano':
  9616. return 'NATS-DANO';
  9617. case 'csnatsdanoadd':
  9618. case 'isoir92':
  9619. case 'natsdanoadd':
  9620. return 'NATS-DANO-ADD';
  9621. case 'csnatssefi':
  9622. case 'isoir81':
  9623. case 'natssefi':
  9624. return 'NATS-SEFI';
  9625. case 'csnatssefiadd':
  9626. case 'isoir82':
  9627. case 'natssefiadd':
  9628. return 'NATS-SEFI-ADD';
  9629. case 'csiso151cuba':
  9630. case 'cuba':
  9631. case 'iso646cu':
  9632. case 'isoir151':
  9633. case 'ncnc1081':
  9634. return 'NC_NC00-10:81';
  9635. case 'csiso69french':
  9636. case 'fr':
  9637. case 'iso646fr':
  9638. case 'isoir69':
  9639. case 'nfz62010':
  9640. return 'NF_Z_62-010';
  9641. case 'csiso25french':
  9642. case 'iso646fr1':
  9643. case 'isoir25':
  9644. case 'nfz620101973':
  9645. return 'NF_Z_62-010_(1973)';
  9646. case 'csiso60danishnorwegian':
  9647. case 'csiso60norwegian1':
  9648. case 'iso646no':
  9649. case 'isoir60':
  9650. case 'no':
  9651. case 'ns45511':
  9652. return 'NS_4551-1';
  9653. case 'csiso61norwegian2':
  9654. case 'iso646no2':
  9655. case 'isoir61':
  9656. case 'no2':
  9657. case 'ns45512':
  9658. return 'NS_4551-2';
  9659. case 'osdebcdicdf3irv':
  9660. return 'OSD_EBCDIC_DF03_IRV';
  9661. case 'osdebcdicdf41':
  9662. return 'OSD_EBCDIC_DF04_1';
  9663. case 'osdebcdicdf415':
  9664. return 'OSD_EBCDIC_DF04_15';
  9665. case 'cspc8danishnorwegian':
  9666. case 'pc8danishnorwegian':
  9667. return 'PC8-Danish-Norwegian';
  9668. case 'cspc8turkish':
  9669. case 'pc8turkish':
  9670. return 'PC8-Turkish';
  9671. case 'csiso16portuguese':
  9672. case 'iso646pt':
  9673. case 'isoir16':
  9674. case 'pt':
  9675. return 'PT';
  9676. case 'csiso84portuguese2':
  9677. case 'iso646pt2':
  9678. case 'isoir84':
  9679. case 'pt2':
  9680. return 'PT2';
  9681. case 'cp154':
  9682. case 'csptcp154':
  9683. case 'cyrillicasian':
  9684. case 'pt154':
  9685. case 'ptcp154':
  9686. return 'PTCP154';
  9687. case 'scsu':
  9688. return 'SCSU';
  9689. case 'csiso10swedish':
  9690. case 'fi':
  9691. case 'iso646fi':
  9692. case 'iso646se':
  9693. case 'isoir10':
  9694. case 'se':
  9695. case 'sen850200b':
  9696. return 'SEN_850200_B';
  9697. case 'csiso11swedishfornames':
  9698. case 'iso646se2':
  9699. case 'isoir11':
  9700. case 'se2':
  9701. case 'sen850200c':
  9702. return 'SEN_850200_C';
  9703. case 'csshiftjis':
  9704. case 'mskanji':
  9705. case 'shiftjis':
  9706. return 'Shift_JIS';
  9707. case 'csiso102t617bit':
  9708. case 'isoir102':
  9709. case 't617bit':
  9710. return 'T.61-7bit';
  9711. case 'csiso103t618bit':
  9712. case 'isoir103':
  9713. case 't61':
  9714. case 't618bit':
  9715. return 'T.61-8bit';
  9716. case 'csiso128t101g2':
  9717. case 'isoir128':
  9718. case 't101g2':
  9719. return 'T.101-G2';
  9720. case 'cstscii':
  9721. case 'tscii':
  9722. return 'TSCII';
  9723. case 'csunicode11':
  9724. case 'unicode11':
  9725. return 'UNICODE-1-1';
  9726. case 'csunicode11utf7':
  9727. case 'unicode11utf7':
  9728. return 'UNICODE-1-1-UTF-7';
  9729. case 'csunknown8bit':
  9730. case 'unknown8bit':
  9731. return 'UNKNOWN-8BIT';
  9732. case 'ansix341968':
  9733. case 'ansix341986':
  9734. case 'ascii':
  9735. case 'cp367':
  9736. case 'csascii':
  9737. case 'ibm367':
  9738. case 'iso646irv1991':
  9739. case 'iso646us':
  9740. case 'isoir6':
  9741. case 'us':
  9742. case 'usascii':
  9743. return 'US-ASCII';
  9744. case 'csusdk':
  9745. case 'usdk':
  9746. return 'us-dk';
  9747. case 'utf7':
  9748. return 'UTF-7';
  9749. case 'utf8':
  9750. return 'UTF-8';
  9751. case 'utf16':
  9752. return 'UTF-16';
  9753. case 'utf16be':
  9754. return 'UTF-16BE';
  9755. case 'utf16le':
  9756. return 'UTF-16LE';
  9757. case 'utf32':
  9758. return 'UTF-32';
  9759. case 'utf32be':
  9760. return 'UTF-32BE';
  9761. case 'utf32le':
  9762. return 'UTF-32LE';
  9763. case 'csventurainternational':
  9764. case 'venturainternational':
  9765. return 'Ventura-International';
  9766. case 'csventuramath':
  9767. case 'venturamath':
  9768. return 'Ventura-Math';
  9769. case 'csventuraus':
  9770. case 'venturaus':
  9771. return 'Ventura-US';
  9772. case 'csiso70videotexsupp1':
  9773. case 'isoir70':
  9774. case 'videotexsuppl':
  9775. return 'videotex-suppl';
  9776. case 'csviqr':
  9777. case 'viqr':
  9778. return 'VIQR';
  9779. case 'csviscii':
  9780. case 'viscii':
  9781. return 'VISCII';
  9782. case 'cswindows31j':
  9783. case 'windows31j':
  9784. return 'Windows-31J';
  9785. case 'iso885911':
  9786. case 'tis620':
  9787. return 'windows-874';
  9788. case 'cseuckr':
  9789. case 'csksc56011987':
  9790. case 'euckr':
  9791. case 'isoir149':
  9792. case 'korean':
  9793. case 'ksc5601':
  9794. case 'ksc56011987':
  9795. case 'ksc56011989':
  9796. case 'windows949':
  9797. return 'windows-949';
  9798. case 'windows1250':
  9799. return 'windows-1250';
  9800. case 'windows1251':
  9801. return 'windows-1251';
  9802. case 'cp819':
  9803. case 'csisolatin1':
  9804. case 'ibm819':
  9805. case 'iso88591':
  9806. case 'iso885911987':
  9807. case 'isoir100':
  9808. case 'l1':
  9809. case 'latin1':
  9810. case 'windows1252':
  9811. return 'windows-1252';
  9812. case 'windows1253':
  9813. return 'windows-1253';
  9814. case 'csisolatin5':
  9815. case 'iso88599':
  9816. case 'iso885991989':
  9817. case 'isoir148':
  9818. case 'l5':
  9819. case 'latin5':
  9820. case 'windows1254':
  9821. return 'windows-1254';
  9822. case 'windows1255':
  9823. return 'windows-1255';
  9824. case 'windows1256':
  9825. return 'windows-1256';
  9826. case 'windows1257':
  9827. return 'windows-1257';
  9828. case 'windows1258':
  9829. return 'windows-1258';
  9830. default:
  9831. return $charset;
  9832. }
  9833. }
  9834. function get_curl_version()
  9835. {
  9836. if (is_array($curl = curl_version()))
  9837. {
  9838. $curl = $curl['version'];
  9839. }
  9840. elseif (substr($curl, 0, 5) === 'curl/')
  9841. {
  9842. $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
  9843. }
  9844. elseif (substr($curl, 0, 8) === 'libcurl/')
  9845. {
  9846. $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
  9847. }
  9848. else
  9849. {
  9850. $curl = 0;
  9851. }
  9852. return $curl;
  9853. }
  9854. function is_subclass_of($class1, $class2)
  9855. {
  9856. if (func_num_args() !== 2)
  9857. {
  9858. trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
  9859. }
  9860. elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
  9861. {
  9862. return is_subclass_of($class1, $class2);
  9863. }
  9864. elseif (is_string($class1) && is_string($class2))
  9865. {
  9866. if (class_exists($class1))
  9867. {
  9868. if (class_exists($class2))
  9869. {
  9870. $class2 = strtolower($class2);
  9871. while ($class1 = strtolower(get_parent_class($class1)))
  9872. {
  9873. if ($class1 === $class2)
  9874. {
  9875. return true;
  9876. }
  9877. }
  9878. }
  9879. }
  9880. else
  9881. {
  9882. trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
  9883. }
  9884. }
  9885. return false;
  9886. }
  9887. /**
  9888. * Strip HTML comments
  9889. *
  9890. * @access public
  9891. * @param string $data Data to strip comments from
  9892. * @return string Comment stripped string
  9893. */
  9894. function strip_comments($data)
  9895. {
  9896. $output = '';
  9897. while (($start = strpos($data, '<!--')) !== false)
  9898. {
  9899. $output .= substr($data, 0, $start);
  9900. if (($end = strpos($data, '-->', $start)) !== false)
  9901. {
  9902. $data = substr_replace($data, '', 0, $end + 3);
  9903. }
  9904. else
  9905. {
  9906. $data = '';
  9907. }
  9908. }
  9909. return $output . $data;
  9910. }
  9911. function parse_date($dt)
  9912. {
  9913. $parser = SimplePie_Parse_Date::get();
  9914. return $parser->parse($dt);
  9915. }
  9916. /**
  9917. * Decode HTML entities
  9918. *
  9919. * @static
  9920. * @access public
  9921. * @param string $data Input data
  9922. * @return string Output data
  9923. */
  9924. function entities_decode($data)
  9925. {
  9926. $decoder = new SimplePie_Decode_HTML_Entities($data);
  9927. return $decoder->parse();
  9928. }
  9929. /**
  9930. * Remove RFC822 comments
  9931. *
  9932. * @access public
  9933. * @param string $data Data to strip comments from
  9934. * @return string Comment stripped string
  9935. */
  9936. function uncomment_rfc822($string)
  9937. {
  9938. $string = (string) $string;
  9939. $position = 0;
  9940. $length = strlen($string);
  9941. $depth = 0;
  9942. $output = '';
  9943. while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
  9944. {
  9945. $output .= substr($string, $position, $pos - $position);
  9946. $position = $pos + 1;
  9947. if ($string[$pos - 1] !== '\\')
  9948. {
  9949. $depth++;
  9950. while ($depth && $position < $length)
  9951. {
  9952. $position += strcspn($string, '()', $position);
  9953. if ($string[$position - 1] === '\\')
  9954. {
  9955. $position++;
  9956. continue;
  9957. }
  9958. elseif (isset($string[$position]))
  9959. {
  9960. switch ($string[$position])
  9961. {
  9962. case '(':
  9963. $depth++;
  9964. break;
  9965. case ')':
  9966. $depth--;
  9967. break;
  9968. }
  9969. $position++;
  9970. }
  9971. else
  9972. {
  9973. break;
  9974. }
  9975. }
  9976. }
  9977. else
  9978. {
  9979. $output .= '(';
  9980. }
  9981. }
  9982. $output .= substr($string, $position);
  9983. return $output;
  9984. }
  9985. function parse_mime($mime)
  9986. {
  9987. if (($pos = strpos($mime, ';')) === false)
  9988. {
  9989. return trim($mime);
  9990. }
  9991. else
  9992. {
  9993. return trim(substr($mime, 0, $pos));
  9994. }
  9995. }
  9996. function htmlspecialchars_decode($string, $quote_style)
  9997. {
  9998. if (function_exists('htmlspecialchars_decode'))
  9999. {
  10000. return htmlspecialchars_decode($string, $quote_style);
  10001. }
  10002. else
  10003. {
  10004. return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
  10005. }
  10006. }
  10007. function atom_03_construct_type($attribs)
  10008. {
  10009. if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
  10010. {
  10011. $mode = SIMPLEPIE_CONSTRUCT_BASE64;
  10012. }
  10013. else
  10014. {
  10015. $mode = SIMPLEPIE_CONSTRUCT_NONE;
  10016. }
  10017. if (isset($attribs['']['type']))
  10018. {
  10019. switch (strtolower(trim($attribs['']['type'])))
  10020. {
  10021. case 'text':
  10022. case 'text/plain':
  10023. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  10024. case 'html':
  10025. case 'text/html':
  10026. return SIMPLEPIE_CONSTRUCT_HTML | $mode;
  10027. case 'xhtml':
  10028. case 'application/xhtml+xml':
  10029. return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
  10030. default:
  10031. return SIMPLEPIE_CONSTRUCT_NONE | $mode;
  10032. }
  10033. }
  10034. else
  10035. {
  10036. return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
  10037. }
  10038. }
  10039. function atom_10_construct_type($attribs)
  10040. {
  10041. if (isset($attribs['']['type']))
  10042. {
  10043. switch (strtolower(trim($attribs['']['type'])))
  10044. {
  10045. case 'text':
  10046. return SIMPLEPIE_CONSTRUCT_TEXT;
  10047. case 'html':
  10048. return SIMPLEPIE_CONSTRUCT_HTML;
  10049. case 'xhtml':
  10050. return SIMPLEPIE_CONSTRUCT_XHTML;
  10051. default:
  10052. return SIMPLEPIE_CONSTRUCT_NONE;
  10053. }
  10054. }
  10055. return SIMPLEPIE_CONSTRUCT_TEXT;
  10056. }
  10057. function atom_10_content_construct_type($attribs)
  10058. {
  10059. if (isset($attribs['']['type']))
  10060. {
  10061. $type = strtolower(trim($attribs['']['type']));
  10062. switch ($type)
  10063. {
  10064. case 'text':
  10065. return SIMPLEPIE_CONSTRUCT_TEXT;
  10066. case 'html':
  10067. return SIMPLEPIE_CONSTRUCT_HTML;
  10068. case 'xhtml':
  10069. return SIMPLEPIE_CONSTRUCT_XHTML;
  10070. }
  10071. if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
  10072. {
  10073. return SIMPLEPIE_CONSTRUCT_NONE;
  10074. }
  10075. else
  10076. {
  10077. return SIMPLEPIE_CONSTRUCT_BASE64;
  10078. }
  10079. }
  10080. else
  10081. {
  10082. return SIMPLEPIE_CONSTRUCT_TEXT;
  10083. }
  10084. }
  10085. function is_isegment_nz_nc($string)
  10086. {
  10087. 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);
  10088. }
  10089. function space_seperated_tokens($string)
  10090. {
  10091. $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
  10092. $string_length = strlen($string);
  10093. $position = strspn($string, $space_characters);
  10094. $tokens = array();
  10095. while ($position < $string_length)
  10096. {
  10097. $len = strcspn($string, $space_characters, $position);
  10098. $tokens[] = substr($string, $position, $len);
  10099. $position += $len;
  10100. $position += strspn($string, $space_characters, $position);
  10101. }
  10102. return $tokens;
  10103. }
  10104. function array_unique($array)
  10105. {
  10106. if (version_compare(PHP_VERSION, '5.2', '>='))
  10107. {
  10108. return array_unique($array);
  10109. }
  10110. else
  10111. {
  10112. $array = (array) $array;
  10113. $new_array = array();
  10114. $new_array_strings = array();
  10115. foreach ($array as $key => $value)
  10116. {
  10117. if (is_object($value))
  10118. {
  10119. if (method_exists($value, '__toString'))
  10120. {
  10121. $cmp = $value->__toString();
  10122. }
  10123. else
  10124. {
  10125. trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
  10126. }
  10127. }
  10128. elseif (is_array($value))
  10129. {
  10130. $cmp = (string) reset($value);
  10131. }
  10132. else
  10133. {
  10134. $cmp = (string) $value;
  10135. }
  10136. if (!in_array($cmp, $new_array_strings))
  10137. {
  10138. $new_array[$key] = $value;
  10139. $new_array_strings[] = $cmp;
  10140. }
  10141. }
  10142. return $new_array;
  10143. }
  10144. }
  10145. /**
  10146. * Converts a unicode codepoint to a UTF-8 character
  10147. *
  10148. * @static
  10149. * @access public
  10150. * @param int $codepoint Unicode codepoint
  10151. * @return string UTF-8 character
  10152. */
  10153. function codepoint_to_utf8($codepoint)
  10154. {
  10155. $codepoint = (int) $codepoint;
  10156. if ($codepoint < 0)
  10157. {
  10158. return false;
  10159. }
  10160. else if ($codepoint <= 0x7f)
  10161. {
  10162. return chr($codepoint);
  10163. }
  10164. else if ($codepoint <= 0x7ff)
  10165. {
  10166. return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
  10167. }
  10168. else if ($codepoint <= 0xffff)
  10169. {
  10170. return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  10171. }
  10172. else if ($codepoint <= 0x10ffff)
  10173. {
  10174. return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
  10175. }
  10176. else
  10177. {
  10178. // U+FFFD REPLACEMENT CHARACTER
  10179. return "\xEF\xBF\xBD";
  10180. }
  10181. }
  10182. /**
  10183. * Re-implementation of PHP 5's stripos()
  10184. *
  10185. * Returns the numeric position of the first occurrence of needle in the
  10186. * haystack string.
  10187. *
  10188. * @static
  10189. * @access string
  10190. * @param object $haystack
  10191. * @param string $needle Note that the needle may be a string of one or more
  10192. * characters. If needle is not a string, it is converted to an integer
  10193. * and applied as the ordinal value of a character.
  10194. * @param int $offset The optional offset parameter allows you to specify which
  10195. * character in haystack to start searching. The position returned is still
  10196. * relative to the beginning of haystack.
  10197. * @return bool If needle is not found, stripos() will return boolean false.
  10198. */
  10199. function stripos($haystack, $needle, $offset = 0)
  10200. {
  10201. if (function_exists('stripos'))
  10202. {
  10203. return stripos($haystack, $needle, $offset);
  10204. }
  10205. else
  10206. {
  10207. if (is_string($needle))
  10208. {
  10209. $needle = strtolower($needle);
  10210. }
  10211. elseif (is_int($needle) || is_bool($needle) || is_double($needle))
  10212. {
  10213. $needle = strtolower(chr($needle));
  10214. }
  10215. else
  10216. {
  10217. trigger_error('needle is not a string or an integer', E_USER_WARNING);
  10218. return false;
  10219. }
  10220. return strpos(strtolower($haystack), $needle, $offset);
  10221. }
  10222. }
  10223. /**
  10224. * Similar to parse_str()
  10225. *
  10226. * Returns an associative array of name/value pairs, where the value is an
  10227. * array of values that have used the same name
  10228. *
  10229. * @static
  10230. * @access string
  10231. * @param string $str The input string.
  10232. * @return array
  10233. */
  10234. function parse_str($str)
  10235. {
  10236. $return = array();
  10237. $str = explode('&', $str);
  10238. foreach ($str as $section)
  10239. {
  10240. if (strpos($section, '=') !== false)
  10241. {
  10242. list($name, $value) = explode('=', $section, 2);
  10243. $return[urldecode($name)][] = urldecode($value);
  10244. }
  10245. else
  10246. {
  10247. $return[urldecode($section)][] = null;
  10248. }
  10249. }
  10250. return $return;
  10251. }
  10252. /**
  10253. * Detect XML encoding, as per XML 1.0 Appendix F.1
  10254. *
  10255. * @todo Add support for EBCDIC
  10256. * @param string $data XML data
  10257. * @return array Possible encodings
  10258. */
  10259. function xml_encoding($data)
  10260. {
  10261. // UTF-32 Big Endian BOM
  10262. if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
  10263. {
  10264. $encoding[] = 'UTF-32BE';
  10265. }
  10266. // UTF-32 Little Endian BOM
  10267. elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
  10268. {
  10269. $encoding[] = 'UTF-32LE';
  10270. }
  10271. // UTF-16 Big Endian BOM
  10272. elseif (substr($data, 0, 2) === "\xFE\xFF")
  10273. {
  10274. $encoding[] = 'UTF-16BE';
  10275. }
  10276. // UTF-16 Little Endian BOM
  10277. elseif (substr($data, 0, 2) === "\xFF\xFE")
  10278. {
  10279. $encoding[] = 'UTF-16LE';
  10280. }
  10281. // UTF-8 BOM
  10282. elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
  10283. {
  10284. $encoding[] = 'UTF-8';
  10285. }
  10286. // UTF-32 Big Endian Without BOM
  10287. 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")
  10288. {
  10289. if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
  10290. {
  10291. $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
  10292. if ($parser->parse())
  10293. {
  10294. $encoding[] = $parser->encoding;
  10295. }
  10296. }
  10297. $encoding[] = 'UTF-32BE';
  10298. }
  10299. // UTF-32 Little Endian Without BOM
  10300. 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")
  10301. {
  10302. if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
  10303. {
  10304. $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
  10305. if ($parser->parse())
  10306. {
  10307. $encoding[] = $parser->encoding;
  10308. }
  10309. }
  10310. $encoding[] = 'UTF-32LE';
  10311. }
  10312. // UTF-16 Big Endian Without BOM
  10313. elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
  10314. {
  10315. if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
  10316. {
  10317. $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
  10318. if ($parser->parse())
  10319. {
  10320. $encoding[] = $parser->encoding;
  10321. }
  10322. }
  10323. $encoding[] = 'UTF-16BE';
  10324. }
  10325. // UTF-16 Little Endian Without BOM
  10326. elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
  10327. {
  10328. if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
  10329. {
  10330. $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
  10331. if ($parser->parse())
  10332. {
  10333. $encoding[] = $parser->encoding;
  10334. }
  10335. }
  10336. $encoding[] = 'UTF-16LE';
  10337. }
  10338. // US-ASCII (or superset)
  10339. elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
  10340. {
  10341. if ($pos = strpos($data, "\x3F\x3E"))
  10342. {
  10343. $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
  10344. if ($parser->parse())
  10345. {
  10346. $encoding[] = $parser->encoding;
  10347. }
  10348. }
  10349. $encoding[] = 'UTF-8';
  10350. }
  10351. // Fallback to UTF-8
  10352. else
  10353. {
  10354. $encoding[] = 'UTF-8';
  10355. }
  10356. return $encoding;
  10357. }
  10358. function output_javascript()
  10359. {
  10360. if (function_exists('ob_gzhandler'))
  10361. {
  10362. ob_start('ob_gzhandler');
  10363. }
  10364. header('Content-type: text/javascript; charset: UTF-8');
  10365. header('Cache-Control: must-revalidate');
  10366. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
  10367. ?>
  10368. function embed_odeo(link) {
  10369. 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>');
  10370. }
  10371. function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
  10372. if (placeholder != '') {
  10373. 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>');
  10374. }
  10375. else {
  10376. 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>');
  10377. }
  10378. }
  10379. function embed_flash(bgcolor, width, height, link, loop, type) {
  10380. 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>');
  10381. }
  10382. function embed_flv(width, height, link, placeholder, loop, player) {
  10383. 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>');
  10384. }
  10385. function embed_wmedia(width, height, link) {
  10386. document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
  10387. }
  10388. <?php
  10389. }
  10390. }
  10391. /**
  10392. * Decode HTML Entities
  10393. *
  10394. * This implements HTML5 as of revision 967 (2007-06-28)
  10395. *
  10396. * @package SimplePie
  10397. */
  10398. class SimplePie_Decode_HTML_Entities
  10399. {
  10400. /**
  10401. * Data to be parsed
  10402. *
  10403. * @access private
  10404. * @var string
  10405. */
  10406. var $data = '';
  10407. /**
  10408. * Currently consumed bytes
  10409. *
  10410. * @access private
  10411. * @var string
  10412. */
  10413. var $consumed = '';
  10414. /**
  10415. * Position of the current byte being parsed
  10416. *
  10417. * @access private
  10418. * @var int
  10419. */
  10420. var $position = 0;
  10421. /**
  10422. * Create an instance of the class with the input data
  10423. *
  10424. * @access public
  10425. * @param string $data Input data
  10426. */
  10427. function SimplePie_Decode_HTML_Entities($data)
  10428. {
  10429. $this->data = $data;
  10430. }
  10431. /**
  10432. * Parse the input data
  10433. *
  10434. * @access public
  10435. * @return string Output data
  10436. */
  10437. function parse()
  10438. {
  10439. while (($this->position = strpos($this->data, '&', $this->position)) !== false)
  10440. {
  10441. $this->consume();
  10442. $this->entity();
  10443. $this->consumed = '';
  10444. }
  10445. return $this->data;
  10446. }
  10447. /**
  10448. * Consume the next byte
  10449. *
  10450. * @access private
  10451. * @return mixed The next byte, or false, if there is no more data
  10452. */
  10453. function consume()
  10454. {
  10455. if (isset($this->data[$this->position]))
  10456. {
  10457. $this->consumed .= $this->data[$this->position];
  10458. return $this->data[$this->position++];
  10459. }
  10460. else
  10461. {
  10462. return false;
  10463. }
  10464. }
  10465. /**
  10466. * Consume a range of characters
  10467. *
  10468. * @access private
  10469. * @param string $chars Characters to consume
  10470. * @return mixed A series of characters that match the range, or false
  10471. */
  10472. function consume_range($chars)
  10473. {
  10474. if ($len = strspn($this->data, $chars, $this->position))
  10475. {
  10476. $data = substr($this->data, $this->position, $len);
  10477. $this->consumed .= $data;
  10478. $this->position += $len;
  10479. return $data;
  10480. }
  10481. else
  10482. {
  10483. return false;
  10484. }
  10485. }
  10486. /**
  10487. * Unconsume one byte
  10488. *
  10489. * @access private
  10490. */
  10491. function unconsume()
  10492. {
  10493. $this->consumed = substr($this->consumed, 0, -1);
  10494. $this->position--;
  10495. }
  10496. /**
  10497. * Decode an entity
  10498. *
  10499. * @access private
  10500. */
  10501. function entity()
  10502. {
  10503. switch ($this->consume())
  10504. {
  10505. case "\x09":
  10506. case "\x0A":
  10507. case "\x0B":
  10508. case "\x0B":
  10509. case "\x0C":
  10510. case "\x20":
  10511. case "\x3C":
  10512. case "\x26":
  10513. case false:
  10514. break;
  10515. case "\x23":
  10516. switch ($this->consume())
  10517. {
  10518. case "\x78":
  10519. case "\x58":
  10520. $range = '0123456789ABCDEFabcdef';
  10521. $hex = true;
  10522. break;
  10523. default:
  10524. $range = '0123456789';
  10525. $hex = false;
  10526. $this->unconsume();
  10527. break;
  10528. }
  10529. if ($codepoint = $this->consume_range($range))
  10530. {
  10531. 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");
  10532. if ($hex)
  10533. {
  10534. $codepoint = hexdec($codepoint);
  10535. }
  10536. else
  10537. {
  10538. $codepoint = intval($codepoint);
  10539. }
  10540. if (isset($windows_1252_specials[$codepoint]))
  10541. {
  10542. $replacement = $windows_1252_specials[$codepoint];
  10543. }
  10544. else
  10545. {
  10546. $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
  10547. }
  10548. if (!in_array($this->consume(), array(';', false), true))
  10549. {
  10550. $this->unconsume();
  10551. }
  10552. $consumed_length = strlen($this->consumed);
  10553. $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
  10554. $this->position += strlen($replacement) - $consumed_length;
  10555. }
  10556. break;
  10557. default:
  10558. 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");
  10559. for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
  10560. {
  10561. $consumed = substr($this->consumed, 1);
  10562. if (isset($entities[$consumed]))
  10563. {
  10564. $match = $consumed;
  10565. }
  10566. }
  10567. if ($match !== null)
  10568. {
  10569. $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
  10570. $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
  10571. }
  10572. break;
  10573. }
  10574. }
  10575. }
  10576. /**
  10577. * IRI parser/serialiser
  10578. *
  10579. * @package SimplePie
  10580. */
  10581. class SimplePie_IRI
  10582. {
  10583. /**
  10584. * Scheme
  10585. *
  10586. * @access private
  10587. * @var string
  10588. */
  10589. var $scheme;
  10590. /**
  10591. * User Information
  10592. *
  10593. * @access private
  10594. * @var string
  10595. */
  10596. var $userinfo;
  10597. /**
  10598. * Host
  10599. *
  10600. * @access private
  10601. * @var string
  10602. */
  10603. var $host;
  10604. /**
  10605. * Port
  10606. *
  10607. * @access private
  10608. * @var string
  10609. */
  10610. var $port;
  10611. /**
  10612. * Path
  10613. *
  10614. * @access private
  10615. * @var string
  10616. */
  10617. var $path;
  10618. /**
  10619. * Query
  10620. *
  10621. * @access private
  10622. * @var string
  10623. */
  10624. var $query;
  10625. /**
  10626. * Fragment
  10627. *
  10628. * @access private
  10629. * @var string
  10630. */
  10631. var $fragment;
  10632. /**
  10633. * Whether the object represents a valid IRI
  10634. *
  10635. * @access private
  10636. * @var array
  10637. */
  10638. var $valid = array();
  10639. /**
  10640. * Return the entire IRI when you try and read the object as a string
  10641. *
  10642. * @access public
  10643. * @return string
  10644. */
  10645. function __toString()
  10646. {
  10647. return $this->get_iri();
  10648. }
  10649. /**
  10650. * Create a new IRI object, from a specified string
  10651. *
  10652. * @access public
  10653. * @param string $iri
  10654. * @return SimplePie_IRI
  10655. */
  10656. function SimplePie_IRI($iri)
  10657. {
  10658. $iri = (string) $iri;
  10659. if ($iri !== '')
  10660. {
  10661. $parsed = $this->parse_iri($iri);
  10662. $this->set_scheme($parsed['scheme']);
  10663. $this->set_authority($parsed['authority']);
  10664. $this->set_path($parsed['path']);
  10665. $this->set_query($parsed['query']);
  10666. $this->set_fragment($parsed['fragment']);
  10667. }
  10668. }
  10669. /**
  10670. * Create a new IRI object by resolving a relative IRI
  10671. *
  10672. * @static
  10673. * @access public
  10674. * @param SimplePie_IRI $base Base IRI
  10675. * @param string $relative Relative IRI
  10676. * @return SimplePie_IRI
  10677. */
  10678. function absolutize($base, $relative)
  10679. {
  10680. $relative = (string) $relative;
  10681. if ($relative !== '')
  10682. {
  10683. $relative = new SimplePie_IRI($relative);
  10684. if ($relative->get_scheme() !== null)
  10685. {
  10686. $target = $relative;
  10687. }
  10688. elseif ($base->get_iri() !== null)
  10689. {
  10690. if ($relative->get_authority() !== null)
  10691. {
  10692. $target = $relative;
  10693. $target->set_scheme($base->get_scheme());
  10694. }
  10695. else
  10696. {
  10697. $target = new SimplePie_IRI('');
  10698. $target->set_scheme($base->get_scheme());
  10699. $target->set_userinfo($base->get_userinfo());
  10700. $target->set_host($base->get_host());
  10701. $target->set_port($base->get_port());
  10702. if ($relative->get_path() !== null)
  10703. {
  10704. if (strpos($relative->get_path(), '/') === 0)
  10705. {
  10706. $target->set_path($relative->get_path());
  10707. }
  10708. elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)
  10709. {
  10710. $target->set_path('/' . $relative->get_path());
  10711. }
  10712. elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
  10713. {
  10714. $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());
  10715. }
  10716. else
  10717. {
  10718. $target->set_path($relative->get_path());
  10719. }
  10720. $target->set_query($relative->get_query());
  10721. }
  10722. else
  10723. {
  10724. $target->set_path($base->get_path());
  10725. if ($relative->get_query() !== null)
  10726. {
  10727. $target->set_query($relative->get_query());
  10728. }
  10729. elseif ($base->get_query() !== null)
  10730. {
  10731. $target->set_query($base->get_query());
  10732. }
  10733. }
  10734. }
  10735. $target->set_fragment($relative->get_fragment());
  10736. }
  10737. else
  10738. {
  10739. // No base URL, just return the relative URL
  10740. $target = $relative;
  10741. }
  10742. }
  10743. else
  10744. {
  10745. $target = $base;
  10746. }
  10747. return $target;
  10748. }
  10749. /**
  10750. * Parse an IRI into scheme/authority/path/query/fragment segments
  10751. *
  10752. * @access private
  10753. * @param string $iri
  10754. * @return array
  10755. */
  10756. function parse_iri($iri)
  10757. {
  10758. preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
  10759. for ($i = count($match); $i <= 9; $i++)
  10760. {
  10761. $match[$i] = '';
  10762. }
  10763. return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
  10764. }
  10765. /**
  10766. * Remove dot segments from a path
  10767. *
  10768. * @access private
  10769. * @param string $input
  10770. * @return string
  10771. */
  10772. function remove_dot_segments($input)
  10773. {
  10774. $output = '';
  10775. while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
  10776. {
  10777. // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
  10778. if (strpos($input, '../') === 0)
  10779. {
  10780. $input = substr($input, 3);
  10781. }
  10782. elseif (strpos($input, './') === 0)
  10783. {
  10784. $input = substr($input, 2);
  10785. }
  10786. // 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,
  10787. elseif (strpos($input, '/./') === 0)
  10788. {
  10789. $input = substr_replace($input, '/', 0, 3);
  10790. }
  10791. elseif ($input === '/.')
  10792. {
  10793. $input = '/';
  10794. }
  10795. // 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,
  10796. elseif (strpos($input, '/../') === 0)
  10797. {
  10798. $input = substr_replace($input, '/', 0, 4);
  10799. $output = substr_replace($output, '', strrpos($output, '/'));
  10800. }
  10801. elseif ($input === '/..')
  10802. {
  10803. $input = '/';
  10804. $output = substr_replace($output, '', strrpos($output, '/'));
  10805. }
  10806. // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
  10807. elseif ($input === '.' || $input === '..')
  10808. {
  10809. $input = '';
  10810. }
  10811. // 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
  10812. elseif (($pos = strpos($input, '/', 1)) !== false)
  10813. {
  10814. $output .= substr($input, 0, $pos);
  10815. $input = substr_replace($input, '', 0, $pos);
  10816. }
  10817. else
  10818. {
  10819. $output .= $input;
  10820. $input = '';
  10821. }
  10822. }
  10823. return $output . $input;
  10824. }
  10825. /**
  10826. * Replace invalid character with percent encoding
  10827. *
  10828. * @access private
  10829. * @param string $string Input string
  10830. * @param string $valid_chars Valid characters
  10831. * @param int $case Normalise case
  10832. * @return string
  10833. */
  10834. function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE)
  10835. {
  10836. // Normalise case
  10837. if ($case & SIMPLEPIE_LOWERCASE)
  10838. {
  10839. $string = strtolower($string);
  10840. }
  10841. elseif ($case & SIMPLEPIE_UPPERCASE)
  10842. {
  10843. $string = strtoupper($string);
  10844. }
  10845. // Store position and string length (to avoid constantly recalculating this)
  10846. $position = 0;
  10847. $strlen = strlen($string);
  10848. // Loop as long as we have invalid characters, advancing the position to the next invalid character
  10849. while (($position += strspn($string, $valid_chars, $position)) < $strlen)
  10850. {
  10851. // If we have a % character
  10852. if ($string[$position] === '%')
  10853. {
  10854. // If we have a pct-encoded section
  10855. if ($position + 2 < $strlen && strspn($string, '0123456789ABCDEFabcdef', $position + 1, 2) === 2)
  10856. {
  10857. // Get the the represented character
  10858. $chr = chr(hexdec(substr($string, $position + 1, 2)));
  10859. // If the character is valid, replace the pct-encoded with the actual character while normalising case
  10860. if (strpos($valid_chars, $chr) !== false)
  10861. {
  10862. if ($case & SIMPLEPIE_LOWERCASE)
  10863. {
  10864. $chr = strtolower($chr);
  10865. }
  10866. elseif ($case & SIMPLEPIE_UPPERCASE)
  10867. {
  10868. $chr = strtoupper($chr);
  10869. }
  10870. $string = substr_replace($string, $chr, $position, 3);
  10871. $strlen -= 2;
  10872. $position++;
  10873. }
  10874. // Otherwise just normalise the pct-encoded to uppercase
  10875. else
  10876. {
  10877. $string = substr_replace($string, strtoupper(substr($string, $position + 1, 2)), $position + 1, 2);
  10878. $position += 3;
  10879. }
  10880. }
  10881. // If we don't have a pct-encoded section, just replace the % with its own esccaped form
  10882. else
  10883. {
  10884. $string = substr_replace($string, '%25', $position, 1);
  10885. $strlen += 2;
  10886. $position += 3;
  10887. }
  10888. }
  10889. // If we have an invalid character, change into its pct-encoded form
  10890. else
  10891. {
  10892. $replacement = sprintf("%%%02X", ord($string[$position]));
  10893. $string = str_replace($string[$position], $replacement, $string);
  10894. $strlen = strlen($string);
  10895. }
  10896. }
  10897. return $string;
  10898. }
  10899. /**
  10900. * Check if the object represents a valid IRI
  10901. *
  10902. * @access public
  10903. * @return bool
  10904. */
  10905. function is_valid()
  10906. {
  10907. return array_sum($this->valid) === count($this->valid);
  10908. }
  10909. /**
  10910. * Set the scheme. Returns true on success, false on failure (if there are
  10911. * any invalid characters).
  10912. *
  10913. * @access public
  10914. * @param string $scheme
  10915. * @return bool
  10916. */
  10917. function set_scheme($scheme)
  10918. {
  10919. if ($scheme === null || $scheme === '')
  10920. {
  10921. $this->scheme = null;
  10922. }
  10923. else
  10924. {
  10925. $len = strlen($scheme);
  10926. switch (true)
  10927. {
  10928. case $len > 1:
  10929. if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
  10930. {
  10931. $this->scheme = null;
  10932. $this->valid[__FUNCTION__] = false;
  10933. return false;
  10934. }
  10935. case $len > 0:
  10936. if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
  10937. {
  10938. $this->scheme = null;
  10939. $this->valid[__FUNCTION__] = false;
  10940. return false;
  10941. }
  10942. }
  10943. $this->scheme = strtolower($scheme);
  10944. }
  10945. $this->valid[__FUNCTION__] = true;
  10946. return true;
  10947. }
  10948. /**
  10949. * Set the authority. Returns true on success, false on failure (if there are
  10950. * any invalid characters).
  10951. *
  10952. * @access public
  10953. * @param string $authority
  10954. * @return bool
  10955. */
  10956. function set_authority($authority)
  10957. {
  10958. if (($userinfo_end = strrpos($authority, '@')) !== false)
  10959. {
  10960. $userinfo = substr($authority, 0, $userinfo_end);
  10961. $authority = substr($authority, $userinfo_end + 1);
  10962. }
  10963. else
  10964. {
  10965. $userinfo = null;
  10966. }
  10967. if (($port_start = strpos($authority, ':')) !== false)
  10968. {
  10969. $port = substr($authority, $port_start + 1);
  10970. $authority = substr($authority, 0, $port_start);
  10971. }
  10972. else
  10973. {
  10974. $port = null;
  10975. }
  10976. return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
  10977. }
  10978. /**
  10979. * Set the userinfo.
  10980. *
  10981. * @access public
  10982. * @param string $userinfo
  10983. * @return bool
  10984. */
  10985. function set_userinfo($userinfo)
  10986. {
  10987. if ($userinfo === null || $userinfo === '')
  10988. {
  10989. $this->userinfo = null;
  10990. }
  10991. else
  10992. {
  10993. $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
  10994. }
  10995. $this->valid[__FUNCTION__] = true;
  10996. return true;
  10997. }
  10998. /**
  10999. * Set the host. Returns true on success, false on failure (if there are
  11000. * any invalid characters).
  11001. *
  11002. * @access public
  11003. * @param string $host
  11004. * @return bool
  11005. */
  11006. function set_host($host)
  11007. {
  11008. if ($host === null || $host === '')
  11009. {
  11010. $this->host = null;
  11011. $this->valid[__FUNCTION__] = true;
  11012. return true;
  11013. }
  11014. elseif ($host[0] === '[' && substr($host, -1) === ']')
  11015. {
  11016. if (Net_IPv6::checkIPv6(substr($host, 1, -1)))
  11017. {
  11018. $this->host = $host;
  11019. $this->valid[__FUNCTION__] = true;
  11020. return true;
  11021. }
  11022. else
  11023. {
  11024. $this->host = null;
  11025. $this->valid[__FUNCTION__] = false;
  11026. return false;
  11027. }
  11028. }
  11029. else
  11030. {
  11031. $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);
  11032. $this->valid[__FUNCTION__] = true;
  11033. return true;
  11034. }
  11035. }
  11036. /**
  11037. * Set the port. Returns true on success, false on failure (if there are
  11038. * any invalid characters).
  11039. *
  11040. * @access public
  11041. * @param string $port
  11042. * @return bool
  11043. */
  11044. function set_port($port)
  11045. {
  11046. if ($port === null || $port === '')
  11047. {
  11048. $this->port = null;
  11049. $this->valid[__FUNCTION__] = true;
  11050. return true;
  11051. }
  11052. elseif (strspn($port, '0123456789') === strlen($port))
  11053. {
  11054. $this->port = (int) $port;
  11055. $this->valid[__FUNCTION__] = true;
  11056. return true;
  11057. }
  11058. else
  11059. {
  11060. $this->port = null;
  11061. $this->valid[__FUNCTION__] = false;
  11062. return false;
  11063. }
  11064. }
  11065. /**
  11066. * Set the path.
  11067. *
  11068. * @access public
  11069. * @param string $path
  11070. * @return bool
  11071. */
  11072. function set_path($path)
  11073. {
  11074. if ($path === null || $path === '')
  11075. {
  11076. $this->path = null;
  11077. $this->valid[__FUNCTION__] = true;
  11078. return true;
  11079. }
  11080. elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)
  11081. {
  11082. $this->path = null;
  11083. $this->valid[__FUNCTION__] = false;
  11084. return false;
  11085. }
  11086. else
  11087. {
  11088. $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
  11089. if ($this->scheme !== null)
  11090. {
  11091. $this->path = $this->remove_dot_segments($this->path);
  11092. }
  11093. $this->valid[__FUNCTION__] = true;
  11094. return true;
  11095. }
  11096. }
  11097. /**
  11098. * Set the query.
  11099. *
  11100. * @access public
  11101. * @param string $query
  11102. * @return bool
  11103. */
  11104. function set_query($query)
  11105. {
  11106. if ($query === null || $query === '')
  11107. {
  11108. $this->query = null;
  11109. }
  11110. else
  11111. {
  11112. $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
  11113. }
  11114. $this->valid[__FUNCTION__] = true;
  11115. return true;
  11116. }
  11117. /**
  11118. * Set the fragment.
  11119. *
  11120. * @access public
  11121. * @param string $fragment
  11122. * @return bool
  11123. */
  11124. function set_fragment($fragment)
  11125. {
  11126. if ($fragment === null || $fragment === '')
  11127. {
  11128. $this->fragment = null;
  11129. }
  11130. else
  11131. {
  11132. $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
  11133. }
  11134. $this->valid[__FUNCTION__] = true;
  11135. return true;
  11136. }
  11137. /**
  11138. * Get the complete IRI
  11139. *
  11140. * @access public
  11141. * @return string
  11142. */
  11143. function get_iri()
  11144. {
  11145. $iri = '';
  11146. if ($this->scheme !== null)
  11147. {
  11148. $iri .= $this->scheme . ':';
  11149. }
  11150. if (($authority = $this->get_authority()) !== null)
  11151. {
  11152. $iri .= '//' . $authority;
  11153. }
  11154. if ($this->path !== null)
  11155. {
  11156. $iri .= $this->path;
  11157. }
  11158. if ($this->query !== null)
  11159. {
  11160. $iri .= '?' . $this->query;
  11161. }
  11162. if ($this->fragment !== null)
  11163. {
  11164. $iri .= '#' . $this->fragment;
  11165. }
  11166. if ($iri !== '')
  11167. {
  11168. return $iri;
  11169. }
  11170. else
  11171. {
  11172. return null;
  11173. }
  11174. }
  11175. /**
  11176. * Get the scheme
  11177. *
  11178. * @access public
  11179. * @return string
  11180. */
  11181. function get_scheme()
  11182. {
  11183. return $this->scheme;
  11184. }
  11185. /**
  11186. * Get the complete authority
  11187. *
  11188. * @access public
  11189. * @return string
  11190. */
  11191. function get_authority()
  11192. {
  11193. $authority = '';
  11194. if ($this->userinfo !== null)
  11195. {
  11196. $authority .= $this->userinfo . '@';
  11197. }
  11198. if ($this->host !== null)
  11199. {
  11200. $authority .= $this->host;
  11201. }
  11202. if ($this->port !== null)
  11203. {
  11204. $authority .= ':' . $this->port;
  11205. }
  11206. if ($authority !== '')
  11207. {
  11208. return $authority;
  11209. }
  11210. else
  11211. {
  11212. return null;
  11213. }
  11214. }
  11215. /**
  11216. * Get the user information
  11217. *
  11218. * @access public
  11219. * @return string
  11220. */
  11221. function get_userinfo()
  11222. {
  11223. return $this->userinfo;
  11224. }
  11225. /**
  11226. * Get the host
  11227. *
  11228. * @access public
  11229. * @return string
  11230. */
  11231. function get_host()
  11232. {
  11233. return $this->host;
  11234. }
  11235. /**
  11236. * Get the port
  11237. *
  11238. * @access public
  11239. * @return string
  11240. */
  11241. function get_port()
  11242. {
  11243. return $this->port;
  11244. }
  11245. /**
  11246. * Get the path
  11247. *
  11248. * @access public
  11249. * @return string
  11250. */
  11251. function get_path()
  11252. {
  11253. return $this->path;
  11254. }
  11255. /**
  11256. * Get the query
  11257. *
  11258. * @access public
  11259. * @return string
  11260. */
  11261. function get_query()
  11262. {
  11263. return $this->query;
  11264. }
  11265. /**
  11266. * Get the fragment
  11267. *
  11268. * @access public
  11269. * @return string
  11270. */
  11271. function get_fragment()
  11272. {
  11273. return $this->fragment;
  11274. }
  11275. }
  11276. /**
  11277. * Class to validate and to work with IPv6 addresses.
  11278. *
  11279. * @package SimplePie
  11280. * @copyright 2003-2005 The PHP Group
  11281. * @license http://www.opensource.org/licenses/bsd-license.php
  11282. * @link http://pear.php.net/package/Net_IPv6
  11283. * @author Alexander Merz <alexander.merz@web.de>
  11284. * @author elfrink at introweb dot nl
  11285. * @author Josh Peck <jmp at joshpeck dot org>
  11286. * @author Geoffrey Sneddon <geoffers@gmail.com>
  11287. */
  11288. class SimplePie_Net_IPv6
  11289. {
  11290. /**
  11291. * Removes a possible existing netmask specification of an IP address.
  11292. *
  11293. * @param string $ip the (compressed) IP as Hex representation
  11294. * @return string the IP the without netmask
  11295. * @since 1.1.0
  11296. * @access public
  11297. * @static
  11298. */
  11299. function removeNetmaskSpec($ip)
  11300. {
  11301. if (strpos($ip, '/') !== false)
  11302. {
  11303. list($addr, $nm) = explode('/', $ip);
  11304. }
  11305. else
  11306. {
  11307. $addr = $ip;
  11308. }
  11309. return $addr;
  11310. }
  11311. /**
  11312. * Uncompresses an IPv6 address
  11313. *
  11314. * RFC 2373 allows you to compress zeros in an address to '::'. This
  11315. * function expects an valid IPv6 address and expands the '::' to
  11316. * the required zeros.
  11317. *
  11318. * Example: FF01::101 -> FF01:0:0:0:0:0:0:101
  11319. * ::1 -> 0:0:0:0:0:0:0:1
  11320. *
  11321. * @access public
  11322. * @static
  11323. * @param string $ip a valid IPv6-address (hex format)
  11324. * @return string the uncompressed IPv6-address (hex format)
  11325. */
  11326. function Uncompress($ip)
  11327. {
  11328. $uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip);
  11329. $c1 = -1;
  11330. $c2 = -1;
  11331. if (strpos($ip, '::') !== false)
  11332. {
  11333. list($ip1, $ip2) = explode('::', $ip);
  11334. if ($ip1 === '')
  11335. {
  11336. $c1 = -1;
  11337. }
  11338. else
  11339. {
  11340. $pos = 0;
  11341. if (($pos = substr_count($ip1, ':')) > 0)
  11342. {
  11343. $c1 = $pos;
  11344. }
  11345. else
  11346. {
  11347. $c1 = 0;
  11348. }
  11349. }
  11350. if ($ip2 === '')
  11351. {
  11352. $c2 = -1;
  11353. }
  11354. else
  11355. {
  11356. $pos = 0;
  11357. if (($pos = substr_count($ip2, ':')) > 0)
  11358. {
  11359. $c2 = $pos;
  11360. }
  11361. else
  11362. {
  11363. $c2 = 0;
  11364. }
  11365. }
  11366. if (strstr($ip2, '.'))
  11367. {
  11368. $c2++;
  11369. }
  11370. // ::
  11371. if ($c1 === -1 && $c2 === -1)
  11372. {
  11373. $uip = '0:0:0:0:0:0:0:0';
  11374. }
  11375. // ::xxx
  11376. else if ($c1 === -1)
  11377. {
  11378. $fill = str_repeat('0:', 7 - $c2);
  11379. $uip = str_replace('::', $fill, $uip);
  11380. }
  11381. // xxx::
  11382. else if ($c2 === -1)
  11383. {
  11384. $fill = str_repeat(':0', 7 - $c1);
  11385. $uip = str_replace('::', $fill, $uip);
  11386. }
  11387. // xxx::xxx
  11388. else
  11389. {
  11390. $fill = str_repeat(':0:', 6 - $c2 - $c1);
  11391. $uip = str_replace('::', $fill, $uip);
  11392. $uip = str_replace('::', ':', $uip);
  11393. }
  11394. }
  11395. return $uip;
  11396. }
  11397. /**
  11398. * Splits an IPv6 address into the IPv6 and a possible IPv4 part
  11399. *
  11400. * RFC 2373 allows you to note the last two parts of an IPv6 address as
  11401. * an IPv4 compatible address
  11402. *
  11403. * Example: 0:0:0:0:0:0:13.1.68.3
  11404. * 0:0:0:0:0:FFFF:129.144.52.38
  11405. *
  11406. * @access public
  11407. * @static
  11408. * @param string $ip a valid IPv6-address (hex format)
  11409. * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)
  11410. */
  11411. function SplitV64($ip)
  11412. {
  11413. $ip = SimplePie_Net_IPv6::Uncompress($ip);
  11414. if (strstr($ip, '.'))
  11415. {
  11416. $pos = strrpos($ip, ':');
  11417. $ip[$pos] = '_';
  11418. $ipPart = explode('_', $ip);
  11419. return $ipPart;
  11420. }
  11421. else
  11422. {
  11423. return array($ip, '');
  11424. }
  11425. }
  11426. /**
  11427. * Checks an IPv6 address
  11428. *
  11429. * Checks if the given IP is IPv6-compatible
  11430. *
  11431. * @access public
  11432. * @static
  11433. * @param string $ip a valid IPv6-address
  11434. * @return bool true if $ip is an IPv6 address
  11435. */
  11436. function checkIPv6($ip)
  11437. {
  11438. $ipPart = SimplePie_Net_IPv6::SplitV64($ip);
  11439. $count = 0;
  11440. if (!empty($ipPart[0]))
  11441. {
  11442. $ipv6 = explode(':', $ipPart[0]);
  11443. for ($i = 0; $i < count($ipv6); $i++)
  11444. {
  11445. $dec = hexdec($ipv6[$i]);
  11446. $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));
  11447. if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))
  11448. {
  11449. $count++;
  11450. }
  11451. }
  11452. if ($count === 8)
  11453. {
  11454. return true;
  11455. }
  11456. elseif ($count === 6 && !empty($ipPart[1]))
  11457. {
  11458. $ipv4 = explode('.', $ipPart[1]);
  11459. $count = 0;
  11460. foreach ($ipv4 as $ipv4_part)
  11461. {
  11462. if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))
  11463. {
  11464. $count++;
  11465. }
  11466. }
  11467. if ($count === 4)
  11468. {
  11469. return true;
  11470. }
  11471. }
  11472. else
  11473. {
  11474. return false;
  11475. }
  11476. }
  11477. else
  11478. {
  11479. return false;
  11480. }
  11481. }
  11482. }
  11483. /**
  11484. * Date Parser
  11485. *
  11486. * @package SimplePie
  11487. */
  11488. class SimplePie_Parse_Date
  11489. {
  11490. /**
  11491. * Input data
  11492. *
  11493. * @access protected
  11494. * @var string
  11495. */
  11496. var $date;
  11497. /**
  11498. * List of days, calendar day name => ordinal day number in the week
  11499. *
  11500. * @access protected
  11501. * @var array
  11502. */
  11503. var $day = array(
  11504. // English
  11505. 'mon' => 1,
  11506. 'monday' => 1,
  11507. 'tue' => 2,
  11508. 'tuesday' => 2,
  11509. 'wed' => 3,
  11510. 'wednesday' => 3,
  11511. 'thu' => 4,
  11512. 'thursday' => 4,
  11513. 'fri' => 5,
  11514. 'friday' => 5,
  11515. 'sat' => 6,
  11516. 'saturday' => 6,
  11517. 'sun' => 7,
  11518. 'sunday' => 7,
  11519. // Dutch
  11520. 'maandag' => 1,
  11521. 'dinsdag' => 2,
  11522. 'woensdag' => 3,
  11523. 'donderdag' => 4,
  11524. 'vrijdag' => 5,
  11525. 'zaterdag' => 6,
  11526. 'zondag' => 7,
  11527. // French
  11528. 'lundi' => 1,
  11529. 'mardi' => 2,
  11530. 'mercredi' => 3,
  11531. 'jeudi' => 4,
  11532. 'vendredi' => 5,
  11533. 'samedi' => 6,
  11534. 'dimanche' => 7,
  11535. // German
  11536. 'montag' => 1,
  11537. 'dienstag' => 2,
  11538. 'mittwoch' => 3,
  11539. 'donnerstag' => 4,
  11540. 'freitag' => 5,
  11541. 'samstag' => 6,
  11542. 'sonnabend' => 6,
  11543. 'sonntag' => 7,
  11544. // Italian
  11545. 'lunedì' => 1,
  11546. 'martedì' => 2,
  11547. 'mercoledì' => 3,
  11548. 'giovedì' => 4,
  11549. 'venerdì' => 5,
  11550. 'sabato' => 6,
  11551. 'domenica' => 7,
  11552. // Spanish
  11553. 'lunes' => 1,
  11554. 'martes' => 2,
  11555. 'miércoles' => 3,
  11556. 'jueves' => 4,
  11557. 'viernes' => 5,
  11558. 'sábado' => 6,
  11559. 'domingo' => 7,
  11560. // Finnish
  11561. 'maanantai' => 1,
  11562. 'tiistai' => 2,
  11563. 'keskiviikko' => 3,
  11564. 'torstai' => 4,
  11565. 'perjantai' => 5,
  11566. 'lauantai' => 6,
  11567. 'sunnuntai' => 7,
  11568. // Hungarian
  11569. 'hétfő' => 1,
  11570. 'kedd' => 2,
  11571. 'szerda' => 3,
  11572. 'csütörtok' => 4,
  11573. 'péntek' => 5,
  11574. 'szombat' => 6,
  11575. 'vasárnap' => 7,
  11576. // Greek
  11577. 'Δευ' => 1,
  11578. 'Τρι' => 2,
  11579. 'Τετ' => 3,
  11580. 'Πεμ' => 4,
  11581. 'Παρ' => 5,
  11582. 'Σαβ' => 6,
  11583. 'Κυρ' => 7,
  11584. );
  11585. /**
  11586. * List of months, calendar month name => calendar month number
  11587. *
  11588. * @access protected
  11589. * @var array
  11590. */
  11591. var $month = array(
  11592. // English
  11593. 'jan' => 1,
  11594. 'january' => 1,
  11595. 'feb' => 2,
  11596. 'february' => 2,
  11597. 'mar' => 3,
  11598. 'march' => 3,
  11599. 'apr' => 4,
  11600. 'april' => 4,
  11601. 'may' => 5,
  11602. // No long form of May
  11603. 'jun' => 6,
  11604. 'june' => 6,
  11605. 'jul' => 7,
  11606. 'july' => 7,
  11607. 'aug' => 8,
  11608. 'august' => 8,
  11609. 'sep' => 9,
  11610. 'september' => 8,
  11611. 'oct' => 10,
  11612. 'october' => 10,
  11613. 'nov' => 11,
  11614. 'november' => 11,
  11615. 'dec' => 12,
  11616. 'december' => 12,
  11617. // Dutch
  11618. 'januari' => 1,
  11619. 'februari' => 2,
  11620. 'maart' => 3,
  11621. 'april' => 4,
  11622. 'mei' => 5,
  11623. 'juni' => 6,
  11624. 'juli' => 7,
  11625. 'augustus' => 8,
  11626. 'september' => 9,
  11627. 'oktober' => 10,
  11628. 'november' => 11,
  11629. 'december' => 12,
  11630. // French
  11631. 'janvier' => 1,
  11632. 'février' => 2,
  11633. 'mars' => 3,
  11634. 'avril' => 4,
  11635. 'mai' => 5,
  11636. 'juin' => 6,
  11637. 'juillet' => 7,
  11638. 'août' => 8,
  11639. 'septembre' => 9,
  11640. 'octobre' => 10,
  11641. 'novembre' => 11,
  11642. 'décembre' => 12,
  11643. // German
  11644. 'januar' => 1,
  11645. 'februar' => 2,
  11646. 'märz' => 3,
  11647. 'april' => 4,
  11648. 'mai' => 5,
  11649. 'juni' => 6,
  11650. 'juli' => 7,
  11651. 'august' => 8,
  11652. 'september' => 9,
  11653. 'oktober' => 10,
  11654. 'november' => 11,
  11655. 'dezember' => 12,
  11656. // Italian
  11657. 'gennaio' => 1,
  11658. 'febbraio' => 2,
  11659. 'marzo' => 3,
  11660. 'aprile' => 4,
  11661. 'maggio' => 5,
  11662. 'giugno' => 6,
  11663. 'luglio' => 7,
  11664. 'agosto' => 8,
  11665. 'settembre' => 9,
  11666. 'ottobre' => 10,
  11667. 'novembre' => 11,
  11668. 'dicembre' => 12,
  11669. // Spanish
  11670. 'enero' => 1,
  11671. 'febrero' => 2,
  11672. 'marzo' => 3,
  11673. 'abril' => 4,
  11674. 'mayo' => 5,
  11675. 'junio' => 6,
  11676. 'julio' => 7,
  11677. 'agosto' => 8,
  11678. 'septiembre' => 9,
  11679. 'setiembre' => 9,
  11680. 'octubre' => 10,
  11681. 'noviembre' => 11,
  11682. 'diciembre' => 12,
  11683. // Finnish
  11684. 'tammikuu' => 1,
  11685. 'helmikuu' => 2,
  11686. 'maaliskuu' => 3,
  11687. 'huhtikuu' => 4,
  11688. 'toukokuu' => 5,
  11689. 'kesäkuu' => 6,
  11690. 'heinäkuu' => 7,
  11691. 'elokuu' => 8,
  11692. 'suuskuu' => 9,
  11693. 'lokakuu' => 10,
  11694. 'marras' => 11,
  11695. 'joulukuu' => 12,
  11696. // Hungarian
  11697. 'január' => 1,
  11698. 'február' => 2,
  11699. 'március' => 3,
  11700. 'április' => 4,
  11701. 'május' => 5,
  11702. 'június' => 6,
  11703. 'július' => 7,
  11704. 'augusztus' => 8,
  11705. 'szeptember' => 9,
  11706. 'október' => 10,
  11707. 'november' => 11,
  11708. 'december' => 12,
  11709. // Greek
  11710. 'Ιαν' => 1,
  11711. 'Φεβ' => 2,
  11712. 'Μάώ' => 3,
  11713. 'Μαώ' => 3,
  11714. 'Απρ' => 4,
  11715. 'Μάι' => 5,
  11716. 'Μαϊ' => 5,
  11717. 'Μαι' => 5,
  11718. 'Ιούν' => 6,
  11719. 'Ιον' => 6,
  11720. 'Ιούλ' => 7,
  11721. 'Ιολ' => 7,
  11722. 'Αύγ' => 8,
  11723. 'Αυγ' => 8,
  11724. 'Σεπ' => 9,
  11725. 'Οκτ' => 10,
  11726. 'Νοέ' => 11,
  11727. 'Δεκ' => 12,
  11728. );
  11729. /**
  11730. * List of timezones, abbreviation => offset from UTC
  11731. *
  11732. * @access protected
  11733. * @var array
  11734. */
  11735. var $timezone = array(
  11736. 'ACDT' => 37800,
  11737. 'ACIT' => 28800,
  11738. 'ACST' => 34200,
  11739. 'ACT' => -18000,
  11740. 'ACWDT' => 35100,
  11741. 'ACWST' => 31500,
  11742. 'AEDT' => 39600,
  11743. 'AEST' => 36000,
  11744. 'AFT' => 16200,
  11745. 'AKDT' => -28800,
  11746. 'AKST' => -32400,
  11747. 'AMDT' => 18000,
  11748. 'AMT' => -14400,
  11749. 'ANAST' => 46800,
  11750. 'ANAT' => 43200,
  11751. 'ART' => -10800,
  11752. 'AZOST' => -3600,
  11753. 'AZST' => 18000,
  11754. 'AZT' => 14400,
  11755. 'BIOT' => 21600,
  11756. 'BIT' => -43200,
  11757. 'BOT' => -14400,
  11758. 'BRST' => -7200,
  11759. 'BRT' => -10800,
  11760. 'BST' => 3600,
  11761. 'BTT' => 21600,
  11762. 'CAST' => 18000,
  11763. 'CAT' => 7200,
  11764. 'CCT' => 23400,
  11765. 'CDT' => -18000,
  11766. 'CEDT' => 7200,
  11767. 'CET' => 3600,
  11768. 'CGST' => -7200,
  11769. 'CGT' => -10800,
  11770. 'CHADT' => 49500,
  11771. 'CHAST' => 45900,
  11772. 'CIST' => -28800,
  11773. 'CKT' => -36000,
  11774. 'CLDT' => -10800,
  11775. 'CLST' => -14400,
  11776. 'COT' => -18000,
  11777. 'CST' => -21600,
  11778. 'CVT' => -3600,
  11779. 'CXT' => 25200,
  11780. 'DAVT' => 25200,
  11781. 'DTAT' => 36000,
  11782. 'EADT' => -18000,
  11783. 'EAST' => -21600,
  11784. 'EAT' => 10800,
  11785. 'ECT' => -18000,
  11786. 'EDT' => -14400,
  11787. 'EEST' => 10800,
  11788. 'EET' => 7200,
  11789. 'EGT' => -3600,
  11790. 'EKST' => 21600,
  11791. 'EST' => -18000,
  11792. 'FJT' => 43200,
  11793. 'FKDT' => -10800,
  11794. 'FKST' => -14400,
  11795. 'FNT' => -7200,
  11796. 'GALT' => -21600,
  11797. 'GEDT' => 14400,
  11798. 'GEST' => 10800,
  11799. 'GFT' => -10800,
  11800. 'GILT' => 43200,
  11801. 'GIT' => -32400,
  11802. 'GST' => 14400,
  11803. 'GST' => -7200,
  11804. 'GYT' => -14400,
  11805. 'HAA' => -10800,
  11806. 'HAC' => -18000,
  11807. 'HADT' => -32400,
  11808. 'HAE' => -14400,
  11809. 'HAP' => -25200,
  11810. 'HAR' => -21600,
  11811. 'HAST' => -36000,
  11812. 'HAT' => -9000,
  11813. 'HAY' => -28800,
  11814. 'HKST' => 28800,
  11815. 'HMT' => 18000,
  11816. 'HNA' => -14400,
  11817. 'HNC' => -21600,
  11818. 'HNE' => -18000,
  11819. 'HNP' => -28800,
  11820. 'HNR' => -25200,
  11821. 'HNT' => -12600,
  11822. 'HNY' => -32400,
  11823. 'IRDT' => 16200,
  11824. 'IRKST' => 32400,
  11825. 'IRKT' => 28800,
  11826. 'IRST' => 12600,
  11827. 'JFDT' => -10800,
  11828. 'JFST' => -14400,
  11829. 'JST' => 32400,
  11830. 'KGST' => 21600,
  11831. 'KGT' => 18000,
  11832. 'KOST' => 39600,
  11833. 'KOVST' => 28800,
  11834. 'KOVT' => 25200,
  11835. 'KRAST' => 28800,
  11836. 'KRAT' => 25200,
  11837. 'KST' => 32400,
  11838. 'LHDT' => 39600,
  11839. 'LHST' => 37800,
  11840. 'LINT' => 50400,
  11841. 'LKT' => 21600,
  11842. 'MAGST' => 43200,
  11843. 'MAGT' => 39600,
  11844. 'MAWT' => 21600,
  11845. 'MDT' => -21600,
  11846. 'MESZ' => 7200,
  11847. 'MEZ' => 3600,
  11848. 'MHT' => 43200,
  11849. 'MIT' => -34200,
  11850. 'MNST' => 32400,
  11851. 'MSDT' => 14400,
  11852. 'MSST' => 10800,
  11853. 'MST' => -25200,
  11854. 'MUT' => 14400,
  11855. 'MVT' => 18000,
  11856. 'MYT' => 28800,
  11857. 'NCT' => 39600,
  11858. 'NDT' => -9000,
  11859. 'NFT' => 41400,
  11860. 'NMIT' => 36000,
  11861. 'NOVST' => 25200,
  11862. 'NOVT' => 21600,
  11863. 'NPT' => 20700,
  11864. 'NRT' => 43200,
  11865. 'NST' => -12600,
  11866. 'NUT' => -39600,
  11867. 'NZDT' => 46800,
  11868. 'NZST' => 43200,
  11869. 'OMSST' => 25200,
  11870. 'OMST' => 21600,
  11871. 'PDT' => -25200,
  11872. 'PET' => -18000,
  11873. 'PETST' => 46800,
  11874. 'PETT' => 43200,
  11875. 'PGT' => 36000,
  11876. 'PHOT' => 46800,
  11877. 'PHT' => 28800,
  11878. 'PKT' => 18000,
  11879. 'PMDT' => -7200,
  11880. 'PMST' => -10800,
  11881. 'PONT' => 39600,
  11882. 'PST' => -28800,
  11883. 'PWT' => 32400,
  11884. 'PYST' => -10800,
  11885. 'PYT' => -14400,
  11886. 'RET' => 14400,
  11887. 'ROTT' => -10800,
  11888. 'SAMST' => 18000,
  11889. 'SAMT' => 14400,
  11890. 'SAST' => 7200,
  11891. 'SBT' => 39600,
  11892. 'SCDT' => 46800,
  11893. 'SCST' => 43200,
  11894. 'SCT' => 14400,
  11895. 'SEST' => 3600,
  11896. 'SGT' => 28800,
  11897. 'SIT' => 28800,
  11898. 'SRT' => -10800,
  11899. 'SST' => -39600,
  11900. 'SYST' => 10800,
  11901. 'SYT' => 7200,
  11902. 'TFT' => 18000,
  11903. 'THAT' => -36000,
  11904. 'TJT' => 18000,
  11905. 'TKT' => -36000,
  11906. 'TMT' => 18000,
  11907. 'TOT' => 46800,
  11908. 'TPT' => 32400,
  11909. 'TRUT' => 36000,
  11910. 'TVT' => 43200,
  11911. 'TWT' => 28800,
  11912. 'UYST' => -7200,
  11913. 'UYT' => -10800,
  11914. 'UZT' => 18000,
  11915. 'VET' => -14400,
  11916. 'VLAST' => 39600,
  11917. 'VLAT' => 36000,
  11918. 'VOST' => 21600,
  11919. 'VUT' => 39600,
  11920. 'WAST' => 7200,
  11921. 'WAT' => 3600,
  11922. 'WDT' => 32400,
  11923. 'WEST' => 3600,
  11924. 'WFT' => 43200,
  11925. 'WIB' => 25200,
  11926. 'WIT' => 32400,
  11927. 'WITA' => 28800,
  11928. 'WKST' => 18000,
  11929. 'WST' => 28800,
  11930. 'YAKST' => 36000,
  11931. 'YAKT' => 32400,
  11932. 'YAPT' => 36000,
  11933. 'YEKST' => 21600,
  11934. 'YEKT' => 18000,
  11935. );
  11936. /**
  11937. * Cached PCRE for SimplePie_Parse_Date::$day
  11938. *
  11939. * @access protected
  11940. * @var string
  11941. */
  11942. var $day_pcre;
  11943. /**
  11944. * Cached PCRE for SimplePie_Parse_Date::$month
  11945. *
  11946. * @access protected
  11947. * @var string
  11948. */
  11949. var $month_pcre;
  11950. /**
  11951. * Array of user-added callback methods
  11952. *
  11953. * @access private
  11954. * @var array
  11955. */
  11956. var $built_in = array();
  11957. /**
  11958. * Array of user-added callback methods
  11959. *
  11960. * @access private
  11961. * @var array
  11962. */
  11963. var $user = array();
  11964. /**
  11965. * Create new SimplePie_Parse_Date object, and set self::day_pcre,
  11966. * self::month_pcre, and self::built_in
  11967. *
  11968. * @access private
  11969. */
  11970. function SimplePie_Parse_Date()
  11971. {
  11972. $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
  11973. $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
  11974. static $cache;
  11975. if (!isset($cache[get_class($this)]))
  11976. {
  11977. $all_methods = get_class_methods($this);
  11978. foreach ($all_methods as $method)
  11979. {
  11980. if (strtolower(substr($method, 0, 5)) === 'date_')
  11981. {
  11982. $cache[get_class($this)][] = $method;
  11983. }
  11984. }
  11985. }
  11986. foreach ($cache[get_class($this)] as $method)
  11987. {
  11988. $this->built_in[] = $method;
  11989. }
  11990. }
  11991. /**
  11992. * Get the object
  11993. *
  11994. * @access public
  11995. */
  11996. function get()
  11997. {
  11998. static $object;
  11999. if (!$object)
  12000. {
  12001. $object = new SimplePie_Parse_Date;
  12002. }
  12003. return $object;
  12004. }
  12005. /**
  12006. * Parse a date
  12007. *
  12008. * @final
  12009. * @access public
  12010. * @param string $date Date to parse
  12011. * @return int Timestamp corresponding to date string, or false on failure
  12012. */
  12013. function parse($date)
  12014. {
  12015. foreach ($this->user as $method)
  12016. {
  12017. if (($returned = call_user_func($method, $date)) !== false)
  12018. {
  12019. return $returned;
  12020. }
  12021. }
  12022. foreach ($this->built_in as $method)
  12023. {
  12024. if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
  12025. {
  12026. return $returned;
  12027. }
  12028. }
  12029. return false;
  12030. }
  12031. /**
  12032. * Add a callback method to parse a date
  12033. *
  12034. * @final
  12035. * @access public
  12036. * @param callback $callback
  12037. */
  12038. function add_callback($callback)
  12039. {
  12040. if (is_callable($callback))
  12041. {
  12042. $this->user[] = $callback;
  12043. }
  12044. else
  12045. {
  12046. trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
  12047. }
  12048. }
  12049. /**
  12050. * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
  12051. * well as allowing any of upper or lower case "T", horizontal tabs, or
  12052. * spaces to be used as the time seperator (including more than one))
  12053. *
  12054. * @access protected
  12055. * @return int Timestamp
  12056. */
  12057. function date_w3cdtf($date)
  12058. {
  12059. static $pcre;
  12060. if (!$pcre)
  12061. {
  12062. $year = '([0-9]{4})';
  12063. $month = $day = $hour = $minute = $second = '([0-9]{2})';
  12064. $decimal = '([0-9]*)';
  12065. $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
  12066. $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
  12067. }
  12068. if (preg_match($pcre, $date, $match))
  12069. {
  12070. /*
  12071. Capturing subpatterns:
  12072. 1: Year
  12073. 2: Month
  12074. 3: Day
  12075. 4: Hour
  12076. 5: Minute
  12077. 6: Second
  12078. 7: Decimal fraction of a second
  12079. 8: Zulu
  12080. 9: Timezone ±
  12081. 10: Timezone hours
  12082. 11: Timezone minutes
  12083. */
  12084. // Fill in empty matches
  12085. for ($i = count($match); $i <= 3; $i++)
  12086. {
  12087. $match[$i] = '1';
  12088. }
  12089. for ($i = count($match); $i <= 7; $i++)
  12090. {
  12091. $match[$i] = '0';
  12092. }
  12093. // Numeric timezone
  12094. if (isset($match[9]) && $match[9] !== '')
  12095. {
  12096. $timezone = $match[10] * 3600;
  12097. $timezone += $match[11] * 60;
  12098. if ($match[9] === '-')
  12099. {
  12100. $timezone = 0 - $timezone;
  12101. }
  12102. }
  12103. else
  12104. {
  12105. $timezone = 0;
  12106. }
  12107. // Convert the number of seconds to an integer, taking decimals into account
  12108. $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
  12109. return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
  12110. }
  12111. else
  12112. {
  12113. return false;
  12114. }
  12115. }
  12116. /**
  12117. * Remove RFC822 comments
  12118. *
  12119. * @access protected
  12120. * @param string $data Data to strip comments from
  12121. * @return string Comment stripped string
  12122. */
  12123. function remove_rfc2822_comments($string)
  12124. {
  12125. $string = (string) $string;
  12126. $position = 0;
  12127. $length = strlen($string);
  12128. $depth = 0;
  12129. $output = '';
  12130. while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
  12131. {
  12132. $output .= substr($string, $position, $pos - $position);
  12133. $position = $pos + 1;
  12134. if ($string[$pos - 1] !== '\\')
  12135. {
  12136. $depth++;
  12137. while ($depth && $position < $length)
  12138. {
  12139. $position += strcspn($string, '()', $position);
  12140. if ($string[$position - 1] === '\\')
  12141. {
  12142. $position++;
  12143. continue;
  12144. }
  12145. elseif (isset($string[$position]))
  12146. {
  12147. switch ($string[$position])
  12148. {
  12149. case '(':
  12150. $depth++;
  12151. break;
  12152. case ')':
  12153. $depth--;
  12154. break;
  12155. }
  12156. $position++;
  12157. }
  12158. else
  12159. {
  12160. break;
  12161. }
  12162. }
  12163. }
  12164. else
  12165. {
  12166. $output .= '(';
  12167. }
  12168. }
  12169. $output .= substr($string, $position);
  12170. return $output;
  12171. }
  12172. /**
  12173. * Parse RFC2822's date format
  12174. *
  12175. * @access protected
  12176. * @return int Timestamp
  12177. */
  12178. function date_rfc2822($date)
  12179. {
  12180. static $pcre;
  12181. if (!$pcre)
  12182. {
  12183. $wsp = '[\x09\x20]';
  12184. $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
  12185. $optional_fws = $fws . '?';
  12186. $day_name = $this->day_pcre;
  12187. $month = $this->month_pcre;
  12188. $day = '([0-9]{1,2})';
  12189. $hour = $minute = $second = '([0-9]{2})';
  12190. $year = '([0-9]{2,4})';
  12191. $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
  12192. $character_zone = '([A-Z]{1,5})';
  12193. $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
  12194. $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';
  12195. }
  12196. if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
  12197. {
  12198. /*
  12199. Capturing subpatterns:
  12200. 1: Day name
  12201. 2: Day
  12202. 3: Month
  12203. 4: Year
  12204. 5: Hour
  12205. 6: Minute
  12206. 7: Second
  12207. 8: Timezone ±
  12208. 9: Timezone hours
  12209. 10: Timezone minutes
  12210. 11: Alphabetic timezone
  12211. */
  12212. // Find the month number
  12213. $month = $this->month[strtolower($match[3])];
  12214. // Numeric timezone
  12215. if ($match[8] !== '')
  12216. {
  12217. $timezone = $match[9] * 3600;
  12218. $timezone += $match[10] * 60;
  12219. if ($match[8] === '-')
  12220. {
  12221. $timezone = 0 - $timezone;
  12222. }
  12223. }
  12224. // Character timezone
  12225. elseif (isset($this->timezone[strtoupper($match[11])]))
  12226. {
  12227. $timezone = $this->timezone[strtoupper($match[11])];
  12228. }
  12229. // Assume everything else to be -0000
  12230. else
  12231. {
  12232. $timezone = 0;
  12233. }
  12234. // Deal with 2/3 digit years
  12235. if ($match[4] < 50)
  12236. {
  12237. $match[4] += 2000;
  12238. }
  12239. elseif ($match[4] < 1000)
  12240. {
  12241. $match[4] += 1900;
  12242. }
  12243. // Second is optional, if it is empty set it to zero
  12244. if ($match[7] !== '')
  12245. {
  12246. $second = $match[7];
  12247. }
  12248. else
  12249. {
  12250. $second = 0;
  12251. }
  12252. return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
  12253. }
  12254. else
  12255. {
  12256. return false;
  12257. }
  12258. }
  12259. /**
  12260. * Parse RFC850's date format
  12261. *
  12262. * @access protected
  12263. * @return int Timestamp
  12264. */
  12265. function date_rfc850($date)
  12266. {
  12267. static $pcre;
  12268. if (!$pcre)
  12269. {
  12270. $space = '[\x09\x20]+';
  12271. $day_name = $this->day_pcre;
  12272. $month = $this->month_pcre;
  12273. $day = '([0-9]{1,2})';
  12274. $year = $hour = $minute = $second = '([0-9]{2})';
  12275. $zone = '([A-Z]{1,5})';
  12276. $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
  12277. }
  12278. if (preg_match($pcre, $date, $match))
  12279. {
  12280. /*
  12281. Capturing subpatterns:
  12282. 1: Day name
  12283. 2: Day
  12284. 3: Month
  12285. 4: Year
  12286. 5: Hour
  12287. 6: Minute
  12288. 7: Second
  12289. 8: Timezone
  12290. */
  12291. // Month
  12292. $month = $this->month[strtolower($match[3])];
  12293. // Character timezone
  12294. if (isset($this->timezone[strtoupper($match[8])]))
  12295. {
  12296. $timezone = $this->timezone[strtoupper($match[8])];
  12297. }
  12298. // Assume everything else to be -0000
  12299. else
  12300. {
  12301. $timezone = 0;
  12302. }
  12303. // Deal with 2 digit year
  12304. if ($match[4] < 50)
  12305. {
  12306. $match[4] += 2000;
  12307. }
  12308. else
  12309. {
  12310. $match[4] += 1900;
  12311. }
  12312. return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
  12313. }
  12314. else
  12315. {
  12316. return false;
  12317. }
  12318. }
  12319. /**
  12320. * Parse C99's asctime()'s date format
  12321. *
  12322. * @access protected
  12323. * @return int Timestamp
  12324. */
  12325. function date_asctime($date)
  12326. {
  12327. static $pcre;
  12328. if (!$pcre)
  12329. {
  12330. $space = '[\x09\x20]+';
  12331. $wday_name = $this->day_pcre;
  12332. $mon_name = $this->month_pcre;
  12333. $day = '([0-9]{1,2})';
  12334. $hour = $sec = $min = '([0-9]{2})';
  12335. $year = '([0-9]{4})';
  12336. $terminator = '\x0A?\x00?';
  12337. $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
  12338. }
  12339. if (preg_match($pcre, $date, $match))
  12340. {
  12341. /*
  12342. Capturing subpatterns:
  12343. 1: Day name
  12344. 2: Month
  12345. 3: Day
  12346. 4: Hour
  12347. 5: Minute
  12348. 6: Second
  12349. 7: Year
  12350. */
  12351. $month = $this->month[strtolower($match[2])];
  12352. return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
  12353. }
  12354. else
  12355. {
  12356. return false;
  12357. }
  12358. }
  12359. /**
  12360. * Parse dates using strtotime()
  12361. *
  12362. * @access protected
  12363. * @return int Timestamp
  12364. */
  12365. function date_strtotime($date)
  12366. {
  12367. $strtotime = strtotime($date);
  12368. if ($strtotime === -1 || $strtotime === false)
  12369. {
  12370. return false;
  12371. }
  12372. else
  12373. {
  12374. return $strtotime;
  12375. }
  12376. }
  12377. }
  12378. /**
  12379. * Content-type sniffing
  12380. *
  12381. * @package SimplePie
  12382. */
  12383. class SimplePie_Content_Type_Sniffer
  12384. {
  12385. /**
  12386. * File object
  12387. *
  12388. * @var SimplePie_File
  12389. * @access private
  12390. */
  12391. var $file;
  12392. /**
  12393. * Create an instance of the class with the input file
  12394. *
  12395. * @access public
  12396. * @param SimplePie_Content_Type_Sniffer $file Input file
  12397. */
  12398. function SimplePie_Content_Type_Sniffer($file)
  12399. {
  12400. $this->file = $file;
  12401. }
  12402. /**
  12403. * Get the Content-Type of the specified file
  12404. *
  12405. * @access public
  12406. * @return string Actual Content-Type
  12407. */
  12408. function get_type()
  12409. {
  12410. if (isset($this->file->headers['content-type']))
  12411. {
  12412. if (!isset($this->file->headers['content-encoding'])
  12413. && ($this->file->headers['content-type'] === 'text/plain'
  12414. || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
  12415. || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
  12416. {
  12417. return $this->text_or_binary();
  12418. }
  12419. if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
  12420. {
  12421. $official = substr($this->file->headers['content-type'], 0, $pos);
  12422. }
  12423. else
  12424. {
  12425. $official = $this->file->headers['content-type'];
  12426. }
  12427. $official = strtolower($official);
  12428. if ($official === 'unknown/unknown'
  12429. || $official === 'application/unknown')
  12430. {
  12431. return $this->unknown();
  12432. }
  12433. elseif (substr($official, -4) === '+xml'
  12434. || $official === 'text/xml'
  12435. || $official === 'application/xml')
  12436. {
  12437. return $official;
  12438. }
  12439. elseif (substr($official, 0, 6) === 'image/')
  12440. {
  12441. if ($return = $this->image())
  12442. {
  12443. return $return;
  12444. }
  12445. else
  12446. {
  12447. return $official;
  12448. }
  12449. }
  12450. elseif ($official === 'text/html')
  12451. {
  12452. return $this->feed_or_html();
  12453. }
  12454. else
  12455. {
  12456. return $official;
  12457. }
  12458. }
  12459. else
  12460. {
  12461. return $this->unknown();
  12462. }
  12463. }
  12464. /**
  12465. * Sniff text or binary
  12466. *
  12467. * @access private
  12468. * @return string Actual Content-Type
  12469. */
  12470. function text_or_binary()
  12471. {
  12472. if (substr($this->file->body, 0, 2) === "\xFE\xFF"
  12473. || substr($this->file->body, 0, 2) === "\xFF\xFE"
  12474. || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
  12475. || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
  12476. {
  12477. return 'text/plain';
  12478. }
  12479. elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
  12480. {
  12481. return 'application/octect-stream';
  12482. }
  12483. else
  12484. {
  12485. return 'text/plain';
  12486. }
  12487. }
  12488. /**
  12489. * Sniff unknown
  12490. *
  12491. * @access private
  12492. * @return string Actual Content-Type
  12493. */
  12494. function unknown()
  12495. {
  12496. $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
  12497. if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
  12498. || strtolower(substr($this->file->body, $ws, 5)) === '<html'
  12499. || strtolower(substr($this->file->body, $ws, 7)) === '<script')
  12500. {
  12501. return 'text/html';
  12502. }
  12503. elseif (substr($this->file->body, 0, 5) === '%PDF-')
  12504. {
  12505. return 'application/pdf';
  12506. }
  12507. elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
  12508. {
  12509. return 'application/postscript';
  12510. }
  12511. elseif (substr($this->file->body, 0, 6) === 'GIF87a'
  12512. || substr($this->file->body, 0, 6) === 'GIF89a')
  12513. {
  12514. return 'image/gif';
  12515. }
  12516. elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
  12517. {
  12518. return 'image/png';
  12519. }
  12520. elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
  12521. {
  12522. return 'image/jpeg';
  12523. }
  12524. elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
  12525. {
  12526. return 'image/bmp';
  12527. }
  12528. else
  12529. {
  12530. return $this->text_or_binary();
  12531. }
  12532. }
  12533. /**
  12534. * Sniff images
  12535. *
  12536. * @access private
  12537. * @return string Actual Content-Type
  12538. */
  12539. function image()
  12540. {
  12541. if (substr($this->file->body, 0, 6) === 'GIF87a'
  12542. || substr($this->file->body, 0, 6) === 'GIF89a')
  12543. {
  12544. return 'image/gif';
  12545. }
  12546. elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
  12547. {
  12548. return 'image/png';
  12549. }
  12550. elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
  12551. {
  12552. return 'image/jpeg';
  12553. }
  12554. elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
  12555. {
  12556. return 'image/bmp';
  12557. }
  12558. else
  12559. {
  12560. return false;
  12561. }
  12562. }
  12563. /**
  12564. * Sniff HTML
  12565. *
  12566. * @access private
  12567. * @return string Actual Content-Type
  12568. */
  12569. function feed_or_html()
  12570. {
  12571. $len = strlen($this->file->body);
  12572. $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
  12573. while ($pos < $len)
  12574. {
  12575. switch ($this->file->body[$pos])
  12576. {
  12577. case "\x09":
  12578. case "\x0A":
  12579. case "\x0D":
  12580. case "\x20":
  12581. $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
  12582. continue 2;
  12583. case '<':
  12584. $pos++;
  12585. break;
  12586. default:
  12587. return 'text/html';
  12588. }
  12589. if (substr($this->file->body, $pos, 3) === '!--')
  12590. {
  12591. $pos += 3;
  12592. if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
  12593. {
  12594. $pos += 3;
  12595. }
  12596. else
  12597. {
  12598. return 'text/html';
  12599. }
  12600. }
  12601. elseif (substr($this->file->body, $pos, 1) === '!')
  12602. {
  12603. if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
  12604. {
  12605. $pos++;
  12606. }
  12607. else
  12608. {
  12609. return 'text/html';
  12610. }
  12611. }
  12612. elseif (substr($this->file->body, $pos, 1) === '?')
  12613. {
  12614. if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
  12615. {
  12616. $pos += 2;
  12617. }
  12618. else
  12619. {
  12620. return 'text/html';
  12621. }
  12622. }
  12623. elseif (substr($this->file->body, $pos, 3) === 'rss'
  12624. || substr($this->file->body, $pos, 7) === 'rdf:RDF')
  12625. {
  12626. return 'application/rss+xml';
  12627. }
  12628. elseif (substr($this->file->body, $pos, 4) === 'feed')
  12629. {
  12630. return 'application/atom+xml';
  12631. }
  12632. else
  12633. {
  12634. return 'text/html';
  12635. }
  12636. }
  12637. return 'text/html';
  12638. }
  12639. }
  12640. /**
  12641. * Parses the XML Declaration
  12642. *
  12643. * @package SimplePie
  12644. */
  12645. class SimplePie_XML_Declaration_Parser
  12646. {
  12647. /**
  12648. * XML Version
  12649. *
  12650. * @access public
  12651. * @var string
  12652. */
  12653. var $version = '1.0';
  12654. /**
  12655. * Encoding
  12656. *
  12657. * @access public
  12658. * @var string
  12659. */
  12660. var $encoding = 'UTF-8';
  12661. /**
  12662. * Standalone
  12663. *
  12664. * @access public
  12665. * @var bool
  12666. */
  12667. var $standalone = false;
  12668. /**
  12669. * Current state of the state machine
  12670. *
  12671. * @access private
  12672. * @var string
  12673. */
  12674. var $state = 'before_version_name';
  12675. /**
  12676. * Input data
  12677. *
  12678. * @access private
  12679. * @var string
  12680. */
  12681. var $data = '';
  12682. /**
  12683. * Input data length (to avoid calling strlen() everytime this is needed)
  12684. *
  12685. * @access private
  12686. * @var int
  12687. */
  12688. var $data_length = 0;
  12689. /**
  12690. * Current position of the pointer
  12691. *
  12692. * @var int
  12693. * @access private
  12694. */
  12695. var $position = 0;
  12696. /**
  12697. * Create an instance of the class with the input data
  12698. *
  12699. * @access public
  12700. * @param string $data Input data
  12701. */
  12702. function SimplePie_XML_Declaration_Parser($data)
  12703. {
  12704. $this->data = $data;
  12705. $this->data_length = strlen($this->data);
  12706. }
  12707. /**
  12708. * Parse the input data
  12709. *
  12710. * @access public
  12711. * @return bool true on success, false on failure
  12712. */
  12713. function parse()
  12714. {
  12715. while ($this->state && $this->state !== 'emit' && $this->has_data())
  12716. {
  12717. $state = $this->state;
  12718. $this->$state();
  12719. }
  12720. $this->data = '';
  12721. if ($this->state === 'emit')
  12722. {
  12723. return true;
  12724. }
  12725. else
  12726. {
  12727. $this->version = '';
  12728. $this->encoding = '';
  12729. $this->standalone = '';
  12730. return false;
  12731. }
  12732. }
  12733. /**
  12734. * Check whether there is data beyond the pointer
  12735. *
  12736. * @access private
  12737. * @return bool true if there is further data, false if not
  12738. */
  12739. function has_data()
  12740. {
  12741. return (bool) ($this->position < $this->data_length);
  12742. }
  12743. /**
  12744. * Advance past any whitespace
  12745. *
  12746. * @return int Number of whitespace characters passed
  12747. */
  12748. function skip_whitespace()
  12749. {
  12750. $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
  12751. $this->position += $whitespace;
  12752. return $whitespace;
  12753. }
  12754. /**
  12755. * Read value
  12756. */
  12757. function get_value()
  12758. {
  12759. $quote = substr($this->data, $this->position, 1);
  12760. if ($quote === '"' || $quote === "'")
  12761. {
  12762. $this->position++;
  12763. $len = strcspn($this->data, $quote, $this->position);
  12764. if ($this->has_data())
  12765. {
  12766. $value = substr($this->data, $this->position, $len);
  12767. $this->position += $len + 1;
  12768. return $value;
  12769. }
  12770. }
  12771. return false;
  12772. }
  12773. function before_version_name()
  12774. {
  12775. if ($this->skip_whitespace())
  12776. {
  12777. $this->state = 'version_name';
  12778. }
  12779. else
  12780. {
  12781. $this->state = false;
  12782. }
  12783. }
  12784. function version_name()
  12785. {
  12786. if (substr($this->data, $this->position, 7) === 'version')
  12787. {
  12788. $this->position += 7;
  12789. $this->skip_whitespace();
  12790. $this->state = 'version_equals';
  12791. }
  12792. else
  12793. {
  12794. $this->state = false;
  12795. }
  12796. }
  12797. function version_equals()
  12798. {
  12799. if (substr($this->data, $this->position, 1) === '=')
  12800. {
  12801. $this->position++;
  12802. $this->skip_whitespace();
  12803. $this->state = 'version_value';
  12804. }
  12805. else
  12806. {
  12807. $this->state = false;
  12808. }
  12809. }
  12810. function version_value()
  12811. {
  12812. if ($this->version = $this->get_value())
  12813. {
  12814. $this->skip_whitespace();
  12815. if ($this->has_data())
  12816. {
  12817. $this->state = 'encoding_name';
  12818. }
  12819. else
  12820. {
  12821. $this->state = 'emit';
  12822. }
  12823. }
  12824. else
  12825. {
  12826. $this->state = 'standalone_name';
  12827. }
  12828. }
  12829. function encoding_name()
  12830. {
  12831. if (substr($this->data, $this->position, 8) === 'encoding')
  12832. {
  12833. $this->position += 8;
  12834. $this->skip_whitespace();
  12835. $this->state = 'encoding_equals';
  12836. }
  12837. else
  12838. {
  12839. $this->state = false;
  12840. }
  12841. }
  12842. function encoding_equals()
  12843. {
  12844. if (substr($this->data, $this->position, 1) === '=')
  12845. {
  12846. $this->position++;
  12847. $this->skip_whitespace();
  12848. $this->state = 'encoding_value';
  12849. }
  12850. else
  12851. {
  12852. $this->state = false;
  12853. }
  12854. }
  12855. function encoding_value()
  12856. {
  12857. if ($this->encoding = $this->get_value())
  12858. {
  12859. $this->skip_whitespace();
  12860. if ($this->has_data())
  12861. {
  12862. $this->state = 'standalone_name';
  12863. }
  12864. else
  12865. {
  12866. $this->state = 'emit';
  12867. }
  12868. }
  12869. else
  12870. {
  12871. $this->state = false;
  12872. }
  12873. }
  12874. function standalone_name()
  12875. {
  12876. if (substr($this->data, $this->position, 10) === 'standalone')
  12877. {
  12878. $this->position += 10;
  12879. $this->skip_whitespace();
  12880. $this->state = 'standalone_equals';
  12881. }
  12882. else
  12883. {
  12884. $this->state = false;
  12885. }
  12886. }
  12887. function standalone_equals()
  12888. {
  12889. if (substr($this->data, $this->position, 1) === '=')
  12890. {
  12891. $this->position++;
  12892. $this->skip_whitespace();
  12893. $this->state = 'standalone_value';
  12894. }
  12895. else
  12896. {
  12897. $this->state = false;
  12898. }
  12899. }
  12900. function standalone_value()
  12901. {
  12902. if ($standalone = $this->get_value())
  12903. {
  12904. switch ($standalone)
  12905. {
  12906. case 'yes':
  12907. $this->standalone = true;
  12908. break;
  12909. case 'no':
  12910. $this->standalone = false;
  12911. break;
  12912. default:
  12913. $this->state = false;
  12914. return;
  12915. }
  12916. $this->skip_whitespace();
  12917. if ($this->has_data())
  12918. {
  12919. $this->state = false;
  12920. }
  12921. else
  12922. {
  12923. $this->state = 'emit';
  12924. }
  12925. }
  12926. else
  12927. {
  12928. $this->state = false;
  12929. }
  12930. }
  12931. }
  12932. class SimplePie_Locator
  12933. {
  12934. var $useragent;
  12935. var $timeout;
  12936. var $file;
  12937. var $local = array();
  12938. var $elsewhere = array();
  12939. var $file_class = 'SimplePie_File';
  12940. var $cached_entities = array();
  12941. var $http_base;
  12942. var $base;
  12943. var $base_location = 0;
  12944. var $checked_feeds = 0;
  12945. var $max_checked_feeds = 10;
  12946. var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
  12947. function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
  12948. {
  12949. $this->file =& $file;
  12950. $this->file_class = $file_class;
  12951. $this->useragent = $useragent;
  12952. $this->timeout = $timeout;
  12953. $this->max_checked_feeds = $max_checked_feeds;
  12954. $this->content_type_sniffer_class = $content_type_sniffer_class;
  12955. }
  12956. function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
  12957. {
  12958. if ($this->is_feed($this->file))
  12959. {
  12960. return $this->file;
  12961. }
  12962. if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
  12963. {
  12964. $sniffer = new $this->content_type_sniffer_class($this->file);
  12965. if ($sniffer->get_type() !== 'text/html')
  12966. {
  12967. return null;
  12968. }
  12969. }
  12970. if ($type & ~SIMPLEPIE_LOCATOR_NONE)
  12971. {
  12972. $this->get_base();
  12973. }
  12974. if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
  12975. {
  12976. return $working[0];
  12977. }
  12978. if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
  12979. {
  12980. if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
  12981. {
  12982. return $working;
  12983. }
  12984. if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
  12985. {
  12986. return $working;
  12987. }
  12988. if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
  12989. {
  12990. return $working;
  12991. }
  12992. if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
  12993. {
  12994. return $working;
  12995. }
  12996. }
  12997. return null;
  12998. }
  12999. function is_feed(&$file)
  13000. {
  13001. if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
  13002. {
  13003. $sniffer = new $this->content_type_sniffer_class($file);
  13004. $sniffed = $sniffer->get_type();
  13005. if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
  13006. {
  13007. return true;
  13008. }
  13009. else
  13010. {
  13011. return false;
  13012. }
  13013. }
  13014. elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
  13015. {
  13016. return true;
  13017. }
  13018. else
  13019. {
  13020. return false;
  13021. }
  13022. }
  13023. function get_base()
  13024. {
  13025. $this->http_base = $this->file->url;
  13026. $this->base = $this->http_base;
  13027. $elements = SimplePie_Misc::get_element('base', $this->file->body);
  13028. foreach ($elements as $element)
  13029. {
  13030. if ($element['attribs']['href']['data'] !== '')
  13031. {
  13032. $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
  13033. $this->base_location = $element['offset'];
  13034. break;
  13035. }
  13036. }
  13037. }
  13038. function autodiscovery()
  13039. {
  13040. $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));
  13041. $done = array();
  13042. $feeds = array();
  13043. foreach ($links as $link)
  13044. {
  13045. if ($this->checked_feeds === $this->max_checked_feeds)
  13046. {
  13047. break;
  13048. }
  13049. if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
  13050. {
  13051. $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
  13052. if ($this->base_location < $link['offset'])
  13053. {
  13054. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
  13055. }
  13056. else
  13057. {
  13058. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
  13059. }
  13060. 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]))
  13061. {
  13062. $this->checked_feeds++;
  13063. $feed = new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
  13064. 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))
  13065. {
  13066. $feeds[$href] = $feed;
  13067. }
  13068. }
  13069. $done[] = $href;
  13070. }
  13071. }
  13072. if (!empty($feeds))
  13073. {
  13074. return array_values($feeds);
  13075. }
  13076. else {
  13077. return null;
  13078. }
  13079. }
  13080. function get_links()
  13081. {
  13082. $links = SimplePie_Misc::get_element('a', $this->file->body);
  13083. foreach ($links as $link)
  13084. {
  13085. if (isset($link['attribs']['href']['data']))
  13086. {
  13087. $href = trim($link['attribs']['href']['data']);
  13088. $parsed = SimplePie_Misc::parse_url($href);
  13089. if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
  13090. {
  13091. if ($this->base_location < $link['offset'])
  13092. {
  13093. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
  13094. }
  13095. else
  13096. {
  13097. $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
  13098. }
  13099. $current = SimplePie_Misc::parse_url($this->file->url);
  13100. if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
  13101. {
  13102. $this->local[] = $href;
  13103. }
  13104. else
  13105. {
  13106. $this->elsewhere[] = $href;
  13107. }
  13108. }
  13109. }
  13110. }
  13111. $this->local = array_unique($this->local);
  13112. $this->elsewhere = array_unique($this->elsewhere);
  13113. if (!empty($this->local) || !empty($this->elsewhere))
  13114. {
  13115. return true;
  13116. }
  13117. return null;
  13118. }
  13119. function extension(&$array)
  13120. {
  13121. foreach ($array as $key => $value)
  13122. {
  13123. if ($this->checked_feeds === $this->max_checked_feeds)
  13124. {
  13125. break;
  13126. }
  13127. if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
  13128. {
  13129. $this->checked_feeds++;
  13130. $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
  13131. 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))
  13132. {
  13133. return $feed;
  13134. }
  13135. else
  13136. {
  13137. unset($array[$key]);
  13138. }
  13139. }
  13140. }
  13141. return null;
  13142. }
  13143. function body(&$array)
  13144. {
  13145. foreach ($array as $key => $value)
  13146. {
  13147. if ($this->checked_feeds === $this->max_checked_feeds)
  13148. {
  13149. break;
  13150. }
  13151. if (preg_match('/(rss|rdf|atom|xml)/i', $value))
  13152. {
  13153. $this->checked_feeds++;
  13154. $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
  13155. 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))
  13156. {
  13157. return $feed;
  13158. }
  13159. else
  13160. {
  13161. unset($array[$key]);
  13162. }
  13163. }
  13164. }
  13165. return null;
  13166. }
  13167. }
  13168. class SimplePie_Parser
  13169. {
  13170. var $error_code;
  13171. var $error_string;
  13172. var $current_line;
  13173. var $current_column;
  13174. var $current_byte;
  13175. var $separator = ' ';
  13176. var $namespace = array('');
  13177. var $element = array('');
  13178. var $xml_base = array('');
  13179. var $xml_base_explicit = array(false);
  13180. var $xml_lang = array('');
  13181. var $data = array();
  13182. var $datas = array(array());
  13183. var $current_xhtml_construct = -1;
  13184. var $encoding;
  13185. function parse(&$data, $encoding)
  13186. {
  13187. // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
  13188. if (strtoupper($encoding) === 'US-ASCII')
  13189. {
  13190. $this->encoding = 'UTF-8';
  13191. }
  13192. else
  13193. {
  13194. $this->encoding = $encoding;
  13195. }
  13196. // Strip BOM:
  13197. // UTF-32 Big Endian BOM
  13198. if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
  13199. {
  13200. $data = substr($data, 4);
  13201. }
  13202. // UTF-32 Little Endian BOM
  13203. elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
  13204. {
  13205. $data = substr($data, 4);
  13206. }
  13207. // UTF-16 Big Endian BOM
  13208. elseif (substr($data, 0, 2) === "\xFE\xFF")
  13209. {
  13210. $data = substr($data, 2);
  13211. }
  13212. // UTF-16 Little Endian BOM
  13213. elseif (substr($data, 0, 2) === "\xFF\xFE")
  13214. {
  13215. $data = substr($data, 2);
  13216. }
  13217. // UTF-8 BOM
  13218. elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
  13219. {
  13220. $data = substr($data, 3);
  13221. }
  13222. if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
  13223. {
  13224. $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
  13225. if ($declaration->parse())
  13226. {
  13227. $data = substr($data, $pos + 2);
  13228. $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
  13229. }
  13230. else
  13231. {
  13232. $this->error_string = 'SimplePie bug! Please report this!';
  13233. return false;
  13234. }
  13235. }
  13236. $return = true;
  13237. static $xml_is_sane = null;
  13238. if ($xml_is_sane === null)
  13239. {
  13240. $parser_check = xml_parser_create();
  13241. xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
  13242. xml_parser_free($parser_check);
  13243. $xml_is_sane = isset($values[0]['value']);
  13244. }
  13245. // Create the parser
  13246. if ($xml_is_sane)
  13247. {
  13248. $xml = xml_parser_create_ns($this->encoding, $this->separator);
  13249. xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
  13250. xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
  13251. xml_set_object($xml, $this);
  13252. xml_set_character_data_handler($xml, 'cdata');
  13253. xml_set_element_handler($xml, 'tag_open', 'tag_close');
  13254. // Parse!
  13255. if (!xml_parse($xml, $data, true))
  13256. {
  13257. $this->error_code = xml_get_error_code($xml);
  13258. $this->error_string = xml_error_string($this->error_code);
  13259. $return = false;
  13260. }
  13261. $this->current_line = xml_get_current_line_number($xml);
  13262. $this->current_column = xml_get_current_column_number($xml);
  13263. $this->current_byte = xml_get_current_byte_index($xml);
  13264. xml_parser_free($xml);
  13265. return $return;
  13266. }
  13267. else
  13268. {
  13269. libxml_clear_errors();
  13270. $xml = new XMLReader();
  13271. $xml->xml($data);
  13272. while (@$xml->read())
  13273. {
  13274. switch ($xml->nodeType)
  13275. {
  13276. case constant('XMLReader::END_ELEMENT'):
  13277. if ($xml->namespaceURI !== '')
  13278. {
  13279. $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
  13280. }
  13281. else
  13282. {
  13283. $tagName = $xml->localName;
  13284. }
  13285. $this->tag_close(null, $tagName);
  13286. break;
  13287. case constant('XMLReader::ELEMENT'):
  13288. $empty = $xml->isEmptyElement;
  13289. if ($xml->namespaceURI !== '')
  13290. {
  13291. $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
  13292. }
  13293. else
  13294. {
  13295. $tagName = $xml->localName;
  13296. }
  13297. $attributes = array();
  13298. while ($xml->moveToNextAttribute())
  13299. {
  13300. if ($xml->namespaceURI !== '')
  13301. {
  13302. $attrName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
  13303. }
  13304. else
  13305. {
  13306. $attrName = $xml->localName;
  13307. }
  13308. $attributes[$attrName] = $xml->value;
  13309. }
  13310. $this->tag_open(null, $tagName, $attributes);
  13311. if ($empty)
  13312. {
  13313. $this->tag_close(null, $tagName);
  13314. }
  13315. break;
  13316. case constant('XMLReader::TEXT'):
  13317. case constant('XMLReader::CDATA'):
  13318. $this->cdata(null, $xml->value);
  13319. break;
  13320. }
  13321. }
  13322. if ($error = libxml_get_last_error())
  13323. {
  13324. $this->error_code = $error->code;
  13325. $this->error_string = $error->message;
  13326. $this->current_line = $error->line;
  13327. $this->current_column = $error->column;
  13328. return false;
  13329. }
  13330. else
  13331. {
  13332. return true;
  13333. }
  13334. }
  13335. }
  13336. function get_error_code()
  13337. {
  13338. return $this->error_code;
  13339. }
  13340. function get_error_string()
  13341. {
  13342. return $this->error_string;
  13343. }
  13344. function get_current_line()
  13345. {
  13346. return $this->current_line;
  13347. }
  13348. function get_current_column()
  13349. {
  13350. return $this->current_column;
  13351. }
  13352. function get_current_byte()
  13353. {
  13354. return $this->current_byte;
  13355. }
  13356. function get_data()
  13357. {
  13358. return $this->data;
  13359. }
  13360. function tag_open($parser, $tag, $attributes)
  13361. {
  13362. list($this->namespace[], $this->element[]) = $this->split_ns($tag);
  13363. $attribs = array();
  13364. foreach ($attributes as $name => $value)
  13365. {
  13366. list($attrib_namespace, $attribute) = $this->split_ns($name);
  13367. $attribs[$attrib_namespace][$attribute] = $value;
  13368. }
  13369. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
  13370. {
  13371. $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
  13372. $this->xml_base_explicit[] = true;
  13373. }
  13374. else
  13375. {
  13376. $this->xml_base[] = end($this->xml_base);
  13377. $this->xml_base_explicit[] = end($this->xml_base_explicit);
  13378. }
  13379. if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
  13380. {
  13381. $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
  13382. }
  13383. else
  13384. {
  13385. $this->xml_lang[] = end($this->xml_lang);
  13386. }
  13387. if ($this->current_xhtml_construct >= 0)
  13388. {
  13389. $this->current_xhtml_construct++;
  13390. if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
  13391. {
  13392. $this->data['data'] .= '<' . end($this->element);
  13393. if (isset($attribs['']))
  13394. {
  13395. foreach ($attribs[''] as $name => $value)
  13396. {
  13397. $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
  13398. }
  13399. }
  13400. $this->data['data'] .= '>';
  13401. }
  13402. }
  13403. else
  13404. {
  13405. $this->datas[] =& $this->data;
  13406. $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
  13407. $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));
  13408. 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')
  13409. || (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'))
  13410. {
  13411. $this->current_xhtml_construct = 0;
  13412. }
  13413. }
  13414. }
  13415. function cdata($parser, $cdata)
  13416. {
  13417. if ($this->current_xhtml_construct >= 0)
  13418. {
  13419. $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
  13420. }
  13421. else
  13422. {
  13423. $this->data['data'] .= $cdata;
  13424. }
  13425. }
  13426. function tag_close($parser, $tag)
  13427. {
  13428. if ($this->current_xhtml_construct >= 0)
  13429. {
  13430. $this->current_xhtml_construct--;
  13431. 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')))
  13432. {
  13433. $this->data['data'] .= '</' . end($this->element) . '>';
  13434. }
  13435. }
  13436. if ($this->current_xhtml_construct === -1)
  13437. {
  13438. $this->data =& $this->datas[count($this->datas) - 1];
  13439. array_pop($this->datas);
  13440. }
  13441. array_pop($this->element);
  13442. array_pop($this->namespace);
  13443. array_pop($this->xml_base);
  13444. array_pop($this->xml_base_explicit);
  13445. array_pop($this->xml_lang);
  13446. }
  13447. function split_ns($string)
  13448. {
  13449. static $cache = array();
  13450. if (!isset($cache[$string]))
  13451. {
  13452. if ($pos = strpos($string, $this->separator))
  13453. {
  13454. static $separator_length;
  13455. if (!$separator_length)
  13456. {
  13457. $separator_length = strlen($this->separator);
  13458. }
  13459. $namespace = substr($string, 0, $pos);
  13460. $local_name = substr($string, $pos + $separator_length);
  13461. if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
  13462. {
  13463. $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
  13464. }
  13465. // Normalize the Media RSS namespaces
  13466. if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
  13467. {
  13468. $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
  13469. }
  13470. $cache[$string] = array($namespace, $local_name);
  13471. }
  13472. else
  13473. {
  13474. $cache[$string] = array('', $string);
  13475. }
  13476. }
  13477. return $cache[$string];
  13478. }
  13479. }
  13480. /**
  13481. * @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
  13482. */
  13483. class SimplePie_Sanitize
  13484. {
  13485. // Private vars
  13486. var $base;
  13487. // Options
  13488. var $remove_div = true;
  13489. var $image_handler = '';
  13490. var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
  13491. var $encode_instead_of_strip = false;
  13492. var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
  13493. var $strip_comments = false;
  13494. var $output_encoding = 'UTF-8';
  13495. var $enable_cache = true;
  13496. var $cache_location = './cache';
  13497. var $cache_name_function = 'md5';
  13498. var $cache_class = 'SimplePie_Cache';
  13499. var $file_class = 'SimplePie_File';
  13500. var $timeout = 10;
  13501. var $useragent = '';
  13502. var $force_fsockopen = false;
  13503. var $replace_url_attributes = array(
  13504. 'a' => 'href',
  13505. 'area' => 'href',
  13506. 'blockquote' => 'cite',
  13507. 'del' => 'cite',
  13508. 'form' => 'action',
  13509. 'img' => array('longdesc', 'src'),
  13510. 'input' => 'src',
  13511. 'ins' => 'cite',
  13512. 'q' => 'cite'
  13513. );
  13514. function remove_div($enable = true)
  13515. {
  13516. $this->remove_div = (bool) $enable;
  13517. }
  13518. function set_image_handler($page = false)
  13519. {
  13520. if ($page)
  13521. {
  13522. $this->image_handler = (string) $page;
  13523. }
  13524. else
  13525. {
  13526. $this->image_handler = false;
  13527. }
  13528. }
  13529. function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
  13530. {
  13531. if (isset($enable_cache))
  13532. {
  13533. $this->enable_cache = (bool) $enable_cache;
  13534. }
  13535. if ($cache_location)
  13536. {
  13537. $this->cache_location = (string) $cache_location;
  13538. }
  13539. if ($cache_name_function)
  13540. {
  13541. $this->cache_name_function = (string) $cache_name_function;
  13542. }
  13543. if ($cache_class)
  13544. {
  13545. $this->cache_class = (string) $cache_class;
  13546. }
  13547. }
  13548. function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
  13549. {
  13550. if ($file_class)
  13551. {
  13552. $this->file_class = (string) $file_class;
  13553. }
  13554. if ($timeout)
  13555. {
  13556. $this->timeout = (string) $timeout;
  13557. }
  13558. if ($useragent)
  13559. {
  13560. $this->useragent = (string) $useragent;
  13561. }
  13562. if ($force_fsockopen)
  13563. {
  13564. $this->force_fsockopen = (string) $force_fsockopen;
  13565. }
  13566. }
  13567. function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
  13568. {
  13569. if ($tags)
  13570. {
  13571. if (is_array($tags))
  13572. {
  13573. $this->strip_htmltags = $tags;
  13574. }
  13575. else
  13576. {
  13577. $this->strip_htmltags = explode(',', $tags);
  13578. }
  13579. }
  13580. else
  13581. {
  13582. $this->strip_htmltags = false;
  13583. }
  13584. }
  13585. function encode_instead_of_strip($encode = false)
  13586. {
  13587. $this->encode_instead_of_strip = (bool) $encode;
  13588. }
  13589. function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
  13590. {
  13591. if ($attribs)
  13592. {
  13593. if (is_array($attribs))
  13594. {
  13595. $this->strip_attributes = $attribs;
  13596. }
  13597. else
  13598. {
  13599. $this->strip_attributes = explode(',', $attribs);
  13600. }
  13601. }
  13602. else
  13603. {
  13604. $this->strip_attributes = false;
  13605. }
  13606. }
  13607. function strip_comments($strip = false)
  13608. {
  13609. $this->strip_comments = (bool) $strip;
  13610. }
  13611. function set_output_encoding($encoding = 'UTF-8')
  13612. {
  13613. $this->output_encoding = (string) $encoding;
  13614. }
  13615. /**
  13616. * Set element/attribute key/value pairs of HTML attributes
  13617. * containing URLs that need to be resolved relative to the feed
  13618. *
  13619. * @access public
  13620. * @since 1.0
  13621. * @param array $element_attribute Element/attribute key/value pairs
  13622. */
  13623. 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'))
  13624. {
  13625. $this->replace_url_attributes = (array) $element_attribute;
  13626. }
  13627. function sanitize($data, $type, $base = '')
  13628. {
  13629. $data = trim($data);
  13630. if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
  13631. {
  13632. if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
  13633. {
  13634. 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))
  13635. {
  13636. $type |= SIMPLEPIE_CONSTRUCT_HTML;
  13637. }
  13638. else
  13639. {
  13640. $type |= SIMPLEPIE_CONSTRUCT_TEXT;
  13641. }
  13642. }
  13643. if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
  13644. {
  13645. $data = base64_decode($data);
  13646. }
  13647. if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
  13648. {
  13649. if ($this->remove_div)
  13650. {
  13651. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
  13652. $data = preg_replace('/<\/div>$/', '', $data);
  13653. }
  13654. else
  13655. {
  13656. $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
  13657. }
  13658. }
  13659. if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
  13660. {
  13661. // Strip comments
  13662. if ($this->strip_comments)
  13663. {
  13664. $data = SimplePie_Misc::strip_comments($data);
  13665. }
  13666. // Strip out HTML tags and attributes that might cause various security problems.
  13667. // Based on recommendations by Mark Pilgrim at:
  13668. // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
  13669. if ($this->strip_htmltags)
  13670. {
  13671. foreach ($this->strip_htmltags as $tag)
  13672. {
  13673. $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
  13674. while (preg_match($pcre, $data))
  13675. {
  13676. $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
  13677. }
  13678. }
  13679. }
  13680. if ($this->strip_attributes)
  13681. {
  13682. foreach ($this->strip_attributes as $attrib)
  13683. {
  13684. $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);
  13685. }
  13686. }
  13687. // Replace relative URLs
  13688. $this->base = $base;
  13689. foreach ($this->replace_url_attributes as $element => $attributes)
  13690. {
  13691. $data = $this->replace_urls($data, $element, $attributes);
  13692. }
  13693. // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
  13694. if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
  13695. {
  13696. $images = SimplePie_Misc::get_element('img', $data);
  13697. foreach ($images as $img)
  13698. {
  13699. if (isset($img['attribs']['src']['data']))
  13700. {
  13701. $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
  13702. $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
  13703. if ($cache->load())
  13704. {
  13705. $img['attribs']['src']['data'] = $this->image_handler . $image_url;
  13706. $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
  13707. }
  13708. else
  13709. {
  13710. $file = new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
  13711. $headers = $file->headers;
  13712. if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
  13713. {
  13714. if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
  13715. {
  13716. $img['attribs']['src']['data'] = $this->image_handler . $image_url;
  13717. $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
  13718. }
  13719. else
  13720. {
  13721. trigger_error("$this->cache_location is not writeable", E_USER_WARNING);
  13722. }
  13723. }
  13724. }
  13725. }
  13726. }
  13727. }
  13728. // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
  13729. $data = trim($data);
  13730. }
  13731. if ($type & SIMPLEPIE_CONSTRUCT_IRI)
  13732. {
  13733. $data = SimplePie_Misc::absolutize_url($data, $base);
  13734. }
  13735. if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
  13736. {
  13737. $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
  13738. }
  13739. if ($this->output_encoding !== 'UTF-8')
  13740. {
  13741. $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
  13742. }
  13743. }
  13744. return $data;
  13745. }
  13746. function replace_urls($data, $tag, $attributes)
  13747. {
  13748. if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
  13749. {
  13750. $elements = SimplePie_Misc::get_element($tag, $data);
  13751. foreach ($elements as $element)
  13752. {
  13753. if (is_array($attributes))
  13754. {
  13755. foreach ($attributes as $attribute)
  13756. {
  13757. if (isset($element['attribs'][$attribute]['data']))
  13758. {
  13759. $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
  13760. $new_element = SimplePie_Misc::element_implode($element);
  13761. $data = str_replace($element['full'], $new_element, $data);
  13762. $element['full'] = $new_element;
  13763. }
  13764. }
  13765. }
  13766. elseif (isset($element['attribs'][$attributes]['data']))
  13767. {
  13768. $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
  13769. $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
  13770. }
  13771. }
  13772. }
  13773. return $data;
  13774. }
  13775. function do_strip_htmltags($match)
  13776. {
  13777. if ($this->encode_instead_of_strip)
  13778. {
  13779. if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  13780. {
  13781. $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
  13782. $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
  13783. return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
  13784. }
  13785. else
  13786. {
  13787. return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
  13788. }
  13789. }
  13790. elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
  13791. {
  13792. return $match[4];
  13793. }
  13794. else
  13795. {
  13796. return '';
  13797. }
  13798. }
  13799. }
  13800. ?>