1 <?php
2 /*
3 * This code is part of GOsa (http://www.gosa-project.org)
4 * Copyright (C) 2003-2008 GONICUS GmbH
5 *
6 * ID: $$Id$$
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
23 /* Simple class to parse the xml help file */
24 class parseXml
25 {
26 var $parser;
27 var $filename;
28 var $entries;
30 function parseXml($file)
31 {
32 $this->parser = xml_parser_create();
33 $this->filename = $file;
34 xml_set_object($this->parser, $this);
35 xml_set_element_handler($this->parser, "tag_open", "tag_close");
36 return($this->entries);
37 }
38 function parse()
39 {
40 $this->entries = array();
41 $fh= fopen($this->filename, "r");
42 $xmldata= fread($fh, 100000);
43 fclose($fh);
44 if(!xml_parse($this->parser, chop($xmldata))){
45 print(sprintf(_("XML error in guide.xml: %s at line %d"),
46 xml_error_string(xml_get_error_code($this->parser)),
47 xml_get_current_line_number($this->parser)));
48 exit;
49 }
50 return($this->entries);
51 }
52 function tag_open($parser,$tag,$attrs)
53 {
54 @$this->entries[$attrs['NAME']]=$attrs;
55 }
56 function tag_close(){; }
58 }
61 /* This function genereates the Index */
62 function genIndex()
63 {
64 global $helpobject;
65 $str = "";
66 $helpobject = session::get('helpobject');
67 $ui= get_userinfo();
68 $test = new pluglist(session::get('config'), $ui);
69 $current_hl = "";
70 foreach($helpobject['helpconf'] as $id => $attrs){
71 $path = $test -> get_path($id);
72 $exists = true;
73 $helpdir = "../doc/core/".$helpobject['lang']."/html/".preg_replace("/^.*\//i","",$path)."/";
74 if(!is_dir($helpdir)){
75 $exists = false;
76 }
77 $print_hl = false;
78 if($current_hl != $attrs['HEADLINE']){
79 $current_hl = $attrs['HEADLINE'];
80 $str .= "<h1>"._($current_hl)."</h1>";
81 }
82 $name = $attrs['NAME'];
83 $file = "index.html";
84 //$path = $plug;
85 if($exists){
86 $str .= "<p style='padding-left:20px;'><a href='?plug=".$id."'><b>"._($name)."</b></a></p>";
87 }else{
88 $str .= "<p style='padding-left:20px;'><b>"._($name)."</b> ("._("No help available for this plugin.").")</p>";
89 }
90 }
91 return (utf8_decode($str));
92 }
95 /* Some replacements */
96 $backwardlink = "<a href=\"?pg=%s\" class=\"maintitlebar\">
97 <img src='images/back.png' align=\"middle\" alt=\""._("previous")."\" border=\"0\">
98 </a>";
100 $forwardlink = "<a href=\"?pg=%s\" class=\"maintitlebar\">
101 <img src='images/forward.png' align=\"middle\" alt=\""._("next")."\" border=\"0\">
102 </a>";
104 $pre_mark = "<span style=\"background-color: #FFFC35;\">" ; // Sign words with this
105 $suf_mark = "</span>"; // and this
108 /* Define which tags musst be delete, header, navigation, banner */
109 $replacements=array();
110 $replacements['from']=array("@<!DOC.*<BODY >@si",
111 "/border=\".*\"/i",
112 "'<code.*code>'",
113 // "/alt=\".*\"/i",
114 "/<HR>/",
115 "@<ADDRESS[^>]*?>.*?ADDRESS>@si",
116 "@<\/BODY[^>]*?>.*?HTML>@si",
117 "'<TABLE.*>'",
118 "/src.*icons/i",
119 "/src=\"/i",
120 "/<H1 ALIGN=\"CENTER\">/",
121 /* picture replacements */
122 // "",
123 );
125 $replacements['to']=array("",
126 " border=\"0\" ",
127 "",
128 // "",
129 "",
130 "",
131 "",
132 "<table border=1 cellspacing=0 bgcolor=\"#E0E0E0\" width=\"95%\" align=\"center\" cellpadding=\"3\" summary=\"\">",
133 "src=\"",
134 "src=\"images/",
135 "<H1>",
136 /* picture replacements */
137 // "",
138 );
141 /* Reads all files in specified directory with contents an some inforations about the file */
142 /* Read all files with contents*/
143 /* |Folder="/var/ww...",
144 | |Fileprefix="node"
145 | | |Filesuffix=".html"
146 | | | |WithoutContent=false(This means : read content)
147 | | | | |Singlepage=false(Means read all, if w want to read single, specify its filename)"*/
148 function readfiles($basedir,$prefix,$suffix,$onlyIndex,$singlepage=false)
149 {
150 global $replacements;
152 $str = array(); // Temporary variable
153 $cnt = 0; // Array index creation
154 $file = ""; // Contains Filename
156 $dir = opendir($basedir);
158 $str['global']['start'] = $cnt; // collect basic informations - Startpage
159 $str['global']['basedir'] = $basedir; // collect basic informations - Basedirectory
161 /* Startime for Benchmark */
162 $start = (time()+microtime());
164 /* if singlepage == false -> Get all pages, */
165 if(!$singlepage) {
167 /* While theres is an unreaded file in our resource */
168 while (($file = readdir($dir)) !== false) {
170 if((is_dir($basedir."/".$file))&&($file != "..")&&($file[0]!=".")){
171 $str[$file]=(readfiles($basedir."/".$file."/",$prefix,$suffix,$onlyIndex,false));
172 }
174 /* Filter all files which arn't intressting */
175 if((strstr($file,$suffix))&&($file!=".")&&($file!="..")&&(strstr($file,$prefix))){
177 /* Collect informations */
178 $str[$file]=array();
179 $str[$file]['name'] = $file;
180 $str[$file]['size'] = filesize($basedir.$file);
182 /* Readfile conent too ? */
183 if(!$onlyIndex){
184 $str[$file]['content'] = remove_unwanted_tags(linkwrapper(getcontents($basedir.$file),""),$replacements);
185 $str[$file]['headline'] = getheader_from_content($str[$file]['content']);
186 }
188 /* Include file status, for debugging, not used in script yet */
189 $str[$file]['stat'] = stat($basedir.$file);
190 $cnt++;
191 }
192 }
194 /* Only get on file*/
195 }else{
196 /* Pages read = 1 */
197 $cnt = 1;
199 /* Prepare result*/
200 $file = $singlepage;
201 $str[$file] = array();
202 $str[$file]['name'] = $file;
203 $str[$file]['size'] = filesize($basedir.$file);
205 /* If onlyIndex == true skip reading content */
206 if(!$onlyIndex){
207 $str[$file]['content'] = remove_unwanted_tags(linkwrapper(getcontents($basedir.$file),""),$replacements);
208 $str[$file]['headline'] = getheader_from_content($str[$file]['content']);
209 }
211 /* Include file status, for debugging, not used in script yet */
212 $str[$file]['stat'] = stat($basedir.$file);
213 }
215 /* Sort to right order */
216 asort($str);
218 /* Endtime for Benchmark*/
219 $end = (time()+microtime());
220 $str['global']['cmptime'] = $end-$start;
222 /* Number of pages readed */
223 $str['global']['numpages']= $cnt;
224 closedir($dir);
225 return($str);
226 }
229 /* Read filecontent */
230 function getcontents($file)
231 {
232 $str = "" ; // Temporary variable for file contents
233 $tmp = "" ; // Temporary varibale for partitial file contents
235 /* open file and read*/
236 $fp = fopen($file,"r");
237 if($fp) {
238 while($tmp = fread($fp,512))
239 {
240 $str.= $tmp;
241 }
242 }else{
243 return(false);
244 }
245 return($str);
246 }
249 /*Remove tags */
250 function remove_unwanted_tags($str,$replacements)
251 {
252 $str=preg_replace($replacements['from'],$replacements['to'],$str);
253 return($str);
254 }
257 /*Converts the all links to specified path, is needed to get simple navigation */
258 function linkwrapper($str,$link)
259 {
260 $str = preg_replace("/HREF=\"http/i","target=\"_blank\" href=\"http",$str);
261 $str = preg_replace("/HREF=\"/","href=\"".$link."?pg=",$str);
262 $str=str_replace("HREF=\"","href=\"".$link."?pg=",$str);
263 return($str);
264 }
267 /* Search content */
268 function search($arr,$word)
269 {
270 global $minwordlength,$allowed_chars_in_searchword;
271 /* Prepare Vars */
272 $result =array(); // Search result, filename, + hits + hits per word + matches
273 $words =array(); // Temporary searchword handling
274 $useablewords =array(); // Temporary searchword handling
275 $tryword = ""; // Temporary searchword handling
276 $result['global']['maxhit'] = 0;
277 session::un_set('lastresults');
278 session::un_set('parsed_search_keyword');
279 session::set('parsed_search_keyword',"");
281 error_reporting(E_ALL | E_STRICT);
283 /* prepare searchwords */
284 $word = trim($word);
286 /* Filter all unusable chars */
287 $word = preg_replace($allowed_chars_in_searchword,"",$word);
288 $words = split(" ",str_replace("+"," ",$word));
290 /* Check all wordlengths */
291 foreach($words as $tryword){
292 $tryword = trim($tryword);
294 /* Filter words smaler than 3 chars */
295 if(strlen($tryword)>=$minwordlength) {
296 session::set('parsed_search_keyword', session::get('parsed_search_keyword').$tryword." ");
297 $useablewords[]=$tryword;
298 }
299 }
301 /* Use words to search the content */
302 foreach($arr as $keys=>$vals)
303 {
304 foreach($vals as $key=>$val){
305 /* overallhits counts hits per page */
306 $overallhits=0;
308 /* Search all words */
309 foreach($useablewords as $word)
310 {
311 /* Skip key global, it contains no file data - it is a summary info*/
312 if($key!="global")
313 {
315 /* Get all hits for the word in $matches*/
316 preg_match_all("/".$word."/i",$arr[$keys][$key]['content'], $matches,PREG_OFFSET_CAPTURE);
318 /* Filter in Tag results*/
319 if(count($matches[0])){
320 foreach($matches[0] as $num=>$hit){
321 if(isset($arr[$keys][$key]['content']) && (is_in_tag($arr[$keys][$key]['content'],$hit[1]))){
322 unset($matches[0][$num]);
323 }
324 }
325 }
327 /* Count matches */
328 $overallhits=$overallhits + count($matches[0]);
330 /* Save collected data */
331 $result[$keys][$key]['hits'][$word] = count($matches[0]);
332 $result[$keys][$key]['hits']['overall']= $overallhits;
334 /* Save max hits for page */
335 if($overallhits > $result['global']['maxhit']){
336 $result['global']['maxhit']=$overallhits;
337 }
339 /* Add results for word to return value*/
340 $result[$keys][$key]['match'][$word]=array();
341 $result[$keys][$key]['match'][$word]=$matches[0];
342 }
343 }
344 }
345 }
347 /* Save result in Session, so we can mark words later, or go back to search, without searching again*/
348 session::set('lastresults',$result);
349 return($result);
350 }
353 /* Detect 10 Best result entries, sort and call createResultEntry to create HTML output for complete list */
354 function searchlist($arr,$res,$maxresults)
355 {
356 $global = $res['global'];
357 $topten = array(); // To detect 10 best solutions
358 $ret = ""; // return value
359 unset($res['global']);
361 /* Detect 10 best Sites */
362 foreach($res as $key=>$resa)
363 foreach($resa as $keya=>$val){
364 /* Skip results with no hits */
365 if($val['hits']['overall']>0){
366 $topten[$key."/".$keya] = $val['hits']['overall'];
367 }
368 }
370 /* Sort by hit position in content, to easier mark words */
371 asort($topten);
372 $topten = array_reverse($topten);
373 $topten = (array_slice($topten,0,$maxresults));
376 /* We have a result, an array with all content, an array with hits and position and we have the 10 best hits */
377 /* Foreach */
378 foreach($topten as $key => $hits) {
380 $ks = split("\/",$key);
381 $k1 = $ks[0];
382 $k2 = $ks[1];
384 $ret.= createResultEntry($arr[$k1][$k2],$res[$k1][$k2],$key,$global['maxhit']);
385 }
387 /* appending footer message for resultlist */
388 $ret.= "<br>
389 ".sprintf(_("%s results for your search with the keyword %s"),
390 "<b>".count($topten)."</b>",
391 "<b>".session::get('parsed_search_keyword')."</b>");
392 $ret.="<br>
393 <br>";
394 return($ret);
395 }
398 /* This function marks a string with the given search result for this string*/
399 function markup_page($arr,$res)
400 {
401 global $pre_mark,$suf_mark;
403 $ret = ""; // return value
404 $repl = array();
405 $posadd = 0;
407 foreach($res['match'] as $word => $matches) {
408 foreach($matches as $matchnr=>$match) {
409 $repl[$match[1]]=$match[0];
410 }
411 }
413 ksort($repl);
415 foreach($repl as $position=>$word) {
416 $pos1 = strlen($arr);
417 $arr= markword($arr,($position+$posadd),$word,$pre_mark,$suf_mark);
418 $pos2 = strlen($arr);
419 $posadd =$posadd + ($pos2 - $pos1);
420 }
421 return($arr);
422 }
425 /* This function marks a single word with the specified prefix and suffix */
426 function markword($string,$position,$word,$prefix,$suffix)
427 {
428 $wordlength = strlen($word);
429 $wholelength = strlen($string);
431 $first = substr($string,0,$position);
432 $last = substr($string,($position+$wordlength),$wholelength);
434 return($first.$prefix.$word.$suffix.$last);
435 }
437 /* Creates HTML output for a single search result entry */
438 function createResultEntry($entry,$res,$name,$max)
439 {
440 $percentage = (int)(($res['hits']['overall'] / $max) * 100) ;
441 $color = dechex($percentage+150);
442 $color2 = dechex(150 - $percentage);
444 $entry['content'] = preg_replace("\"".$entry['headline']."\"","",$entry['content'],1);
446 if(strlen($color)==1) $color = "0".$color;
450 /* the object tag is needed for W3c */
451 $str = "<a href=\"?pg=".$name."&mark=1\" title=\"".$percentage."% ".$entry['headline']."\">
452 <object>
453 <table summary=\"\" width=\"98%\" align=\"center\">
454 <tr>
455 <td height=15>
456 <b>".utf8_encode($entry['headline'])."</b> -".utf8_encode(substr(strip_tags($entry['content']),0,120))."...
457 </td>
458 <td width=50 valign=\"top\">".progressbar($percentage,50,8)."</td>
459 </tr>
460 <tr>
461 <td colspan=2>
462 <b>
463 ".(sprintf(_("%s%% hit rate in file %s"),$percentage,$name))."
464 </b>
465 </td>
466 </tr>
467 </table>
468 </object></a>
469 ";
470 $str.= "<hr size=\"1\">";
472 return($str);
473 }
476 /*Simple function to detect if we prepare to change a tag or visible text */
477 function is_in_tag($string,$pos)
478 {
479 $pos1 = $pos2 = 0;
480 if(preg_match("/</",$string)){
481 $pos1 = strpos($string,"<",$pos);
482 }
483 if(preg_match("/>/",$string)){
484 $pos2 = strpos($string,">",$pos);
485 }
486 if ($pos1 > $pos2) {
487 return(true);
488 }else{
489 return(false);
490 }
491 }
493 /*Returns frist line of readable text, it should be the headline */
494 function getheader_from_content($str)
495 {
496 $str = strip_tags($str);
497 $pos = 0;
498 $arr = split("\n",$str);
499 foreach($arr as $possibleheadline){
500 if(strlen($possibleheadline)>=3){
501 return $possibleheadline;
502 }
503 }
504 }
506 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
507 ?>