| // | | // | Proxy and authentication methods added by: | // | Marco Kraus | // | | // | Decoding of data by htmlentities or utf8_decode added by: | // | Roland Haeder | // | | // +----------------------------------------------------------------------+ // | Ref: | // | @link http://www.fase4.com/rdf/ Latest release | // +----------------------------------------------------------------------+ /** * Class RSS Parser * * This class offers methods to parse RSS Files * * @link http://www.fase4.com/rdf/ Latest release of this class * @package rss * @copyright Copyright (c) 2001 fase4.com. All rights reserved. * @author Stefan Saasen * @author Roland Haeder * @version 1.7 ($Date$Revision: 856 $ * @access public */ class fase4_rdf { /** * Word-wrapping mode for description, set it to 0 do disable this feature! Ommits _use_nl2br! * * @access private * @var integer */ var $_word_wrap = '0'; /** * Wether to recode \n ->
or not in description * * @access private * @var boolean */ var $_use_nl2br = TRUE; /** * Sets the decoding mode of the read data (UTF8 scrambles some german umlauts here!) * * "htmlentities" - Use the function htmlentities() * "utf8_decode" - Use the function ut8_decode() when you have UTF8 encoded text * - Use non of both * * @access private * @var string */ var $_decoding_mode = ''; /** * If $_link_target is set a target='xxx' attribute in each and
html tag will be added * * Possible values are "_blank", "_content", "_parent", "_self", "_top" * * @access private * @var string */ var $_link_target = '_blank'; /** * vars for proxy settings - Prox Host * * @access private * @var string */ var $_phost = ''; /** * vars for proxy settings - Prox Port * * @access private * @var string */ var $_pport = ''; /** * vars for proxy settings - Prox Username * * @access private * @var string */ var $_pname = ''; /** * vars for proxy settings - Prox Password * * @access private * @var string */ var $_ppasswd = ''; /** * just a flag for checking if proxy-support should be enabled * set default to false (will be enabled if set_proxy is called) * * @access private * @see set_proxy() * @var bool */ var $_use_proxy = FALSE; /** * just a flag for checking if proxy-support with authentication * should be enabled * set default to false (will be enabled if set_proxy is called) * * @access private * @see set_proxy() * @var boolean */ var $_use_proxy_auth = FALSE; /** * The time the Files will be cached (in seconds). * * @access private * @var int */ var $_refresh = 60; // int /** * The Name of the cached File. * * @access private * @var string */ var $_cached_file = ''; // String /** * Indicates whether the cached or the remote file was used. * * @access private * @var boolean */ var $_use_cached_file = TRUE; /** * (fast|normal) depends on _use_dynamic_display(). _use_dynamic_display( TRUE ) -> 'normal', otherwise 'fast' * * @access private * @var string */ var $_cache_type = 'fast'; /** * The Name of the Remote File. * * @access private * @var string */ var $_remote_file = ''; /** * Path to the Cache Directory. * * @access private * @var string */ var $_cache_dir = 'cache/'; // String /** * Indicates whether the Creating of the Cache Directory needs to be done or not. * * @access private * @var boolean */ var $_cache_dir_ok = FALSE; /** * Type of the file to be parsed (RSS or RDF). * * The Type depends on the root node * * @access private * @var string */ var $_type = 'rss'; // string (rss or rdf) /** * Array of Display Settings. * * Specific Parameters can be set to hidden. These are: * image, channel and textinput. If set to "hidden" those elements won't be displayed. * * @access private * @var array */ var $_display_opt = array( 'build' => '', 'image' => '', 'channel' => '', 'textinput' => '', 'cache_update' => '', 'sitelink' => '', 'refid' => '', 'reflink' => '', ); /** * Defines the width attribute in the table that holds the rdf/rss representation * * @access private * @var int * @see see_table_width() */ var $_table_width = '100%'; /** * Indicates whether or not to use dynamic Display Settings * * @access private * @var array */ var $_use_dynamic_display = FALSE; /** * count * * @access private * @var int */ var $_item_count = '0'; /** * No of max s * * @access private * @var boolean */ var $_max_count = FALSE; /** * Array containing the content of * * @access private * @var array */ var $_array_channel = array(); /** * Array containing the content of each * * @access private * @var array */ var $_array_item = array(); /** * Array containing the content of * * @access private * @var array */ var $_array_textinput = array(); /** * Array containing the content of * * @access private * @var array */ var $_array_image = array(); /** * Array containing the Channel content. Just For internal XML Parser Purposes. * * @access private * @var array */ var $_citem = array(); /** * Array containing the Channel Parser Depth. Just For internal XML Parser Purposes. * * @access private * @var array */ var $_cdepth = array(); /** * Array containing the Channel tags. Just For internal XML Parser Purposes. * * @access private * @var array */ var $_ctags = array( 'x' ); /** * Array containing the Channel content. Just For internal XML Parser Purposes. * * @access private * @var array */ var $_item = array(); // Array /** * Array containing the Channel Parser Depth. Just For internal XML Parser Purposes. * * @access private * @var array */ var $_depth = array(); // Array /** * Array containing the tags. Just For internal XML Parser Purposes. * * @access private * @var array */ var $_tags = array( 'x' ); // Array /** * Garbage collection: probability in percent * * @var integer 0 => never * @access public */ var $gc_probability = 1; /** * HTML Output * * @var string * @access private */ var $_output = ''; /** * @var string */ var $_parse_mode = ''; // Output variable var $out = ''; // Salt for hashing var $salt = ''; /** * Constructor of our Class * * This Method checks if the Cache Directory can be found. Otherwise it tries to creat the Cache Directory at the specified Path. * Additionally the Refresh Time is set to a default Value of 1200s (20 min). * * @access public * @author Stefan Saasen * @see _refresh */ function fase4_rdf() { // default Value, to be overwritten in set_refresh() $this->_refresh = (time() - 1200); $this->_clear_cItems(); $this->_clear_Items(); } /** * This Method starts the parsing of the specified RDF File. The File can be a local or a remote File. * * @access public * @author Stefan Saasen * @param string $rdf RDF File (Location) * @return string Displays RDF Content ( using _display() ) * @see _remote_file, cache() */ function parse_RDF( $rdf ) { unset($this->_array_item); $this->_remote_file = $rdf; $this->out .= ""; $this->out .= "_table_width."\">"; $this->out .= $this->cache(); $this->out .= "
"; $this->_output = ''; $this->_item_count = '0'; return TRUE; } /** * This Method is called when all parsing is finished to use the garbage collection * * @access public * @author Stefan Saasen * @param string $rdf RDF File (Location) * @return string Displays RDF Content ( using _display() ) * @see _remote_file, cache() */ function finish($return = FALSE) { $this->out = str_replace('$', '$', $this->out); if (!$return) { echo $this->out; } else { return $this->out; } $this->_garbage_collection(); } /** * With this method you can decide whether to use the normal cache and dynamic display Options or to use a static cache. * * In the first case the rdf/rss File will be stored locally, in the second case the html output of the specified source will be stored. * In this case you can not modify the display settings. * processing time: ( 1.4792) --> remote file * processing time: ( 0.0313) --> using 'normal cache' with display Modification turned on. * processing time: ( 0.0019) --> using 'fast cache' * * @access public * @author Stefan Saasen * @param string $rdf RDF File (Location) * @return string Displays RDF Content ( using _display() ) * @see _remote_file, cache() */ function use_dynamic_display( $bool ) { $this->_use_dynamic_display = $bool; return TRUE; } /** * This Method avtually parses the XML data. * * @access private * @author Stefan Saasen * @param string $data RDF File XML Data * @see _clear_Items() */ function _parse_xRDF( $data ) { $this->_clear_Items(); $xml_parser = xml_parser_create(); xml_set_object($xml_parser,$this); xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0); xml_set_element_handler($xml_parser, '_startElement', '_endElement'); xml_set_character_data_handler($xml_parser, '_parseData'); if (!xml_parse($xml_parser, trim($data))) { $this->_throw_exception(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser)).'

Exception in function parse_RDF().'); } // END - if xml_parser_free($xml_parser); } /** * This Methods allows you to set the Refresh Time * * @access public * @author Stefan Saasen * @param int $seconds time files will be cached (in seconds). * @return boolean * @see _refresh */ function set_refresh( $seconds ) { $this->_refresh = (time() - $seconds); return TRUE; } function set_salt( $saltPara ) { $this->salt = $saltPara; return TRUE; } /** * This Methods allows you to set the No. of s to display * * @access public * @param int $int No of max s * @author Stefan Saasen * @return boolean * @see _max_count, _endElement() */ function set_max_item( $int ) { $this->_max_count = $int; return TRUE; } /** * This Methods allows you to set the Cache Directory * * @access public * @author Stefan Saasen * @param string $dir Path to Directory. * @return boolean * @see _cache_dir */ function set_CacheDir( $dir ) { if(substr($dir, -1) != '/') { $dir = $dir.'/'; } $this->_cache_dir = $dir; } /** * This Method displays Error Messages and terminates the Execution of the Script * * @access private * @param string $msg Message to display on failure * @author Stefan Saasen */ function _throw_exception( $msg ) { $this->out .= "
fase4 RDF Error: ".$msg."
"; return TRUE; } /** * This Method clears the Array containig the Items. * * @access private * @author Stefan Saasen * @see _item */ function _clear_Items( ) { $this->_item = array( 'title' => '', 'link' => '', 'description' => '', 'url' => '', 'language' => '', 'pubDate' => '', 'lastBuildDate' => '', 'width' => '', 'height' => '' ); } /** * This Method clears the Array containig the Channel Items. * * @access private * @author Stefan Saasen * @see _item */ function _clear_cItems( ) { $this->_citem = array( 'title' => '', 'link' => '', 'description' => '', 'url' => '', 'language' => '', 'copyright' => '', 'managingEditor' => '', 'webMaster' => '', 'pubDate' => '', 'lastBuildDate' => '', 'category' => '', 'generator' => '', 'docs' => '', 'cloud' => '', 'ttl' => '', 'image' => '', 'textinput' => '', 'skipHours' => '', 'skipDays' => '', 'sitelink' => '', 'refid' => '', 'reflink' => '', ); } /** * XML Parser Start Element Handler * * @access private * @author Stefan Saasen * @param mixed $parser a reference to the XML parser calling the handler. * @param string $name contains the name of the element for which this handler is called. * @param string $attrs contains an associative array with the element's attributes (if any). * @see _get_ChannelData(), _clear_Items(), _type, _parse_mode, _depth, _tags, _cdepth, _ctags */ function _startElement($parser, $name, $attrs) { // We have to determine, which type of xml data we have to parse if($name == 'rss') { $this->_type = 'rss'; } elseif($name == 'rdf:RDF' OR $name == 'rdf') { $this->_type = 'rdf'; } if ( $name == 'channel' AND $this->_type != 'rdf' ) { $this->_parse_mode = 'channel'; } elseif ( ($name=='item') ||($name=='image') ||($name=='textinput') ||(($name=='channel') && ($this->_type != 'rss')) ) { if($this->_parse_mode=='channel') { $this->_get_ChannelData( $parser ); } $this->_parse_mode = 'all'; } if( !isset( $this->_depth[$this->get_parser_id($parser)] ) ) { $this->_depth[$this->get_parser_id($parser)] = '0'; } $this->_depth[$this->get_parser_id($parser)]++; array_push($this->_tags, $name); if( !isset( $this->_cdepth[$this->get_parser_id($parser)] ) ) { $this->_cdepth[$this->get_parser_id($parser)] = '0'; } $this->_cdepth[$this->get_parser_id($parser)]++; array_push($this->_ctags, $name); } // END _startElement() /** * Retrives the Channel Data in File * * @access private * @author Stefan Saasen * @param mixed $parser a reference to the XML parser calling the handler. * @see _output, _display_opt, _citem */ function _get_ChannelData( $parser ) { $this->_citem['link'] = trim($this->_citem['link']); if (($this->_display_opt['sitelink'] == $this->_citem['link']) && (!empty($this->_display_opt['reflink'])) && (!empty($this->_display_opt['refid']))) { $this->_citem['link'] .= $this->_display_opt['reflink'].$this->_display_opt['refid']; } if( empty($this->_display_opt['channel']) OR $this->_display_opt['channel'] != 'hidden') { $this->_output .= "\n"; $this->_output .= "\n"; $this->_output .= "\n"; $this->_output .= "\n"; $this->_output .= "\n"; $this->_output .= "\n"; $this->_output .= "\n"; $this->_output .= "
".htmlspecialchars($this->_citem['title'])."
".strip_tags($this->_citem['description'], ', ')."
 
\n"; if(isset($this->_display_opt['build']) && $this->_display_opt['build'] != 'hidden') { if($this->_citem['lastBuildDate']){$this->_output .= 'build: '. $this->_citem['lastBuildDate'].'
';} } if(isset($this->_display_opt['cache_update']) && $this->_display_opt['cache_update'] != 'hidden' && ( $_update = $this->get_cache_update_time()) ) { $this->_output .= 'cache update: '.$_update."
\n"; } $this->_output .= "_citem['link']."\" "; if(isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; } $this->_output .= ">".$this->_cut_string($this->_citem['link']) . ''; $this->_output .= "

"; } $this->_array_channel = array( 'title' => $this->_citem['title'], 'link' => $this->_citem['link'], 'description' => $this->_citem['description'], 'lastBuildDate' => $this->_citem['lastBuildDate']); } /** * XML Parser End Element Handler * * @access private * @author Stefan Saasen * @param mixed $parser a reference to the XML parser calling the handler. * @param string $name contains the name of the element for which this handler is called. * @see _clear_Items(), _type, _parse_mode, _depth, _tags, _cdepth, _ctags, _item, _output, _display_opt */ function _endElement($parser, $name) { array_pop($this->_tags); $this->_depth[$this->get_parser_id($parser)]--; array_pop($this->_ctags); $this->_cdepth[$this->get_parser_id($parser)]--; $this->_item['link'] = trim($this->_item['link']); if ((!empty($this->_display_opt['refid'])) && (!empty($this->_item['link']))) { if (!isInString('refid=', $this->_item['link'])) $this->_item['link'] .= '?refid=' . $this->_display_opt['refid']; } switch ($name) { case 'item': if(empty($this->_max_count) OR $this->_item_count < $this->_max_count) { if($this->_item['title'] != $this->_item['description'] AND $this->_item['description']) { // word-wrapping added by Roland Haeder if (($this->_word_wrap > 0) && (strlen($this->_item['description']) > $this->_word_wrap)) { // Switch off _use_nl2br $this->_use_nl2br = FALSE; // First remove all \n $this->_item['description'] = str_replace('\n', ' ', $this->_item['description']); // Wrap with
\n $this->_item['description'] = wordwrap($this->_item['description'], $this->_word_wrap, "*
\n"); } elseif (($this->_word_wrap == '0') && (!$this->_use_nl2br)) { // Strip tags out instead when word-wrap is disabled $this->_item['description'] = strip_tags($this->_item['description'], '
, '); } // nl2br added by Roland Haeder if ($this->_use_nl2br) $this->_item['description'] = nl2br($this->_item['description']); $this->_output .= "\n"; $this->_output .= "".$this->_item['description']."\n"; // we just display the
if there is a description $this->_output .= "
\n"; } else { $this->_output .= "\n"; $this->_output .= "_item["link"]."\" "; if(isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; } $this->_output .= ">".$this->_item["title"]."\n"; } $this->_array_item[] = array( 'title' => $this->_item['title'], 'link' => $this->_item['link'], 'description' => $this->_item['description'] ); ++$this->_item_count; } $this->_clear_Items(); break; case 'image': if(isset($this->_display_opt['image']) && ($this->_display_opt['image'] != 'hidden') && $this->_item['url']) { $this->_output .= "\n"; $this->_output .= "_item['link']."\" "; if(isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; } $this->_output .= ">_item['url']."\""; if(isset($this->_item['width']) && isset($this->_item['height'])) { $this->_output .= " width=\"".$this->_item['width']."\" height=\"".$this->_item['height']."\""; } $this->_output .= " alt=\"".$this->_item['title']."\" border=\"0\" />\n"; $this->_array_image[] = array( 'url' => $this->_item['url'], 'link' => $this->_item['link'], 'width' => $this->_item['width'], 'height' => $this->_item['height'] ); $this->_clear_Items(); } elseif( isset($this->_display_opt['image'] ) && ($this->_display_opt['image'] == 'hidden') ) { $this->_clear_Items(); } break; case 'channel': if(isset($this->_display_opt['channel']) AND $this->_display_opt['channel'] != 'hidden' AND $this->_item['title'] != '') { $this->_output .= "\n"; $this->_output .= "\n"; $this->_output .= "\n"; $this->_output .= "\n"; $this->_output .= "\n"; $this->_output .= "\n"; $this->_output .= "
".htmlspecialchars($this->_item['title'])."
".strip_tags($this->_item['description'], ', ')."
 
\n"; if($this->_display_opt['build'] != 'hidden') { if($this->_item['lastBuildDate']){$this->_output .= 'build: '. $this->_item['lastBuildDate'].'
';} } if($this->_display_opt['cache_update'] != 'hidden' && ( $_update = $this->get_cache_update_time()) ) { $this->_output .= 'cache update: '.$_update."
\n"; } $this->_output .= "_item['link']."\" "; if(isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; } $this->_output .= ">".$this->_cut_string($this->_item['link'])."\n"; $this->_output .= "
\n"; } $this->_array_channel = array( 'title' => $this->_item['title'], 'link' => $this->_item['link'], 'description' => $this->_item['description'], 'lastBuildDate' => $this->_item['lastBuildDate'] ); $this->_clear_Items(); $this->_clear_cItems(); break; case 'textinput': if(isset($this->_display_opt['textinput']) && ($this->_display_opt['textinput'] != 'hidden') && $this->_item['name'] && $this->_item['link']) { $this->_output .= "\n"; $this->_output .= "_item['link']."\" "; if(isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; } $this->_output .= "method=\"get\">\n"; $this->_output .= "
".$this->_item['title']."
"; $this->_output .= strip_tags($this->_item['description'], ', ')."

\n"; $this->_output .= "_item['name']."\"> \n"; $this->_output .= ""; $this->_output .= "\n"; $this->_output .= "\n"; $this->_array_textinput = array( 'title' => $this->_item['title'], 'name' => $this->_item['name'], 'link' => $this->_item['link'], 'description' => $this->_item['description'] ); $this->_clear_Items(); } elseif( isset($this->_display_opt['textinput']) && ($this->_display_opt['textinput'] == 'hidden') ) { $this->_clear_Items(); } break; } } /** * This Method returns the data from the paragraph. * * @access public * @author Stefan Saasen * @return array * @see _array_channel */ function get_array_channel( ) { return $this->_array_channel; } /** * This Method returns the data from each paragraph. * * @access public * @author Stefan Saasen * @return array * @see _array_item */ function get_array_item( ) { return $this->_array_item; } /** * This Method returns the data from . * * @access public * @author Stefan Saasen * @return array * @see _array_textinput */ function get_array_textinput( ) { return $this->_array_textinput; } /** * Getter for parser id from resource * * @access private * @author Roland Haeder * @return int */ function get_parser_id ($parser) { // Default is zero $id = '0'; // Is it a resource? if (is_resource($parser)) { // Cast the resource into id $id = (int) $parser; } // END - if // Return the id return $id; } /** * This Method returns the data from . * * @access public * @author Stefan Saasen * @return array * @see _array_image */ function get_array_image( ) { return $this->_array_image; } /** * XML Parser Data Handler * * @access private * @author Stefan Saasen * @param mixed $parser a reference to the XML parser calling the handler. * @param string $text contains the character data as a string. * @see _parse_mode, _item, _tags, _depth, _citem, _ctags, _cdepth */ function _parseData($parser, $text) { // Deocing mode added by Roland Haeder switch ($this->_decoding_mode) { case 'utf8_decode': $text = utf8_decode($text); break; case 'htmlentities': $text = htmlentities($text); break; } $clean = preg_replace("/\s/", "", $text); if ($clean) { $text = preg_replace("/^\s+/", "", $text)."\n"; if($this->_parse_mode == 'all') { if ( isset($this->_item[$this->_tags[$this->_depth[$this->get_parser_id($parser)]]]) && $this->_item[$this->_tags[$this->_depth[$this->get_parser_id($parser)]]] ) { $this->_item[$this->_tags[$this->_depth[$this->get_parser_id($parser)]]] .= $text; } else { $this->_item[$this->_tags[$this->_depth[$this->get_parser_id($parser)]]] = $text; } } elseif (isset($this->_parse_mode) && $this->_parse_mode == 'channel') { if ( isset($this->_citem[$this->_ctags[$this->_cdepth[$this->get_parser_id($parser)]]]) ) { $this->_citem[$this->_ctags[$this->_cdepth[$this->get_parser_id($parser)]]] .= $text; } else { $this->_citem[$this->_ctags[$this->_cdepth[$this->get_parser_id($parser)]]] = $text; } } } } /** * This Method allows you to choose if specific Parameters are displayed or not. These are: * image, channel, textinput, build and cache_update. If set to "hidden" those elements won't be displayed. * * @access public * @author Stefan Saasen * @param array $options * @see _display_opt */ function set_Options( $options = '' ) { if(is_array( $options )) { $this->_display_opt = $options; return TRUE; } else { unset($this->_display_opt); return FALSE; } } /** * This Method allows you to define the width of the table that holds the representation of the rdf/rss file. * * @access public * @author Stefan Saasen * @param int $width attribute width in tag * @see _table_width */ function set_table_width( $width = 400 ) { $this->_table_width = $width; return TRUE; } /** * This Method returns an assocative Array with available Options. * * The Keys are the Name of the Options to be set. * The Values are short Description of available Options. * * @access public * @author Stefan Saasen * @return array $options * @see _display_opt */ function get_Options() { $options = array( 'image' => "If 'image' is set to \"hidden\" no image provided by the RDF Publisher will be displayed.", 'channel' => "If 'channel' is set to \"hidden\" the Channel Meta Data (i.e the Title and the short description regarding the RDF Publisher will not be displayed", 'textinput' => "If set to \"hidden\" no Input Form will be displayed", 'build' => "If set to \"hidden\" the Build Date (if provided) of the RDF File will not be displayed", 'cache_update' => "If set to \"hidden\" the Update Date/Time of the cached Rdf File will not be displayed" ); return $options; } /** * This Method returns the Content of the RDF File in one string. The String actually holds the whole XML Document. * * @access public * @author Stefan Saasen * @param string $rdf RDF File (Location) * @return string XML Presentation of parsed RDF File * @see _cached_file, _remote_file, _cache_dir, _refresh, _update_cache() */ function cache() { // checks if the cache directory already exists // if not, the cache directory will be created if(!$this->_cache_dir_ok) { $this->_create_cache_dir(); } if($this->_use_dynamic_display == TRUE) { $this->_cached_file = md5('dynamic'.$this->salt.$this->_remote_file) . '.cache'; $this->_cache_type = 'normal'; } else { $this->_cached_file = md5($this->salt.$this->_remote_file) . '.cache'; $this->_cache_type = 'fast'; } $_cache_f = $this->_cache_dir.$this->_cached_file; if ( (!file_exists($_cache_f)) || (filemtime($_cache_f) < $this->_refresh) || (filesize($_cache_f) == 0)) { // We have to parse the remote file $this->_use_cached_file = FALSE; // --> we want to provide proper Information for Use in // get_cache_update_time() clearstatcache(); if($this->_use_dynamic_display == TRUE) { $_rdf = implode(' ', $this->_rdf_data()); // -> proxy if(!$_rdf) { $this->_throw_exception( $this->_remote_file.' is not available' ); } $this->_parse_xRDF( $_rdf ); $this->_update_cache( $_rdf ); $data = $this->_output; } else { $_rdf = implode(' ', $this->_rdf_data()); // -> proxy if(!$_rdf) { $this->_throw_exception( $this->_remote_file.' is not available' ); } $this->_parse_xRDF( $_rdf ); $this->_update_cache( $this->_output ); $data = $this->_output; } } else { // we can use the cached file $this->_use_cached_file = TRUE; if($this->_use_dynamic_display == TRUE) { $this->_parse_xRDF( implode(' ', file($_cache_f)) ); $data = $this->_output; } else { $data = implode(' ', file($_cache_f)); } } return trim($data); } // END cache() /** * This Methods creates the Cache Directory if the specified Directory does not exist. * * @access private * @author Stefan Saasen * @param string $dir Path to Directory. * @return boolean * @see _cache_dir, _cache_dir_ok */ function _create_cache_dir() { $path = ''; if(!@is_dir($this->_cache_dir)) { $arr = explode('/', $this->_cache_dir); $c = count($arr); if($arr[0]=='') { $path = '/'; } for($i = '0';$i<$c;$i++) { if($arr[$i]!='') { $path .= $arr[$i].'/'; if(!@is_dir($path)) { if(!@mkdir($path, 0777)) { $this->_throw_exception("failed to create directory:".$this->_cache_dir.".

Exception on Line: ".__LINE__); return FALSE; } } } } $this->_cache_dir_ok = TRUE; return TRUE; } else { $this->_cache_dir_ok = TRUE; return TRUE; } } // END _create_cache_dir() /** * This Method updates the cached RDF Files and synchronises them with their remote Counterparts. * * @access private * @author Stefan Saasen * @param string $rdf RDF File (Location) * @see _cache_dir, _cached_file, _throw_exception() */ function _update_cache( $content = '' ) { $_local = @fopen( $this->_cache_dir.$this->_cached_file, 'w' ); if(!$_local) { $this->_throw_exception( 'Cannot open '.$this->_cached_file.'

Exception at Line: '.__LINE__ ); return FALSE; } if (fwrite( $_local, $content) === FALSE) { $this->_throw_exception( 'Cannot write to '.$this->_cached_file.'
Exeception at Line: '.__LINE__); return FALSE; } fclose( $_local ); @chmod( $this->_cache_dir.$this->_cached_file, 0666); return TRUE; } // END _update_cache() /** * This Method returns the Date/Time of last Cache Update of the actually parsed RDF File. * * @access public * @author Stefan Saasen * @return string Date/Time of last Update * @see _cache_dir, _cached_file */ function get_cache_update_time() { return (file_exists($this->_cache_dir.$this->_cached_file))?date('d.m.Y H:i:s', filemtime($this->_cache_dir.$this->_cached_file)):'Cachemiss'; } // END get_cache_update_time() /** * This Method returns the Type of Cache that was used ('normal' or 'fast') * * @access public * @author Stefan Saasen * @param string $rdf RDF File (Location) * @return string Displays RDF Content ( using _display() ) * @see _remote_file, cache() */ function get_CacheType() { return $this->_cache_type; } /** * Returns true if cached file was used, otherwise false * * @access public * @author Stefan Saasen * @return array $options * @see _use_cached_file */ function is_cachedFile() { return $this->_use_cached_file; } /** * This Method deletes all the cached Files. * * Please keep in mind to use this method just as a 'manual garbage collection' * You should cache the rss/rdf files locally to avoid unnecessary traffic. * (Both for your visitors and the Publisher) * * @access public * @author Stefan Saasen * @see _cache_dir */ function clear_cache() { $dir = dir($this->_cache_dir); while($file=$dir->read()) { // Exclude directories if (is_file($dir->path.$file) && substr($file, -6, 6) != '.cache' && substr($file, -4, 4) != '.log') { if(!@unlink($dir->path.$file)) { $this->_throw_exception("Unable to unlink ".$dir->path.$file."
\n
\nException at Line: ".__LINE__ ); return FALSE; } // END - if } // END - if } // END - while $dir->close(); return TRUE; } // END clear_cache() /** * Cuts the String $string after $str_len and adds '... ' * * @access private * @param string $string String to be shortened * @param int $str_len length of the returned String (overall length including '... ') * @return string Cut String */ function _cut_string( $string, $str_len = '30' ) { if(strlen(trim($string))>$str_len) { $string = substr( trim($string) , 0, $str_len - 4); $string .= ' ...'; } return $string; } // END _cut_string() /** * this Method implements simple Garbage Collection * * @access private * @author Stefan Saasen * @see _cache_dir, gc_probability, gc_maxlifetime */ function _garbage_collection() { srand((double) microtime() * 1000000); if (mt_rand(1, 100) <= $this->gc_probability) { $dir = dir($this->_cache_dir); while($file=$dir->read()) { if (is_file($dir->path.$file) && substr($file, -6, 6) != '.cache' && substr($file, -4, 4) != '.log' && filemtime($dir->path.$file) <= time() - $this->_refresh ) { @unlink($dir->path.$file); } // END - if } $dir->close(); } // END if } /* ==== Proxy/Auth methods ==== */ /** * this method sets a proxy server * * @access public * @param string $phost Proxy Host * @param string $pport Prox Port * @author Marco Kraus */ function set_proxy($phost, $pport) { $this->_use_proxy = TRUE; if ($phost != '') $this->_phost = $phost; if ($pport != '') $this->_pport = $pport; } /** * this method sets a proxy server authentification * * @access public * @param string $pname Username * @param string $ppaswd Password * @author Marco Kraus */ function set_proxy_auth( $pname, $ppasswd ) { $this->_use_proxy_auth = TRUE; if ($pname != '') $this->_pname = $pname; if ($ppasswd != '') $this->_ppasswd = $ppasswd; } /** * gets _remote_file into an array * * needed, cause if you use a proxy, you have to open * a raw-tcp-socket to get the data * * @access private * @author Marco Kraus * @return array * @see _use_proxy, cache() */ function _rdf_data() { if ( $this->_use_proxy == TRUE ) { // we need a raw socket here to connect to proxy $fp = fsockopen($this->_phost,$this->_pport); if (!$fp) { $this->_throw_exception( $this->_remote_file.' is not available with proxy' ); } else { if ( $this->_use_proxy_auth == TRUE ) { fputs($fp, "GET ".$this->_remote_file." HTTP/1.0\r\nUser-Agent: Fase4 RDF-Reader/1.40 modified by Quix0r\r\n\r\n"); } else { fputs($fp, "GET ".$this->_remote_file." HTTP/1.0\r\nUser-Agent: Fase4 RDF-Reader/1.40 modified by Quix0r\r\nProxy-Authorization: Basic ".base64_encode("$this->_pname:$this->_ppasswd") ."\r\n\r\n"); } } for ( $i = '0'; !feof ($fp) ; $i++) { $usable_data[$i] = ""; $usable_data[$i] = fgets($fp,4096); // PARSE HEADER ---- first line has to be _remote_file, 0, 7) != 'http://') { $this->_throw_exception( 'Cannot find http:// in '.$this->_remote_file.'!' ); return ''; } else { // Extract host information $host = substr($this->_remote_file, 7); // Extract the GET part $get = '/'; if (strpos($host, '/') > 0) { $get = substr($host, strpos($host, '/')); $host = substr($host, 0, strpos($host, '/')); } // Extract port $port = '80'; if (strpos($host, ':') > 0) { $port = substr($host, (strpos($host, ':') + 1)); $host = substr($host, 0, (strpos($host, ':') - 1)); } // Start connection to server $fp = fsockopen($host, $port); if (!$fp) { $this->_throw_exception( $this->_remote_file.' is maybe not available.' ); return ''; } // Repare request line $request = sprintf("GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Fase4 RDF-Reader/1.40 modified by Quix0r\r\n\r\n", $get, $host); // Send request out fputs($fp, $request); $reply = ''; $isContent = FALSE; $dummy = ''; // Read reply $i=0; while ( !feof($fp) ) { $read = trim(fgets($fp, 4096)); if (substr($read, 0, 5) == ' 0) && (count($reply) == 0) && (!$isContent)) { // Transfer content from dummy $reply = $content; } fclose($fp); //die(htmlentities($reply)); return $reply; } } } // END _rdf_data() } // END class ?>