PageRenderTime 52ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/domit/xml_domit_rss_shared.php

https://bitbucket.org/asosso/joomla15
PHP | 1025 lines | 519 code | 133 blank | 373 comment | 105 complexity | 75318f4feda2990d6ecf1504c64d60b6 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. <?php
  2. /**
  3. * @package domit-rss
  4. * @version 0.51
  5. * @copyright (C) 2004 John Heinstein. All rights reserved
  6. * @license http://www.gnu.org/copyleft/lesser.html LGPL License
  7. * @author John Heinstein <johnkarl@nbnet.nb.ca>
  8. * @link http://www.engageinteractive.com/domitrss/ DOMIT! RSS Home Page
  9. * DOMIT! RSS is Free Software
  10. **/
  11. /** channel constant */
  12. define('DOMIT_RSS_ELEMENT_CHANNEL', 'channel');
  13. /** item constant */
  14. define('DOMIT_RSS_ELEMENT_ITEM', 'item');
  15. /** title constant */
  16. define('DOMIT_RSS_ELEMENT_TITLE', 'title');
  17. /** link constant */
  18. define('DOMIT_RSS_ELEMENT_LINK', 'link');
  19. /** description constant */
  20. define('DOMIT_RSS_ELEMENT_DESCRIPTION', 'description');
  21. /** version constant */
  22. define('DOMIT_RSS_ATTR_VERSION', 'version');
  23. /** name of array containing list of existing RSS items */
  24. define('DOMIT_RSS_ARRAY_ITEMS', 'item'); //formerly named 'domit_rss_items'
  25. /** name of array containing list of existing RSS channels */
  26. define('DOMIT_RSS_ARRAY_CHANNELS', 'channel'); //formerly named 'domit_rss_channels'
  27. /** name of array containing list of existing RSS categories */
  28. define('DOMIT_RSS_ARRAY_CATEGORIES', 'category'); //formerly named 'domit_rss_categories'
  29. /** DOMIT RSS error, attempt to call an abstract method */
  30. define('DOMIT_RSS_ABSTRACT_METHOD_INVOCATION_ERR', 101);
  31. /** DOMIT RSS error, specified element not present */
  32. define('DOMIT_RSS_ELEMENT_NOT_FOUND_ERR', 102);
  33. /** DOMIT RSS error, specified attribute not present */
  34. define('DOMIT_RSS_ATTR_NOT_FOUND_ERR', 103);
  35. /** DOMIT RSS error, parsing failed */
  36. define('DOMIT_RSS_PARSING_ERR', 104);
  37. //DOMIT! RSS Error Modes
  38. /** continue on error */
  39. define('DOMIT_RSS_ONERROR_CONTINUE', 1);
  40. /** die on error */
  41. define('DOMIT_RSS_ONERROR_DIE', 2);
  42. /** die on error */
  43. define('DOMIT_RSS_ONERROR_RETURN', 3);
  44. /**
  45. * The base class of all DOMIT! RSS objects
  46. *
  47. * @package domit-rss
  48. * @author John Heinstein <johnkarl@nbnet.nb.ca>
  49. */
  50. class xml_domit_rss_base {
  51. /** @var Object The underlying DOMIT! node of the element */
  52. var $node = null;
  53. /** @var array A list of valid RSS defined child elements */
  54. var $rssDefinedElements = array();
  55. /**
  56. * Retrieves the underlying DOMIT node
  57. * @return Object The underlying DOMIT node
  58. */
  59. function getNode() {
  60. return $this->node;
  61. } //getNode
  62. /**
  63. * Retrieves the text of the named attribute, checking first if the attribute exists
  64. * @param string The attribute name
  65. * @return string The attribute value, or an empty string
  66. */
  67. function getAttribute($attr) {
  68. if ($this->node->hasAttribute($attr)) {
  69. return $this->node->getAttribute($attr);
  70. }
  71. return "";
  72. } //getAttribute
  73. /**
  74. * Checks whether the named attribute exists
  75. * @param string The attribute name
  76. * @return boolean True if the attribute exists
  77. */
  78. function hasAttribute($attr) {
  79. return (($this->node->nodeType == DOMIT_ELEMENT_NODE) && $this->node->hasAttribute($attr));
  80. } //hasAttribute
  81. /**
  82. * Tests whether the named element is predefined by the RSS spec
  83. * @param string The element name
  84. * @return boolean True if the element is predefined by the RSS spec
  85. */
  86. function isRSSDefined($elementName) {
  87. $isDefined = false;
  88. foreach ($this->rssDefinedElements as $key => $value) {
  89. if ($elementName == $value) {
  90. $isDefined = true;
  91. break;
  92. }
  93. }
  94. return $isDefined;
  95. } //isRSSDefined
  96. /**
  97. * Tests whether the named element has a single child text node
  98. * @param string The element name
  99. * @return boolean True if the named element has a single child text node
  100. */
  101. function isSimpleRSSElement($elementName) {
  102. $elementName = strtolower($elementName);
  103. if (isset($this->DOMIT_RSS_indexer[$elementName])) {
  104. return (get_class($this->getElement($elementName)) == 'xml_domit_rss_simpleelement');
  105. }
  106. else {
  107. return false;
  108. }
  109. } //isSimpleRSSElement
  110. /**
  111. * Generates a string representation of the node and its children
  112. * @param boolean True if HTML readable output is desired
  113. * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities
  114. * @return string The string representation
  115. */
  116. function get($htmlSafe = false, $subEntities = false) {
  117. return $this->node->toString($htmlSafe, $subEntities);
  118. } //toString
  119. /**
  120. * Generates a normalized (formatted for readability) representation of the node and its children
  121. * @param boolean True if HTML readable output is desired
  122. * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities
  123. * @return string The formatted string representation
  124. */
  125. function toNormalizedString($htmlSafe = false, $subEntities = false) {
  126. return $this->node->toNormalizedString($htmlSafe, $subEntities);
  127. } //toNormalizedString
  128. } //xml_domit_rss_base
  129. /**
  130. * Represents a collection of custom RSS elements, e.g. a set of dc:creator entries
  131. *
  132. * @package domit-rss
  133. * @subpackage domit-rss-main
  134. * @author John Heinstein <johnkarl@nbnet.nb.ca>
  135. */
  136. class xml_domit_rss_collection extends xml_domit_rss_elementindexer {
  137. /** @var array An array holding the collection of custom elements */
  138. var $elements = array();
  139. /** @var int The number of custom elements in the collection */
  140. var $elementCount = 0;
  141. /**
  142. * Adds a custom RSS element (DOM node) to the collection
  143. * @param Object A DOM node representing a custom RSS element
  144. */
  145. function addElement(&$node) {
  146. $this->elements[] =& $node;
  147. $this->elementCount++;
  148. } //addElement
  149. /**
  150. * Retrieves the element at the specified index
  151. * @param int The index of the requested custom RSS element
  152. * @return Object The DOMIT node representing the requested element
  153. */
  154. function &getElementAt($index) {
  155. return $this->elements[$index];
  156. } //getElementAt
  157. /**
  158. * Retrieves the element at the specified index (alias for getElementAt)
  159. * @param int The index of the requested custom RSS element
  160. * @return Object The DOMIT node representing the requested element
  161. */
  162. function &getElement($index) {
  163. return $this->getElementAt($index);
  164. } //getElement
  165. /**
  166. * Returns the number of elements in the collection
  167. * @return int The number of members in the collection
  168. */
  169. function getElementCount() {
  170. return $this->elementCount;
  171. } //getElementCount
  172. /**
  173. * Gets a text representation of the collection (applies the toString method to each member and concatenates)
  174. * @return string The element text
  175. */
  176. function getElementText() {
  177. $total = $this->getElementCount();
  178. $result = '';
  179. for ($i = 0; $i < $total; $i++) {
  180. $result .= $currElement->toString();
  181. }
  182. return $result;
  183. } //getElementText
  184. } //xml_domit_rss_collection
  185. /**
  186. * Provides indexing functionality to RSS classes
  187. *
  188. * @package domit-rss
  189. * @author John Heinstein <johnkarl@nbnet.nb.ca>
  190. */
  191. class xml_domit_rss_elementindexer extends xml_domit_rss_base {
  192. /** @var Array Name based index to RSS elements */
  193. var $DOMIT_RSS_indexer = array();
  194. /** @var Array Numerical index to RSS elements; for optimization purposes, only set if requested by getElementAt */
  195. var $DOMIT_RSS_numericalIndexer;
  196. /**
  197. * Performs generic initialization of elements
  198. */
  199. function _init(){
  200. $total = $this->node->childCount;
  201. for($i = 0; $i < $total; $i++) {
  202. $currNode =& $this->node->childNodes[$i];
  203. //$this->DOMIT_RSS_indexer[$currNode->nodeName] =& $currNode;
  204. $this->addIndexedElement($currNode);
  205. }
  206. } //_init
  207. /**
  208. * Adds a custom element (one not defined by the RSS specs, e..g., dc:creator) to the indexer
  209. * @param Object A DOMIT! node representing the custom element
  210. */
  211. function addIndexedElement(&$node) {
  212. $tagName = strtolower($node->nodeName);
  213. if (isset($this->DOMIT_RSS_indexer[$tagName])) {
  214. if (strtolower(get_class($this->DOMIT_RSS_indexer[$tagName])) == 'domit_element') {
  215. $collection = new xml_domit_rss_collection();
  216. $collection->addElement($this->DOMIT_RSS_indexer[$tagName]);
  217. $collection->addElement($node);
  218. $this->DOMIT_RSS_indexer[$tagName] =& $collection;
  219. }
  220. else {
  221. //Don't think I need this case???
  222. //$this->DOMIT_RSS_indexer[$tagName]->addElement($node);
  223. }
  224. }
  225. else {
  226. $this->DOMIT_RSS_indexer[$tagName] =& $node;
  227. }
  228. } //addIndexedElement
  229. /**
  230. * Indicates whether the requested element is actually a collection of elements of the same type
  231. * @param string The name of the requested element
  232. * @return boolean True if a collection of elements exists
  233. */
  234. function isCollection($elementName) {
  235. $elementName = strtolower($elementName);
  236. if (isset($this->DOMIT_RSS_indexer[$elementName])) {
  237. return (get_class($this->DOMIT_RSS_indexer[$elementName]) == 'xml_domit_rss_collection');
  238. }
  239. else {
  240. return false;
  241. }
  242. } //isCollection
  243. /**
  244. * Indicates whether the requested element is a DOMIT! node
  245. * @param string The name of the requested element
  246. * @return boolean True if the requested element is a DOMIT! node
  247. */
  248. function isNode($elementName) {
  249. $elementName = strtolower($elementName);
  250. if (isset($this->DOMIT_RSS_indexer[$elementName])) {
  251. return (strtolower(get_class($this->DOMIT_RSS_indexer[$elementName])) == 'domit_element');
  252. }
  253. else {
  254. return false;
  255. }
  256. } //isNode
  257. /**
  258. * Indicates whether the requested element is a DOMIT! node (alias for isNode)
  259. * @param string The name of the requested element
  260. * @return boolean True if the requested element is a DOMIT! node
  261. */
  262. function isCustomRSSElement($elementName) {
  263. return isNode($elementName);
  264. } //isCustomRSSElement
  265. /**
  266. * Gets a named list of existing elements as a child of the current element
  267. * @return array A named list of existing elements
  268. */
  269. function getElementList() {
  270. return array_keys($this->DOMIT_RSS_indexer);
  271. } //getElementList
  272. /**
  273. * Indicates whether a particular element exists
  274. * @param string The name of the requested element
  275. * @return boolean True if an element with the specified name exists
  276. */
  277. function hasElement($elementName) {
  278. return isset($this->DOMIT_RSS_indexer[strtolower($elementName)]);
  279. } //hasElement
  280. /**
  281. * Gets a reference to an element with the specified name
  282. * @param string The name of the requested element
  283. * @return mixed A reference to an element with the specified name, or the text of the element if it is a text node
  284. */
  285. function &getElement($elementName) {
  286. $elementName = strtolower($elementName);
  287. if (isset($this->DOMIT_RSS_indexer[$elementName])) {
  288. return $this->DOMIT_RSS_indexer[$elementName];
  289. }
  290. else {
  291. xml_domit_rss_exception::raiseException(DOMIT_RSS_ELEMENT_NOT_FOUND_ERR,
  292. 'Element ' . $elementName . ' not present.');
  293. }
  294. } //getElement
  295. /**
  296. * Gets a reference to an element at the specified index
  297. * @param int The index of the requested element
  298. * @return mixed A reference to an element at the specified index, or the text of the element if it is a text node
  299. */
  300. function &getElementAt($index) {
  301. $this->indexNumerically();
  302. if (isset($this->DOMIT_RSS_numericalIndexer[$index])) {
  303. return $this->DOMIT_RSS_numericalIndexer[$index];
  304. }
  305. else {
  306. xml_domit_rss_exception::raiseException(DOMIT_RSS_ELEMENT_NOT_FOUND_ERR,
  307. 'Element ' . $index . ' not present.');
  308. }
  309. } //getElementAt
  310. /**
  311. * Populates an integer-based index for elements if one isn't already present.
  312. */
  313. function indexNumerically() {
  314. if (!isset($this->DOMIT_RSS_numericalIndexer)) {
  315. $counter = 0;
  316. foreach ($this->DOMIT_RSS_indexer as $key => $value) {
  317. $this->DOMIT_RSS_numericalIndexer[$counter] =& $this->DOMIT_RSS_indexer[$key];
  318. $counter++;
  319. }
  320. }
  321. } //indexNumerically
  322. /**
  323. * Gets the text of the specified element
  324. * @param string The name of the requested element
  325. * @return string The element text, or an empty string
  326. */
  327. function getElementText($elementName) {
  328. $elementName = strtolower($elementName);
  329. return $this->_getElementText($elementName, $this->DOMIT_RSS_indexer);
  330. } //getElementText
  331. /**
  332. * Gets the text at the specified index
  333. * @param int The index of the requested element
  334. * @return string The element text, or an empty string
  335. */
  336. function getElementTextAt($index) {
  337. $this->indexNumerically();
  338. return $this->_getElementText($index, $this->DOMIT_RSS_numericalIndexer);
  339. } //getElementTextAt
  340. /**
  341. * Gets the text at the specified index
  342. * @param mixed The index or name of the requested element
  343. * @param array The indexing array from which to extract data
  344. * @return string The element text, or an empty string
  345. */
  346. function _getElementText($index, &$myArray) {
  347. if (isset($myArray[$index])) {
  348. $element =& $myArray[$index];
  349. $result = '';
  350. if (is_array($element)) {
  351. //do nothing; data for domit_rss_channels, domit_rss_items,
  352. //and domit_rss_categories should be extracted with their own methods
  353. }
  354. else {
  355. switch (strtolower(get_class($element))) {
  356. case 'xml_domit_rss_simpleelement':
  357. $result = $element->getElementText();
  358. break;
  359. case 'xml_domit_rss_collection':
  360. $result = $element->getElementText();
  361. break;
  362. case 'domit_element':
  363. $total = $element->childCount;
  364. for ($i = 0; $i < $total; $i++) {
  365. $currNode =& $element->childNodes[$i];
  366. if ($currNode->nodeType == DOMIT_CDATA_SECTION_NODE) {
  367. $result .= $currNode->nodeValue;
  368. }
  369. else {
  370. $result .= $currNode->toString();
  371. }
  372. }
  373. break;
  374. }
  375. }
  376. return $result;
  377. }
  378. return '';
  379. } //_getElementText
  380. } //xml_domit_rss_elementindexer
  381. /**
  382. * A base class for DOMIT! RSS and DOMIT! RSS Lite documents
  383. *
  384. * @package domit-rss
  385. * @author John Heinstein <johnkarl@nbnet.nb.ca>
  386. */
  387. class xml_domit_rss_base_document extends xml_domit_rss_elementindexer {
  388. /** @var array An array of item elements (only present in some RSS formats) */
  389. var $domit_rss_items = array();
  390. /** @var array An array of existing channel elements */
  391. var $domit_rss_channels = array();
  392. /** @var array An array of existing category elements */
  393. var $domit_rss_categories = array();
  394. /** @var boolean True if caching is enabled */
  395. var $cacheEnabled = true;
  396. /** @var Object A reference to the file caching object */
  397. var $cache;
  398. /** @var boolean True if PEAR:Cache_Lite is to be used instead of php_text_cache */
  399. var $useCacheLite = false;
  400. /** @var boolean True if php_http_client_generic is to be used instead of PHP get_file_contents */
  401. var $doUseHTTPClient = false;
  402. /** @var string The name of the current parser - either 'DOMIT_RSS' or 'DOMIT_RSS_LITE' */
  403. var $parser;
  404. /** @var object A reference to a http connection or proxy, if one is required */
  405. var $httpConnection = null;
  406. /** @var int The timeout value for an http connection */
  407. var $rssTimeout = 0;
  408. /**
  409. * Constructor
  410. * @param string Path to the rss file
  411. * @param string Directory in which cache files are to be stored
  412. * @param int Expiration time (in seconds) for the cache file
  413. * @return mixed Null if an url was not provided, true if an url was provided and parsing was successful, false otherwise
  414. */
  415. function xml_domit_rss_base_document ($url = '', $cacheDir = './', $cacheTime = 3600) {
  416. $success = null;
  417. $this->createDocument();
  418. if ($url != '') { //if rss data is from filesystem
  419. if (substr($url, 0, 4) != "http") {
  420. $rssText = $this->getTextFromFile($url);
  421. $this->parseRSS($rssText);
  422. }
  423. else {
  424. $this->createDefaultCache($cacheDir, $cacheTime);
  425. $success = $this->loadRSS($url, $cacheDir, $cacheTime);
  426. }
  427. }
  428. return $success;
  429. } //xml_domit_rss_base_document
  430. /**
  431. * Specifies the default timeout value for connecting to a host
  432. * @param int The number of seconds to timeout when attempting to connect to a server
  433. */
  434. function setRSSTimeout($rssTimeout) {
  435. $this->rssTimeout = $rssTimeout;
  436. if (!$this->useCacheLite && !($this->cache == null)) {
  437. $this->cache->setTimeout($rssTimeout);
  438. }
  439. } //setRSSTimeout
  440. /**
  441. * Specifies the parameters of the http conection used to obtain the xml data
  442. * @param string The ip address or domain name of the connection
  443. * @param string The path of the connection
  444. * @param int The port that the connection is listening on
  445. * @param int The timeout value for the connection
  446. * @param string The user name, if authentication is required
  447. * @param string The password, if authentication is required
  448. */
  449. function setConnection($host, $path = '/', $port = 80, $timeout = 0, $user = null, $password = null) {
  450. require_once(DOMIT_RSS_INCLUDE_PATH . 'php_http_client_generic.php');
  451. $this->httpConnection = new php_http_client_generic($host, $path, $port, $timeout, $user, $password);
  452. } //setConnection
  453. /**
  454. * Specifies basic authentication for an http connection
  455. * @param string The user name
  456. * @param string The password
  457. */
  458. function setAuthorization($user, $password) {
  459. $this->httpConnection->setAuthorization($user, $password);
  460. } //setAuthorization
  461. /**
  462. * Specifies that a proxy is to be used to obtain the xml data
  463. * @param string The ip address or domain name of the proxy
  464. * @param string The path to the proxy
  465. * @param int The port that the proxy is listening on
  466. * @param int The timeout value for the connection
  467. * @param string The user name, if authentication is required
  468. * @param string The password, if authentication is required
  469. */
  470. function setProxyConnection($host, $path = '/', $port = 80, $timeout = 0, $user = null, $password = null) {
  471. require_once(DOMIT_RSS_INCLUDE_PATH . 'php_http_proxy.php');
  472. $this->httpConnection = new php_http_proxy($host, $path, $port, $timeout, $user, $password);
  473. } //setProxyConnection
  474. /**
  475. * Specifies a user name and password for the proxy
  476. * @param string The user name
  477. * @param string The password
  478. */
  479. function setProxyAuthorization($user, $password) {
  480. $this->httpConnection->setProxyAuthorization($user, $password);
  481. } //setProxyAuthorization
  482. /**
  483. * Specifies whether an HTTP client should be used to establish a connection
  484. * @param boolean True if an HTTP client is to be used to establish the connection
  485. */
  486. function useHTTPClient($truthVal) {
  487. $this->doUseHTTPClient = $truthVal;
  488. } //useHTTPClient
  489. /**
  490. * Returns the name of the parser
  491. *@return string Either 'DOMIT_RSS' or 'DOMIT_RSS_LITE'
  492. */
  493. function parsedBy() {
  494. return $this->parser;
  495. } //parsedBy
  496. /**
  497. * Creates an empty DOMIT! document to contain the RSS nodes
  498. */
  499. function createDocument() {
  500. require_once(DOMIT_RSS_INCLUDE_PATH . 'xml_domit_include.php');
  501. $this->node = new DOMIT_Document();
  502. $this->node->resolveErrors(true);
  503. } //createDocument
  504. /**
  505. * Substitutes PEAR::Cache_Lite for the default php_text_cache
  506. * @param boolean True if Cache Lite is to be used
  507. * @param string Absolute or relative path to the Cache Lite library
  508. * @param string Directory for cache files
  509. * @param int Expiration time for a cache file
  510. */
  511. function useCacheLite($doUseCacheLite, $pathToLibrary = './Lite.php', $cacheDir = './', $cacheTime = 3600) {
  512. $this->useCacheLite = $doUseCacheLite;
  513. if ($doUseCacheLite) {
  514. if (!file_exists($pathToLibrary)) {
  515. $this->useCacheLite(false);
  516. }
  517. else {
  518. require_once($pathToLibrary);
  519. $cacheOptions = array('cacheDir' => $cacheDir, 'lifeTime' => $cacheTime);
  520. $this->cache = new Cache_Lite($cacheOptions);
  521. }
  522. }
  523. else {
  524. $this->createDefaultCache($cacheDir, $cacheTime);
  525. }
  526. } //useCacheLite
  527. /**
  528. * Instantiates a default cache (php_text_cache)
  529. * @param string Directory for cache files
  530. * @param int Expiration time for a cache file
  531. */
  532. function createDefaultCache($cacheDir = './', $cacheTime = 3600) {
  533. require_once(DOMIT_RSS_INCLUDE_PATH . 'php_text_cache.php');
  534. $this->cache = new php_text_cache($cacheDir, $cacheTime, $this->rssTimeout);
  535. } //initDefaultCache
  536. /**
  537. * Disables caching mechanism
  538. */
  539. function disableCache() {
  540. $this->cacheEnabled = false;
  541. } //initDefaultCache
  542. /**
  543. * Loads and parses the RSS at the specified url
  544. * @param string The url of the RSS feed
  545. * @return boolean True if parsing is successful
  546. */
  547. function loadRSS($url) {
  548. if (substr($url, 0, 4) != "http") {
  549. $rssText = $this->getTextFromFile($url);
  550. return $this->parseRSS($rssText);
  551. }
  552. else {
  553. if ($this->cacheEnabled && !isset($this->cache)) {
  554. $this->createDefaultCache();
  555. $this->cache->httpConnection =& $this->httpConnection;
  556. }
  557. $success = $this->loadRSSData($url);
  558. if ($success) {
  559. $this->_init();
  560. }
  561. return $success;
  562. }
  563. } //loadRSS
  564. /**
  565. * Parses the RSS text provided
  566. * @param string The RSS text
  567. * @return boolean True if parsing is successful
  568. */
  569. function parseRSS($rssText) {
  570. if ($this->cacheEnabled && !isset($this->cache)) $this->createDefaultCache();
  571. $success = $this->parseRSSData($rssText);
  572. if ($success) {
  573. $this->_init();
  574. }
  575. return $success;
  576. } //parseRSS
  577. /**
  578. * Retrieves the RSS data from the url/cache file and parses
  579. * @param string The url for the RSS data
  580. * @return boolean True if parsing is successful
  581. */
  582. function loadRSSData($url) {
  583. $rssText = $this->getDataFromCache($url);
  584. return $this->parseRSSData($rssText);
  585. } //loadRSSData
  586. /**
  587. * Retrieves the RSS data from the url/cache file
  588. * @param string The url for the RSS data
  589. * @return string The RSS data
  590. */
  591. function getDataFromCache($url) {
  592. if ($this->cacheEnabled) {
  593. if ($this->useCacheLite) {
  594. if ($rssText = $this->cache->get($url)) {
  595. return $rssText;
  596. }
  597. else {
  598. $rssText = $this->getTextFromFile($url);
  599. if ($rssText != '') $this->cache->save($rssText, $url);
  600. return $rssText;
  601. }
  602. }
  603. else {
  604. $this->cache->useHTTPClient($this->doUseHTTPClient);
  605. return $this->cache->getData($url);
  606. }
  607. }
  608. else {
  609. return $this->getTextFromFile($url);
  610. }
  611. } //getDataFromCache
  612. /**
  613. * Parses the RSS data provided
  614. * @param string The the RSS data
  615. * @return boolean True if parsing is successful
  616. */
  617. function parseRSSData($rssText) {
  618. if ($rssText != '') {
  619. return $this->fromString($rssText);
  620. }
  621. else {
  622. return false;
  623. }
  624. } //parseRSSData
  625. /**
  626. * Reads in RSS text from a file and parses it
  627. * @param string The file path
  628. * @return boolean True if parsing is successful
  629. */
  630. function &fromFile($filename) {
  631. $success = $this->node->loadXML($filename, false);
  632. return $success;
  633. } //fromFile
  634. /**
  635. * Reads in RSS text from a string and parses it
  636. * @param string The RSS text
  637. * @return boolean True if parsing is successful
  638. */
  639. function &fromString($rssText) {
  640. $success = $this->node->parseXML($rssText, false);
  641. return $success;
  642. } //fromString
  643. /**
  644. * Establishes a connection, given an url
  645. * @param string The url of the data
  646. */
  647. function establishConnection($url) {
  648. require_once(DOMIT_RSS_INCLUDE_PATH . 'php_http_client_generic.php');
  649. $host = php_http_connection::formatHost($url);
  650. $host = substr($host, 0, strpos($host, '/'));
  651. $this->setConnection($host, '/', 80, $this->rssTimeout);
  652. } //establishConnection
  653. /**
  654. * Get text from an url or file
  655. * @param string The url or file path
  656. * @return string The text contained in the url or file, or an empty string
  657. */
  658. function getTextFromFile($filename) {
  659. $fileContents = '';
  660. if ($this->doUseHTTPClient) {
  661. $this->establishConnection($filename);
  662. $response =& $this->httpConnection->get($filename);
  663. if ($response != null) {
  664. $fileContents = $response->getResponse();
  665. }
  666. }
  667. else {
  668. if (function_exists('file_get_contents')) {
  669. $fileContents = @file_get_contents($filename);
  670. }
  671. else {
  672. require_once(DOMIT_RSS_INCLUDE_PATH . 'php_file_utilities.php');
  673. $fileContents =& php_file_utilities::getDataFromFile($filename, 'r');
  674. }
  675. if ($fileContents == '') {
  676. $this->establishConnection($filename);
  677. $response =& $this->httpConnection->get($filename);
  678. if ($response != null) {
  679. $fileContents = $response->getResponse();
  680. }
  681. }
  682. }
  683. return $fileContents;
  684. } //getTextFromFile
  685. /**
  686. * Gets a reference to the underlying DOM document
  687. * @return Object A reference to the underlying DOM document
  688. */
  689. function &getDocument() {
  690. return $this->node;
  691. } //getDocument
  692. /**
  693. * Gets a reference to the root DOM element
  694. * @return Object A reference to the root DOM element
  695. */
  696. function &getNode() {
  697. return $this->node->documentElement;
  698. } //getNode
  699. /**
  700. * Forces channel elements that are external to a channel to be referenced as subelements of that channel
  701. */
  702. function handleChannelElementsEmbedded() {
  703. if (count($this->domit_rss_items) > 0) {
  704. foreach ($this->domit_rss_channels as $key => $value) {
  705. $this->domit_rss_channels[$key]->domit_rss_items =& $this->domit_rss_items;
  706. if (count($this->DOMIT_RSS_indexer) > 0) {
  707. foreach ($this->DOMIT_RSS_indexer as $ikey => $ivalue) {
  708. if ($ikey != DOMIT_RSS_ARRAY_CHANNELS) {
  709. $this->domit_rss_channels[$key]->DOMIT_RSS_indexer[$ikey] =& $this->DOMIT_RSS_indexer[$ikey];
  710. unset($this->DOMIT_RSS_indexer[$ikey]);
  711. }
  712. }
  713. }
  714. }
  715. }
  716. } //handleChannelElementsEmbedded
  717. /**
  718. * Returns the version of RSS used to format the data
  719. * @return string The version of RSS used to format the data
  720. */
  721. function getRSSVersion() {
  722. $version = $this->node->documentElement->getAttribute(DOMIT_RSS_ATTR_VERSION);
  723. if ($version == '') {
  724. $xmlns = $this->node->documentElement->getAttribute('xmlns');
  725. $total = strlen($xmlns);
  726. if (substr($xmlns, $total) == '/') {
  727. $total--;
  728. }
  729. for ($i = ($total - 1); $i > -1; $i--) {
  730. $currentChar = substr($xmlns, $i);
  731. if ($currentChar == '/') {
  732. break;
  733. }
  734. else {
  735. $version = $currentChar . $version;
  736. }
  737. }
  738. }
  739. return $version;
  740. } //getRSSVersion
  741. /**
  742. * Returns the number of channels in the document
  743. * @return int The number of channels in the document
  744. */
  745. function getChannelCount() {
  746. return count($this->domit_rss_channels);
  747. } //getChannelCount()
  748. /**
  749. * Returns a reference to the channel located at the specified index
  750. * @return Object A reference to the channel located at the specified index
  751. */
  752. function &getChannel($index) {
  753. return $this->domit_rss_channels[$index];
  754. } //getChannel
  755. } //xml_domit_rss_base_document
  756. /**
  757. * Represents a simple RSS element, without attributes and only a single child text node
  758. *
  759. * @package domit-rss
  760. * @subpackage domit-rss-main
  761. * @author John Heinstein <johnkarl@nbnet.nb.ca>
  762. */
  763. class xml_domit_rss_simpleelement extends xml_domit_rss_elementindexer {
  764. /**
  765. * Constructor
  766. * @param Object A DOM node containing element data
  767. */
  768. function xml_domit_rss_simpleelement(&$element) {
  769. $this->node =& $element;
  770. } //xml_domit_rss_simpleelement
  771. /**
  772. * Gets the text of the element
  773. * @return string The element text
  774. */
  775. function getElementText() {
  776. $element =& $this->node;
  777. $result = '';
  778. $total = $element->childCount;
  779. for ($i = 0; $i < $total; $i++) {
  780. $currNode =& $element->childNodes[$i];
  781. if ($currNode->nodeType == DOMIT_CDATA_SECTION_NODE) {
  782. $result .= $currNode->nodeValue;
  783. }
  784. else {
  785. $result .= $currNode->toString();
  786. }
  787. }
  788. return $result;
  789. } //getElementText
  790. } //xml_domit_rss_simpleelement
  791. /**
  792. * @global object Reference to custom error handler for DOMIT RSS Exception class
  793. */
  794. $GLOBALS['DOMIT_RSS_Exception_errorHandler'] = null;
  795. /**
  796. * @global int Error mode; specifies whether to die on error or simply return
  797. */
  798. //$GLOBALS['DOMIT_RSS_Exception_mode'] = DOMIT_RSS_ONERROR_RETURN;
  799. // fixes bug identified here: sarahk.pcpropertymanager.com/blog/using-domit-rss/225/
  800. $GLOBALS['DOMIT_RSS_Exception_mode'] = 1;
  801. /**
  802. * @global string Log file for errors
  803. */
  804. $GLOBALS['DOMIT_RSS_Exception_log'] = null;
  805. /**
  806. * A DOMIT! RSS exception handling class
  807. *
  808. * @package domit-rss
  809. * @author John Heinstein <johnkarl@nbnet.nb.ca>
  810. */
  811. class xml_domit_rss_exception {
  812. /**
  813. * Raises the specified exception
  814. * @param int The error number
  815. * @param string A string explanation of the error
  816. */
  817. function raiseException($errorNum, $errorString) {
  818. if ($GLOBALS['DOMIT_RSS_Exception_errorHandler'] != null) {
  819. call_user_func($GLOBALS['DOMIT_RSS_Exception_errorHandler'], $errorNum, $errorString);
  820. }
  821. else {
  822. $errorMessageText = $errorNum . ' ' . $errorString;
  823. $errorMessage = 'Error: ' . $errorMessageText;
  824. if ((!isset($GLOBALS['DOMIT_RSS_ERROR_FORMATTING_HTML'])) ||
  825. ($GLOBALS['DOMIT_RSS_ERROR_FORMATTING_HTML'] == true)) {
  826. $errorMessage = "<p><pre>" . $errorMessage . "</pre></p>";
  827. }
  828. //log error to file
  829. if ((isset($GLOBALS['DOMIT_RSS_Exception_log'])) &&
  830. ($GLOBALS['DOMIT_RSS_Exception_log'] != null)) {
  831. require_once(DOMIT_RSS_INCLUDE_PATH . 'php_file_utilities.php');
  832. $logItem = "\n" . date('Y-m-d H:i:s') . 'DOMIT! RSS Error ' . $errorMessageText;
  833. php_file_utilities::putDataToFile($GLOBALS['DOMIT_RSS_Exception_log'], $logItem, 'a');
  834. }
  835. switch ($GLOBALS['DOMIT_RSS_Exception_mode']) {
  836. case DOMIT_RSS_ONERROR_CONTINUE:
  837. return;
  838. break;
  839. case DOMIT_RSS_ONERROR_DIE:
  840. die($errorMessage);
  841. break;
  842. }
  843. }
  844. } //raiseException
  845. /**
  846. * custom handler for DOM RSS errors
  847. * @param object A reference to the custom error handler
  848. */
  849. function setErrorHandler($method) {
  850. $GLOBALS['DOMIT_RSS_Exception_errorHandler'] =& $method;
  851. require_once(DOMIT_RSS_INCLUDE_PATH . 'php_http_exceptions.php');
  852. $GLOBALS['HTTP_Exception_errorHandler'] =& $method;
  853. require_once(DOMIT_RSS_INCLUDE_PATH . 'xml_domit_shared.php');
  854. $GLOBALS['HTTP_Exception_errorHandler'] =& $method;
  855. } //setErrorHandler
  856. /**
  857. * Set error mode
  858. * @param int The DOMIT RSS error mode
  859. */
  860. function setErrorMode($mode) {
  861. $GLOBALS['DOMIT_RSS_Exception_mode'] = $mode;
  862. require_once(DOMIT_RSS_INCLUDE_PATH . 'php_http_exceptions.php');
  863. require_once(DOMIT_RSS_INCLUDE_PATH . 'xml_domit_shared.php');
  864. if ($mode == DOMIT_RSS_ONERROR_CONTINUE) {
  865. $GLOBALS['HTTP_Exception_mode'] = HTTP_ONERROR_CONTINUE;
  866. $GLOBALS['DOMIT_DOMException_mode'] = DOMIT_ONERROR_CONTINUE;
  867. }
  868. else {
  869. $GLOBALS['HTTP_Exception_mode'] = HTTP_ONERROR_DIE;
  870. $GLOBALS['DOMIT_DOMException_mode'] = DOMIT_ONERROR_DIE;
  871. }
  872. } //setErrorMode
  873. /**
  874. * Set error mode
  875. * @param boolean True if errors should be logged
  876. * @param string Absolute or relative path to log file
  877. */
  878. function setErrorLog($doLogErrors, $logfile) {
  879. require_once(DOMIT_RSS_INCLUDE_PATH . 'php_http_exceptions.php');
  880. if ($doLogErrors) {
  881. $GLOBALS['DOMIT_RSS_Exception_log'] = $logfile;
  882. $GLOBALS['HTTP_Exception_log'] = $logfile;
  883. $GLOBALS['DOMIT_Exception_log'] = $logfile;
  884. }
  885. else {
  886. $GLOBALS['DOMIT_RSS_Exception_log'] = null;
  887. $GLOBALS['HTTP_Exception_log'] = null;
  888. $GLOBALS['DOMIT_Exception_log'] = null;
  889. }
  890. } //setErrorLog
  891. } //xml_domit_rss_exception
  892. ?>