List active/inactive extensions
[mailer.git] / 0.2.1 / inc / rdf.class.php
1 <?php\r
2 /* $Id: rdf.class.php,v 1.40 2003/07/06 20:33:58 sts Exp $ */\r
3 \r
4 //\r
5 // +----------------------------------------------------------------------+\r
6 // | rss Parser                                                           |\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
13 // |                                                                      |\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
19 // |                                                                      |\r
20 // | Maintainer and initial developer:                                    |\r
21 // | Stefan Saasen <s@fase4.com>                                          |\r
22 // |                                                                      |\r
23 // | Proxy and authentication methods added by:                           |\r
24 // | Marco Kraus <marco.kraus@siemens.com>                                |\r
25 // |                                                                      |\r
26 // | Decoding of data by htmlentities or utf8_decode added by:            |\r
27 // | Roland Haeder <webmaster@mxchange.org>                               |\r
28 // |                                                                      |\r
29 // +----------------------------------------------------------------------+\r
30 // | Ref:                                                                 |\r
31 // |   @link http://www.fase4.com/rdf/                   Latest release   |\r
32 // +----------------------------------------------------------------------+\r
33 \r
34 /**\r
35 * Class RSS Parser\r
36 *\r
37 * This class offers methods to parse RSS Files\r
38 *\r
39 * @link      http://www.fase4.com/rdf/ Latest release of this class\r
40 * @package   rss\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
44 * @access    public\r
45 */\r
46 \r
47 class fase4_rdf {\r
48 \r
49     /**\r
50     * Word-wrapping mode for description, set it to 0 do disable this feature! Ommits _use_nl2br!\r
51     *\r
52     * @access private\r
53     * @var    integer\r
54     */\r
55     var $_word_wrap = 0;\r
56 \r
57     /**\r
58     * Wether to recode \n -> <BR> or not in description\r
59     *\r
60     * @access private\r
61     * @var    boolean\r
62     */\r
63     var $_use_nl2br = true;\r
64 \r
65     /**\r
66     * Sets the decoding mode of the read data (UTF8 scrambles some german umlauts here!)\r
67     *\r
68     * "htmlentities" - Use the function htmlentities()\r
69     * "utf8_decode"  - Use the function ut8_decode() when you have UTF8 encoded text\r
70     *\r
71     * @access private\r
72     * @var    string\r
73     */\r
74     var $_decoding_mode = "utf8_decode";\r
75 \r
76     /**\r
77     * If $_link_target is set a target='xxx' attribute in each <a /> and <form /> html tag will be added\r
78     *\r
79     * Possible values are "_blank", "_content", "_parent", "_self", "_top"\r
80     *\r
81     * @access private\r
82     * @var    string\r
83     */\r
84     var $_link_target = "_blank";\r
85 \r
86     /**\r
87     * vars for proxy settings - Prox Host\r
88     *\r
89     * @access private\r
90     * @var      string\r
91     */\r
92     var $_phost = "";\r
93 \r
94     /**\r
95     * vars for proxy settings - Prox Port\r
96     *\r
97     * @access private\r
98     * @var      string\r
99     */\r
100     var $_pport = "";\r
101 \r
102     /**\r
103     * vars for proxy settings - Prox Username\r
104     *\r
105     * @access private\r
106     * @var      string\r
107     */\r
108     var $_pname = "";\r
109 \r
110     /**\r
111     * vars for proxy settings - Prox Password\r
112     *\r
113     * @access private\r
114     * @var      string\r
115     */\r
116     var $_ppasswd = "";\r
117 \r
118     /**\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
121     *\r
122     * @access   private\r
123     * @see      set_proxy()\r
124     * @var      bool\r
125     */\r
126     var $_use_proxy = false;\r
127 \r
128     /**\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
132     *\r
133     * @access   private\r
134     * @see      set_proxy()\r
135     * @var      boolean\r
136     */\r
137     var $_use_proxy_auth = false;\r
138 \r
139     /**\r
140     * The time the Files will be cached (in seconds).\r
141     *\r
142     * @access private\r
143     * @var    int\r
144     */\r
145     var $_refresh = 60;   // int\r
146 \r
147     /**\r
148     * The Name of the cached File.\r
149     *\r
150     * @access private\r
151     * @var    string\r
152     */\r
153     var $_cached_file = "";   // String\r
154 \r
155     /**\r
156     * Indicates whether the cached or the remote file was used.\r
157     *\r
158     * @access private\r
159     * @var    boolean\r
160     */\r
161     var $_use_cached_file = true;\r
162 \r
163     /**\r
164     * (fast|normal) depends on _use_dynamic_display(). _use_dynamic_display( TRUE ) -> 'normal', otherwise 'fast'\r
165     *\r
166     * @access private\r
167     * @var    string\r
168     */\r
169     var $_cache_type = "fast";\r
170 \r
171     /**\r
172     * The Name of the Remote File.\r
173     *\r
174     * @access private\r
175     * @var    string\r
176     */\r
177     var $_remote_file = "";\r
178 \r
179     /**\r
180     * Path to the Cache Directory.\r
181     *\r
182     * @access private\r
183     * @var    string\r
184     */\r
185     var $_cache_dir = "cache/";  // String\r
186 \r
187     /**\r
188     * Indicates whether the Creating of the Cache Directory needs to be done or not.\r
189     *\r
190     * @access private\r
191     * @var    boolean\r
192     */\r
193     var $_cache_dir_ok = false;\r
194 \r
195     /**\r
196     * Type of the file to be parsed (RSS or RDF).\r
197     *\r
198     * The Type depends on the root node\r
199     *\r
200     * @access private\r
201     * @var    string\r
202     */\r
203     var $_type = "rss"; // string (rss or rdf)\r
204 \r
205     /**\r
206     * Array of Display Settings.\r
207     *\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
210     *\r
211     * @access private\r
212     * @var    array\r
213     */\r
214     var $_display_opt = array(\r
215                 'build' => '',\r
216                 'image' => '',\r
217                 'channel' => '',\r
218                 'textinput' => '',\r
219                 'cache_update' => '',\r
220                 'sitelink' => '',\r
221                 'refid' => '',\r
222                 'reflink' => '',\r
223     );\r
224 \r
225     /**\r
226     * Defines the width attribute in the table that holds the rdf/rss representation\r
227     *\r
228     * @access private\r
229     * @var    int\r
230     * @see    see_table_width()\r
231     */\r
232     var $_table_width = "100%";\r
233 \r
234     /**\r
235     * Indicates whether or not to use dynamic Display Settings\r
236     *\r
237     * @access private\r
238     * @var    array\r
239     */\r
240     var $_use_dynamic_display = false;\r
241 \r
242     /**\r
243     * <item> count\r
244     *\r
245     * @access private\r
246     * @var    int\r
247     */\r
248     var $_item_count = 0;\r
249 \r
250     /**\r
251     * No of max <item>s\r
252     *\r
253     * @access private\r
254     * @var    boolean\r
255     */\r
256     var $_max_count = false;\r
257 \r
258     /**\r
259     * Array containing the content of <channel />\r
260     *\r
261     * @access private\r
262     * @var    array\r
263     */\r
264     var $_array_channel = array();\r
265 \r
266     /**\r
267     * Array containing the content of each <item />\r
268     *\r
269     * @access private\r
270     * @var    array\r
271     */\r
272     var $_array_item = array();\r
273 \r
274     /**\r
275     * Array containing the content of <textinput />\r
276     *\r
277     * @access private\r
278     * @var    array\r
279     */\r
280     var $_array_textinput = array();\r
281 \r
282     /**\r
283     * Array containing the content of <image />\r
284     *\r
285     * @access private\r
286     * @var    array\r
287     */\r
288     var $_array_image = array();\r
289 \r
290     /**\r
291     * Array containing the Channel content. Just For internal XML Parser Purposes.\r
292     *\r
293     * @access private\r
294     * @var    array\r
295     */\r
296     var $_citem = array();\r
297 \r
298     /**\r
299     * Array containing the Channel Parser Depth. Just For internal XML Parser Purposes.\r
300     *\r
301     * @access private\r
302     * @var    array\r
303     */\r
304     var $_cdepth = array();\r
305 \r
306     /**\r
307     * Array containing the Channel tags. Just For internal XML Parser Purposes.\r
308     *\r
309     * @access private\r
310     * @var    array\r
311     */\r
312     var $_ctags = array( "x" );\r
313 \r
314     /**\r
315     * Array containing the Channel content. Just For internal XML Parser Purposes.\r
316     *\r
317     * @access private\r
318     * @var    array\r
319     */\r
320     var $_item = array();   // Array\r
321 \r
322     /**\r
323     * Array containing the Channel Parser Depth. Just For internal XML Parser Purposes.\r
324     *\r
325     * @access private\r
326     * @var    array\r
327     */\r
328     var $_depth = array();  // Array\r
329 \r
330     /**\r
331     * Array containing the tags. Just For internal XML Parser Purposes.\r
332     *\r
333     * @access private\r
334     * @var    array\r
335     */\r
336     var $_tags = array( "x" );  // Array\r
337 \r
338     /**\r
339     * Garbage collection: probability in percent\r
340     *\r
341     * @var      integer     0 => never\r
342     * @access   public\r
343     */\r
344     var $gc_probability = 1;\r
345 \r
346     /**\r
347     * HTML Output\r
348     *\r
349     * @var      string\r
350     * @access   private\r
351     */\r
352     var $_output = "";\r
353 \r
354     /**\r
355     * @var  string\r
356     */\r
357     var $_parse_mode = "";\r
358 \r
359     // Output variable\r
360     var $out = "";\r
361 \r
362     // Salt for hashing\r
363     var $salt = "";\r
364 \r
365     /**\r
366     * Constructor of our Class\r
367     *\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
370         *\r
371     * @access    public\r
372         * @author    Stefan Saasen <s@fase4.com>\r
373         * @see           _refresh\r
374     */\r
375     function fase4_rdf()\r
376     {\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
381     }\r
382 \r
383     /**\r
384     * This Method starts the parsing of the specified RDF File. The File can be a local or a remote File.\r
385     *\r
386     * @access    public\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
391     */\r
392     function parse_RDF( $rdf )\r
393     {\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
402         return true;\r
403     }\r
404 \r
405     /**\r
406     * This Method is called when all parsing is finished to use the garbage collection\r
407     *\r
408     * @access    public\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
413     */\r
414     function finish($return = false)\r
415     {\r
416                 if (!$return) {\r
417                         echo $this->out;\r
418                 } else {\r
419                         return $this->out;\r
420                 }\r
421         flush();\r
422         $this->_garbage_collection();\r
423     }\r
424 \r
425     /**\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
427     *\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
433     *\r
434     * @access    public\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
439     */\r
440     function use_dynamic_display( $bool )\r
441     {\r
442         $this->_use_dynamic_display = $bool;\r
443         return true;\r
444     }\r
445 \r
446     /**\r
447     * This Method avtually parses the XML data.\r
448     *\r
449     * @access    private\r
450         * @author    Stefan Saasen <s@fase4.com>\r
451     * @param     string $data    RDF File XML Data\r
452         * @see           _clear_Items()\r
453     */\r
454     function _parse_xRDF( $data )\r
455     {\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
466             }\r
467         xml_parser_free($xml_parser);\r
468     }\r
469 \r
470 \r
471     /**\r
472     * This Methods allows you to set the Refresh Time\r
473     *\r
474     * @access    public\r
475         * @author    Stefan Saasen <s@fase4.com>\r
476     * @param     int $seconds time files will be cached (in seconds).\r
477         * @return        boolean\r
478         * @see           _refresh\r
479     */\r
480     function set_refresh( $seconds )\r
481     {\r
482         $this->_refresh = (time() - $seconds);\r
483         return true;\r
484     }\r
485 \r
486     function set_salt( $saltPara )\r
487     {\r
488         $this->salt = $saltPara;\r
489         return true;\r
490     }\r
491 \r
492     /**\r
493     * This Methods allows you to set the No. of <item>s to display\r
494     *\r
495     * @access    public\r
496     * @param     int $int No of max <item>s\r
497         * @author    Stefan Saasen <s@fase4.com>\r
498         * @return        boolean\r
499         * @see           _max_count, _endElement()\r
500     */\r
501     function set_max_item( $int )\r
502     {\r
503         $this->_max_count = $int;\r
504         return true;\r
505     }\r
506 \r
507     /**\r
508     * This Methods allows you to set the Cache Directory\r
509     *\r
510     * @access    public\r
511         * @author    Stefan Saasen <s@fase4.com>\r
512     * @param     string $dir Path to Directory.\r
513         * @return        boolean\r
514         * @see           _cache_dir\r
515     */\r
516     function set_CacheDir( $dir )\r
517     {\r
518         if(substr($dir, -1) != "/") {\r
519             $dir = $dir."/";\r
520         }\r
521         $this->_cache_dir = $dir;\r
522     }\r
523 \r
524     /**\r
525     * This Method displays Error Messages and terminates the Execution of the Script\r
526     *\r
527     * @access    private\r
528     * @param     string $msg Message to display on failure\r
529         * @author    Stefan Saasen <s@fase4.com>\r
530     */\r
531     function _throw_exception( $msg )\r
532     {\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
534         return true;\r
535     }\r
536 \r
537     /**\r
538     * This Method clears the Array containig the Items.\r
539     *\r
540     * @access    private\r
541         * @author    Stefan Saasen <s@fase4.com>\r
542     * @see       _item\r
543     */\r
544     function _clear_Items( ) {\r
545         $this->_item = array(\r
546             'title'=>"",\r
547             'link'=>"",\r
548             'description'=>"",\r
549             'url'=>"",\r
550             'language'=>"",\r
551             'pubDate'=>"",\r
552             'lastBuildDate'=>"",\r
553             'width'=>'',\r
554             'height'=>''\r
555         );\r
556     }\r
557     /**\r
558     * This Method clears the Array containig the Channel Items.\r
559     *\r
560     * @access    private\r
561         * @author    Stefan Saasen <s@fase4.com>\r
562     * @see       _item\r
563     */\r
564     function _clear_cItems( ) {\r
565         $this->_citem = array(\r
566             'title'=>"",\r
567             'link'=>"",\r
568             'description'=>"",\r
569             'url'=>"",\r
570             'language'=>"",\r
571             'copyright'=>"",\r
572             'managingEditor'=>"",\r
573             'webMaster'=>"",\r
574             'pubDate'=>"",\r
575             'lastBuildDate'=>"",\r
576             'category'=>"",\r
577             'generator'=>"",\r
578             'docs'=>"",\r
579             'cloud'=>"",\r
580             'ttl'=>"",\r
581             'image'=>"",\r
582             'textinput'=>"",\r
583             'skipHours'=>"",\r
584             'skipDays' =>"",\r
585             'sitelink'=>"",\r
586             'refid'=>"",\r
587             'reflink'=>"",\r
588         );\r
589     }\r
590 \r
591     /**\r
592     * XML Parser Start Element Handler\r
593     *\r
594     * @access    private\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
600     */\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
607         }\r
608 \r
609 \r
610         if ( $name == "channel" AND $this->_type != "rdf" ) {\r
611             $this->_parse_mode = "channel";\r
612         } elseif ( ($name=="item")\r
613                     ||($name=="image")\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
618             }\r
619             $this->_parse_mode = "all";\r
620         }\r
621 \r
622         if( !isset( $this->_depth[$parser] ) ) {\r
623             $this->_depth[$parser] = 0;\r
624         }\r
625         $this->_depth[$parser]++;\r
626         array_push($this->_tags, $name);\r
627 \r
628         if( !isset( $this->_cdepth[$parser] ) ) {\r
629             $this->_cdepth[$parser] = 0;\r
630         }\r
631         $this->_cdepth[$parser]++;\r
632         array_push($this->_ctags, $name);\r
633     }   // END _startElement()\r
634 \r
635     /**\r
636     * Retrives the Channel Data in <rss> File\r
637     *\r
638     * @access    private\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
642     */\r
643     function _get_ChannelData( $parser )\r
644     {\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
647                 {\r
648                     $this->_citem["link"] .= $this->_display_opt["reflink"].$this->_display_opt["refid"];\r
649                 }\r
650 \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>&nbsp;</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
661                 }\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
664                 }\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
671                 }\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
676     }\r
677 \r
678     /**\r
679     * XML Parser End Element Handler\r
680     *\r
681     * @access    private\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
686     */\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
694            {\r
695             if (!ereg("refid=", $this->_item["link"])) $this->_item["link"] .= "?refid=" . $this->_display_opt["refid"];\r
696            }\r
697         switch ($name) {\r
698             case "item":\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
702 \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
705                         {\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
712                         }\r
713                          elseif (($this->_word_wrap == 0) && (!$this->_use_nl2br))\r
714                         {\r
715                             // Strip tags out instead when word-wrap is disabled\r
716                             $this->_item["description"] = strip_tags($this->_item["description"], "<a>, <img>");\r
717                         }\r
718 \r
719                         // nl2br added by Roland Haeder <webmaster@mxchange.org>\r
720                         if ($this->_use_nl2br) $this->_item["description"] = nl2br($this->_item["description"]);\r
721 \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
728                     } else {\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
733                     }\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
738                 }\r
739                     $this->_clear_Items();\r
740             break;\r
741             case "image":\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
749                 }\r
750                 $this->_output .= " alt=\"".$this->_item["title"]."\" border=\"0\" /></a></td></tr>\n";\r
751 \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
759                 }\r
760 \r
761             break;\r
762             case "channel":\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>&nbsp;</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
772                 }\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
775                 }\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
781                 }\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
788             break;\r
789                         case "textinput":\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"]."\">&nbsp;\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
808                 }\r
809 \r
810                         break;\r
811         }\r
812     }\r
813 \r
814     /**\r
815     * This Method returns the data from the <channel /> paragraph.\r
816     *\r
817     * @access    public\r
818         * @author    Stefan Saasen <s@fase4.com>\r
819     * @return    array\r
820         * @see           _array_channel\r
821     */\r
822     function get_array_channel( )\r
823     {\r
824         return $this->_array_channel;\r
825     }\r
826 \r
827     /**\r
828     * This Method returns the data from each <item /> paragraph.\r
829     *\r
830     * @access    public\r
831         * @author    Stefan Saasen <s@fase4.com>\r
832     * @return    array\r
833         * @see           _array_item\r
834     */\r
835     function get_array_item( )\r
836     {\r
837         return $this->_array_item;\r
838     }\r
839 \r
840     /**\r
841     * This Method returns the data from <textinput />.\r
842     *\r
843     * @access    public\r
844         * @author    Stefan Saasen <s@fase4.com>\r
845     * @return    array\r
846         * @see           _array_textinput\r
847     */\r
848     function get_array_textinput( )\r
849     {\r
850         return $this->_array_textinput;\r
851     }\r
852 \r
853     /**\r
854     * This Method returns the data from <image />.\r
855     *\r
856     * @access    public\r
857         * @author    Stefan Saasen <s@fase4.com>\r
858     * @return    array\r
859         * @see           _array_image\r
860     */\r
861     function get_array_image( )\r
862     {\r
863         return $this->_array_image;\r
864     }\r
865 \r
866     /**\r
867     * XML Parser Data Handler\r
868     *\r
869     * @access    private\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
874     */\r
875     function _parseData($parser, $text)\r
876     {\r
877         // Deocing mode added by Roland Haeder <webmaster@mxchange.org>\r
878         switch ($this->_decoding_mode)\r
879         {\r
880         case "utf8_decode":\r
881             $text = utf8_decode($text);\r
882             break;\r
883 \r
884         case "htmlentities":\r
885             $text = htmlentities($text);\r
886             break;\r
887         }\r
888 \r
889         $clean = preg_replace("/\s/", "", $text);\r
890         if ($clean) {\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
896                         } else {\r
897                            $this->_item[$this->_tags[$this->_depth[$parser]]] = $text;\r
898                         }\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
902                         } else {\r
903                            $this->_citem[$this->_ctags[$this->_cdepth[$parser]]] = $text;\r
904                         }\r
905                 }\r
906         }\r
907     }\r
908 \r
909     /**\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
912     *\r
913     * @access    public\r
914         * @author    Stefan Saasen <s@fase4.com>\r
915     * @param     array  $options\r
916         * @see           _display_opt\r
917     */\r
918     function set_Options( $options = "" )\r
919     {\r
920         if(is_array( $options )) {\r
921             $this->_display_opt = $options;\r
922             return true;\r
923         } else {\r
924             unset($this->_display_opt);\r
925             return false;\r
926         }\r
927     }\r
928 \r
929     /**\r
930     * This Method allows you to define the width of the table that holds the representation of the rdf/rss file.\r
931     *\r
932     * @access    public\r
933         * @author    Stefan Saasen <s@fase4.com>\r
934     * @param     int  $width  attribute width in tag <table>\r
935         * @see           _table_width\r
936     */\r
937     function set_table_width( $width = 400 )\r
938     {\r
939         $this->_table_width = $width;\r
940         return true;\r
941     }\r
942 \r
943     /**\r
944     * This Method returns an assocative Array with available Options.\r
945     *\r
946     * The Keys are the Name of the Options to be set.\r
947     * The Values are  short Description of available Options.\r
948     *\r
949     * @access    public\r
950         * @author    Stefan Saasen <s@fase4.com>\r
951     * @return    array  $options\r
952         * @see           _display_opt\r
953     */\r
954     function get_Options()\r
955     {\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
961         return $options;\r
962     }\r
963 \r
964     /**\r
965     * This Method returns the Content of the RDF File in one string. The String actually holds the whole XML Document.\r
966     *\r
967     * @access    public\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
972     */\r
973     function cache()\r
974     {\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
979         }\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
983         } else {\r
984             $this->_cached_file = md5($this->salt.$this->_remote_file);\r
985             $this->_cache_type = "fast";\r
986         }\r
987 \r
988         $_cache_f = $this->_cache_dir.$this->_cached_file;\r
989 \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
995             clearstatcache();\r
996             if($this->_use_dynamic_display == true) {\r
997                 $_rdf = @implode(" ", $this->_rdf_data()); // -> proxy\r
998                 if(!$_rdf) {\r
999                     $this->_throw_exception( $this->_remote_file." is not available" );\r
1000                 }\r
1001                 $this->_parse_xRDF( $_rdf );\r
1002                 $this->_update_cache( $_rdf );\r
1003                 $data = $this->_output;\r
1004             } else {\r
1005                 $_rdf = @implode(" ", $this->_rdf_data()); // -> proxy\r
1006                 if(!$_rdf) {\r
1007                     $this->_throw_exception( $this->_remote_file." is not available" );\r
1008                 }\r
1009                 $this->_parse_xRDF( $_rdf );\r
1010                 $this->_update_cache( $this->_output );\r
1011                 $data = $this->_output;\r
1012             }\r
1013         } else {\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
1019             } else {\r
1020                 $data = @implode(" ", file($_cache_f));\r
1021             }\r
1022         }\r
1023         return trim($data);\r
1024     }   // END cache()\r
1025 \r
1026     /**\r
1027     * This Methods creates the Cache Directory if the specified Directory does not exist.\r
1028     *\r
1029     * @access    private\r
1030         * @author    Stefan Saasen <s@fase4.com>\r
1031     * @param     string $dir Path to Directory.\r
1032         * @return        boolean\r
1033         * @see           _cache_dir, _cache_dir_ok\r
1034     */\r
1035     function _create_cache_dir()\r
1036     {\r
1037         $path = "";\r
1038         if(!@is_dir($this->_cache_dir)) {\r
1039             $arr = explode("/", $this->_cache_dir);\r
1040             $c = count($arr);\r
1041             if($arr[0]=="") {\r
1042                 $path = "/";\r
1043             }\r
1044             for($i = 0;$i<$c;$i++)\r
1045             {\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
1051                         return false;\r
1052                         }\r
1053                     }\r
1054                 }\r
1055             }\r
1056             $this->_cache_dir_ok = true;\r
1057             return true;\r
1058         } else {\r
1059             $this->_cache_dir_ok = true;\r
1060             return true;\r
1061         }\r
1062     }   // END _create_cache_dir()\r
1063 \r
1064     /**\r
1065     * This Method updates the cached RDF Files and synchronises them with their remote Counterparts.\r
1066     *\r
1067     * @access    private\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
1071     */\r
1072     function _update_cache( $content = "" )\r
1073     {\r
1074              $_local = @fopen( $this->_cache_dir.$this->_cached_file, 'w' );\r
1075              if(!$_local) {\r
1076                 $this->_throw_exception( "Cannot open ".$this->_cached_file."<br /><br />Exception at Line: ".__LINE__ );\r
1077                 return false;\r
1078              }\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
1081                         return false;\r
1082                    }\r
1083              fclose( $_local );\r
1084                    @chmod( $this->_cache_dir.$this->_cached_file, 0666);\r
1085              return true;\r
1086     }   // END _update_cache()\r
1087 \r
1088     /**\r
1089     * This Method returns the Date/Time of last Cache Update of the actually parsed RDF File.\r
1090         *\r
1091     * @access    public\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
1095     */\r
1096     function get_cache_update_time()\r
1097     {\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
1100 \r
1101     /**\r
1102     * This Method returns the Type of Cache that was used ('normal' or 'fast')\r
1103     *\r
1104     * @access    public\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
1109     */\r
1110     function get_CacheType()\r
1111     {\r
1112         return $this->_cache_type;\r
1113     }\r
1114 \r
1115     /**\r
1116     * Returns true if cached file was used, otherwise false\r
1117     *\r
1118     * @access    public\r
1119         * @author    Stefan Saasen <s@fase4.com>\r
1120     * @return    array  $options\r
1121         * @see           _use_cached_file\r
1122     */\r
1123     function is_cachedFile()\r
1124     {\r
1125         return $this->_use_cached_file;\r
1126     }\r
1127 \r
1128     /**\r
1129     * This Method deletes all the cached Files.\r
1130     *\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
1134         *\r
1135     * @access    public\r
1136         * @author    Stefan Saasen <s@fase4.com>\r
1137         * @see           _cache_dir\r
1138     */\r
1139     function clear_cache()\r
1140     {\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
1148                     return false;\r
1149                 }\r
1150             }\r
1151         }\r
1152         $dir->close();\r
1153         return true;\r
1154     }   // END clear_cache()\r
1155 \r
1156     /**\r
1157     * Cuts the String $string after $str_len and adds "... "\r
1158     *\r
1159     * @access   private\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
1163     */\r
1164     function _cut_string( $string, $str_len = "30" )\r
1165     {\r
1166         if(strlen(trim($string))>$str_len) {\r
1167         $string = substr( trim($string) , 0, $str_len - 4);\r
1168         $string .= " ...";\r
1169         }\r
1170         return $string;\r
1171     }   // END _cut_string()\r
1172 \r
1173     /**\r
1174     * this Method implements simple Garbage Collection\r
1175     *\r
1176     * @access    private\r
1177         * @author    Stefan Saasen <s@fase4.com>\r
1178         * @see           _cache_dir, gc_probability, gc_maxlifetime\r
1179     */\r
1180     function _garbage_collection()\r
1181     {\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
1188                 }\r
1189         }\r
1190         $dir->close();\r
1191         }   // END if\r
1192     }\r
1193 \r
1194     /* ==== Proxy/Auth methods ==== */\r
1195 \r
1196    /**\r
1197     * this method sets a proxy server\r
1198     *\r
1199     * @access    public\r
1200     * @param     string $phost Proxy Host\r
1201     * @param     string $pport Prox Port\r
1202     * @author    Marco Kraus <marco.kraus@siemens.com>\r
1203     */\r
1204     function set_proxy($phost, $pport)\r
1205     {\r
1206      $this->_use_proxy = true;\r
1207 \r
1208      if ($phost != "")\r
1209         $this->_phost = $phost;\r
1210 \r
1211      if ($pport != "")\r
1212         $this->_pport = $pport;\r
1213     }\r
1214 \r
1215     /**\r
1216     * this method sets a proxy server authentification\r
1217     *\r
1218     * @access    public\r
1219     * @param     string $pname Username\r
1220     * @param     string $ppaswd Password\r
1221     * @author    Marco Kraus <marco.kraus@siemens.com>\r
1222     */\r
1223     function set_proxy_auth( $pname, $ppasswd )\r
1224     {\r
1225      $this->_use_proxy_auth = true;\r
1226 \r
1227      if ($pname != "")\r
1228         $this->_pname = $pname;\r
1229 \r
1230      if ($ppasswd != "")\r
1231         $this->_ppasswd = $ppasswd;\r
1232     }\r
1233 \r
1234 \r
1235    /**\r
1236     * gets _remote_file into an array\r
1237     *\r
1238     * needed, cause if you use a proxy, you have to open\r
1239     * a raw-tcp-socket to get the data\r
1240     *\r
1241     * @access    private\r
1242     * @author    Marco Kraus <Marco.Kraus@siemens.com>\r
1243     * @return array\r
1244     * @see _use_proxy, cache()\r
1245     */\r
1246     function _rdf_data()\r
1247     {\r
1248       if ( $this->_use_proxy == true )\r
1249       {\r
1250        // we need a raw socket here to connect to proxy\r
1251        $fp = fsockopen($this->_phost,$this->_pport);\r
1252 \r
1253        if (!$fp) {\r
1254            $this->_throw_exception( $this->_remote_file." is not available with proxy" );\r
1255        } else {\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
1258            } else {\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
1260            }\r
1261         }\r
1262 \r
1263 \r
1264        for ( $i = 0; !feof ($fp) ; $i++)\r
1265        {\r
1266           $usable_data[$i] = "";\r
1267           $usable_data[$i] = fgets($fp,4096);\r
1268 \r
1269         // PARSE HEADER ---- first line has to be <?xml, second rdf or rss, and third is blank\r
1270 \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
1279               }\r
1280 \r
1281         // there seems to be proxystuff after the <?xml....we delete this\r
1282             if ( (\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
1288                )\r
1289                ||\r
1290                (\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
1295                )\r
1296             ) {\r
1297 \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
1301           }\r
1302        }\r
1303 \r
1304        fclose($fp);\r
1305        return $usable_data;\r
1306      } else {\r
1307                 if (substr($this->_remote_file, 0, 7) != "http://") {\r
1308                         $this->_throw_exception( "Cannot find http:// in ".$this->_remote_file."!" );\r
1309                         return "";\r
1310                 } else {\r
1311                         // Extract host information\r
1312                         $host = substr($this->_remote_file, 7);\r
1313                         // Extract the GET part\r
1314                         $get = "/";\r
1315                         if (strpos($host, "/") > 0) {\r
1316                                 $get = substr($host, strpos($host, "/"));\r
1317                                 $host = substr($host, 0, strpos($host, "/"));\r
1318                         }\r
1319                         // Extract port\r
1320                         $port = "80";\r
1321                         if (strpos($host, ":") > 0) {\r
1322                                 $port = substr($host, (strpos($host, ":") + 1));\r
1323                                 $host = substr($host, 0, (strpos($host, ":") - 1));\r
1324                         }\r
1325 \r
1326                         // Start connection to server\r
1327                         $fp = fsockopen($host, $port);\r
1328                         if (!$fp) {\r
1329                     $this->_throw_exception( $this->_remote_file." is maybe not available." );\r
1330                           return "";\r
1331                         }\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
1337                         // Read reply\r
1338                         while ( !feof($fp) ) {\r
1339                                 $read = trim(fgets($fp, 4096));\r
1340                                 if (substr($read, 0, 5) == "<?xml" || $isContent) {\r
1341                                         // Add content\r
1342                                         $reply[] = $read;\r
1343                                         $isContent = true;\r
1344                                 } else {\r
1345                                         // Put in dummy\r
1346                                         $dummy[] = $read;\r
1347                                 }\r
1348                                 $i++;\r
1349                         }\r
1350                         if ((count($dummy) > 0) && (count($reply) == 0) && (!$isContent)) {\r
1351                                 // Transfer content from dummy\r
1352                                 $reply = $content;\r
1353                         }\r
1354                         fclose($fp);\r
1355                         //die(htmlentities($reply));\r
1356                         return $reply;\r
1357                 }\r
1358      }\r
1359    }    // END _rdf_data()\r
1360 }   // END class\r
1361 ?>\r