2 /* $Id: rdf.class.php,v 1.40 2003/07/06 20:33:58 sts Exp $ */
\r
5 // +----------------------------------------------------------------------+
\r
7 // | Copyright (c) 2001 Stefan Saasen |
\r
8 // +----------------------------------------------------------------------+
\r
9 // | The contents of this file are subject to the Mozilla Public License |
\r
10 // | Version 1.1 (the "License"); you may not use this file except in |
\r
11 // | compliance with the License. You may obtain a copy of the License at |
\r
12 // | http://www.mozilla.org/MPL/ |
\r
14 // | Software distributed under the License is distributed on an "AS IS" |
\r
15 // | basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See |
\r
16 // | the License for the specific language governing rights and |
\r
17 // | limitations under the License. |
\r
18 // +----------------------------------------------------------------------+
\r
20 // | Maintainer and initial developer: |
\r
21 // | Stefan Saasen <s@fase4.com> |
\r
23 // | Proxy and authentication methods added by: |
\r
24 // | Marco Kraus <marco.kraus@siemens.com> |
\r
26 // | Decoding of data by htmlentities or utf8_decode added by: |
\r
27 // | Roland Haeder <webmaster@mxchange.org> |
\r
29 // +----------------------------------------------------------------------+
\r
31 // | @link http://www.fase4.com/rdf/ Latest release |
\r
32 // +----------------------------------------------------------------------+
\r
37 * This class offers methods to parse RSS Files
\r
39 * @link http://www.fase4.com/rdf/ Latest release of this class
\r
41 * @copyright Copyright (c) 2001 fase4.com. All rights reserved.
\r
42 * @author Stefan Saasen <s@fase4.com>
\r
43 * @version 1.7 ($Date: 2003/07/06 20:33:58 $) $Revision: 1.40 $
\r
50 * Word-wrapping mode for description, set it to 0 do disable this feature! Ommits _use_nl2br!
\r
55 var $_word_wrap = 0;
\r
58 * Wether to recode \n -> <BR> or not in description
\r
63 var $_use_nl2br = true;
\r
66 * Sets the decoding mode of the read data (UTF8 scrambles some german umlauts here!)
\r
68 * "htmlentities" - Use the function htmlentities()
\r
69 * "utf8_decode" - Use the function ut8_decode() when you have UTF8 encoded text
\r
74 var $_decoding_mode = "utf8_decode";
\r
77 * If $_link_target is set a target='xxx' attribute in each <a /> and <form /> html tag will be added
\r
79 * Possible values are "_blank", "_content", "_parent", "_self", "_top"
\r
84 var $_link_target = "_blank";
\r
87 * vars for proxy settings - Prox Host
\r
95 * vars for proxy settings - Prox Port
\r
103 * vars for proxy settings - Prox Username
\r
111 * vars for proxy settings - Prox Password
\r
116 var $_ppasswd = "";
\r
119 * just a flag for checking if proxy-support should be enabled
\r
120 * set default to false (will be enabled if set_proxy is called)
\r
126 var $_use_proxy = false;
\r
129 * just a flag for checking if proxy-support with authentication
\r
130 * should be enabled
\r
131 * set default to false (will be enabled if set_proxy is called)
\r
137 var $_use_proxy_auth = false;
\r
140 * The time the Files will be cached (in seconds).
\r
145 var $_refresh = 60; // int
\r
148 * The Name of the cached File.
\r
153 var $_cached_file = ""; // String
\r
156 * Indicates whether the cached or the remote file was used.
\r
161 var $_use_cached_file = true;
\r
164 * (fast|normal) depends on _use_dynamic_display(). _use_dynamic_display( TRUE ) -> 'normal', otherwise 'fast'
\r
169 var $_cache_type = "fast";
\r
172 * The Name of the Remote File.
\r
177 var $_remote_file = "";
\r
180 * Path to the Cache Directory.
\r
185 var $_cache_dir = "cache/"; // String
\r
188 * Indicates whether the Creating of the Cache Directory needs to be done or not.
\r
193 var $_cache_dir_ok = false;
\r
196 * Type of the file to be parsed (RSS or RDF).
\r
198 * The Type depends on the root node
\r
203 var $_type = "rss"; // string (rss or rdf)
\r
206 * Array of Display Settings.
\r
208 * Specific Parameters can be set to hidden. These are:
\r
209 * image, channel and textinput. If set to "hidden" those elements won't be displayed.
\r
214 var $_display_opt = array(
\r
219 'cache_update' => '',
\r
226 * Defines the width attribute in the table that holds the rdf/rss representation
\r
230 * @see see_table_width()
\r
232 var $_table_width = "100%";
\r
235 * Indicates whether or not to use dynamic Display Settings
\r
240 var $_use_dynamic_display = false;
\r
248 var $_item_count = 0;
\r
251 * No of max <item>s
\r
256 var $_max_count = false;
\r
259 * Array containing the content of <channel />
\r
264 var $_array_channel = array();
\r
267 * Array containing the content of each <item />
\r
272 var $_array_item = array();
\r
275 * Array containing the content of <textinput />
\r
280 var $_array_textinput = array();
\r
283 * Array containing the content of <image />
\r
288 var $_array_image = array();
\r
291 * Array containing the Channel content. Just For internal XML Parser Purposes.
\r
296 var $_citem = array();
\r
299 * Array containing the Channel Parser Depth. Just For internal XML Parser Purposes.
\r
304 var $_cdepth = array();
\r
307 * Array containing the Channel tags. Just For internal XML Parser Purposes.
\r
312 var $_ctags = array( "x" );
\r
315 * Array containing the Channel content. Just For internal XML Parser Purposes.
\r
320 var $_item = array(); // Array
\r
323 * Array containing the Channel Parser Depth. Just For internal XML Parser Purposes.
\r
328 var $_depth = array(); // Array
\r
331 * Array containing the tags. Just For internal XML Parser Purposes.
\r
336 var $_tags = array( "x" ); // Array
\r
339 * Garbage collection: probability in percent
\r
341 * @var integer 0 => never
\r
344 var $gc_probability = 1;
\r
357 var $_parse_mode = "";
\r
362 // Salt for hashing
\r
366 * Constructor of our Class
\r
368 * This Method checks if the Cache Directory can be found. Otherwise it tries to creat the Cache Directory at the specified Path.
\r
369 * Additionally the Refresh Time is set to a default Value of 1200s (20 min).
\r
372 * @author Stefan Saasen <s@fase4.com>
\r
375 function fase4_rdf()
\r
377 // default Value, to be overwritten in set_refresh()
\r
378 $this->_refresh = (time() - 1200);
\r
379 $this->_clear_cItems();
\r
380 $this->_clear_Items();
\r
384 * This Method starts the parsing of the specified RDF File. The File can be a local or a remote File.
\r
387 * @author Stefan Saasen <s@fase4.com>
\r
388 * @param string $rdf RDF File (Location)
\r
389 * @return string Displays RDF Content ( using _display() )
\r
390 * @see _remote_file, cache()
\r
392 function parse_RDF( $rdf )
\r
394 unset($this->_array_item);
\r
395 $this->_remote_file = $rdf;
\r
396 $this->out .= "<!-- http://www.fase4.com/rdf/ -->";
\r
397 $this->out .= "<table width=\"".$this->_table_width."\">";
\r
398 $this->out .= $this->cache();
\r
399 $this->out .= "</table>";
\r
400 $this->_output = "";
\r
401 $this->_item_count = 0;
\r
406 * This Method is called when all parsing is finished to use the garbage collection
\r
409 * @author Stefan Saasen <s@fase4.com>
\r
410 * @param string $rdf RDF File (Location)
\r
411 * @return string Displays RDF Content ( using _display() )
\r
412 * @see _remote_file, cache()
\r
414 function finish($return = false)
\r
422 $this->_garbage_collection();
\r
426 * With this method you can decide whether to use the normal cache and dynamic display Options or to use a static cache.
\r
428 * 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.
\r
429 * In this case you can not modify the display settings.
\r
430 * processing time: ( 1.4792) --> remote file
\r
431 * processing time: ( 0.0313) --> using 'normal cache' with display Modification turned on.
\r
432 * processing time: ( 0.0019) --> using 'fast cache'
\r
435 * @author Stefan Saasen <s@fase4.com>
\r
436 * @param string $rdf RDF File (Location)
\r
437 * @return string Displays RDF Content ( using _display() )
\r
438 * @see _remote_file, cache()
\r
440 function use_dynamic_display( $bool )
\r
442 $this->_use_dynamic_display = $bool;
\r
447 * This Method avtually parses the XML data.
\r
450 * @author Stefan Saasen <s@fase4.com>
\r
451 * @param string $data RDF File XML Data
\r
452 * @see _clear_Items()
\r
454 function _parse_xRDF( $data )
\r
456 $this->_clear_Items();
\r
457 $xml_parser = xml_parser_create();
\r
458 xml_set_object($xml_parser,$this);
\r
459 xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
\r
460 xml_set_element_handler($xml_parser, "_startElement", "_endElement");
\r
461 xml_set_character_data_handler($xml_parser, "_parseData");
\r
462 if (!xml_parse($xml_parser, trim($data))) {
\r
463 $this->_throw_exception(sprintf("XML error: %s at line %d",
\r
464 xml_error_string(xml_get_error_code($xml_parser)),
\r
465 xml_get_current_line_number($xml_parser))."<br /><br />Exception in function parse_RDF().");
\r
467 xml_parser_free($xml_parser);
\r
472 * This Methods allows you to set the Refresh Time
\r
475 * @author Stefan Saasen <s@fase4.com>
\r
476 * @param int $seconds time files will be cached (in seconds).
\r
480 function set_refresh( $seconds )
\r
482 $this->_refresh = (time() - $seconds);
\r
486 function set_salt( $saltPara )
\r
488 $this->salt = $saltPara;
\r
493 * This Methods allows you to set the No. of <item>s to display
\r
496 * @param int $int No of max <item>s
\r
497 * @author Stefan Saasen <s@fase4.com>
\r
499 * @see _max_count, _endElement()
\r
501 function set_max_item( $int )
\r
503 $this->_max_count = $int;
\r
508 * This Methods allows you to set the Cache Directory
\r
511 * @author Stefan Saasen <s@fase4.com>
\r
512 * @param string $dir Path to Directory.
\r
516 function set_CacheDir( $dir )
\r
518 if(substr($dir, -1) != "/") {
\r
521 $this->_cache_dir = $dir;
\r
525 * This Method displays Error Messages and terminates the Execution of the Script
\r
528 * @param string $msg Message to display on failure
\r
529 * @author Stefan Saasen <s@fase4.com>
\r
531 function _throw_exception( $msg )
\r
533 $this->out .= "<div style=\"font-family: verdana, helvetica, arial, sans-serif;font-size:11px; color: #6699cc;margin-top:10px;margin-bottom:10px;\" align=\"center\">fase4 RDF Error: ".$msg."</div>";
\r
538 * This Method clears the Array containig the Items.
\r
541 * @author Stefan Saasen <s@fase4.com>
\r
544 function _clear_Items( ) {
\r
545 $this->_item = array(
\r
552 'lastBuildDate'=>"",
\r
558 * This Method clears the Array containig the Channel Items.
\r
561 * @author Stefan Saasen <s@fase4.com>
\r
564 function _clear_cItems( ) {
\r
565 $this->_citem = array(
\r
572 'managingEditor'=>"",
\r
575 'lastBuildDate'=>"",
\r
592 * XML Parser Start Element Handler
\r
595 * @author Stefan Saasen <s@fase4.com>
\r
596 * @param mixed $parser a reference to the XML parser calling the handler.
\r
597 * @param string $name contains the name of the element for which this handler is called.
\r
598 * @param string $attrs contains an associative array with the element's attributes (if any).
\r
599 * @see _get_ChannelData(), _clear_Items(), _type, _parse_mode, _depth, _tags, _cdepth, _ctags
\r
601 function _startElement($parser, $name, $attrs) {
\r
602 // We have to determine, which type of xml data we have to parse
\r
603 if($name == "rss") {
\r
604 $this->_type = "rss";
\r
605 } elseif($name == "rdf:RDF" OR $name == "rdf") {
\r
606 $this->_type = "rdf";
\r
610 if ( $name == "channel" AND $this->_type != "rdf" ) {
\r
611 $this->_parse_mode = "channel";
\r
612 } elseif ( ($name=="item")
\r
614 ||($name=="textinput")
\r
615 ||(($name=="channel") && ($this->_type != "rss")) ) {
\r
616 if($this->_parse_mode=="channel") {
\r
617 $this->_get_ChannelData( $parser );
\r
619 $this->_parse_mode = "all";
\r
622 if( !isset( $this->_depth[$parser] ) ) {
\r
623 $this->_depth[$parser] = 0;
\r
625 $this->_depth[$parser]++;
\r
626 array_push($this->_tags, $name);
\r
628 if( !isset( $this->_cdepth[$parser] ) ) {
\r
629 $this->_cdepth[$parser] = 0;
\r
631 $this->_cdepth[$parser]++;
\r
632 array_push($this->_ctags, $name);
\r
633 } // END _startElement()
\r
636 * Retrives the Channel Data in <rss> File
\r
639 * @author Stefan Saasen <s@fase4.com>
\r
640 * @param mixed $parser a reference to the XML parser calling the handler.
\r
641 * @see _output, _display_opt, _citem
\r
643 function _get_ChannelData( $parser )
\r
645 $this->_citem["link"] = trim($this->_citem["link"]);
\r
646 if (($this->_display_opt["sitelink"] == $this->_citem["link"]) && (!empty($this->_display_opt["reflink"])) && (!empty($this->_display_opt["refid"])))
\r
648 $this->_citem["link"] .= $this->_display_opt["reflink"].$this->_display_opt["refid"];
\r
651 if( empty($this->_display_opt["channel"]) OR
\r
652 $this->_display_opt["channel"] != "hidden") {
\r
653 $this->_output .= "<tr><td>\n";
\r
654 $this->_output .= "<table border=\"0\" width=\"100%\" class=\"fase4_rdf_meta\" cellspacing=\"5\" cellpadding=\"2\">\n";
\r
655 $this->_output .= "<tr><td class=\"fase4_rdf_main_title\"><div class=\"fase4_rdf_main_title\">".htmlspecialchars($this->_citem["title"])."</div></td></tr>\n";
\r
656 $this->_output .= "<tr><td class=\"fase4_rdf\">".strip_tags($this->_citem["description"], "<a>, <img>")."</td></tr>\n";
\r
657 $this->_output .= "<tr><td> </td></tr>\n";
\r
658 $this->_output .= "<tr><td class=\"fase4_rdf\">\n";
\r
659 if(isset($this->_display_opt["build"]) && $this->_display_opt["build"] != "hidden") {
\r
660 if($this->_citem["lastBuildDate"]){$this->_output .= "build: ". $this->_citem["lastBuildDate"]."<br />";}
\r
662 if(isset($this->_display_opt["cache_update"]) && $this->_display_opt["cache_update"] != "hidden" && ( $_update = $this->get_cache_update_time()) ) {
\r
663 $this->_output .= "cache update: ".$_update."<br />\n";
\r
665 $this->_output .= "<a href=\"".$this->_citem["link"]."\" ";
\r
666 if(isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; }
\r
667 $this->_output .= ">".$this->_cut_string($this->_citem["link"])."</a>";
\r
668 $this->_output .= "</td></tr>\n";
\r
669 $this->_output .= "<tr><td><hr noshade width=\"100%\" size=\"1\"></td></tr>\n";
\r
670 $this->_output .= "</table></td></tr>";
\r
672 $this->_array_channel = array( "title"=>$this->_citem["title"],
\r
673 "link"=>$this->_citem["link"],
\r
674 "description"=>$this->_citem["description"],
\r
675 "lastBuildDate"=>$this->_citem["lastBuildDate"]);
\r
679 * XML Parser End Element Handler
\r
682 * @author Stefan Saasen <s@fase4.com>
\r
683 * @param mixed $parser a reference to the XML parser calling the handler.
\r
684 * @param string $name contains the name of the element for which this handler is called.
\r
685 * @see _clear_Items(), _type, _parse_mode, _depth, _tags, _cdepth, _ctags, _item, _output, _display_opt
\r
687 function _endElement($parser, $name) {
\r
688 array_pop($this->_tags);
\r
689 $this->_depth[$parser]--;
\r
690 array_pop($this->_ctags);
\r
691 $this->_cdepth[$parser]--;
\r
692 $this->_item["link"] = trim($this->_item["link"]);
\r
693 if ((!empty($this->_display_opt["refid"])) && (!empty($this->_item["link"])))
\r
695 if (!ereg("refid=", $this->_item["link"])) $this->_item["link"] .= "?refid=" . $this->_display_opt["refid"];
\r
699 if(empty($this->_max_count) OR $this->_item_count < $this->_max_count) {
\r
700 if($this->_item["title"] != $this->_item["description"]
\r
701 AND $this->_item["description"]) {
\r
703 // word-wrapping added by Roland Haeder <webmaster@mxchange.org>
\r
704 if (($this->_word_wrap > 0) && (strlen($this->_item["description"]) > $this->_word_wrap))
\r
706 // Switch off _use_nl2br
\r
707 $this->_use_nl2br = false;
\r
708 // First remove all \n
\r
709 $this->_item["description"] = str_replace('\n', ' ', $this->_item["description"]);
\r
710 // Wrap with <br />\n
\r
711 $this->_item["description"] = wordwrap($this->_item["description"], $this->_word_wrap, "*<br>\n");
\r
713 elseif (($this->_word_wrap == 0) && (!$this->_use_nl2br))
\r
715 // Strip tags out instead when word-wrap is disabled
\r
716 $this->_item["description"] = strip_tags($this->_item["description"], "<a>, <img>");
\r
719 // nl2br added by Roland Haeder <webmaster@mxchange.org>
\r
720 if ($this->_use_nl2br) $this->_item["description"] = nl2br($this->_item["description"]);
\r
722 $this->_output .= "<tr><td class=\"fase4_rdf_title\"><div class=\"fase4_rdf_title\"><a class=\"fase4_rdf_title\" href=\"".$this->_item["link"]."\" ";
\r
723 if(isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; }
\r
724 $this->_output .= ">".strip_tags($this->_item["title"], "<a>, <img>")."</a> (".$this->_item["pubDate"].")</div></td></tr>\n";
\r
725 $this->_output .= "<tr><td class=\"fase4_rdf\">".$this->_item["description"]."</td></tr>\n";
\r
726 // we just display the <hr> if there is a description
\r
727 $this->_output .= "<tr><td><hr noshade=\"noshade\" size=\"1\" /></td></tr>\n";
\r
729 $this->_output .= "<tr><td class=\"fase4_rdf\">\n";
\r
730 $this->_output .= "<a href=\"".$this->_item["link"]."\" ";
\r
731 if(isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; }
\r
732 $this->_output .= ">".$this->_item["title"]."</a></td></tr>\n";
\r
734 $this->_array_item[] = array( "title"=>$this->_item["title"],
\r
735 "link"=>$this->_item["link"],
\r
736 "description"=>$this->_item["description"]);
\r
737 ++$this->_item_count;
\r
739 $this->_clear_Items();
\r
742 if(isset($this->_display_opt["image"]) && ($this->_display_opt["image"] != "hidden") && $this->_item["url"]) {
\r
743 $this->_output .= "<tr><td class=\"fase4_rdf\">\n";
\r
744 $this->_output .= "<a href=\"".$this->_item["link"]."\" ";
\r
745 if(isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; }
\r
746 $this->_output .= "><img src=\"".$this->_item["url"]."\"";
\r
747 if(isset($this->_item["width"]) && isset($this->_item["height"])) {
\r
748 $this->_output .= " width=\"".$this->_item["width"]."\" height=\"".$this->_item["height"]."\"";
\r
750 $this->_output .= " alt=\"".$this->_item["title"]."\" border=\"0\" /></a></td></tr>\n";
\r
752 $this->_array_image[] = array( "url"=>$this->_item["url"],
\r
753 "link"=>$this->_item["link"],
\r
754 "width"=>$this->_item["width"],
\r
755 "height"=>$this->_item["height"]);
\r
756 $this->_clear_Items();
\r
757 } elseif( isset($this->_display_opt["image"] ) && ($this->_display_opt["image"] == "hidden") ) {
\r
758 $this->_clear_Items();
\r
763 if(isset($this->_display_opt["channel"]) AND $this->_display_opt["channel"] != "hidden" AND $this->_item["title"] != "") {
\r
764 $this->_output .= "<tr><td>\n";
\r
765 $this->_output .= '<table border="0" width="100%" class="fase4_rdf_meta" cellspacing="5" cellpadding="2">'."\n";
\r
766 $this->_output .= "<tr><td class=\"fase4_rdf\"><div class=\"fase4_rdf_title\">".htmlspecialchars($this->_item["title"])."</div></td></tr>\n";
\r
767 $this->_output .= "<tr><td class=\"fase4_rdf\">".strip_tags($this->_item["description"], "<a>, <img>")."</td></tr>\n";
\r
768 $this->_output .= "<tr><td> </td></tr>\n";
\r
769 $this->_output .= "<tr><td class=\"fase4_rdf\">\n";
\r
770 if($this->_display_opt["build"] != "hidden") {
\r
771 if($this->_item["lastBuildDate"]){$this->_output .= "build: ". $this->_item["lastBuildDate"]."<br />";}
\r
773 if($this->_display_opt["cache_update"] != "hidden" && ( $_update = $this->get_cache_update_time()) ) {
\r
774 $this->_output .= "cache update: ".$_update."<br />\n";
\r
776 $this->_output .= "<a href=\"".$this->_item["link"]."\" ";
\r
777 if(isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; }
\r
778 $this->_output .= ">".$this->_cut_string($this->_item["link"])."</a>\n";
\r
779 $this->_output .= "</td></tr>\n";
\r
780 $this->_output .= "</table></td></tr>\n";
\r
782 $this->_array_channel = array( "title"=>$this->_item["title"],
\r
783 "link"=>$this->_item["link"],
\r
784 "description"=>$this->_item["description"],
\r
785 "lastBuildDate"=>$this->_item["lastBuildDate"]);
\r
786 $this->_clear_Items();
\r
787 $this->_clear_cItems();
\r
790 if(isset($this->_display_opt["textinput"]) && ($this->_display_opt["textinput"] != "hidden") && $this->_item["name"] && $this->_item["link"]) {
\r
791 $this->_output .= "<tr><td class=\"fase4_rdf\">\n";
\r
792 $this->_output .= "<form action=\"".$this->_item["link"]."\" ";
\r
793 if(isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; }
\r
794 $this->_output .= "method=\"get\">\n";
\r
795 $this->_output .= "<div class=\"fase4_rdf_title\">".$this->_item["title"]."</div>";
\r
796 $this->_output .= strip_tags($this->_item["description"], "<a>, <img>")."<br><br>\n";
\r
797 $this->_output .= "<input class=\"fase4_rdf_input\" type=\"text\" name=\"".$this->_item["name"]."\"> \n";
\r
798 $this->_output .= "<input class=\"fase4_rdf_input\" type=\"submit\" value=\"go\">";
\r
799 $this->_output .= "</form>\n";
\r
800 $this->_output .= "</td></tr>\n";
\r
801 $this->_array_textinput = array( "title"=>$this->_item["title"],
\r
802 "name"=>$this->_item["name"],
\r
803 "link"=>$this->_item["link"],
\r
804 "description"=>$this->_item["description"]);
\r
805 $this->_clear_Items();
\r
806 } elseif( isset($this->_display_opt["textinput"]) && ($this->_display_opt["textinput"] == "hidden") ) {
\r
807 $this->_clear_Items();
\r
815 * This Method returns the data from the <channel /> paragraph.
\r
818 * @author Stefan Saasen <s@fase4.com>
\r
820 * @see _array_channel
\r
822 function get_array_channel( )
\r
824 return $this->_array_channel;
\r
828 * This Method returns the data from each <item /> paragraph.
\r
831 * @author Stefan Saasen <s@fase4.com>
\r
835 function get_array_item( )
\r
837 return $this->_array_item;
\r
841 * This Method returns the data from <textinput />.
\r
844 * @author Stefan Saasen <s@fase4.com>
\r
846 * @see _array_textinput
\r
848 function get_array_textinput( )
\r
850 return $this->_array_textinput;
\r
854 * This Method returns the data from <image />.
\r
857 * @author Stefan Saasen <s@fase4.com>
\r
859 * @see _array_image
\r
861 function get_array_image( )
\r
863 return $this->_array_image;
\r
867 * XML Parser Data Handler
\r
870 * @author Stefan Saasen <s@fase4.com>
\r
871 * @param mixed $parser a reference to the XML parser calling the handler.
\r
872 * @param string $text contains the character data as a string.
\r
873 * @see _parse_mode, _item, _tags, _depth, _citem, _ctags, _cdepth
\r
875 function _parseData($parser, $text)
\r
877 // Deocing mode added by Roland Haeder <webmaster@mxchange.org>
\r
878 switch ($this->_decoding_mode)
\r
880 case "utf8_decode":
\r
881 $text = utf8_decode($text);
\r
884 case "htmlentities":
\r
885 $text = htmlentities($text);
\r
889 $clean = preg_replace("/\s/", "", $text);
\r
891 $text = preg_replace("/^\s+/", "", $text)."\n";
\r
892 if($this->_parse_mode == "all") {
\r
893 if ( isset($this->_item[$this->_tags[$this->_depth[$parser]]]) &&
\r
894 $this->_item[$this->_tags[$this->_depth[$parser]]] ) {
\r
895 $this->_item[$this->_tags[$this->_depth[$parser]]] .= $text;
\r
897 $this->_item[$this->_tags[$this->_depth[$parser]]] = $text;
\r
899 } elseif (isset($this->_parse_mode) && $this->_parse_mode == "channel") {
\r
900 if ( isset($this->_citem[$this->_ctags[$this->_cdepth[$parser]]]) ) {
\r
901 $this->_citem[$this->_ctags[$this->_cdepth[$parser]]] .= $text;
\r
903 $this->_citem[$this->_ctags[$this->_cdepth[$parser]]] = $text;
\r
910 * This Method allows you to choose if specific Parameters are displayed or not. These are:
\r
911 * image, channel, textinput, build and cache_update. If set to "hidden" those elements won't be displayed.
\r
914 * @author Stefan Saasen <s@fase4.com>
\r
915 * @param array $options
\r
916 * @see _display_opt
\r
918 function set_Options( $options = "" )
\r
920 if(is_array( $options )) {
\r
921 $this->_display_opt = $options;
\r
924 unset($this->_display_opt);
\r
930 * This Method allows you to define the width of the table that holds the representation of the rdf/rss file.
\r
933 * @author Stefan Saasen <s@fase4.com>
\r
934 * @param int $width attribute width in tag <table>
\r
935 * @see _table_width
\r
937 function set_table_width( $width = 400 )
\r
939 $this->_table_width = $width;
\r
944 * This Method returns an assocative Array with available Options.
\r
946 * The Keys are the Name of the Options to be set.
\r
947 * The Values are short Description of available Options.
\r
950 * @author Stefan Saasen <s@fase4.com>
\r
951 * @return array $options
\r
952 * @see _display_opt
\r
954 function get_Options()
\r
956 $options = array( "image"=>"If 'image' is set to \"hidden\" no image provided by the RDF Publisher will be displayed.",
\r
957 "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",
\r
958 "textinput"=>"If set to \"hidden\" no Input Form will be displayed",
\r
959 "build"=>"If set to \"hidden\" the Build Date (if provided) of the RDF File will not be displayed",
\r
960 "cache_update"=>"If set to \"hidden\" the Update Date/Time of the cached Rdf File will not be displayed");
\r
965 * This Method returns the Content of the RDF File in one string. The String actually holds the whole XML Document.
\r
968 * @author Stefan Saasen <s@fase4.com>
\r
969 * @param string $rdf RDF File (Location)
\r
970 * @return string XML Presentation of parsed RDF File
\r
971 * @see _cached_file, _remote_file, _cache_dir, _refresh, _update_cache()
\r
975 // checks if the cache directory already exists
\r
976 // if not, the cache directory will be created
\r
977 if(!$this->_cache_dir_ok) {
\r
978 $this->_create_cache_dir();
\r
980 if($this->_use_dynamic_display == true) {
\r
981 $this->_cached_file = md5("dynamic".$this->salt.$this->_remote_file);
\r
982 $this->_cache_type = "normal";
\r
984 $this->_cached_file = md5($this->salt.$this->_remote_file);
\r
985 $this->_cache_type = "fast";
\r
988 $_cache_f = $this->_cache_dir.$this->_cached_file;
\r
990 if ( (!file_exists($_cache_f)) || (filemtime($_cache_f) < $this->_refresh) || (filesize($_cache_f) == 0)) {
\r
991 // We have to parse the remote file
\r
992 $this->_use_cached_file = false;
\r
993 // --> we want to provide proper Information for Use in
\r
994 // get_cache_update_time()
\r
996 if($this->_use_dynamic_display == true) {
\r
997 $_rdf = @implode(" ", $this->_rdf_data()); // -> proxy
\r
999 $this->_throw_exception( $this->_remote_file." is not available" );
\r
1001 $this->_parse_xRDF( $_rdf );
\r
1002 $this->_update_cache( $_rdf );
\r
1003 $data = $this->_output;
\r
1005 $_rdf = @implode(" ", $this->_rdf_data()); // -> proxy
\r
1007 $this->_throw_exception( $this->_remote_file." is not available" );
\r
1009 $this->_parse_xRDF( $_rdf );
\r
1010 $this->_update_cache( $this->_output );
\r
1011 $data = $this->_output;
\r
1014 // we can use the cached file
\r
1015 $this->_use_cached_file = true;
\r
1016 if($this->_use_dynamic_display == true) {
\r
1017 $this->_parse_xRDF( implode(" ", file($_cache_f)) );
\r
1018 $data = $this->_output;
\r
1020 $data = @implode(" ", file($_cache_f));
\r
1023 return trim($data);
\r
1027 * This Methods creates the Cache Directory if the specified Directory does not exist.
\r
1030 * @author Stefan Saasen <s@fase4.com>
\r
1031 * @param string $dir Path to Directory.
\r
1033 * @see _cache_dir, _cache_dir_ok
\r
1035 function _create_cache_dir()
\r
1038 if(!@is_dir($this->_cache_dir)) {
\r
1039 $arr = explode("/", $this->_cache_dir);
\r
1044 for($i = 0;$i<$c;$i++)
\r
1046 if($arr[$i]!="") {
\r
1047 $path .= $arr[$i]."/";
\r
1048 if(!@is_dir($path)) {
\r
1049 if(!@mkdir($path, 0777)) {
\r
1050 $this->_throw_exception("failed to create directory:<b>".$this->_cache_dir."</b>.<br /><br />Exception on Line: ".__LINE__);
\r
1056 $this->_cache_dir_ok = true;
\r
1059 $this->_cache_dir_ok = true;
\r
1062 } // END _create_cache_dir()
\r
1065 * This Method updates the cached RDF Files and synchronises them with their remote Counterparts.
\r
1068 * @author Stefan Saasen <s@fase4.com>
\r
1069 * @param string $rdf RDF File (Location)
\r
1070 * @see _cache_dir, _cached_file, _throw_exception()
\r
1072 function _update_cache( $content = "" )
\r
1074 $_local = @fopen( $this->_cache_dir.$this->_cached_file, 'w' );
\r
1076 $this->_throw_exception( "Cannot open ".$this->_cached_file."<br /><br />Exception at Line: ".__LINE__ );
\r
1079 if (fwrite( $_local, $content) === false) {
\r
1080 $this->_throw_exception( "Cannot write to ".$this->_cached_file."<br /<br />Exeception at Line: ".__LINE__);
\r
1083 fclose( $_local );
\r
1084 @chmod( $this->_cache_dir.$this->_cached_file, 0666);
\r
1086 } // END _update_cache()
\r
1089 * This Method returns the Date/Time of last Cache Update of the actually parsed RDF File.
\r
1092 * @author Stefan Saasen <s@fase4.com>
\r
1093 * @return string Date/Time of last Update
\r
1094 * @see _cache_dir, _cached_file
\r
1096 function get_cache_update_time()
\r
1098 return (file_exists($this->_cache_dir.$this->_cached_file))?date("d.m.Y H:i:s", filemtime($this->_cache_dir.$this->_cached_file)):"Cachemiss";
\r
1099 } // END get_cache_update_time()
\r
1102 * This Method returns the Type of Cache that was used ('normal' or 'fast')
\r
1105 * @author Stefan Saasen <s@fase4.com>
\r
1106 * @param string $rdf RDF File (Location)
\r
1107 * @return string Displays RDF Content ( using _display() )
\r
1108 * @see _remote_file, cache()
\r
1110 function get_CacheType()
\r
1112 return $this->_cache_type;
\r
1116 * Returns true if cached file was used, otherwise false
\r
1119 * @author Stefan Saasen <s@fase4.com>
\r
1120 * @return array $options
\r
1121 * @see _use_cached_file
\r
1123 function is_cachedFile()
\r
1125 return $this->_use_cached_file;
\r
1129 * This Method deletes all the cached Files.
\r
1131 * Please keep in mind to use this method just as a 'manual garbage collection'
\r
1132 * You should cache the rss/rdf files locally to avoid unnecessary traffic.
\r
1133 * (Both for your visitors and the Publisher)
\r
1136 * @author Stefan Saasen <s@fase4.com>
\r
1139 function clear_cache()
\r
1141 $dir = dir($this->_cache_dir);
\r
1142 while($file=$dir->read()) {
\r
1143 if($file!="." && $file!="..") {
\r
1144 if(!@unlink($dir->path.$file)) {
\r
1145 $this->_throw_exception(
\r
1146 "Unable to unlink ".$dir->path.$file
\r
1147 ."<br /><br />Exception at Line: ".__LINE__ );
\r
1154 } // END clear_cache()
\r
1157 * Cuts the String $string after $str_len and adds "... "
\r
1160 * @param string $string String to be shortened
\r
1161 * @param int $str_len length of the returned String (overall length including "... ")
\r
1162 * @return string Cut String
\r
1164 function _cut_string( $string, $str_len = "30" )
\r
1166 if(strlen(trim($string))>$str_len) {
\r
1167 $string = substr( trim($string) , 0, $str_len - 4);
\r
1168 $string .= " ...";
\r
1171 } // END _cut_string()
\r
1174 * this Method implements simple Garbage Collection
\r
1177 * @author Stefan Saasen <s@fase4.com>
\r
1178 * @see _cache_dir, gc_probability, gc_maxlifetime
\r
1180 function _garbage_collection()
\r
1182 srand((double) microtime() * 1000000);
\r
1183 if (rand(1, 100) <= $this->gc_probability) {
\r
1184 $dir = dir($this->_cache_dir);
\r
1185 while($file=$dir->read()) {
\r
1186 if($file!="." AND $file!=".." AND filemtime($dir->path.$file) <= time() - $this->_refresh ) {
\r
1187 @unlink($dir->path.$file);
\r
1194 /* ==== Proxy/Auth methods ==== */
\r
1197 * this method sets a proxy server
\r
1200 * @param string $phost Proxy Host
\r
1201 * @param string $pport Prox Port
\r
1202 * @author Marco Kraus <marco.kraus@siemens.com>
\r
1204 function set_proxy($phost, $pport)
\r
1206 $this->_use_proxy = true;
\r
1209 $this->_phost = $phost;
\r
1212 $this->_pport = $pport;
\r
1216 * this method sets a proxy server authentification
\r
1219 * @param string $pname Username
\r
1220 * @param string $ppaswd Password
\r
1221 * @author Marco Kraus <marco.kraus@siemens.com>
\r
1223 function set_proxy_auth( $pname, $ppasswd )
\r
1225 $this->_use_proxy_auth = true;
\r
1228 $this->_pname = $pname;
\r
1230 if ($ppasswd != "")
\r
1231 $this->_ppasswd = $ppasswd;
\r
1236 * gets _remote_file into an array
\r
1238 * needed, cause if you use a proxy, you have to open
\r
1239 * a raw-tcp-socket to get the data
\r
1242 * @author Marco Kraus <Marco.Kraus@siemens.com>
\r
1244 * @see _use_proxy, cache()
\r
1246 function _rdf_data()
\r
1248 if ( $this->_use_proxy == true )
\r
1250 // we need a raw socket here to connect to proxy
\r
1251 $fp = fsockopen($this->_phost,$this->_pport);
\r
1254 $this->_throw_exception( $this->_remote_file." is not available with proxy" );
\r
1256 if ( $this->_use_proxy_auth == true ) {
\r
1257 fputs($fp, "GET ".$this->_remote_file." HTTP/1.0\r\nUser-Agent: Fase4 RDF-Reader/1.40 modified by Quix0r\r\n\r\n");
\r
1259 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");
\r
1264 for ( $i = 0; !feof ($fp) ; $i++)
\r
1266 $usable_data[$i] = "";
\r
1267 $usable_data[$i] = fgets($fp,4096);
\r
1269 // PARSE HEADER ---- first line has to be <?xml, second rdf or rss, and third is blank
\r
1271 // strstr did not fit (ask Rasmus why), so we compare each character
\r
1272 if ( ($usable_data[$i][0] == "<" ) &&
\r
1273 ($usable_data[$i][1] == "?" ) &&
\r
1274 ($usable_data[$i][2] == "x" ) &&
\r
1275 ($usable_data[$i][3] == "m" ) &&
\r
1276 ($usable_data[$i][4] == "l" ) ) {
\r
1277 $usable_data[0] = $usable_data[$i]; // save current field
\r
1278 $i = 1; // just reset array to start
\r
1281 // there seems to be proxystuff after the <?xml....we delete this
\r
1283 ($usable_data[$i][0] == "<" ) &&
\r
1284 ($usable_data[$i][1] == "r" ) &&
\r
1285 ($usable_data[$i][2] == "d" ) &&
\r
1286 ($usable_data[$i][3] == "f" ) &&
\r
1287 ($usable_data[$i][4] == ":" )
\r
1291 ($usable_data[$i][0] == "<" ) &&
\r
1292 ($usable_data[$i][1] == "r" ) &&
\r
1293 ($usable_data[$i][2] == "s" ) &&
\r
1294 ($usable_data[$i][3] == "s" )
\r
1298 $usable_data[1] = $usable_data[$i]; // save current field
\r
1299 $usable_data[2] = "\n";
\r
1300 $i = 2; // just reset array to start
\r
1305 return $usable_data;
\r
1307 if (substr($this->_remote_file, 0, 7) != "http://") {
\r
1308 $this->_throw_exception( "Cannot find http:// in ".$this->_remote_file."!" );
\r
1311 // Extract host information
\r
1312 $host = substr($this->_remote_file, 7);
\r
1313 // Extract the GET part
\r
1315 if (strpos($host, "/") > 0) {
\r
1316 $get = substr($host, strpos($host, "/"));
\r
1317 $host = substr($host, 0, strpos($host, "/"));
\r
1321 if (strpos($host, ":") > 0) {
\r
1322 $port = substr($host, (strpos($host, ":") + 1));
\r
1323 $host = substr($host, 0, (strpos($host, ":") - 1));
\r
1326 // Start connection to server
\r
1327 $fp = fsockopen($host, $port);
\r
1329 $this->_throw_exception( $this->_remote_file." is maybe not available." );
\r
1332 // Repare request line
\r
1333 $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);
\r
1334 // Send request out
\r
1335 fputs($fp, $request);
\r
1336 $reply = ""; $isContent = false; $dummy = "";
\r
1338 while ( !feof($fp) ) {
\r
1339 $read = trim(fgets($fp, 4096));
\r
1340 if (substr($read, 0, 5) == "<?xml" || $isContent) {
\r
1343 $isContent = true;
\r
1350 if ((count($dummy) > 0) && (count($reply) == 0) && (!$isContent)) {
\r
1351 // Transfer content from dummy
\r
1352 $reply = $content;
\r
1355 //die(htmlentities($reply));
\r
1359 } // END _rdf_data()
\r