1<?php
2/******************************************************************************
3*  rater Plugin
4//session_start(); */
5if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
6if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
7require_once(DOKU_PLUGIN.'syntax.php');
8
9/******************************************************************************
10* All DokuWiki plugins to extend the parser/rendering mechanism
11* need to inherit from this class
12*/
13class syntax_plugin_rater extends DokuWiki_Syntax_Plugin
14{
15/******************************************************************************/
16/* return some info
17*/
18    function getInfo(){
19        return confToHash(dirname(__FILE__).'/plugin.info.txt');
20    }
21
22    function getType(){ return 'substition';}
23    function getPType(){ return 'block';}
24    function getSort(){ return 168;}
25
26/******************************************************************************/
27/* Connect pattern to lexer
28*/
29    function connectTo($mode){
30        $this->Lexer->addSpecialPattern('\{\(rater>[^}]*?\)\}',$mode,'plugin_rater');
31    }
32/******************************************************************************/
33/* Handle the match
34*/
35    function handle($match, $state, $pos, Doku_Handler &$handler){
36        $match = substr($match,8,-2); //strip markup from start and end
37
38        //handle params
39        $data = array();
40        $params = explode('|',$match);
41
42        //Default Value
43        $data['rater_id']           = 1;
44        $data['rater_name']         = "this";
45        $data['rater_type']         = "rate";
46        $data['rater_end']          = "never";
47        $data['rater_trace']        = "ip";
48        $data['rater_tracedetails'] = '0';
49        $data['rater_headline']     = "on";
50        $data['stat_sort']          = "id";
51
52        foreach($params as $param){
53            $splitparam = explode('=',$param);
54            if ($splitparam[1] != '')
55            {
56                if ($splitparam[0]=='id')
57                	{$data['rater_id'] = $splitparam[1];    // unique item id
58                    /*continue;*/}
59                if ($splitparam[0]=='name')
60                	{$data['rater_name'] = $splitparam[1];  // descriptive item name
61                   $needles = array(":","/","\\");
62                   $data['rater_name'] = str_replace($needles, "_", $data['rater_name']);
63                    }
64                if ($splitparam[0]=='type')
65                	{$data['rater_type'] = $splitparam[1];  // rate or vote or stat
66                    /*continue;*/}
67                if ($splitparam[0]=='end')
68                	{$data['rater_end'] = $splitparam[1];   // date or never
69                    /*continue;*/}
70                if ($splitparam[0]=='trace')
71                	{$data['rater_trace'] = $splitparam[1]; // ip, user name, none
72                    /*continue;*/}
73                if ($splitparam[0]=='tracedetails')
74                	{$data['rater_tracedetails'] = $splitparam[1]; // ip, user name, none
75                    /*continue;*/}
76                if ($splitparam[0]=='headline')
77                	{$data['rater_headline'] = $splitparam[1]; // ip, user name, none
78                    /*continue;*/}
79                if ($splitparam[0]=='sort')
80                	{$data['rater_stat_sort'] = $splitparam[1]; // ip, user name, none
81                    /*continue;*/}
82                if ($splitparam[0]=='img')
83                	{$data['rater_img'] = $splitparam[1]; // ip, user name, none
84                    /*continue;*/}
85                if ($splitparam[0]=='zoom')
86                	{$data['rater_zoom'] = $splitparam[1]; // ip, user name, none
87                    /*continue;*/}
88                if ($splitparam[0]=='sid')
89                	{$data['rater_sid'] = $splitparam[1]; // ip, user name, none
90                    /*continue;*/}
91                if ($splitparam[0]=='ns')
92                	{$data['rater_ns'] = $splitparam[1]; // ip, user name, none
93                    /*continue;*/}
94            }
95        }
96        return $data;
97    }
98/******************************************************************************/
99/* Create output
100*/
101    function render($mode, Doku_Renderer &$renderer, $data) {
102        global $ID;
103        global $lang;
104        global $conf;
105        if ($mode == 'xhtml'){
106            $renderer->info['cache']   = false;
107
108          // Config settings
109          $rater_ip_voting_restriction = $this->getConf('voting_restriction'); // restrict ip address voting (true or false)
110          $rater_ip_vote_qty           = $this->getConf('vote_qty');           // how many times an ip address / user name can vote
111          $rater_already_rated_msg     = sprintf($this->getConf('already_rated_msg'),$rater_ip_vote_qty);
112          $rater_not_selected_msg      = $this->getConf('not_selected_msg');
113          $rater_thankyou_msg          = $this->getConf('thankyou_msg');
114          $rater_generic_text          = $this->getConf('generic_text');       // generic item text
115          $rater_end_of_line_char      = $this->getConf('eol_char');           // to separate the records
116          if($rater_end_of_line_char == '') $rater_end_of_line_char = '\n';
117
118          $msg_ratingend               = $this->getLang('msg_ratingend');
119          $msg_ratingended             = $this->getLang('msg_ratingended');
120          $msg_votend                  = $this->getLang('msg_votend');
121          $msg_votended                = $this->getLang('msg_votended');
122          $btn_submit                  = $this->getLang('btn_submit');
123
124          $rater_id                    = trim($data['rater_id']);
125          $rater_name                  = trim($data['rater_name']);
126          $rater_headline              = trim($data['rater_headline']);
127          $rater_stat_sort             = trim($data['rater_stat_sort']);
128          $rater_img                   = $data['rater_img'];
129          $rater_zoom                  = $data['rater_zoom'];
130          $rater_sid                   = $data['rater_sid'];
131          $rater_ns                    = $data['rater_ns'];
132
133          if (!isset($data['rater_end'])) {$data['rater_end']='never'; $rater_end='never';}
134          else {$rater_end=$data['rater_end'];}
135
136          if(!isset($data['rater_tracedetails'])) $data['rater_tracedetails']='0';
137          if(!isset($rater_id)) $rater_id = 1;
138          $rater_item_name = $data['rater_name'];                              // item name what is to be rated
139          if(!isset($rater_item_name)) $rater_item_name=$rater_generic_text;
140          $rater_type = $data['rater_type'];
141          if(!isset($rater_type)) $rater_type="stars";
142
143          // DO NOT MODIFY BELOW THIS LINE
144          $rater_filename = metaFN('rater_'.$data['rater_id'].'_'.$data['rater_name'].'_'.$data['rater_type'], '.rating');
145          $rater_rating=0;
146          $rater_stars="";
147          $rater_stars_txt="";
148          $rater_rating=0;
149          $rater_votes=0;
150          $rater_msg="";
151          $today = date('d.m.Y');
152          // check to trace ip or user name
153          $user_grp = pageinfo();
154          $rater_realname =  $user_grp['userinfo']['name'];
155          if ($data['rater_trace']==='user') {
156             $rater_ip = $user_grp['userinfo']['name'];
157          }
158          else {
159             $rater_ip = getenv("REMOTE_ADDR");
160          }
161
162/******************************************************************************/
163          // Rating action
164          if(isset($_REQUEST["rate".$rater_id])){
165           if(isset($_REQUEST["rating_".$rater_id])){
166              while(list($key,$val)=each($_REQUEST["rating_".$rater_id])){
167                $rater_rating=$val;
168              }
169              $rater_file=fopen($rater_filename,"a+");
170              $rater_str="";
171              $rater_str = rtrim(fread($rater_file, 1024*8),$rater_end_of_line_char);
172              if($rater_str!=""){
173                 if($rater_ip_voting_restriction){
174                    $rater_data=explode($rater_end_of_line_char,$rater_str);
175                	  $rater_ip_vote_count=0;
176                    foreach($rater_data as $d){
177                    	 $rater_tmp=explode("|",$d);
178                    	 $rater_oldip=str_replace($rater_end_of_line_char,"",$rater_tmp[1]);
179                    	 if($rater_ip==$rater_oldip){
180                    	  $rater_ip_vote_count++;
181                    	 }
182                    }
183                  	if($rater_ip_vote_count > ($rater_ip_vote_qty - 1)){
184                       $rater_msg=$rater_already_rated_msg;
185                  	}else{
186                       fwrite($rater_file,$rater_rating."|".$rater_ip.$rater_end_of_line_char);
187                       $rater_msg=$rater_thankyou_msg;
188                  	}
189                 }else{
190                   fwrite($rater_file,$rater_rating."|".$rater_ip.$rater_end_of_line_char);
191                   $rater_msg=$rater_thankyou_msg;                 }
192              }else{
193                fwrite($rater_file,$rater_rating."|".$rater_ip.$rater_end_of_line_char);
194                $rater_msg=$rater_thankyou_msg;              }
195              fclose($rater_file);
196           }else{
197              $rater_msg=$rater_not_selected_msg;
198           }
199          }
200
201/******************************************************************************/
202          if ($rater_type=="rate") {
203              // Get current rating
204              $r1 = '0'; $r2 = '0'; $r3 = '0'; $r4 = '0'; $r5 = '0';
205              $rater_votes = '0'; $rater_sum = '0';
206
207              if(is_file($rater_filename)){
208                 $tmp_array = $this->calc_rater_rating($rater_filename);
209                 $rater_rating = $tmp_array[0][0];
210                 $r1 += $tmp_array[0][1];
211                 $r2 += $tmp_array[0][2];
212                 $r3 += $tmp_array[0][3];
213                 $r4 += $tmp_array[0][4];
214                 $r5 += $tmp_array[0][5];
215                 $rater_votes  += $tmp_array[0][6];
216                 $rater_sum += $tmp_array[0][7];
217              }
218              else{
219               $rater_file=fopen($rater_filename,"w");
220               fclose($rater_file);
221              }
222
223              // Assign star image
224              $rater_stars = $this->assign_star_image($rater_rating);
225              $anker_id = 'rateanker_'. uniqid((double)microtime()*1000000,1);
226
227              // build the return value for details
228              if (($rater_end!='never') && (strtotime($today) > strtotime($rater_end)))
229              {  $ret_details = '<div class="rating__details">'.sprintf($msg_ratingended,date('d.m.Y',strtotime($data['rater_end']))).'<br />';
230                 $alink_Details = '<a href="#'.$anker_id.'" onclick="hidden'.$rater_id.'()">(Details)</a>'; }
231              elseif (($rater_end!='never') || (strtotime($today) <= strtotime($rater_end)))
232              {  $ret_details = '<div class="rating__details">'.sprintf($msg_ratingend,date('d.m.Y',strtotime($data['rater_end']))).'<br />';
233                 $alink_Details = '<a href="#'.$anker_id.'" onclick="hidden'.$rater_id.'()">(Details)</a>';}
234              else
235              {  $ret_details ='<p class="rating__details">';
236                 $alink_Details = '';}
237
238              if ($data['rater_tracedetails']==='1') {
239                  if ($alink_Details === '')
240                    {
241                  $alink_Details = '<a href="#'.$anker_id.'" onclick="hidden'.$rater_id.'()">(Details)</a>'; }
242                  $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/1star.gif?w=40&amp;" alt="1 Star" width="40" align="left" /> '.$r1.' visitor votes<br />';
243                  $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/2star.gif?w=40&amp;" alt="2 Stars" width="40" align="left" /> '.$r2.' visitor votes<br />';
244                  $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/3star.gif?w=40&amp;" alt="3 Stars" width="40" align="left" /> '.$r3.' visitor votes<br />';
245                  $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/4star.gif?w=40&amp;" alt="4 Stars" width="40" align="left" /> '.$r4.' visitor votes<br />';
246                  $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/5star.gif?w=40&amp;" alt="5 Stars" width="40" align="left" /> '.$r5.' visitor votes';
247              }
248              $ret_details .= '</p>';
249
250
251              // Output rate
252              $rater_img_xhtml = "";
253              if($rater_img!=false) {
254                // render the image link and output centralized within rater box
255                $info = array();
256                $rater_img_xhtml = p_render('xhtml',p_get_instructions("{{".$rater_img."}}"),$info);
257                $rater_img_xhtml = str_replace("<p>","",$rater_img_xhtml);
258                $rater_img_xhtml = str_replace("</p>","",$rater_img_xhtml);
259                $rater_img_xhtml  = '<tr><td class="rater_item">'.$rater_img_xhtml.'</td></tr>'.NL;
260              }
261
262              $ret .= '<form method="post" action="doku.php?id=' . $ID .'" >
263                       <table class="rater_table">'.NL;
264              $ret .= $rater_img_xhtml;
265              $ul_rater_item_name = str_replace("_"," ",$rater_item_name);
266              if($rater_headline !== "off") {
267                $ret .= '<tr>
268                           <td class="rater_item">'.$ul_rater_item_name.'</td>
269                         </tr>'.NL;
270              }
271              $ret .= '<tr>
272                        <td class="rater_rating" id="'.$anker_id.'">
273                          <span><script type="text/javascript" language="JavaScript1.2">
274                            var visible = false;
275                            function hidden'.$rater_id.'()
276                            {   if (visible)
277                                {   document.getElementById("details_'.$rater_id.'").style.display = "none";
278                                    visible = false; }
279                                else
280                                {   document.getElementById("details_'.$rater_id.'").style.display = "block";
281                                    visible = true; }
282                            }
283                          </script></span>
284                        <div style="display:inline;margin-left:auto; margin-right:0;">
285                        <div style="display:table-cell; text-align:left;">
286                        <img src="'.$rater_stars.'?x='.uniqid((double)microtime()*1000000,1).'" alt="'.$rater_stars_txt.' stars" />&nbsp;'.$rater_stars_txt.' from
287                        <span class="reviewcount"> '.$rater_votes.' votes '.$alink_Details.'</span><br />';
288
289              if (($rater_end!='never') && (strtotime($today) > strtotime($rater_end)))
290              {
291                  $rater_msg =''; }
292              else {
293                  $ret .= '<label for="rate1_'.$rater_id.'"><input type="radio" value="1" name="rating_'.$rater_id.'[]" id="rate1_'.$rater_id.'" />&nbsp;</label>';
294                  $ret .= '<label for="rate2_'.$rater_id.'"><input type="radio" value="2" name="rating_'.$rater_id.'[]" id="rate2_'.$rater_id.'" />&nbsp;</label>';
295                  $ret .= '<label for="rate3_'.$rater_id.'"><input type="radio" value="3" name="rating_'.$rater_id.'[]" id="rate3_'.$rater_id.'" />&nbsp;</label>';
296                  $ret .= '<label for="rate4_'.$rater_id.'"><input type="radio" value="4" name="rating_'.$rater_id.'[]" id="rate4_'.$rater_id.'" />&nbsp;</label>';
297                  $ret .= '<label for="rate5_'.$rater_id.'"><input type="radio" value="5" name="rating_'.$rater_id.'[]" id="rate5_'.$rater_id.'" />&nbsp;</label>';
298                  $ret .= '<input type="hidden" name="rs_id" value="'.$rater_id.'" />';
299                  $ret .= '<input type="hidden" name="rs_anker" value="'.$anker_id.'" />';
300                  $ret .= '<input type="submit" name="rate'.$rater_id.'" value="'.$btn_submit.'" />'; // </td></tr>';
301              }
302
303              $ret .= '<div style="display : none" id="details_'.$rater_id.'">'.$ret_details.'</div> </div></div></td></tr>';
304
305              if($rater_msg!="") $ret .= "<div>".$rater_msg."</div>";
306              $ret .= '</table>';
307              $ret .= '</form>';
308          }
309
310/******************************************************************************/
311          elseif ($rater_type=="vote") {
312              // Get current rating
313              if(is_file($rater_filename)){
314                 $rater_file=fopen($rater_filename,"r");
315                 $rater_str="";
316                 $rater_str = fread($rater_file, 1024*8);
317                 if($rater_str!=""){
318                    $rater_data=explode($rater_end_of_line_char,$rater_str);
319                    $rater_votes=count($rater_data)-1;
320                    $vote1='0';
321                    $vote2='0';
322                    foreach($rater_data as $d){
323                       $d=explode("|",$d);
324                       if ($d[0]==='1') {
325                          $vote1 = $vote1 +1;
326                          $who1 .= $d[1]."<br />";
327                       }
328                       elseif ($d[0]==='2') {
329                          $vote2 = $vote2 +1;
330                          $who2 .= $d[1]."<br />";
331                       }
332                    }
333                 }
334                 else{
335                    $vote1='0';
336                    $vote2='0';
337                 }
338                 fclose($rater_file);
339               }
340
341              $rater_img_xhtml = "";
342              if($rater_img!=false) {
343                // render the image link and output centralized within rater box
344                $info = array();
345                $rater_img_xhtml = p_render('xhtml',p_get_instructions("{{".$rater_img."}}"),$info);
346                $rater_img_xhtml = str_replace("<p>","",$rater_img_xhtml);
347                $rater_img_xhtml = str_replace("</p>","",$rater_img_xhtml);
348                $rater_img_xhtml  = '<tr><td class="rater_item">'.$rater_img_xhtml.'</td></tr>'.NL;
349              }
350
351               //check if vote period already ended
352              if (($rater_end!='never') && (strtotime($today) > strtotime($rater_end)))
353                  {$rater_endmsg = sprintf($msg_votended,date('d.m.Y',strtotime($data['rater_end']))).'<br />';}
354              elseif (($rater_end!='never') || (strtotime($today) <= strtotime($rater_end)))
355                  {$rater_endmsg = sprintf($msg_votend,date('d.m.Y',strtotime($data['rater_end']))).'<br />';}
356              else
357                  {$rater_endmsg ='';}
358              // build the return value for details if details option is on
359              $ret_details = '<p class="rating__details">'.$rater_endmsg;
360              if ($data['rater_tracedetails']==='1') {
361                  $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/thumbup.gif?h=12&amp;" alt="Pro" align="left" /> <p align="left">('.$vote1.') </p><p>'. $who1.'</p><br />';
362                  $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/thumbdown.gif?h=12&amp;" alt="Contra" align="left" /> <p align="left">('.$vote2.') </p><p>'. $who2.'</p>';
363              }
364              $ret_details .= '</p>';
365
366              // Output vote
367//              $ret .= '<form name="'.$data['rater_id'].$data['rater_name'].$data['rater_type'].'" method="post" action="doku.php?id=' . $ID .'">';
368              $ret .= '<table class="hreview">'.NL;
369              $ret .= $rater_img_xhtml;
370
371              if($_REQUEST["info"]!="ppp") { $addMSG = '';}
372              else { $addMSG = $rater_already_rated_msg.'<br />';}
373
374              $anker_id = 'voteanker_'.$data['rater_id'].'_'.$data['rater_name'];
375              $ul_rater_item_name = str_replace("_"," ",$rater_item_name);
376              if($rater_headline !== "off") {
377                $ret .= '<tr>
378                           <td class="rater_item">'.$ul_rater_item_name.'</td>
379                         </tr>'.NL;
380              }
381              $ret .= '<tr><td class="rater_rating" id="'.$anker_id.'">';
382              $ret .= '<span><script type="text/javascript" language="JavaScript1.2">
383                          var visible = false;
384                          function hidden'.$rater_id.'()
385                          {   if (visible)
386                              {   document.getElementById("details_'.$rater_id.'").style.display = "none";
387                                  visible = false; }
388                              else
389                              {   document.getElementById("details_'.$rater_id.'").style.display = "block";
390                                  visible = true; }
391                          }
392                        </script></span>
393                        <div style="display:inline;margin-left:auto; margin-right:0;">
394                        <div style="display:table-cell; text-align:left;">';
395
396              $ret .= $addMSG.'<a class="thumbup tup" href="doku.php?id='.$ID.'&do=rate_voteup&rater_id='.$rater_id.'&rater_ip='.$rater_ip.'&rater_end='.$data['rater_end'].'&anker='.$anker_id.'&rater_name='.$rater_name.'"></a>'.
397                   '<span id="vote1_1" style="color:#5b8f22">('.$vote1.')&nbsp;</span>'.
398                   '<a class="thumbdown tdn" href="doku.php?id='.$ID.'&do=rate_votedown&rater_id='.$rater_id.'&rater_ip='.$rater_ip.'&rater_end='.$data['rater_end'].'&anker='.$anker_id.'&rater_name='.$rater_name.'"></a>'.
399                   '<span id="vote1_2" style="color:#FF1822">('.$vote2.')</span>';
400              if($data['rater_tracedetails']==='1') {
401                    $ret .= '<a href="#'.$anker_id.'" onclick="hidden'.$rater_id.'()">(Details)</a><br />'.
402                         '<div style="display : none" id="details_'.$rater_id.'">'.$ret_details.'</div></div></div></td></tr>';
403              }
404              else $ret .='</td></tr>';
405              if($rater_msg!="") $ret .= "<div>".$rater_msg."</div>";
406              $ret .= '</table>';
407//              $ret .= '</form>';
408          }
409/******************************************************************************/
410          elseif (($rater_type=="stat") || ($rater_type=="localstat")) {
411            global $conf;
412            // 1. load all rating files into array
413            // create an array of all rating files
414            $delim1 = ".rating";
415            $delim2 = ".txt";
416            clearstatcache();
417            $listRatingFiles = $this->list_files_in_array($conf['metadir'], $delim1, $params_array);
418            // create a list of all page-files, consider ns syntax parameer
419            if(strlen($rater_ns)>1) {
420                if(is_file($conf['datadir']."/".str_replace(":","/",$rater_ns))) {
421                    $listPages = array($conf['datadir']."/".str_replace(":","/",$rater_ns));
422                }
423                else {
424                    $r_datadir = $conf['datadir']."/".str_replace(":","/",$rater_ns);
425                    $listPages = $this->list_rec_files_in_array($r_datadir, $delim2, $params_array);
426                }
427            }
428            else {
429                $r_datadir = $conf['datadir'];
430                $listPages = $this->list_rec_files_in_array($r_datadir, $delim2, $params_array);
431            }
432            // loop through all wiki pages
433            $returns['ratings'] = array();
434            $returns['votings'] = array();
435            if ($rater_type=="stat") {
436                foreach($listPages as &$page_filepath) {
437                    //read the content of the page file to be analyzed for rater items
438                    $body = '';
439                    $body = file_get_contents($page_filepath);
440
441                    // find all rater items on this page file
442                    $links = array();
443
444                    // define('LINK_PATTERN', "/\{\{.*\}\}/");
445                    $body = preg_replace('/<code.*?\>.*?<\/code>/si', '', $body);
446                    define('LINK_PATTERN', "(rater>[^}]*)");
447                    // check for rater syntax on current page
448                    if( preg_match(LINK_PATTERN, $body) ) {
449                       preg_match_all(LINK_PATTERN, $body, $links);
450                    }
451
452                    // loop through all rater items of this page
453                    // needs:   $links, $listRatingFiles, $page_filepath, $returns
454                    // returns: $found_ratings, $found_votings
455                    if (count($links)>0) $returns = $this->rater_on_page($links, $listRatingFiles, $page_filepath, $returns);
456                }
457             }
458             elseif ($rater_type=="localstat") {
459                $tmp = pageinfo();
460
461                $body = '';
462                $body = file_get_contents($tmp['filepath']);
463
464                // find all rater items on this page file
465                $links = array();
466
467                // define('LINK_PATTERN', "/\{\{.*\}\}/");
468                $body = preg_replace('/<code.*?\>.*?<\/code>/si', '', $body);
469                define('LINK_PATTERN', "(rater>[^}]*)");
470                // check for rater syntax on current page
471                if( preg_match(LINK_PATTERN, $body) ) {
472                   preg_match_all(LINK_PATTERN, $body, $links);
473                }
474                if (count($links)>0) $returns = $this->rater_on_page($links, $listRatingFiles, $tmp['filepath'], $returns);
475             }
476
477             $found_ratings = $returns['ratings'];
478             $found_votings = $returns['votings'];
479
480            // calculate ratings
481            for ($a=0;$a<count($found_ratings);$a++) {
482                $rater_filename = $conf['metadir'].'/'.$found_ratings[$a]['file'];
483                if(is_file($rater_filename)) {
484                    $tmp_array = $this->calc_rater_rating($rater_filename);
485                    $rater_rating = $tmp_array[0][0];
486                    if($rater_rating=='') $rater_rating='0.00';
487                    if ($tmp_array[0][1] < 1) { $tmp_array[0][1] = '0'; }
488                    if ($tmp_array[0][2] < 1) { $tmp_array[0][2] = '0'; }
489                    if ($tmp_array[0][3] < 1) { $tmp_array[0][3] = '0'; }
490                    if ($tmp_array[0][4] < 1) { $tmp_array[0][4] = '0'; }
491                    if ($tmp_array[0][5] < 1) { $tmp_array[0][5] = '0'; }
492                    if ($tmp_array[0][6] < 1) { $tmp_array[0][6] = '0'; }
493                    if ($tmp_array[0][7] < 1) { $tmp_array[0][7] = '0'; }
494                    $found_ratings[$a][] = array('value' => $rater_rating);
495                    $rater_stars = $this->assign_star_image($rater_rating);
496                    $found_ratings[$a][] = array('image' => $rater_stars);
497                    $found_ratings[$a][] = array($tmp_array[0][1],$tmp_array[0][2],$tmp_array[0][3],$tmp_array[0][4],$tmp_array[0][5],$tmp_array[0][6]);
498                }
499            }
500            // sort array
501            if($rater_stat_sort=='') $rater_stat_sort = 'value' ;
502            $found_ratings = $this->array_sort($found_ratings, $rater_stat_sort, SORT_DESC);
503
504            // script template
505            $ret_script = '<span><script type="text/javascript" language="JavaScript1.2">
506                          var visible = false;
507                          function hidden$blink_id()
508                          {   if (visible)
509                              {   document.getElementById("details_$blink_id").style.display = "none";
510                                  visible = false; }
511                              else
512                              {   document.getElementById("details_$blink_id").style.display = "block";
513                                  visible = true; }
514                          }
515                        </script></span>';
516
517            // calculate votes
518            for ($a=0;$a<count($found_votings);$a++) {
519                $rater_filename = $conf['metadir'].'/'.$found_votings[$a]['file'];
520                $rater_thumbs='';
521
522                if(is_file($rater_filename)) {
523                    $alink_id++;
524                    $blink_id     = 'statanker_'.$alink_id;
525                    $anker_id     = 'anker_'.$alink_id;
526                    $ret_script1  = str_ireplace('$blink_id', $blink_id, $ret_script);
527
528                    $alink_id++;
529                    $blink_id2    = 'statanker_'.$alink_id;
530                    $anker_id2    = 'anker_'.$alink_id;
531                    $ret_script2  = str_ireplace('$blink_id', $blink_id2, $ret_script);
532
533                    $tmp_array = $this->calc_rater_voting($rater_filename);
534                    // returns array($rater_votes, $r1, $who1, $r2, $who2, $rater_sum)
535                    $rater_voting = $tmp_array[0][0];
536                    if($rater_voting=='') $rater_voting='0';
537                    if ($tmp_array[0][1] < 1) { $tmp_array[0][1] = '0'; }    // no thumb-up votes so far
538                    if ($tmp_array[0][3] < 1) { $tmp_array[0][3] = '0'; }    // no thumb-down votes so far
539                    $found_votings[$a][] = array('value' => $rater_voting);
540                    $found_votings[$a][] = array($tmp_array[0][1], $tmp_array[0][2],$tmp_array[0][3],$tmp_array[0][4]);
541                    $found_votings[$a][] = array('votes' => $tmp_array[0][0],);
542                    //number_format(($rater_sum/$rater_votes), 2, '.', '');
543                    if(($tmp_array[0][1]+$tmp_array[0][3])>0) $calc_result=($tmp_array[0][1]/($tmp_array[0][1]+$tmp_array[0][3])*100);
544                    else $calc_result=0;
545                    $rater_thumbs = '<div width="100%"><img src="'.DOKU_BASE.'lib/plugins/rater/img/thumbup.gif?h=12&amp;" alt="Pro" /><span style="color:#5b8f22">&nbsp;('.$tmp_array[0][1].')&nbsp;</span>'.
546                                     '<span>&nbsp;'.number_format($calc_result,2,'.','').'% &nbsp;</span>'.NL;
547
548                    if($data['rater_tracedetails']=== '1') {
549                        $rater_thumbs .= $ret_script1.
550                                     '<a href="#'.$anker_id.'" onclick="hidden'.$blink_id.'()" style="float: right;">(Details)</a><br />'.
551                                     '<div class="rater_div_details" id="details_'.$blink_id.'">'.$tmp_array[0][2].'</div>'.
552                                     '</div>'.NL;
553                    }
554
555                    if(($tmp_array[0][1]+$tmp_array[0][3])>0) $calc_result=($tmp_array[0][3]/($tmp_array[0][1]+$tmp_array[0][3])*100);
556                    else $calc_result=0;
557                    $rater_thumbs .= '<div width="100%"><img src="'.DOKU_BASE.'lib/plugins/rater/img/thumbdown.gif?h=12&amp;" alt="Contra" /><span style="color:#FF1822">&nbsp;('.$tmp_array[0][3].')&nbsp;</span>'.
558                                     '<span>&nbsp;'.number_format($calc_result,2,'.','').'% &nbsp;</span>'.NL;
559
560                    if($data['rater_tracedetails']=== '1') {
561                        $rater_thumbs .= $ret_script2.
562                                         '<a href="#'.$anker_id2.'" onclick="hidden'.$blink_id2.'()" style="float: right;">(Details)</a><br />'.
563                                         '<div class="rater_div_details" id="details_'.$blink_id2.'">'.$tmp_array[0][4].'</div>'.
564                                         '</div>'.NL;
565                    }
566                    $found_votings[$a][] = array('image' => $rater_thumbs);
567                }
568            }
569            // sort array
570            if($rater_stat_sort=='') $rater_stat_sort = 'value' ;
571            $found_ratings = $this->array_sort($found_ratings, $rater_stat_sort, SORT_DESC);
572
573            // script to make table sortable
574            $ret .=' <script type="text/javascript" src="'.DOKU_URL.'lib/plugins/rater/scripts/jquery.tablesorter.js"></script>
575                      <script type="text/javascript">
576                        ( function($) {
577                        $(document).ready(function(){
578                        // Adds class to th to identify sorting ability to users
579                        $(".sortable th").addClass("ittheader");
580                        // Adds sorting functionality to table. The widgets / zebra declaration sets "odd" or "even" as classes for alternating rows.
581                        $(".sortable").tablesorter({widgets: ["zebra"]});
582                        // Adds "over" class to rows on mouseover
583                        $(".sortable tr").mouseover(function(){
584                        $(this).addClass("over");
585                        });
586                        // Removes "over" class from rows on mouseout
587                        $(".sortable tr").mouseout(function(){
588                        $(this).removeClass("over");
589                        });
590                        });
591                        })( jQuery );
592                    </script>';
593            $d2="";
594            // output statistic table
595            if (strlen($rater_zoom) >0) {
596              $d2 = '<th class="rating_stat_th" style="cursor: pointer;">Thumbs</th>'.NL;
597            }
598            if($rater_sid!=false) {
599              $d2 .= '<th class="rating_stat_th" style="cursor: pointer;">ID</th>'.NL;
600            }
601            $ret .= ' <table class="sortable rating_stat_table" id="rating_stat_table">
602                         <thead>
603                             <tr  class="">
604                                '.$d2.'
605                                <th class="rating_stat_th" style="cursor: pointer;">Item</th>
606                                <th class="rating_stat_th" style="cursor: pointer;">Value</th>
607                                <th class="rating_stat_th" style="cursor: pointer;">Details</th>
608                             </tr>
609                         </thead>
610                         <tbody>';
611
612            foreach($found_ratings as $findings) {
613                $dtls_id = uniqid((double)microtime()*1000000,1);
614                $alink_id++;
615                $blink_id = 'statanker_'.$alink_id;
616                $anker_id = 'anker_'.$alink_id;
617                $info = array();
618                $d3 ="";
619                $d1=array();
620
621                if (strlen($rater_zoom) >0) {
622                    $d1=explode("?",$findings['img']);
623                    if(strlen($d1[0])>1) {
624                        $rater_img_xhtml = p_render('xhtml',p_get_instructions("{{".trim($d1[0])."?".$rater_zoom."}}"),$info);
625                        $rater_img_xhtml = str_replace("<p>","",$rater_img_xhtml);
626                        $rater_img_xhtml = str_replace("</p>","",$rater_img_xhtml);
627                    }
628                    else $rater_img_xhtml="&nbsp";
629                    $d3 = '<td class="rating_stat_td_col0">'.$rater_img_xhtml.'</td>'.NL;
630                }
631
632                if ($rater_sid!=false) {
633                    $d3 .= '<td class="rating_stat_td_col0">'.$findings['id'].'</td>';
634                }
635
636                $ret .= '<tr class="rating_stat_tr">'.
637                           $d3.
638                           '<td class="rating_stat_td_col1">'.$findings['item'].'</td>'.
639                           '<td class="rating_stat_td_col2">'.$findings[0]['value'].'</td>'.
640                           '<td class="rating_stat_td_col3" id="'.$anker_id.'">'.$ret_script1.
641                           '<img src="'.$findings[1]['image'].'?x='.$dtls_id.'" alt="'.$findings[0]['value'].' stars" />'.
642                           '&nbsp; '.$findings[2][5].' votes ';
643
644                if($data['rater_tracedetails']=== '1') {
645                    $ret_details ='<p class="rating__details">';
646                    $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/1star.gif?w=40&amp;" alt="1 Star" width="40" align="left" /> '.$findings[2][0].' visitor votes<br />';
647                    $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/2star.gif?w=40&amp;" alt="2 Stars" width="40" align="left" /> '.$findings[2][1].' visitor votes<br />';
648                    $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/3star.gif?w=40&amp;" alt="3 Stars" width="40" align="left" /> '.$findings[2][2].' visitor votes<br />';
649                    $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/4star.gif?w=40&amp;" alt="4 Stars" width="40" align="left" /> '.$findings[2][3].' visitor votes<br />';
650                    $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/5star.gif?w=40&amp;" alt="5 Stars" width="40" align="left" /> '.$findings[2][4].' visitor votes';
651                    $ret_details .= '</p>';
652                    $ret_script1  = str_ireplace('$blink_id', $blink_id, $ret_script);
653                    $ret .= '<a href="#'.$anker_id.'" onclick="hidden'.$blink_id.'()">(Details)</a>'.
654                           '<div style="display : none" id="details_'.$blink_id.'">'.$ret_details.'</div>'.NL;
655                }
656
657                $ret .= '</td></tr>';
658            }
659
660            foreach($found_votings as $findings) {
661              // build the return value for details if details option is on
662              $dtls_id = uniqid((double)microtime()*1000000,1);
663              $alink_id++;
664              $blink_id = 'statanker_'.$alink_id;
665              $anker_id = 'anker_'.$alink_id;
666              $info = array();
667              $d3 = '';
668              $d1=array();
669
670              if($data['rater_tracedetails']=== '1') {
671                  // build the return value for details
672                  $ret_details = '<p class="rating__details">';
673                  $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/thumbup.gif?h=12&amp;" alt="Pro" align="left" /> <p align="left">('.$findings[0][0].') </p><p>'. $findings[0][1].'</p><br />';
674                  $ret_details .= '<img src="'.DOKU_BASE.'lib/plugins/rater/img/thumbdown.gif?h=12&amp;" alt="Contra" align="left" /> <p align="left">('.$findings[0][2].') </p><p>'. $findings[0][3].'</p>';
675                  $ret_details .= '</p>';
676              }
677
678              if (strlen($rater_zoom) >0) {
679                  $d1=explode("?",$findings['img']);
680                  if(strlen($d1[0])>1) {
681                      $rater_img_xhtml = p_render('xhtml',p_get_instructions("{{".trim($d1[0])."?".$rater_zoom."}}"),$info);
682                      $rater_img_xhtml = str_replace("<p>","",$rater_img_xhtml);
683                      $rater_img_xhtml = str_replace("</p>","",$rater_img_xhtml);
684                  }
685                  else $rater_img_xhtml="&nbsp";
686                  $d3 = '<td class="rating_stat_td_col0">'.$rater_img_xhtml.'</td>';
687              }
688
689              if ($rater_sid!=false) {
690                  $d3 .= '<td class="rating_stat_td_col0">'.$findings['id'].'</td>';
691              }
692
693              $ret .= '<tr class="rating_stat_tr">'.
694                           $d3.
695                         '<td class="rating_stat_td_col1">'.$findings['item'].'</td>'.
696                         '<td class="rating_stat_td_col2">'.$findings[2]['votes'].' votes </td>'.
697                         '<td class="rating_stat_td_col3">'.$findings[3]['image'].
698                         '</td>'.
699                      '</tr>';
700            }
701
702            $ret .= '</tbody></form></table>'.NL;
703      }
704
705      // Render
706      $renderer->doc .= $ret;
707    }
708  }
709/******************************************************************************/
710  function assign_star_image($rater_rating) {
711                  // Assign star image
712              if ($rater_rating <= 0  ){$rater_stars = DOKU_BASE."lib/plugins/rater/img/00star.gif";$rater_stars_txt="Not Rated";}
713              if ($rater_rating >= 0.5){$rater_stars = DOKU_BASE."lib/plugins/rater/img/05star.gif";$rater_stars_txt="0.5";}
714              if ($rater_rating >= 1  ){$rater_stars = DOKU_BASE."lib/plugins/rater/img/1star.gif";$rater_stars_txt="1";}
715              if ($rater_rating >= 1.5){$rater_stars = DOKU_BASE."lib/plugins/rater/img/15star.gif";$rater_stars_txt="1.5";}
716              if ($rater_rating >= 2  ){$rater_stars = DOKU_BASE."lib/plugins/rater/img/2star.gif";$rater_stars_txt="2";}
717              if ($rater_rating >= 2.5){$rater_stars = DOKU_BASE."lib/plugins/rater/img/25star.gif";$rater_stars_txt="2.5";}
718              if ($rater_rating >= 3  ){$rater_stars = DOKU_BASE."lib/plugins/rater/img/3star.gif";$rater_stars_txt="3";}
719              if ($rater_rating >= 3.5){$rater_stars = DOKU_BASE."lib/plugins/rater/img/35star.gif";$rater_stars_txt="3.5";}
720              if ($rater_rating >= 4  ){$rater_stars = DOKU_BASE."lib/plugins/rater/img/4star.gif";$rater_stars_txt="4";}
721              if ($rater_rating >= 4.5){$rater_stars = DOKU_BASE."lib/plugins/rater/img/45star.gif";$rater_stars_txt="4.5";}
722              if ($rater_rating >= 5  ){$rater_stars = DOKU_BASE."lib/plugins/rater/img/5star.gif";$rater_stars_txt="5";}
723              return $rater_stars;
724  }
725/******************************************************************************/
726  function array_sort($array, $on, $order)
727  {
728     $new_array = array();
729     $sortable_array = array();
730
731    if (count($array) > 0) {
732         foreach ($array as $k => $v) {
733             if (is_array($v)) {
734                 foreach ($v as $k2 => $v2) {
735                     if ($k2 == $on) {
736                         $sortable_array[$k] = $v2;
737                     }
738                 }
739             } else {
740                 $sortable_array[$k] = $v;
741             }
742         }
743
744        switch ($order) {
745             case SORT_ASC:
746                 asort($sortable_array);
747             break;
748             case SORT_DESC:
749                 arsort($sortable_array);
750             break;
751         }
752
753        foreach ($sortable_array as $k => $v) {
754             $new_array[$k] = $array[$k];
755         }
756     }
757    return $new_array;
758  }
759/******************************************************************************/
760  function calc_rater_rating($rater_filename) {
761        $rater_end_of_line_char      = $this->getConf('eol_char');
762        if($rater_end_of_line_char == '') $rater_end_of_line_char = '\n';
763        $rater_file=fopen($rater_filename,"r");
764        $rater_str="";
765        $rater_str = fread($rater_file, 1024*8);
766        if($rater_str!=""){
767          $rater_data=explode($rater_end_of_line_char,$rater_str);
768          $rater_votes=count($rater_data)-1;
769          $rater_sum=0;
770
771          foreach($rater_data as $d){
772              $d=explode("|",$d);
773              $rater_sum+=$d[0];
774
775              // collect votes per level to display the details
776              if ($d[0] === '1'  ){$r1 = $r1 + 1;}
777              if ($d[0] === '2'  ){$r2 = $r2 + 1;}
778              if ($d[0] === '3'  ){$r3 = $r3 + 1;}
779              if ($d[0] === '4'  ){$r4 = $r4 + 1;}
780              if ($d[0] === '5'  ){$r5 = $r5 + 1;}
781          }
782          if($rater_votes>0) $rater_rating=number_format(($rater_sum/$rater_votes), 2, '.', '');
783        }
784        fclose($rater_file);
785        $tmp_array[] = array($rater_rating,$r1,$r2,$r3,$r4,$r5,$rater_votes,$rater_sum);
786        return $tmp_array;
787    }
788/******************************************************************************/
789    function calc_rater_voting($rater_filename) {
790        $rater_end_of_line_char      = $this->getConf('eol_char');
791        if($rater_end_of_line_char == '') $rater_end_of_line_char = '\n';
792        $rater_file=fopen($rater_filename,"r");
793        $rater_str="";
794        $rater_str = fread($rater_file, 1024*8);
795        if($rater_str!=""){
796          $rater_data=explode($rater_end_of_line_char,$rater_str);
797          $rater_votes=count($rater_data)-1;
798          $rater_sum=0;
799          foreach($rater_data as $d){
800              $d=explode("|",$d);
801              $rater_sum++;
802              if($d[1]=="") $d[1] = $this->getLang('foreigner'); // text & styling
803              // collect votes per level to display the details
804              if ($d[0] === '1'  ){$r1++;$who1 .= $d[1]."<br />";}
805              if ($d[0] === '2'  ){$r2++;$who2 .= $d[1]."<br />";}
806          }
807          if (!$r1) { $r1='0'; $who1 = ''; }
808          if (!$r2) { $r2='0'; $who2 = ''; }
809          $rater_rating=$r1." : ".$r2;
810        }
811        fclose($rater_file);
812        $tmp_array[] = array($rater_votes, $r1, $who1, $r2, $who2, $rater_sum);
813//        echo '<br />'.var_dump($tmp_array).'<br />';
814        return $tmp_array;
815    }
816/******************************************************************************/
817    // search given directory store all files into array
818    function list_files_in_array($dir, $delim)
819    {
820        $listDir = array();
821        if($handler = opendir($dir)) {
822            while (FALSE !== ($sub = readdir($handler))) {
823                if ($sub !== "." && $sub !== "..") {
824                    if(is_file($dir."/".$sub)) {
825                        $x = strpos(basename($dir."/".$sub),$delim);
826                        if(($x > 0)){
827                            $listDir[] = $dir."/".$sub;
828                        }
829                      //if(DEBUG) echo sprintf("<p><b>%s</b></p>\n", $dir."/".$sub);
830                    }
831                }
832            }
833            closedir($handler);
834        }
835        return $listDir;
836    }
837/******************************************************************************/
838    // search given directory recursively and store all files into array
839    function list_rec_files_in_array($dir, $delim, $excludes)
840    {
841        $max_count_files = 10;
842        $listDir = array();
843        if($handler = opendir($dir)) {
844            while (FALSE !== ($sub = readdir($handler))) {
845                if ($sub !== "." && $sub !== "..") {
846                    if(is_file($dir."/".$sub)) {
847                        $x = strpos(basename($dir."/".$sub),".txt");
848                        if(($delim === '.txt') && ($x > 0)){
849                            $listDir[] = $dir."/".$sub;
850                          }
851                        elseif($delim === 'all') {
852                            $listDir[] = $dir."/".$sub;
853                        }
854                    }
855                    elseif(is_dir($dir."/".$sub)) {
856                        $listDir[$sub] = $this->list_rec_files_in_array($dir."/".$sub, $delim,$excludes);
857                    }
858                }
859            }
860            closedir($handler);
861        }
862        $listDir = $this->array_flat($listDir);
863        sort($listDir);
864        return $listDir;
865    }
866/******************************************************************************/
867    // flatten the hierarchical arry to store path + file at first "column"
868    function array_flat($array) {
869        $out=array();
870        foreach($array as $k=>$v){
871            if(is_array($array[$k]))  { $out=array_merge($out,$this->array_flat($array[$k])); }
872            else  { $out[]=$v; }
873        }
874        return $out;
875    }
876/******************************************************************************/
877    // to elaborate the ns:page for stat link to rater obj on the pages
878    function __savedir($page_filepath) {
879        global $conf;
880        $savedir = $this->getConf('savedir');
881        if($savedir == '') $savedir='data';
882        $savedir = str_replace("../", "", $savedir);
883        $savedir = str_replace("./", "", $savedir);
884        $y_pos   = stripos($page_filepath, $savedir."/pages");
885        $t1      = substr($page_filepath, $y_pos);
886        $t1      = substr(str_replace( ".txt" , "" , $t1 ) , strlen($savedir."/pages"), 9999);
887        // turn it into wiki link without "pages"
888        $t2 = str_replace("/", ":", $t1);
889        $t2 = substr($t2, 1, strlen($t2));
890//echo '('.$savedir.') '.$t2.'<br />';
891        return $t2;
892    }
893/******************************************************************************/
894    // search and load all rater objects of a given page
895    function rater_on_page($links, $listRatingFiles, $page_filepath, $returns) {
896         foreach($links as $wse) {
897            foreach($wse as $link) {
898                // strip pr�fix "rater>" = left 6 signs and last sign = ")"
899                $link = substr($link,6,-1);
900                $type = '';
901                $img = '';
902                $name = '';
903
904                // ignore all "type=stat" references
905                if ((stripos($link,"type=stat") === false) && (stripos($link,"type=localstat") === false)) {
906                    // extract rater file name
907                    $fileReference = explode("|",$link);
908                    foreach ($fileReference as $param) {
909                        if(stripos($param,"id=")!== false) { $rater_id = substr($param,4); }
910                        elseif(stripos($param,"name=")!== false) {
911                            $name = substr($param,5);
912                            $needles = array(":","/","\\");
913                            $name = str_replace($needles, "_", $name);
914                        }
915                        elseif(stripos($param,"type=")!== false) { $type = substr($param,5); }
916                        elseif(stripos($param,"img=")!== false)  { $img  = substr($param,4); }
917                    }
918                    $cFlag = false;
919                    // loop through rater list to find matching rater
920                    foreach($listRatingFiles as $ratingFile) {
921                        // check if rater name is part of path
922                        if(stripos($ratingFile,$this->sonderzeichen($rater_id.'_'.$name.'_'.$type))>0) {
923                            //extract page file name
924                            $p_filename = basename($page_filepath);
925
926                            //cut everything before pages/ from link
927                            $t2 = $this->__savedir($page_filepath);
928                            // make a link out of it
929                            //$t1 = html_wikilink(':'.$t2, $rater_id.' '.$name);
930                            $t1 = html_wikilink(':'.$t2, $name);
931
932                            // differ between rate and vote
933                            if (stripos($ratingFile,'rate.rating')>0){
934                                $rate_counter = $rate_counter+1;
935                                // store page file and rater file link for output
936                                $returns['ratings'][] = array('id' => $rater_id, 'item' => $t1 , 'file' => basename($ratingFile), 'img' => $img);
937                                $cFlag = true;
938                                break;
939                            }
940                            elseif (stripos($ratingFile,'vote.rating')>0){
941                                $vote_counter = $vote_counter+1;
942                                // store page file and rater file link for output
943                                $returns['votings'][] = array('id' => $rater_id, 'item' => $t1 , 'file' => basename($ratingFile), 'img' => $img);
944                                $cFlag = true;
945                                break;
946                            }
947                        }
948                    }
949                    // link on page but rater file not existent due to no votes registerd so far
950                    if($cFlag === false) {
951                        $mis_counter = $mis_counter+1;
952                        //extract page file name
953                        $p_filename = basename($page_filepath);
954                        //cut everything before pages/ from link
955                        $t2 = $this->__savedir($page_filepath);
956                        // make a link out of it
957                        $t1 = html_wikilink(':'.$t2,$rater_id.' '.$name);
958                        // store page file where rater file not existent
959                        $found_nok[] = $t1 . " : " . basename($ratingFile);
960                    }
961                }
962            }
963         }
964      return $returns;
965    }
966/******************************************************************************/
967    function sonderzeichen($string)
968    {
969//      utf8 decoding in function call not valid anymore, following deleted there
970//      utf8_decode($rater_id.'_'.$name.'_'.$type)
971//      former replacements for German umlauts now in language files defined
972//      $search  = array(" ", "�",  "�",  "�",  "�",  "�",  "�",  "�",  "�", "&");
973//      $replace = array("_", "ae", "oe", "ue", "Ae", "Oe", "Ue", "ss", "",  "");
974      $search  = explode(",",$this->getLang('search'));
975      $replace  = explode(",",$this->getLang('replace'));
976      $string  = str_replace($search, $replace, $string);
977      return $string;
978}
979/******************************************************************************/
980}