]> git.mxchange.org Git - mailer.git/blob - inc/classes/rdf.class.php
Cleanups + optional binding to mailer functions
[mailer.git] / inc / classes / rdf.class.php
1 <?php
2 /* $Id$ */
3
4 //
5 // +----------------------------------------------------------------------+
6 // | rss Parser                                                           |
7 // | Copyright (c) 2001 Stefan Saasen                                     |
8 // +----------------------------------------------------------------------+
9 // | The contents of this file are subject to the Mozilla Public License  |
10 // | Version 1.1 (the "License"); you may not use this file except in     |
11 // | compliance with the License. You may obtain a copy of the License at |
12 // | http://www.mozilla.org/MPL/                                          |
13 // |                                                                      |
14 // | Software distributed under the License is distributed on an "AS IS"  |
15 // | basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See  |
16 // | the License for the specific language governing rights and           |
17 // | limitations under the License.                                       |
18 // +----------------------------------------------------------------------+
19 // |                                                                      |
20 // | Maintainer and initial developer:                                    |
21 // | Stefan Saasen <s@fase4.com>                                          |
22 // |                                                                      |
23 // | Proxy and authentication methods added by:                           |
24 // | Marco Kraus <marco.kraus@siemens.com>                                |
25 // |                                                                      |
26 // | Decoding of data by htmlentities or utf8_decode added by:            |
27 // | Roland Haeder <webmaster@mxchange.org>                               |
28 // |                                                                      |
29 // +----------------------------------------------------------------------+
30 // | Ref:                                                                 |
31 // |   @link http://www.fase4.com/rdf/                   Latest release   |
32 // +----------------------------------------------------------------------+
33
34 /**
35  * Class RSS Parser
36  *
37  * This class offers methods to parse RSS Files
38  *
39  * @link      http://www.fase4.com/rdf/ Latest release of this class
40  * @package   rss
41  * @copyright Copyright (c) 2001 fase4.com. All rights reserved.
42  * @author    Stefan Saasen <s@fase4.com>
43  * @author    Roland Haeder <webmaster@mxchange.org>
44  * @version   1.7 ($Date$Revision: 856 $
45  * @access    public
46  */
47
48 class fase4_rdf {
49
50         /**
51          * Word-wrapping mode for description, set it to 0 do disable this feature! Ommits _use_nl2br!
52          *
53          * @access private
54          * @var    integer
55          */
56         var $_word_wrap = '0';
57
58         /**
59          * Wether to recode \n -> <br /> or not in description
60          *
61          * @access private
62          * @var    boolean
63          */
64         var $_use_nl2br = TRUE;
65
66         /**
67          * Sets the decoding mode of the read data (UTF8 scrambles some german umlauts here!)
68          *
69          * "htmlentities" - Use the function htmlentities()
70          * "utf8_decode"  - Use the function ut8_decode() when you have UTF8 encoded text
71          * <empty>        - Use non of both
72          *
73          * @access private
74          * @var    string
75          */
76         var $_decoding_mode = '';
77
78         /**
79          * If $_link_target is set a target='xxx' attribute in each <a /> and <form accept-charset="utf-8" /> html tag will be added
80          *
81          * Possible values are "_blank", "_content", "_parent", "_self", "_top"
82          *
83          * @access private
84          * @var    string
85          */
86         var $_link_target = '_blank';
87
88         /**
89          * vars for proxy settings - Prox Host
90          *
91          * @access private
92          * @var      string
93          */
94         var $_phost = '';
95
96         /**
97          * vars for proxy settings - Prox Port
98          *
99          * @access private
100          * @var      string
101          */
102         var $_pport = '';
103
104         /**
105          * vars for proxy settings - Prox Username
106          *
107          * @access private
108          * @var      string
109          */
110         var $_pname = '';
111
112         /**
113          * vars for proxy settings - Prox Password
114          *
115          * @access private
116          * @var      string
117          */
118         var $_ppasswd = '';
119
120         /**
121          * just a flag for checking if proxy-support should be enabled
122          * set default to false (will be enabled if set_proxy is called)
123          *
124          * @access   private
125          * @see      set_proxy()
126          * @var      bool
127          */
128         var $_use_proxy = FALSE;
129
130         /**
131          * just a flag for checking if proxy-support with authentication
132          * should be enabled
133          * set default to false (will be enabled if set_proxy is called)
134          *
135          * @access   private
136          * @see      set_proxy()
137          * @var      boolean
138          */
139         var $_use_proxy_auth = FALSE;
140
141         /**
142          * The time the Files will be cached (in seconds).
143          *
144          * @access private
145          * @var    int
146          */
147         var $_refresh = 60;   // int
148
149         /**
150          * The Name of the cached File.
151          *
152          * @access private
153          * @var    string
154          */
155         var $_cached_file = '';   // String
156
157         /**
158          * Indicates whether the cached or the remote file was used.
159          *
160          * @access private
161          * @var    boolean
162          */
163         var $_use_cached_file = TRUE;
164
165         /**
166          * (fast|normal) depends on _use_dynamic_display(). _use_dynamic_display(TRUE) -> 'normal', otherwise 'fast'
167          *
168          * @access private
169          * @var    string
170          */
171         var $_cache_type = 'fast';
172
173         /**
174          * The Name of the Remote File.
175          *
176          * @access private
177          * @var    string
178          */
179         var $_remote_file = '';
180
181         /**
182          * Path to the Cache Directory.
183          *
184          * @access private
185          * @var    string
186          */
187         var $_cache_dir = 'cache/';  // String
188
189         /**
190          * Indicates whether the Creating of the Cache Directory needs to be done or not.
191          *
192          * @access private
193          * @var    boolean
194          */
195         var $_cache_dir_ok = FALSE;
196
197         /**
198          * Type of the file to be parsed (RSS or RDF).
199          *
200          * The Type depends on the root node
201          *
202          * @access private
203          * @var    string
204          */
205         var $_type = 'rss'; // string (rss or rdf)
206
207         /**
208          * Array of Display Settings.
209          *
210          * Specific Parameters can be set to hidden. These are:
211          * image, channel and textinput. If set to "hidden" those elements won't be displayed.
212          *
213          * @access private
214          * @var    array
215          */
216         var $_display_opt = array(
217                 'build'        => '',
218                 'image'        => '',
219                 'channel'      => '',
220                 'textinput'    => '',
221                 'cache_update' => '',
222                 'sitelink'     => '',
223                 'refid'        => '',
224                 'reflink'      => '',
225         );
226
227         /**
228          * Defines the width attribute in the table that holds the rdf/rss representation
229          *
230          * @access private
231          * @var    int
232          * @see    see_table_width()
233          */
234         var $_table_width = '100%';
235
236         /**
237          * Indicates whether or not to use dynamic Display Settings
238          *
239          * @access private
240          * @var    array
241          */
242         var $_use_dynamic_display = FALSE;
243
244         /**
245          * <item> count
246          *
247          * @access private
248          * @var    int
249          */
250         var $_item_count = '0';
251
252         /**
253          * No of max <item>s
254          *
255          * @access private
256          * @var    boolean
257          */
258         var $_max_count = FALSE;
259
260         /**
261          * Array containing the content of <channel />
262          *
263          * @access private
264          * @var    array
265          */
266         var $_array_channel = array();
267
268         /**
269          * Array containing the content of each <item />
270          *
271          * @access private
272          * @var    array
273          */
274         var $_array_item = array();
275
276         /**
277          * Array containing the content of <textinput />
278          *
279          * @access private
280          * @var    array
281          */
282         var $_array_textinput = array();
283
284         /**
285          * Array containing the content of <image />
286          *
287          * @access private
288          * @var    array
289          */
290         var $_array_image = array();
291
292         /**
293          * Array containing the Channel content. Just For internal XML Parser Purposes.
294          *
295          * @access private
296          * @var    array
297          */
298         var $_citem = array();
299
300         /**
301          * Array containing the Channel Parser Depth. Just For internal XML Parser Purposes.
302          *
303          * @access private
304          * @var    array
305          */
306         var $_cdepth = array();
307
308         /**
309          * Array containing the Channel tags. Just For internal XML Parser Purposes.
310          *
311          * @access private
312          * @var    array
313          */
314         var $_ctags = array('x');
315
316         /**
317          * Array containing the Channel content. Just For internal XML Parser Purposes.
318          *
319          * @access private
320          * @var    array
321          */
322         var $_item = array();   // Array
323
324         /**
325          * Array containing the Channel Parser Depth. Just For internal XML Parser Purposes.
326          *
327          * @access private
328          * @var    array
329          */
330         var $_depth = array();  // Array
331
332         /**
333          * Array containing the tags. Just For internal XML Parser Purposes.
334          *
335          * @access private
336          * @var    array
337          */
338         var $_tags = array('x');  // Array
339
340         /**
341          * Garbage collection: probability in percent
342          *
343          * @var      integer     0 => never
344          * @access   public
345          */
346         var $gc_probability = 1;
347
348         /**
349          * HTML Output
350          *
351          * @var      string
352          * @access   private
353          */
354         var $_output = '';
355
356         /**
357          * @var  string
358          */
359         var $_parse_mode = '';
360
361         // Output variable
362         var $out = '';
363
364         // Salt for hashing
365         var $salt = '';
366
367         /**
368          * Constructor of our Class
369          *
370          * This Method checks if the Cache Directory can be found. Otherwise it tries to creat the Cache Directory at the specified Path.
371          * Additionally the Refresh Time is set to a default Value of 1200s (20 min).
372          *
373          * @access    public
374          * @author    Stefan Saasen <s@fase4.com>
375          * @see          _refresh
376          */
377         function fase4_rdf()
378         {
379                 // default Value, to be overwritten in set_refresh()
380                 $this->_refresh = (time() - 1200);
381                 $this->_clear_cItems();
382                 $this->_clear_Items();
383         }
384
385         /**
386          * This Method starts the parsing of the specified RDF File. The File can be a local or a remote File.
387          *
388          * @access    public
389          * @author    Stefan Saasen <s@fase4.com>
390          * @param     string $rdf    RDF File (Location)
391          * @return    string Displays RDF Content (using _display())
392          * @see          _remote_file, cache()
393          */
394         function parse_RDF($rdf)
395         {
396                 unset($this->_array_item);
397                 $this->_remote_file = $rdf;
398                 $this->out .= "<!-- http://www.fase4.com/rdf/ -->";
399                 $this->out .= "<table width=\"".$this->_table_width."\">";
400                 $this->out .= $this->cache();
401                 $this->out .= "</table>";
402                 $this->_output = '';
403                 $this->_item_count = '0';
404                 return TRUE;
405         }
406
407         /**
408          * This Method is called when all parsing is finished to use the garbage collection
409          *
410          * @access    public
411          * @author    Stefan Saasen <s@fase4.com>
412          * @param     string $rdf    RDF File (Location)
413          * @return    string Displays RDF Content (using _display())
414          * @see          _remote_file, cache()
415          */
416         function finish($return = FALSE) {
417                 $this->out = str_replace('$', '&#36;', $this->out);
418
419                 if (!$return) {
420                         echo $this->out;
421                 } else {
422                         return $this->out;
423                 }
424                 $this->_garbage_collection();
425         }
426
427         /**
428          * With this method you can decide whether to use the normal cache and dynamic display Options or to use a static cache.
429          *
430          * 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.
431          * In this case you can not modify the display settings.
432          * processing time: (1.4792) --> remote file
433          * processing time: (0.0313) --> using 'normal cache' with display Modification turned on.
434          * processing time: (0.0019) --> using 'fast cache'
435          *
436          * @access    public
437          * @author    Stefan Saasen <s@fase4.com>
438          * @param     string $rdf    RDF File (Location)
439          * @return    string Displays RDF Content (using _display())
440          * @see          _remote_file, cache()
441          */
442         function use_dynamic_display($bool) {
443                 $this->_use_dynamic_display = $bool;
444                 return TRUE;
445         }
446
447         /**
448          * This Method avtually parses the XML data.
449          *
450          * @access    private
451          * @author    Stefan Saasen <s@fase4.com>
452          * @param     string $data    RDF File XML Data
453          * @see       _clear_Items()
454          */
455         function _parse_xRDF($data) {
456                 $this->_clear_Items();
457                 $xml_parser = xml_parser_create();
458                 xml_set_object($xml_parser,$this);
459                 xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
460                 xml_set_element_handler($xml_parser, '_startElement', '_endElement');
461                 xml_set_character_data_handler($xml_parser, '_parseData');
462                 if (!xml_parse($xml_parser, trim($data))) {
463                         $this->_throw_exception(sprintf("XML error: %s at line %d",
464                         xml_error_string(xml_get_error_code($xml_parser)),
465                         xml_get_current_line_number($xml_parser)).'<br /><br />Exception in function parse_RDF().');
466                 } // END - if
467                 xml_parser_free($xml_parser);
468         }
469
470
471         /**
472          * This Methods allows you to set the Refresh Time
473          *
474          * @access    public
475          * @author    Stefan Saasen <s@fase4.com>
476          * @param     int $seconds time files will be cached (in seconds).
477          * @return    boolean
478          * @see       _refresh
479          */
480         function set_refresh($seconds) {
481                 $this->_refresh = (time() - $seconds);
482                 return TRUE;
483         }
484
485         function set_salt($saltPara) {
486                 $this->salt = $saltPara;
487                 return TRUE;
488         }
489
490         /**
491          * This Methods allows you to set the No. of <item>s to display
492          *
493          * @access    public
494          * @param     int $int No of max <item>s
495          * @author    Stefan Saasen <s@fase4.com>
496          * @return       boolean
497          * @see          _max_count, _endElement()
498          */
499         function set_max_item($int)
500         {
501                 $this->_max_count = $int;
502                 return TRUE;
503         }
504
505         /**
506          * This Methods allows you to set the Cache Directory
507          *
508          * @access    public
509          * @author    Stefan Saasen <s@fase4.com>
510          * @param     string $dir Path to Directory.
511          * @return       boolean
512          * @see          _cache_dir
513          */
514         function set_CacheDir($dir)
515         {
516                 if (substr($dir, -1) != '/') {
517                         $dir = $dir.'/';
518                 }
519                 $this->_cache_dir = $dir;
520         }
521
522         /**
523          * This Method displays Error Messages and terminates the Execution of the Script
524          *
525          * @access    private
526          * @param     string $msg Message to display on failure
527          * @author    Stefan Saasen <s@fase4.com>
528          */
529         function _throw_exception($msg)
530         {
531                 $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>";
532                 return TRUE;
533         }
534
535         /**
536          * This Method clears the Array containig the Items.
537          *
538          * @access    private
539          * @author    Stefan Saasen <s@fase4.com>
540          * @see       _item
541          */
542         function _clear_Items() {
543                 $this->_item = array(
544                         'title'         => '',
545                         'link'          => '',
546                         'description'   => '',
547                         'url'           => '',
548                         'language'      => '',
549                         'pubDate'       => '',
550                         'lastBuildDate' => '',
551                         'width'         => '',
552                         'height'        => ''
553                 );
554         }
555         /**
556          * This Method clears the Array containig the Channel Items.
557          *
558          * @access    private
559          * @author    Stefan Saasen <s@fase4.com>
560          * @see       _item
561          */
562         function _clear_cItems() {
563                 $this->_citem = array(
564                         'title'          => '',
565                         'link'           => '',
566                         'description'    => '',
567                         'url'            => '',
568                         'language'       => '',
569                         'copyright'      => '',
570                         'managingEditor' => '',
571                         'webMaster'      => '',
572                         'pubDate'        => '',
573                         'lastBuildDate'  => '',
574                         'category'       => '',
575                         'generator'      => '',
576                         'docs'           => '',
577                         'cloud'          => '',
578                         'ttl'            => '',
579                         'image'          => '',
580                         'textinput'      => '',
581                         'skipHours'      => '',
582                         'skipDays'       => '',
583                         'sitelink'       => '',
584                         'refid'          => '',
585                         'reflink'        => '',
586                 );
587         }
588
589         /**
590          * XML Parser Start Element Handler
591          *
592          * @access    private
593          * @author    Stefan Saasen <s@fase4.com>
594          * @param     mixed  $parser a reference to the XML parser calling the handler.
595          * @param     string $name contains the name of the element for which this handler is called.
596          * @param     string $attrs contains an associative array with the element's attributes (if any).
597          * @see          _get_ChannelData(), _clear_Items(), _type, _parse_mode, _depth, _tags, _cdepth, _ctags
598          */
599         function _startElement($parser, $name, $attrs) {
600                 // We have to determine, which type of xml data we have to parse
601                 if ($name == 'rss') {
602                         $this->_type = 'rss';
603                 } elseif ($name == 'rdf:RDF' || $name == 'rdf') {
604                         $this->_type = 'rdf';
605                 }
606
607
608                 if ($name == 'channel' && $this->_type != 'rdf') {
609                         $this->_parse_mode = 'channel';
610                 } elseif (($name == 'item')
611                 || ($name == 'image')
612                 || ($name == 'textinput')
613                 || (($name == 'channel') && ($this->_type != 'rss'))) {
614                         if ($this->_parse_mode == 'channel') {
615                                 $this->_get_ChannelData($parser);
616                         }
617                         $this->_parse_mode = 'all';
618                 }
619
620                 if (!isset($this->_depth[$this->get_parser_id($parser)])) {
621                         $this->_depth[$this->get_parser_id($parser)] = '0';
622                 }
623                 $this->_depth[$this->get_parser_id($parser)]++;
624                 array_push($this->_tags, $name);
625
626                 if (!isset($this->_cdepth[$this->get_parser_id($parser)])) {
627                         $this->_cdepth[$this->get_parser_id($parser)] = '0';
628                 }
629                 $this->_cdepth[$this->get_parser_id($parser)]++;
630                 array_push($this->_ctags, $name);
631         }   // END _startElement()
632
633         /**
634          * Retrives the Channel Data in <rss> File
635          *
636          * @access    private
637          * @author    Stefan Saasen <s@fase4.com>
638          * @param     mixed  $parser a reference to the XML parser calling the handler.
639          * @see          _output, _display_opt, _citem
640          */
641         function _get_ChannelData($parser)
642         {
643                 $this->_citem['link'] = trim($this->_citem['link']);
644                 if (($this->_display_opt['sitelink'] == $this->_citem['link']) && (!empty($this->_display_opt['reflink'])) && (!empty($this->_display_opt['refid'])))
645                 {
646                         $this->_citem['link'] .= $this->_display_opt['reflink'].$this->_display_opt['refid'];
647                 }
648
649                 if (empty($this->_display_opt['channel']) ||
650                 $this->_display_opt['channel'] != 'hidden') {
651                         $this->_output .= "<tr><td>\n";
652                         $this->_output .= "<table border=\"0\" width=\"100%\" class=\"fase4_rdf_meta\" cellspacing=\"5\" cellpadding=\"2\">\n";
653                         $this->_output .= "<tr><td class=\"fase4_rdf_main_title\"><div class=\"fase4_rdf_main_title\">".htmlspecialchars($this->_citem['title'])."</div></td></tr>\n";
654                         $this->_output .= "<tr><td class=\"fase4_rdf\">".strip_tags($this->_citem['description'], '<a>, <img>')."</td></tr>\n";
655                         $this->_output .= "<tr><td>&nbsp;</td></tr>\n";
656                         $this->_output .= "<tr><td class=\"fase4_rdf\">\n";
657                         if (isset($this->_display_opt['build']) && $this->_display_opt['build'] != 'hidden') {
658                                 if ($this->_citem['lastBuildDate']) { $this->_output .= 'build: '. $this->_citem['lastBuildDate'].'<br />';}
659                         }
660                         if (isset($this->_display_opt['cache_update']) && $this->_display_opt['cache_update'] != 'hidden' && ($_update = $this->get_cache_update_time())) {
661                                 $this->_output .= 'cache update: '.$_update."<br />\n";
662                         }
663                         $this->_output .= "<a href=\"".$this->_citem['link']."\" ";
664                         if (isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; }
665                         $this->_output .= ">".$this->_cut_string($this->_citem['link']) . '</a>';
666                         $this->_output .= "</td></tr>\n";
667                         $this->_output .= "<tr><td><hr noshade width=\"100%\" size=\"1\"></td></tr>\n";
668                         $this->_output .= "</table></td></tr>";
669                 }
670                 $this->_array_channel = array(
671                         'title'         => $this->_citem['title'],
672                         'link'          => $this->_citem['link'],
673                         'description'   => $this->_citem['description'],
674                         'lastBuildDate' => $this->_citem['lastBuildDate']);
675         }
676
677         /**
678          * XML Parser End Element Handler
679          *
680          * @access    private
681          * @author    Stefan Saasen <s@fase4.com>
682          * @param     mixed  $parser a reference to the XML parser calling the handler.
683          * @param     string $name contains the name of the element for which this handler is called.
684          * @see          _clear_Items(), _type, _parse_mode, _depth, _tags, _cdepth, _ctags, _item, _output, _display_opt
685          */
686         function _endElement($parser, $name) {
687                 array_pop($this->_tags);
688                 $this->_depth[$this->get_parser_id($parser)]--;
689                 array_pop($this->_ctags);
690                 $this->_cdepth[$this->get_parser_id($parser)]--;
691                 $this->_item['link'] = trim($this->_item['link']);
692                 if ((!empty($this->_display_opt['refid'])) && (!empty($this->_item['link'])))
693                 {
694                         if (!isInString('refid=', $this->_item['link'])) $this->_item['link'] .= '?refid=' . $this->_display_opt['refid'];
695                 }
696                 switch ($name) {
697                         case 'item':
698                                 if (empty($this->_max_count) || $this->_item_count < $this->_max_count) {
699                                         if ($this->_item['title'] != $this->_item['description']
700                                         && $this->_item['description']) {
701
702                                                 // word-wrapping added by Roland Haeder <webmaster@mxchange.org>
703                                                 if (($this->_word_wrap > 0) && (strlen($this->_item['description']) > $this->_word_wrap))
704                                                 {
705                                                         // Switch off _use_nl2br
706                                                         $this->_use_nl2br = FALSE;
707                                                         // First remove all \n
708                                                         $this->_item['description'] = str_replace('\n', ' ', $this->_item['description']);
709                                                         // Wrap with <br />\n
710                                                         $this->_item['description'] = wordwrap($this->_item['description'], $this->_word_wrap, "*<br />\n");
711                                                 }
712                                                 elseif (($this->_word_wrap == '0') && (!$this->_use_nl2br))
713                                                 {
714                                                         // Strip tags out instead when word-wrap is disabled
715                                                         $this->_item['description'] = strip_tags($this->_item['description'], '<a>, <img>');
716                                                 }
717
718                                                 // nl2br added by Roland Haeder <webmaster@mxchange.org>
719                                                 if ($this->_use_nl2br) $this->_item['description'] = nl2br($this->_item['description']);
720
721                                                 $this->_output .= "<tr><td class=\"fase4_rdf_title\"><div class=\"fase4_rdf_title\"><a class=\"fase4_rdf_title\" href=\"".$this->_item['link']."\" ";
722                                                 if (isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; }
723                                                 $this->_output .= ">".strip_tags($this->_item['title'], '<a>, <img>').'</a> ('.$this->_item['pubDate'].")</div></td></tr>\n";
724                                                 $this->_output .= "<tr><td class=\"fase4_rdf\">".$this->_item['description']."</td></tr>\n";
725                                                 // we just display the <hr> if there is a description
726                                                 $this->_output .= "<tr><td><hr noshade=\"noshade\" size=\"1\" /></td></tr>\n";
727                                         } else {
728                                                 $this->_output .= "<tr><td class=\"fase4_rdf\">\n";
729                                                 $this->_output .= "<a href=\"".$this->_item["link"]."\" ";
730                                                 if (isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; }
731                                                 $this->_output .= ">".$this->_item["title"]."</a></td></tr>\n";
732                                         }
733
734                                         $this->_array_item[] = array(
735                                                 'title'       => $this->_item['title'],
736                                                 'link'        => $this->_item['link'],
737                                                 'description' => $this->_item['description']
738                                         );
739
740                                         ++$this->_item_count;
741                                 }
742                                 $this->_clear_Items();
743                                 break;
744
745                         case 'image':
746                                 if (isset($this->_display_opt['image']) && ($this->_display_opt['image'] != 'hidden') && $this->_item['url']) {
747                                         $this->_output .= "<tr><td class=\"fase4_rdf\">\n";
748                                         $this->_output .= "<a href=\"".$this->_item['link']."\" ";
749                                         if (isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; }
750                                         $this->_output .= "><img src=\"".$this->_item['url']."\"";
751                                         if (isset($this->_item['width']) && isset($this->_item['height'])) {
752                                                 $this->_output .= " width=\"".$this->_item['width']."\" height=\"".$this->_item['height']."\"";
753                                         }
754                                         $this->_output .= " alt=\"".$this->_item['title']."\" border=\"0\" /></a></td></tr>\n";
755
756                                         $this->_array_image[] = array(
757                                                 'url'    => $this->_item['url'],
758                                                 'link'   => $this->_item['link'],
759                                                 'width'  => $this->_item['width'],
760                                                 'height' => $this->_item['height']
761                                         );
762                                         $this->_clear_Items();
763                                 } elseif (isset($this->_display_opt['image']) && ($this->_display_opt['image'] == 'hidden')) {
764                                         $this->_clear_Items();
765                                 }
766
767                                 break;
768
769                         case 'channel':
770                                 if (isset($this->_display_opt['channel']) && $this->_display_opt['channel'] != 'hidden' && $this->_item['title'] != '') {
771                                         $this->_output .= "<tr><td>\n";
772                                         $this->_output .= "<table border=\"0\" width=\"100%\" class=\"fase4_rdf_meta\" cellspacing=\"5\" cellpadding=\"2\">\n";
773                                         $this->_output .= "<tr><td class=\"fase4_rdf\"><div class=\"fase4_rdf_title\">".htmlspecialchars($this->_item['title'])."</div></td></tr>\n";
774                                         $this->_output .= "<tr><td class=\"fase4_rdf\">".strip_tags($this->_item['description'], '<a>, <img>')."</td></tr>\n";
775                                         $this->_output .= "<tr><td>&nbsp;</td></tr>\n";
776                                         $this->_output .= "<tr><td class=\"fase4_rdf\">\n";
777                                         if ($this->_display_opt['build'] != 'hidden') {
778                                                 if ($this->_item['lastBuildDate']) { $this->_output .= 'build: '. $this->_item['lastBuildDate'].'<br />';}
779                                         }
780                                         if ($this->_display_opt['cache_update'] != 'hidden' && ($_update = $this->get_cache_update_time())) {
781                                                 $this->_output .= 'cache update: '.$_update."<br />\n";
782                                         }
783                                         $this->_output .= "<a href=\"".$this->_item['link']."\" ";
784                                         if (isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; }
785                                         $this->_output .= ">".$this->_cut_string($this->_item['link'])."</a>\n";
786                                         $this->_output .= "</td></tr>\n";
787                                         $this->_output .= "</table></td></tr>\n";
788                                 }
789                                 $this->_array_channel = array(
790                                         'title'         => $this->_item['title'],
791                                         'link'          => $this->_item['link'],
792                                         'description'   => $this->_item['description'],
793                                         'lastBuildDate' => $this->_item['lastBuildDate']
794                                 );
795                                 $this->_clear_Items();
796                                 $this->_clear_cItems();
797                                 break;
798
799                         case 'textinput':
800                                 if (isset($this->_display_opt['textinput']) && ($this->_display_opt['textinput'] != 'hidden') && $this->_item['name'] && $this->_item['link']) {
801                                         $this->_output .= "<tr><td class=\"fase4_rdf\">\n";
802                                         $this->_output .= "<form accept-charset=\"UTF-8\" action=\"".$this->_item['link']."\" ";
803                                         if (isset($this->_link_target)) { $this->_output .= "target=\"".$this->_link_target."\" "; }
804                                         $this->_output .= "method=\"get\">\n";
805                                         $this->_output .= "<div class=\"fase4_rdf_title\">".$this->_item['title']."</div>";
806                                         $this->_output .= strip_tags($this->_item['description'], '<a>, <img>')."<br /><br />\n";
807                                         $this->_output .= "<input class=\"fase4_rdf_input\" type=\"text\" name=\"".$this->_item['name']."\">&nbsp;\n";
808                                         $this->_output .= "<input class=\"fase4_rdf_input\" type=\"submit\" value=\"go\">";
809                                         $this->_output .= "</form>\n";
810                                         $this->_output .= "</td></tr>\n";
811                                         $this->_array_textinput = array(
812                                                 'title'       => $this->_item['title'],
813                                                 'name'        => $this->_item['name'],
814                                                 'link'        => $this->_item['link'],
815                                                 'description' => $this->_item['description']
816                                         );
817                                         $this->_clear_Items();
818                                 } elseif (isset($this->_display_opt['textinput']) && ($this->_display_opt['textinput'] == 'hidden')) {
819                                         $this->_clear_Items();
820                                 }
821
822                                 break;
823                 }
824         }
825
826         /**
827          * This Method returns the data from the <channel /> paragraph.
828          *
829          * @access    public
830          * @author    Stefan Saasen <s@fase4.com>
831          * @return    array
832          * @see       _array_channel
833          */
834         function get_array_channel()
835         {
836                 return $this->_array_channel;
837         }
838
839         /**
840          * This Method returns the data from each <item /> paragraph.
841          *
842          * @access    public
843          * @author    Stefan Saasen <s@fase4.com>
844          * @return    array
845          * @see       _array_item
846          */
847         function get_array_item()
848         {
849                 return $this->_array_item;
850         }
851
852         /**
853          * This Method returns the data from <textinput />.
854          *
855          * @access    public
856          * @author    Stefan Saasen <s@fase4.com>
857          * @return    array
858          * @see       _array_textinput
859          */
860         function get_array_textinput()
861         {
862                 return $this->_array_textinput;
863         }
864
865         /**
866          * Getter for parser id from resource
867          *
868          * @access   private
869          * @author   Roland Haeder <webmaster@mxchange.org>
870          * @return   int
871          */
872         function get_parser_id ($parser) {
873                 // Default is zero
874                 $id = '0';
875
876                 // Is it a resource?
877                 if (is_resource($parser)) {
878                         // Cast the resource into id
879                         $id = (int) $parser;
880                 } // END - if
881
882                 // Return the id
883                 return $id;
884         }
885
886         /**
887          * This Method returns the data from <image />.
888          *
889          * @access    public
890          * @author    Stefan Saasen <s@fase4.com>
891          * @return    array
892          * @see       _array_image
893          */
894         function get_array_image()
895         {
896                 return $this->_array_image;
897         }
898
899         /**
900          * XML Parser Data Handler
901          *
902          * @access    private
903          * @author    Stefan Saasen <s@fase4.com>
904          * @param     mixed  $parser a reference to the XML parser calling the handler.
905          * @param     string $text contains the character data as a string.
906          * @see          _parse_mode, _item, _tags, _depth, _citem, _ctags, _cdepth
907          */
908         function _parseData($parser, $text)
909         {
910                 // Deocing mode added by Roland Haeder <webmaster@mxchange.org>
911                 switch ($this->_decoding_mode)
912                 {
913                         case 'utf8_decode':
914                                 $text = utf8_decode($text);
915                                 break;
916
917                         case 'htmlentities':
918                                 $text = htmlentities($text);
919                                 break;
920                 }
921
922                 $clean = preg_replace("/\s/", "", $text);
923                 if ($clean) {
924                         $text = preg_replace("/^\s+/", "", $text)."\n";
925                         if ($this->_parse_mode == 'all') {
926                                 if (isset($this->_item[$this->_tags[$this->_depth[$this->get_parser_id($parser)]]]) &&
927                                 $this->_item[$this->_tags[$this->_depth[$this->get_parser_id($parser)]]]) {
928                                         $this->_item[$this->_tags[$this->_depth[$this->get_parser_id($parser)]]] .= $text;
929                                 } else {
930                                         $this->_item[$this->_tags[$this->_depth[$this->get_parser_id($parser)]]] = $text;
931                                 }
932                         } elseif (isset($this->_parse_mode) && $this->_parse_mode == 'channel') {
933                                 if (isset($this->_citem[$this->_ctags[$this->_cdepth[$this->get_parser_id($parser)]]])) {
934                                         $this->_citem[$this->_ctags[$this->_cdepth[$this->get_parser_id($parser)]]] .= $text;
935                                 } else {
936                                         $this->_citem[$this->_ctags[$this->_cdepth[$this->get_parser_id($parser)]]] = $text;
937                                 }
938                         }
939                 }
940         }
941
942         /**
943          * This Method allows you to choose if specific Parameters are displayed or not. These are:
944          * image, channel, textinput, build and cache_update. If set to "hidden" those elements won't be displayed.
945          *
946          * @access    public
947          * @author    Stefan Saasen <s@fase4.com>
948          * @param     array  $options
949          * @see          _display_opt
950          */
951         function set_Options($options = '')
952         {
953                 if (is_array($options)) {
954                         $this->_display_opt = $options;
955                         return TRUE;
956                 } else {
957                         unset($this->_display_opt);
958                         return FALSE;
959                 }
960         }
961
962         /**
963          * This Method allows you to define the width of the table that holds the representation of the rdf/rss file.
964          *
965          * @access    public
966          * @author    Stefan Saasen <s@fase4.com>
967          * @param     int  $width  attribute width in tag <table>
968          * @see          _table_width
969          */
970         function set_table_width($width = 400)
971         {
972                 $this->_table_width = $width;
973                 return TRUE;
974         }
975
976         /**
977          * This Method returns an assocative Array with available Options.
978          *
979          * The Keys are the Name of the Options to be set.
980          * The Values are  short Description of available Options.
981          *
982          * @access    public
983          * @author    Stefan Saasen <s@fase4.com>
984          * @return    array  $options
985          * @see          _display_opt
986          */
987         function get_Options() {
988                 $options = array(
989                         'image'        => "If 'image' is set to \"hidden\" no image provided by the RDF Publisher will be displayed.",
990                         '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",
991                         'textinput'    => "If set to \"hidden\" no Input Form will be displayed",
992                         'build'        => "If set to \"hidden\" the Build Date (if provided) of the RDF File will not be displayed",
993                         'cache_update' => "If set to \"hidden\" the Update Date/Time of the cached Rdf File will not be displayed"
994                 );
995                 return $options;
996         }
997
998         /**
999          * This Method returns the Content of the RDF File in one string. The String actually holds the whole XML Document.
1000          *
1001          * @access    public
1002          * @author    Stefan Saasen <s@fase4.com>
1003          * @param     string $rdf    RDF File (Location)
1004          * @return    string XML Presentation of parsed RDF File
1005          * @see          _cached_file, _remote_file, _cache_dir, _refresh, _update_cache()
1006          */
1007         function cache()
1008         {
1009                 // checks if the cache directory already exists
1010                 // if not, the cache directory will be created
1011                 if (!$this->_cache_dir_ok) {
1012                         $this->_create_cache_dir();
1013                 }
1014                 if ($this->_use_dynamic_display == TRUE) {
1015                         $this->_cached_file = md5('dynamic'.$this->salt.$this->_remote_file) . '.cache';
1016                         $this->_cache_type = 'normal';
1017                 } else {
1018                         $this->_cached_file = md5($this->salt.$this->_remote_file) . '.cache';
1019                         $this->_cache_type = 'fast';
1020                 }
1021
1022                 $_cache_f = $this->_cache_dir.$this->_cached_file;
1023
1024                 if ((!file_exists($_cache_f)) || (filemtime($_cache_f) < $this->_refresh) || (filesize($_cache_f) == 0)) {
1025                         // We have to parse the remote file
1026                         $this->_use_cached_file = FALSE;
1027                         // --> we want to provide proper Information for Use in
1028                         // get_cache_update_time()
1029                         clearstatcache();
1030                         if ($this->_use_dynamic_display == TRUE) {
1031                                 $_rdf = implode(' ', $this->_rdf_data()); // -> proxy
1032                                 if (!$_rdf) {
1033                                         $this->_throw_exception($this->_remote_file.' is not available');
1034                                 }
1035                                 $this->_parse_xRDF($_rdf);
1036                                 $this->_update_cache($_rdf);
1037                                 $data = $this->_output;
1038                         } else {
1039                                 $_rdf = implode(' ', $this->_rdf_data()); // -> proxy
1040                                 if (!$_rdf) {
1041                                         $this->_throw_exception($this->_remote_file.' is not available');
1042                                 }
1043                                 $this->_parse_xRDF($_rdf);
1044                                 $this->_update_cache($this->_output);
1045                                 $data = $this->_output;
1046                         }
1047                 } elseif (defined('__SECURITY') && function_exists('readFromFile')) {
1048                         // Use readFromFile() from mailer project
1049                         $this->_use_cached_file = TRUE;
1050                         if ($this->_use_dynamic_display == TRUE) {
1051                                 $this->_parse_xRDF(readFromFile($_cache_f));
1052                                 $data = $this->_output;
1053                         } else {
1054                                 $data = readFromFile($_cache_f);
1055                         }
1056                 } else {
1057                         // we can use the cached file
1058                         $this->_use_cached_file = TRUE;
1059                         if ($this->_use_dynamic_display == TRUE) {
1060                                 $this->_parse_xRDF(implode(' ', file($_cache_f)));
1061                                 $data = $this->_output;
1062                         } else {
1063                                 $data = implode(' ', file($_cache_f));
1064                         }
1065                 }
1066                 return trim($data);
1067         }   // END cache()
1068
1069         /**
1070          * This Methods creates the Cache Directory if the specified Directory does not exist.
1071          *
1072          * @access    private
1073          * @author    Stefan Saasen <s@fase4.com>
1074          * @param     string $dir Path to Directory.
1075          * @return       boolean
1076          * @see          _cache_dir, _cache_dir_ok
1077          */
1078         function _create_cache_dir()
1079         {
1080                 $path = '';
1081                 if (!is_dir($this->_cache_dir)) {
1082                         $arr = explode('/', $this->_cache_dir);
1083                         $c = count($arr);
1084                         if ($arr[0] == '') {
1085                                 $path = '/';
1086                         }
1087                         for($i = '0';$i<$c;$i++) {
1088                                 if ($arr[$i]!='') {
1089                                         $path .= $arr[$i].'/';
1090                                         if (!is_dir($path)) {
1091                                                 if (!mkdir($path, 0777)) {
1092                                                         $this->_throw_exception("failed to create directory:<b>".$this->_cache_dir."</b>.<br /><br />Exception on Line: ".__LINE__);
1093                                                         return FALSE;
1094                                                 }
1095                                         }
1096                                 }
1097                         }
1098                         $this->_cache_dir_ok = TRUE;
1099                         return TRUE;
1100                 } else {
1101                         $this->_cache_dir_ok = TRUE;
1102                         return TRUE;
1103                 }
1104         }   // END _create_cache_dir()
1105
1106         /**
1107          * This Method updates the cached RDF Files and synchronises them with their remote Counterparts.
1108          *
1109          * @access    private
1110          * @author    Stefan Saasen <s@fase4.com>
1111          * @param     string $rdf    RDF File (Location)
1112          * @see          _cache_dir, _cached_file, _throw_exception()
1113          */
1114         function _update_cache($content = '')
1115         {
1116                 if (defined('__SECURITY') && function_exists('writeToFile')) {
1117                         // Use mailer-project function
1118                         return writeToFile($this->_cache_dir.$this->_cached_file, $content);
1119                 }
1120                 $_local = @fopen($this->_cache_dir.$this->_cached_file, 'w');
1121                 if (!$_local) {
1122                         $this->_throw_exception('Cannot open '.$this->_cached_file.'<br /><br />Exception at Line: '.__LINE__);
1123                         return FALSE;
1124                 }
1125                 if (fwrite($_local, $content) === FALSE) {
1126                         $this->_throw_exception('Cannot write to '.$this->_cached_file.'<br /<br />Exeception at Line: '.__LINE__);
1127                         return FALSE;
1128                 }
1129                 fclose($_local);
1130                 @chmod($this->_cache_dir.$this->_cached_file, 0666);
1131                 return TRUE;
1132         }   // END _update_cache()
1133
1134         /**
1135          * This Method returns the Date/Time of last Cache Update of the actually parsed RDF File.
1136          *
1137          * @access    public
1138          * @author    Stefan Saasen <s@fase4.com>
1139          * @return       string Date/Time of last Update
1140          * @see          _cache_dir, _cached_file
1141          */
1142         function get_cache_update_time()
1143         {
1144                 return (file_exists($this->_cache_dir.$this->_cached_file))?date('d.m.Y H:i:s', filemtime($this->_cache_dir.$this->_cached_file)):'Cachemiss';
1145         }   // END get_cache_update_time()
1146
1147         /**
1148          * This Method returns the Type of Cache that was used ('normal' or 'fast')
1149          *
1150          * @access    public
1151          * @author    Stefan Saasen <s@fase4.com>
1152          * @param     string $rdf    RDF File (Location)
1153          * @return    string Displays RDF Content (using _display())
1154          * @see          _remote_file, cache()
1155          */
1156         function get_CacheType()
1157         {
1158                 return $this->_cache_type;
1159         }
1160
1161         /**
1162          * Returns true if cached file was used, otherwise false
1163          *
1164          * @access    public
1165          * @author    Stefan Saasen <s@fase4.com>
1166          * @return    array  $options
1167          * @see          _use_cached_file
1168          */
1169         function is_cachedFile()
1170         {
1171                 return $this->_use_cached_file;
1172         }
1173
1174         /**
1175          * This Method deletes all the cached Files.
1176          *
1177          * Please keep in mind to use this method just as a 'manual garbage collection'
1178          * You should cache the rss/rdf files locally to avoid unnecessary traffic.
1179          * (Both for your visitors and the Publisher)
1180          *
1181          * @access    public
1182          * @author    Stefan Saasen <s@fase4.com>
1183          * @see          _cache_dir
1184          */
1185         function clear_cache()
1186         {
1187                 $dir = dir($this->_cache_dir);
1188                 while($file=$dir->read()) {
1189                         // Exclude directories
1190                         if (is_file($dir->path.$file) && substr($file, -6, 6) != '.cache' && substr($file, -4, 4) != '.log')  {
1191                                 if ((defined('__SECURITY') && function_exists('removeFile')) && (!removeFile($dir->path.$file))) {
1192                                         $this->_throw_exception("removeFile() was unable to unlink ".$dir->path.$file."<br />\n<br />\nException at Line: ".__LINE__);
1193                                         return FALSE;
1194                                 } elseif (!unlink($dir->path.$file)) {
1195                                         $this->_throw_exception("Unable to unlink ".$dir->path.$file."<br />\n<br />\nException at Line: ".__LINE__);
1196                                         return FALSE;
1197                                 } // END - if
1198                         } // END - if
1199                 } // END - while
1200                 $dir->close();
1201                 return TRUE;
1202         }   // END clear_cache()
1203
1204         /**
1205          * Cuts the String $string after $str_len and adds '... '
1206          *
1207          * @access   private
1208          * @param    string  $string String to be shortened
1209          * @param    int     $str_len length of the returned String (overall length including '... ')
1210          * @return   string  Cut String
1211          */
1212         function _cut_string($string, $str_len = '30')
1213         {
1214                 if (strlen(trim($string))>$str_len) {
1215                         $string = substr(trim($string) , 0, $str_len - 4);
1216                         $string .= ' ...';
1217                 }
1218                 return $string;
1219         }   // END _cut_string()
1220
1221         /**
1222          * this Method implements simple Garbage Collection
1223          *
1224          * @access    private
1225          * @author    Stefan Saasen <s@fase4.com>
1226          * @see          _cache_dir, gc_probability, gc_maxlifetime
1227          */
1228         function _garbage_collection()
1229         {
1230                 srand((double) microtime() * 1000000);
1231                 if (mt_rand(1, 100) <= $this->gc_probability) {
1232                         $dir = dir($this->_cache_dir);
1233                         while($file=$dir->read()) {
1234                                 if (is_file($dir->path.$file) && substr($file, -6, 6) != '.cache' && substr($file, -4, 4) != '.log' && filemtime($dir->path.$file) <= time() - $this->_refresh)  {
1235                                         @unlink($dir->path.$file);
1236                                 } // END - if
1237                         }
1238                         $dir->close();
1239                 }   // END if
1240         }
1241
1242         /* ==== Proxy/Auth methods ==== */
1243
1244         /**
1245          * this method sets a proxy server
1246          *
1247          * @access    public
1248          * @param     string $phost Proxy Host
1249          * @param     string $pport Prox Port
1250          * @author    Marco Kraus <marco.kraus@siemens.com>
1251          */
1252         function set_proxy($phost, $pport)
1253         {
1254                 $this->_use_proxy = TRUE;
1255
1256                 if ($phost != '')
1257                 $this->_phost = $phost;
1258
1259                 if ($pport != '')
1260                 $this->_pport = $pport;
1261         }
1262
1263         /**
1264          * this method sets a proxy server authentification
1265          *
1266          * @access    public
1267          * @param     string $pname Username
1268          * @param     string $ppaswd Password
1269          * @author    Marco Kraus <marco.kraus@siemens.com>
1270          */
1271         function set_proxy_auth($pname, $ppasswd)
1272         {
1273                 $this->_use_proxy_auth = TRUE;
1274
1275                 if ($pname != '')
1276                 $this->_pname = $pname;
1277
1278                 if ($ppasswd != '')
1279                 $this->_ppasswd = $ppasswd;
1280         }
1281
1282
1283         /**
1284          * gets _remote_file into an array
1285          *
1286          * needed, cause if you use a proxy, you have to open
1287          * a raw-tcp-socket to get the data
1288          *
1289          * @access    private
1290          * @author    Marco Kraus <Marco.Kraus@siemens.com>
1291          * @return array
1292          * @see _use_proxy, cache()
1293          */
1294         function _rdf_data()
1295         {
1296                 if (defined('__SECURITY') && function_exists('sendGetRequest')) {
1297                         // Use mailer-project instead (see http://mxchange.org)
1298                         $useable_data = sendGetRequest($this->_remote_file, array(), TRUE);
1299                 } elseif ($this->_use_proxy == TRUE) {
1300                         // we need a raw socket here to connect to proxy
1301                         $fp = fsockopen($this->_phost,$this->_pport);
1302
1303                         if (!$fp) {
1304                                 $this->_throw_exception($this->_remote_file.' is not available with proxy');
1305                         } else {
1306                                 if ($this->_use_proxy_auth == TRUE) {
1307                                         fputs($fp, "GET ".$this->_remote_file." HTTP/1.0\r\nUser-Agent: Fase4 RDF-Reader/1.40 modified by Quix0r\r\n\r\n");
1308                                 } else {
1309                                         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");
1310                                 }
1311                         }
1312
1313
1314                         for ($i = '0'; !feof ($fp) ; $i++)
1315                         {
1316                                 $usable_data[$i] = "";
1317                                 $usable_data[$i] = fgets($fp,4096);
1318
1319                                 // PARSE HEADER ---- first line has to be <?xml, second rdf or rss, and third is blank
1320
1321                                 // strstr did not fit (ask Rasmus why), so we compare each character
1322                                 if (($usable_data[$i][0] == '<') &&
1323                                 ($usable_data[$i][1] == '?') &&
1324                                 ($usable_data[$i][2] == 'x') &&
1325                                 ($usable_data[$i][3] == 'm') &&
1326                                 ($usable_data[$i][4] == 'l')) {
1327                                         $usable_data[0] = $usable_data[$i]; // save current field
1328                                         $i = 1; // just reset array to start
1329                                 }
1330
1331                                 // there seems to be proxystuff after the <?xml....we delete this
1332                                 if ((
1333                                 ($usable_data[$i][0] == '<') &&
1334                                 ($usable_data[$i][1] == 'r') &&
1335                                 ($usable_data[$i][2] == 'd') &&
1336                                 ($usable_data[$i][3] == 'f') &&
1337                                 ($usable_data[$i][4] == ':')
1338                                 )
1339                                 ||
1340                                 (
1341                                 ($usable_data[$i][0] == '<') &&
1342                                 ($usable_data[$i][1] == 'r') &&
1343                                 ($usable_data[$i][2] == 's') &&
1344                                 ($usable_data[$i][3] == 's')
1345                                 )
1346                                 ) {
1347
1348                                         $usable_data[1] = $usable_data[$i]; // save current field
1349                                         $usable_data[2] = "\n";
1350                                         $i = 2; // just reset array to start
1351                                 }
1352                         }
1353
1354                         fclose($fp);
1355                         return $usable_data;
1356                 } else {
1357                         if (substr($this->_remote_file, 0, 7) != 'http://') {
1358                                 $this->_throw_exception('Cannot find http:// in '.$this->_remote_file.'!');
1359                                 return '';
1360                         } else {
1361                                 // Extract host information
1362                                 $host = substr($this->_remote_file, 7);
1363                                 // Extract the GET part
1364                                 $get = '/';
1365                                 if (strpos($host, '/') > 0) {
1366                                         $get = substr($host, strpos($host, '/'));
1367                                         $host = substr($host, 0, strpos($host, '/'));
1368                                 }
1369                                 // Extract port
1370                                 $port = '80';
1371                                 if (strpos($host, ':') > 0) {
1372                                         $port = substr($host, (strpos($host, ':') + 1));
1373                                         $host = substr($host, 0, (strpos($host, ':') - 1));
1374                                 }
1375
1376                                 // Start connection to server
1377                                 $fp = fsockopen($host, $port);
1378                                 if (!$fp) {
1379                                         $this->_throw_exception($this->_remote_file.' is maybe not available.');
1380                                         return '';
1381                                 }
1382                                 // Repare request line
1383                                 $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);
1384                                 // Send request out
1385                                 fputs($fp, $request);
1386                                 $reply = ''; $isContent = FALSE; $dummy = '';
1387                                 // Read reply
1388                                 $i=0;
1389                                 while (!feof($fp)) {
1390                                         $read = trim(fgets($fp, 4096));
1391                                         if (substr($read, 0, 5) == '<?xml' || $isContent) {
1392                                                 // Add content
1393                                                 $reply[] = $read;
1394                                                 $isContent = TRUE;
1395                                         } else {
1396                                                 // Put in dummy
1397                                                 $dummy[] = $read;
1398                                         }
1399                                         $i++;
1400                                 }
1401                                 if ((count($dummy) > 0) && (count($reply) == 0) && (!$isContent)) {
1402                                         // Transfer content from dummy
1403                                         $reply = $content;
1404                                 }
1405                                 fclose($fp);
1406                                 //die(htmlentities($reply));
1407                                 return $reply;
1408                         }
1409                 }
1410         }    // END _rdf_data()
1411 }   // END class
1412 ?>