1<?php
2/******************************************************************************
3**
4**  action script related to IssueTracker
5**  Action to display details of a selected issue
6*/
7/******************************************************************************
8**  must run within Dokuwiki
9**/
10if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../../').'/');
11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
12require_once(DOKU_PLUGIN.'action.php');
13require_once(DOKU_PLUGIN.'issuetracker/assilist.php');
14
15/******************************************************************************/
16class action_plugin_issuetracker extends DokuWiki_Action_Plugin {
17
18    var $parameter = "";
19
20  /**
21   * return some info
22   */
23  function getInfo(){
24    return array(
25         'author' => 'Taggic',
26         'email'  => 'Taggic@t-online.de',
27         'date'   => '2016-06-02',
28         'name'   => 'Issue comments (action plugin component)',
29         'desc'   => 'to display details of a dedicated issue.',
30         'url'    => 'https://www.dokuwiki.org/plugin:issuetracker',
31         );
32  }
33/******************************************************************************
34**  Register its handlers with the dokuwiki's event controller
35*/
36     function register(Doku_Event_Handler $controller) {
37         $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, '_handle_act', array());
38         $controller->register_hook('TPL_ACT_UNKNOWN', 'BEFORE', $this, 'output', array());
39                                    //HTML_UPDATEPROFILEFORM_OUTPUT
40         $controller->register_hook( 'AUTH_USER_CHANGE',
41                          			'BEFORE',
42                          			$this,
43                          			'handle_usermod_before',
44                          			array());
45
46          $controller->register_hook( 'AUTH_USER_CHANGE',
47                          			'AFTER',
48                          			$this,
49                          			'handle_usermod_after',
50                          			array());
51//          $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, '_hookjs');
52     }
53
54/******************************************************************************/
55  /**
56   * Hook js script into page headers.
57   */
58  function _hookjs(&$event, $param) {
59
60    $css=DOKU_URL."lib/plugins/issuetracker/datepick/jsDatePick_ltr.css";
61    $jquery=DOKU_URL."lib/plugins/issuetracker/datepick/jquery.1.4.2.js";
62    $datepicker=DOKU_URL."lib/plugins/issuetracker/datepick/jsDatePick.min.1.3.js";
63
64
65    $event->data["link"][] = array (
66                "rel" => "stylesheet",
67                "media" => "all",
68                "type" => "text/css",
69				        "href" =>  $css
70				        );
71
72
73
74    $event->data["script"][] = array (  "type" => "text/javascript",
75				        "charset" => "utf-8",
76				        "_data" => "",
77				        "src" =>  $jquery
78				        );
79
80    $event->data["script"][] = array (  "type" => "text/javascript",
81				        "charset" => "utf-8",
82				        "_data" => "",
83				        "src" =>  $datepicker
84				        );
85
86    $event->data["script"][] = array (  "type" => "text/javascript",
87				        "charset" => "utf-8",
88				        "_data" => "
89                window.onload = function(){
90                      		new JsDatePick({
91                      			useMode:2,
92                      			target:'dev_start',
93                      			dateFormat:'%d.%M.%Y'
94                      		});
95                          new JsDatePick({
96                      			useMode:2,
97                      			target:'dev_deadline',
98                      			dateFormat:'%d.%M.%Y'
99                      		});
100                      	};",
101				        "src" =>  ""
102				        );
103  }
104
105/******************************************************************************
106**  Handle the action
107*/
108     function _handle_act(&$event, $param) {
109         if (($event->data === 'showcase') || ($event->data === 'store_resolution') || ($event->data === 'store_workaround')){
110             $this->parameter  = $_POST['showid'];
111             $this->project    = $_POST['itl_project'];
112         }
113         elseif ($event->data === 'showcaselink') {
114            $this->parameter   = $_GET['showid'];
115            $this->project     = $_GET['project'];
116         }
117         elseif($event->data === 'btn_add_contact') {
118            $this->project     = $_POST['project'];
119            $this->issue_ID    = $_POST['issue_ID'];
120            $this->add_contact = $_POST['add_contact'];
121         }
122         elseif($event->data === 'btn_upd_addinfo') {
123            $this->project       = $_POST['project'];
124            $this->parameter     = $_POST['issue_ID'];
125            $this->new_component = $_POST['new_component'];
126            $this->trgt_version  = $_POST['trgt_version'];
127            $this->itl_block     = $_POST['itl__block_filter'];
128            $this->dev_start     = $_POST['dev_start'];
129            $this->dev_deadline  = $_POST['dev_deadline'];
130            $this->dev_progress  = $_POST['dev_progress'];
131         }
132         elseif ($event->data === 'it_search') {
133            $this->parameter   = $_POST['it_str_search'];
134            $this->project     = $_POST['itl_project'];
135         }
136         elseif ($event->data === 'issuelist_next') {
137            $this->itl_start   = $_POST['itl_start'];
138            $this->itl_step    = $_POST['itl_step'];
139            $this->itl_next    = $_POST['itl_next'];
140            $this->itl_pjct    = $_POST['itl_project'];
141            $this->itl_sort    = $_POST['it_glbl_sort'];
142            $this->itl_stat    = $_POST['itl_stat_filter'];
143            $this->itl_sev     = $_POST['itl_sev_filter'];
144            $this->itl_prod    = $_POST['itl__prod_filter'];
145            $this->itl_vers    = $_POST['itl__vers_filter'];
146            $this->itl_comp    = $_POST['itl__comp_filter'];
147            $this->itl_block   = $_POST['itl__block_filter'];
148            $this->itl_assi    = $_POST['itl__assi_filter'];
149            $this->itl_reporter= $_POST['itl__user_filter'];
150            $this->itl_myis    = $_POST['itl_myis_filter'];
151            $this->project     = $_POST['itl_project'];
152            $this->it_th_cols  = $_POST['it_th_cols'];
153
154         }
155         elseif ($event->data === 'issuelist_previous') {
156            $this->itl_start   = $_POST['itl_start'];
157            $this->itl_step    = $_POST['itl_step'];
158            $this->itl_next    = $_POST['itl_next'];
159            $this->itl_pjct    = $_POST['itl_project'];
160            $this->itl_sort    = $_POST['it_glbl_sort'];
161            $this->itl_stat    = $_POST['itl_stat_filter'];
162            $this->itl_sev     = $_POST['itl_sev_filter'];
163            $this->itl_prod    = $_POST['itl__prod_filter'];
164            $this->itl_vers    = $_POST['itl__vers_filter'];
165            $this->itl_comp    = $_POST['itl__comp_filter'];
166            $this->itl_block   = $_POST['itl__block_filter'];
167            $this->itl_assi    = $_POST['itl__assi_filter'];
168            $this->itl_reporter= $_POST['itl__user_filter'];
169            $this->itl_myis    = $_POST['itl_myis_filter'];
170            $this->project     = $_POST['itl_project'];
171            $this->it_th_cols  = $_POST['it_th_cols'];
172         }
173         elseif ($event->data === 'issuelist_filter') {
174            $this->itl_start   = $_POST['itl_start'];
175            $this->itl_step    = $_POST['itl_step'];
176            $this->itl_next    = $_POST['itl_next'];
177            $this->itl_pjct    = $_POST['itl_project'];
178            $this->itl_sort    = $_POST['it_glbl_sort'];
179            $this->itl_stat    = $_POST['itl_stat_filter'];
180            $this->itl_sev     = $_POST['itl_sev_filter'];
181            $this->itl_prod    = $_POST['itl__prod_filter'];
182            $this->itl_vers    = $_POST['itl__vers_filter'];
183            $this->itl_comp    = $_POST['itl__comp_filter'];
184            $this->itl_block   = $_POST['itl__block_filter'];
185            $this->itl_assi    = $_POST['itl__assi_filter'];
186            $this->itl_reporter= $_POST['itl__user_filter'];
187            $this->itl_myis    = $_POST['itl_myis_filter'];
188            $this->project     = $_POST['itl_project'];
189            $this->it_th_cols  = $_POST['it_th_cols'];
190         }
191         elseif ($event->data === 'issuelist_filterlink') {
192            $this->itl_start   = $_GET['itl_start'];
193            $this->itl_step    = $_GET['itl_step'];
194            $this->itl_next    = $_GET['itl_next'];
195            $this->itl_pjct    = $_GET['itl_project'];
196            $this->itl_sort    = $_GET['it_glbl_sort'];
197            $this->itl_stat    = $_GET['itl_stat_filter'];
198            $this->itl_sev     = $_GET['itl_sev_filter'];
199            $this->itl_prod    = $_GET['itl__prod_filter'];
200            $this->itl_vers    = $_GET['itl__vers_filter'];
201            $this->itl_comp    = $_GET['itl__comp_filter'];
202            $this->itl_block   = $_GET['itl__block_filter'];
203            $this->itl_assi    = $_GET['itl__assi_filter'];
204            $this->itl_reporter= $_GET['itl__user_filter'];
205            $this->itl_myis    = $_GET['itl_myis_filter'];
206            $this->project     = $_GET['itl_project'];
207            $this->it_th_cols  = $_POST['it_th_cols'];
208         }
209         elseif ($event->data === 'showmodlog') {
210            $this->parameter   = $_GET['showid'];
211            $this->project     = $_GET['project'];
212         }
213         elseif ($event->data === 'savecfgelement') {
214          $this->parameter     = "addcfgelement";
215          $this->elmnt_name    = $_POST['name1'];
216          $this->elmnt_type    = $_POST['type1'];
217         }
218         elseif ($event->data === 'savecfgmatrix') {
219          $this->parameter     = "cfgmatrix";
220          $this->elmnt_type    = $_POST['type2'];
221          $this->elmnt_name    = $_POST['name2'];
222          $this->elmnt_childs  = $_POST['childs2'];
223         }
224         elseif ($event->data === 'deletecfgelement') {
225          $this->parameter     = "deletecfgelement";
226          $this->elmnt_type    = $_POST['type3'];
227          $this->elmnt_name    = $_POST['name3'];
228         }
229         else return;
230
231         $event->preventDefault(); // https://www.dokuwiki.org/devel:events#event_object
232     }
233/******************************************************************************
234**  format string for comment label
235*/
236    function convertlabel($txt){
237        $len = strlen($txt);
238        $res = "";
239        $tmp = explode(chr(10),$txt);
240        foreach($tmp as $line) {
241          if((stripos($line,'ul]')!==false) || (stripos($line,'ol]')!==false) || (stripos($line,'li]')!==false)) {
242              $res .= $line;
243          }
244          else $res .= $line."<br />";
245        }
246        return $res;
247    }
248/******************************************************************************/
249/* improved implode needed
250*/
251    function array_implode($arrays, &$target = array())
252    {
253         foreach ($arrays as $item) {
254             if (is_array($item)) {
255                 $this->array_implode($item, $target);
256             } else {
257                 $target[] = $item;
258             }
259         }
260         return $target;
261    }
262/******************************************************************************
263**  Generate output
264*/
265    function output(&$data) {
266             global $ID;
267
268         if (($data->data == 'showcase') || ($data->data == 'showcaselink') || ($data->data == 'store_resolution') || ($data->data == 'store_workaround')) {
269             $data->preventDefault();
270    //        if ($mode == 'xhtml'){
271                 $renderer->info['cache'] = false;
272                 $issue_id = $this->parameter;
273                 $project  = $this->project;
274                 $user_grp = pageinfo();
275                 $usr      = $user_grp['userinfo']['name'] ;  //to log issue mods
276                 $Generated_Header  = '';
277                 $Generated_Message = '';
278
279                 // get issues file contents
280                 if($this->getConf('it_data')==false) $pfile = DOKU_CONF."../data/meta/".$project.'.issues';
281                 else $pfile = DOKU_CONF."../". $this->getConf('it_data').$project.'.issues';
282
283                 if (is_file($pfile))
284                	 {  $issues  = unserialize(@file_get_contents($pfile));}
285                 elseif(strlen($project)>1)
286                	 {// promt error message that issue with ID does not exist
287                      echo '<div class="it__negative_feedback">'.sprintf($this->getLang('msg_pfilemissing'), $project) . '</div><br />';
288                   }
289
290                 // showcase can refer to multiple issues in the event of multi-project tuned on
291                 // 1. check if multiproject is on
292                 if(($data->data == 'showcase') && ($this->getConf('multi_projects')!== false)) {
293                   // 2. get list of projects and issues
294                   $issues = $this->_get_issues($project, true);
295
296                   // 3. filter for related issue id
297                   foreach($issues as $issue) {
298                      if($issue['id']==$issue_id) {
299                        $tmp[] = $issue;
300                        $pstring = sprintf("showid=%s&amp;project=%s", urlencode($issue['id']), urlencode($issue['project']));
301                        $p = $p + 1;
302                        $referrer = "p".$p;
303                        $itl_item_title .= '<label for="'.$referrer.'">'.$issue['project'].': </label>&nbsp'.
304                                           '<a  name="'.$referrer.'"   id="'.$referrer.'" href="doku.php?id='.$ID.'&do=showcaselink&'.$pstring.'" title="'.$issue['title'].'">'.$issue['title'].'</a><br />';
305                      }
306                   }
307                   $issues = $tmp;
308                   if(count($issues)>1) {
309                       // list issues
310                       echo $this->getLang('msg_showCase') . '<br />';
311                       echo $itl_item_title;
312                       return;
313                   }
314                   elseif(count($issues)===1) {
315                     // just one issue but of which project ?
316                      $project = $issue['project'];
317                   }
318                 }
319
320                 //If comment to be deleted
321                 elseif ($_REQUEST['del_cmnt']==='TRUE') {
322                     // check if captcha is to be used by issue tracker in general
323                     if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
324                     else { $captcha_ok = ($this->_captcha_ok());}
325                     if ($captcha_ok)
326                     {    if (checkSecurityToken())
327                          {  // get comment file contents
328                             if($this->getConf('it_data')==false) $comments_file = DOKU_CONF."../data/meta/".$project."_".$_REQUEST['comment_issue_ID'].'.cmnts';
329                             else $comments_file = DOKU_CONF."../". $this->getConf('it_data').$project."_".$_REQUEST['comment_issue_ID'].'.cmnts';
330                             if (@file_exists($comments_file))  {  $comments  = unserialize(@file_get_contents($comments_file));  }
331                             else  {  $txt='Comments file does not exist.';  }
332                             // delete fieldset from $comments array
333                             $comment_id = htmlspecialchars(stripslashes($_REQUEST['comment_id']));
334                             $comment_id = htmlspecialchars($_REQUEST['comment_id']);
335                             //$comments[$comment_id]
336                             unset($comments[$comment_id]);
337                             // store comments to file
338                             $xvalue = io_saveFile($comments_file,serialize($comments));
339                             if($this->getConf('mail_modify_comment') ===1) $this->_emailForMod($_REQUEST['project'],$issues[$_REQUEST['comment_issue_ID']], $comments[$comment_id],'delete');
340                             //sprintf($format, $num
341                             msg(sprintf($this->getLang('msg_commentdeltrue'),$comment_id),1);
342//                             $Generated_Header = '<div class="it__positive_feedback">'.sprintf($this->getLang('msg_commentdeltrue'),$comment_id).'</div><br />';
343                          }
344                      }
345                 }
346                 //Comment to be added  or modified
347                 elseif ((isset($_REQUEST['comment'])) || (isset($_REQUEST['comment_id'])))
348                 {  if ((($_REQUEST['comment']) || (isset($_REQUEST['comment_id']))) && (isset($_REQUEST['comment_issue_ID'])))
349                       {
350                       // check if captcha is to be used by issue tracker in general
351                       if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
352                       else { $captcha_ok = ($this->_captcha_ok());}
353
354                       if (@file_exists($pfile))
355                    	 {  $issues  = unserialize(@file_get_contents($pfile)); }
356                        else
357                    	 {  msg('Issue file not found !'.NL.$pfile,-1);
358                          return false; }
359
360                       if ($captcha_ok)
361                             {
362                                if (checkSecurityToken())
363                                {  // get comment file contents
364                                   if($this->getConf('it_data')==false) $comments_file = DOKU_CONF."../data/meta/".$project."_".$_REQUEST['comment_issue_ID'].'.cmnts';
365                                   else $comments_file = DOKU_CONF."../". $this->getConf('it_data').$project."_".$_REQUEST['comment_issue_ID'].'.cmnts';
366
367                                   if (@file_exists($comments_file))  {  $comments  = unserialize(@file_get_contents($comments_file));  }
368                                   else  {  $comments = array();  }
369                                   $checkFlag=false;
370
371                                   //Add new comment to the comment file
372                                   $comment_id=count($comments);
373                                   // check if comment content already exist
374                                   foreach ($comments as $value)
375                                       {  if ($value['id'] >= $comment_id) { $comment_id=$value['id'] + 1; }
376                                          if ($_REQUEST['comment'] === $value['comment'])
377                                          {   msg($this->getLang('msg_commentfalse').'.',-1);
378//                                              $Generated_Header = '<div class="it__negative_feedback">'.$this->getLang('msg_commentfalse').'</div><br />';
379                                              $checkFlag=true;
380                                          }
381                                       }
382                                   //If comment to be modified
383                                   if (($checkFlag === false) && (isset($_REQUEST['comment_id'])))
384                                   { $comment_id = htmlspecialchars(stripslashes($_REQUEST['comment_id']));
385                                     if ($_REQUEST['comment_mod'] === $comments[$comment_id]['comment'])
386                                        {   msg($this->getLang('msg_commentfalse').$comment_id.'.',-1);
387//                                            $Generated_Header = '<div class="it__negative_feedback">'.$this->getLang('msg_commentmodfalse').$comment_id.'</div><br />';
388                                            $checkFlag=true;
389                                        }
390                                     else
391                                     {  $cur_date = date($this->getConf('d_format'));
392                                        $comments[$comment_id]['mod_timestamp'] = $cur_date;
393//                                        $comments[$comment_id]['comment'] = htmlspecialchars(stripslashes($_REQUEST['comment_mod']));
394                                        $comments[$comment_id]['comment'] = htmlspecialchars($_REQUEST['comment_mod']);
395//                                        $Generated_Header = '<div class="it__positive_feedback">'.$this->getLang('msg_commentmodtrue').$comment_id.'.</div><br />';
396                                        //Create comments file
397                                        $xvalue = io_saveFile($comments_file,serialize($comments));
398                                        if(($this->getConf('mail_modify_comment') ===1) && ($_REQUEST['minor_mod']!=="true")) $this->_emailForMod($_REQUEST['project'],$issues[$_REQUEST['comment_issue_ID']], $comments[$comment_id], 'modify');
399                                        msg($this->getLang('msg_commenttrue').$comment_id.'.',1);
400//                                        $Generated_Header = '<div class="it__positive_feedback">'.$this->getLang('msg_commenttrue').$comment_id.'.</div><br />';
401                                      }
402                                   }
403                                   //If comment to be added
404                                   elseif ($checkFlag === false)
405                                   {   $comments[$comment_id]['id'] = $comment_id;
406                                       $comments[$comment_id]['author'] = htmlspecialchars(stripslashes($_REQUEST['author']));
407                                       $cur_date = date($this->getConf('d_format'));
408                                       $comments[$comment_id]['timestamp'] = $cur_date;
409//                                       $comments[$comment_id]['comment'] = htmlspecialchars(stripslashes($_REQUEST['comment']));
410                                       $comments[$comment_id]['comment'] = htmlspecialchars($_REQUEST['comment']);
411                                       //Create comments file
412                                       $xvalue = io_saveFile($comments_file,serialize($comments));
413                                       if($this->getConf('mail_add_comment') ===1) $this->_emailForMod($_REQUEST['project'],$issues[$_REQUEST['comment_issue_ID']], $comments[$comment_id], 'new');
414                                       msg($this->getLang('msg_commenttrue').$comment_id.'.',1);
415//                                       $Generated_Header = '<div class="it__positive_feedback">'.$this->getLang('msg_commenttrue').$comment_id.'.</div><br />';
416                                    }
417                                    // update issues modification date
418                                    if ($checkFlag === false)
419                                    {   // inform user (or assignee) about update
420                                        // update modified date
421                                        $cur_date = date($this->getConf('d_format'));
422                                        $issues[$_REQUEST['comment_issue_ID']]['modified'] = $cur_date;
423                                        $xvalue = io_saveFile($pfile,serialize($issues));
424                                        // if($this->getConf('mail_modify_comment') ===1) $this->_emailForMod($_REQUEST['project'],$issues[$_REQUEST['comment_issue_ID']], $comments[$comment_id], 'modify');
425                                        $anker_id = 'resolved_'. uniqid((double)microtime()*1000000,1);
426                                    }
427                                 }
428                            }
429                       }
430                 }
431                 elseif (isset($_REQUEST['mod_add_data']))
432                 {
433                    $old_value = '<u>Planning info modified:</u><br />'.
434                                  'Component: '.$issues[$issue_id]['component'].'<br />'.
435                                  'Target version: '.$issues[$issue_id]['trgt_version'].'<br />'.
436                                  'Test blocking: '.$issues[$issue_id]['tblock'].'<br />'.
437                                  'Begin: '.$issues[$issue_id]['dev_start'].'<br />'.
438                                  'Deadline: '.$issues[$issue_id]['dev_deadline'].'<br />'.
439                                  'Progress: '.$issues[$issue_id]['dev_progress'];
440
441                    $issues[$issue_id]['component']     = $_REQUEST['new_component'];
442                    $issues[$issue_id]['trgt_version']  = $_REQUEST['trgt_version'];
443                    $issues[$issue_id]['tblock']        = $_REQUEST['itl__block_filter'];
444                    $issues[$issue_id]['dev_start']     = $_REQUEST['dev_start'];
445                    $issues[$issue_id]['dev_deadline']  = $_REQUEST['dev_deadline'];
446                    $issues[$issue_id]['dev_progress']  = $_REQUEST['dev_progress'];
447
448                    //save issue-file
449                    $xvalue = io_saveFile($pfile,serialize($issues));
450                    $new_value = '<u>Planning info modified:</u><br />'.
451                                  'Component: '.$issues[$issue_id]['component'].'<br />'.
452                                  'Target version: '.$issues[$issue_id]['trgt_version'].'<br />'.
453                                  'Test blocking: '.$issues[$issue_id]['tblock'].'<br />'.
454                                  'Begin: '.$issues[$issue_id]['dev_start'].'<br />'.
455                                  'Deadline: '.$issues[$issue_id]['dev_deadline'].'<br />'.
456                                  'Progress: '.$issues[$issue_id]['dev_progress'];
457
458//                    echo $issue_id.' ... '.$old_value.'<br>'.'<br>'.$new_value.'<br>';
459
460                    $this->_log_mods($project, $issues[$issue_id], $usr, 'planning data', $old_value, $new_value);
461                 }
462                  elseif (isset($_REQUEST['mod_description']))
463                 {
464                    // check if captcha is to be used by issue tracker in general
465                    if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
466                    else { $captcha_ok = ($this->_captcha_ok());}
467
468                    if ($captcha_ok)
469                    {   if (checkSecurityToken())
470                        {   // find issue and description
471                              $issue_id = trim($_REQUEST['comment_issue_ID']);
472                              $cFlag = false;
473
474                              foreach ($issues as $value)
475                              { $ist = $value['id'];
476                                if ($value['id'] == $issue_id)
477                                { $cFlag = true;
478                                  break;}
479                              }
480
481                              if ($cFlag === true)
482                              {   $old_value = $issues[$issue_id]['description'];
483//                                  $issues[$issue_id]['description'] = htmlspecialchars(stripslashes($_REQUEST['description_mod']));
484                                  $issues[$issue_id]['description'] = htmlspecialchars($_REQUEST['description_mod']);
485                                  //save issue-file
486                                  $xvalue = io_saveFile($pfile,serialize($issues));
487                                  if(($this->getConf('mail_modify__description') ===1) && ($_REQUEST['minor_mod']!=="true")) $this->_emailForDscr($_REQUEST['project'], $issues[$issue_id]);
488                                  $this->_log_mods($project, $issues[$issue_id], $usr, 'description mod', $old_value, $issues[$issue_id]['description']);
489                                  msg($this->getLang('msg_descrmodtrue'),1);
490                      //            $Generated_Header = '<div class="it__positive_feedback">'.$this->getLang('msg_descrmodtrue').$issue_id.'</div>';
491                              }
492                              else { msg("Issue with ID: $issue_id not found.",-1); }
493                        }
494                    }
495                 }
496                 elseif(isset($_REQUEST['mod_contacts']))
497                 {  // check if captcha is to be used by issue tracker in general
498                    if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
499                    else { $captcha_ok = ($this->_captcha_ok());}
500                    if ($captcha_ok)
501                    {   if (checkSecurityToken())
502                        {   // find issue and description
503                            $issue_id = trim($_REQUEST['issue_ID']);
504                            $a1 = $_REQUEST['add_contact'];
505                            $a1 = preg_replace("/ +/", ',', $a1);
506                            $a1 = preg_replace('/;/',',',$a1);
507                            $a1 = preg_replace('/,+/',',',$a1);
508                            $xvalue = false;
509                            //check if register or unregister a follower
510                            if((strlen($a1)>0) && (stripos($issues[$issue_id]['add_user_mail'],$a1) === false)) {
511                                $issues[$issue_id]['add_user_mail'] .= ",".$a1;
512                                //save issue-file
513                                $xvalue = io_saveFile($pfile,serialize($issues));
514                                if($xvalue!==false) { msg(sprintf($this->getLang('msg_addFollower_true'),$issue_id).$a1,1);}
515                                $this->_log_mods($project, $issues[$issue_id], $usr, 'follower added', '', $a1);
516                            }
517                            // delete mail address from followers
518                            elseif((strlen($a1)>0) && (stripos($issues[$issue_id]['add_user_mail'],$a1) !== false)) {
519                                $tmp = explode(',', $issues[$issue_id]['add_user_mail']);
520                                foreach($tmp as $email) {
521                                    if (stripos($email,$a1) === false) $ret_mails .= $email.',';
522                                }
523                                //save issue-file
524                                $issues[$issue_id]['add_user_mail'] = $ret_mails;
525                                $xvalue = io_saveFile($pfile,serialize($issues));
526                                if($xvalue!==false) { msg(sprintf($this->getLang('msg_rmvFollower_true'),$issue_id).$a1,1);}
527                                $this->_log_mods($project, $issues[$issue_id], $usr, 'follower deleted', $a1, '');
528                            }
529                            if($xvalue===false) { msg(sprintf($this->getLang('msg_addFollower_failed'),$issue_id).$a1,-1); }
530                        }
531                    }
532                 }
533                 elseif(isset($_REQUEST['mod_symptomlinks']))
534                 {
535                    // check if captcha is to be used by issue tracker in general
536                    if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
537                    else { $captcha_ok = ($this->_captcha_ok());}
538
539                    if ($captcha_ok)
540                    {   if (checkSecurityToken())
541                        {   // find issue and description
542                              $issue_id = trim($_REQUEST['comment_issue_ID']);
543                              $cFlag = false;
544
545                              foreach ($issues as $value)
546                              { if ($value['id'] == $issue_id)
547                                { $cFlag = true;
548                                  break;}
549                              }
550
551                              if ($cFlag === true) {
552// *****************************************************************************
553// upload a symptom file
554// *****************************************************************************
555                                    $mime_type1 = $_FILES['attachment1']['type'];
556                                    if(($this->getConf('upload')> 0) && (strlen($mime_type1)>1)) {
557                                      $Generated_Header = $this->_symptom_file_upload($issues,$issue_id,'attachment1');
558                                    }
559                                    $mime_type2 = $_FILES['attachment2']['type'];
560                                    if(($this->getConf('upload')> 0) && (strlen($mime_type2)>1)) {
561                                      $Generated_Header = $this->_symptom_file_upload($issues,$issue_id,'attachment2');
562                                    }
563                                    $mime_type3 = $_FILES['attachment3']['type'];
564                                    if(($this->getConf('upload')> 0) && (strlen($mime_type3)>1)) {
565                                      $Generated_Header = $this->_symptom_file_upload($issues,$issue_id,'attachment3');
566                                    }
567                                                                      //save issue-file
568                                   $xvalue = io_saveFile($pfile,serialize($issues));
569                                   $new_value = $issues[$issue_id]['attachment1'].'<br />'.$issues[$issue_id]['attachment2'].'<br />'.$issues[$issue_id]['attachment3'];
570                                   $this->_log_mods($project, $issues[$issue_id], $usr, 'symptom links', $old_value, $new_value);
571                              }
572                              else { msg("Issue with ID: $issue_id not found.",-1); }
573                        }
574                    }
575                 }
576                 elseif (isset($_REQUEST['add_resolution']))
577                 {  $renderer->info['cache'] = false;
578
579                    if (@file_exists($pfile))
580                    	{ $issues  = unserialize(@file_get_contents($pfile)); }
581                    else
582                    	{ msg('Issue file not found !'.NL.$pfile,-1);
583                        return false; }
584
585                    // check if captcha is to be used by issue tracker in general
586                    if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
587                    else { $captcha_ok = ($this->_captcha_ok());}
588
589                    if ($captcha_ok)
590                      {   if (checkSecurityToken())
591                          {   //Add resolution text to the issue file and set the issue to solved
592                              $issue_id = trim($_REQUEST['comment_issue_ID']);
593                              $cFlag = false;
594
595                              foreach ($issues as $value)
596                                  { $ist = $value['id'];
597                                    if ($value['id'] == $issue_id)
598                                    { $cFlag = true;
599                                      break;}
600                                  }
601
602                              if ($cFlag === true)
603                              {   $old_value                       = $issues[$issue_id]['resolution'];
604//                                  $issues[$issue_id]['resolution'] = htmlspecialchars(stripslashes($_REQUEST['x_resolution']));
605                                  $issues[$issue_id]['resolution'] = htmlspecialchars($_REQUEST['x_resolution']);
606                                  $issues[$issue_id]['status']     = $this->getLang('issue_resolved_status');
607                                  $xuser                           = $issues[$issue_id]['user_mail'];
608                                  $xdescription                    = $issues[$issue_id]['description'];
609
610                                  //save issue-file
611                                  $xvalue                          = io_saveFile($pfile,serialize($issues));
612                                  $anker_id                        = 'resolved_'. uniqid((double)microtime()*1000000,1);
613                                  if($this->getConf('mail_modify_resolution') ===1) $this->_emailForRes($_REQUEST['project'], $issues[$_REQUEST['comment_issue_ID']]);
614//                                  $Generated_Message               = '<div class="it__positive_feedback"><a href="#'.$anker_id.'"></a>'.$this->getLang('msg_resolution_true').$issue_id.'</div>';
615                                  msg($this->getLang('msg_resolution_true').$issue_id.'.',1);
616                                  $usr                             = $_POST['usr'];
617                                  $this->_log_mods($project, $issues[$issue_id], $usr, 'resolution', $old_value, $issues[$issue_id]['resolution']);
618                              }
619                              else { msg("Issue with ID: $issue_id not found.",-1); }
620
621                          }
622                      }
623                 }
624                 elseif(isset($_REQUEST['mod_severity']))
625                 {  // check if captcha is to be used by issue tracker in general
626//                    msg("severity mod detected",0);
627                    if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
628                    else { $captcha_ok = ($this->_captcha_ok());}
629                    if ($captcha_ok)
630                    {   if (checkSecurityToken())
631                        {    $old_value = $issues[$issue_id]['severity'];
632                             $issue_id  = htmlspecialchars(stripslashes($_REQUEST['issue_ID']));
633                             $project   = htmlspecialchars(stripslashes($_REQUEST['project']));
634                             $usr       = htmlspecialchars(stripslashes($_REQUEST['ausr']));
635                             $column    = 'severity';
636                             $issues[$issue_id]['severity'] = htmlspecialchars(stripslashes($_REQUEST['new_severity']));
637//                             echo 'new severity = '.$issues[$issue_id]['severity'].'<br />';
638                            //save issue-file
639                            $xvalue     = io_saveFile($pfile,serialize($issues));                    // $project, $issue,             $old_value, $column, $new_value
640                            if($this->getConf('userinfo_email') >0) $this->_emailForIssueMod($project, $issues[$issue_id], $old_value, $column, $issues[$issue_id]['severity']);
641                            $this->_log_mods($project, $issues[$issue_id], $usr, $column, $old_value, $issues[$issue_id]['severity']);
642                            msg($this->getLang('msg_severitymodtrue'),1);
643                        }
644                    }
645                 }
646                 elseif(isset($_REQUEST['mod_status']))
647                 {  // check if captcha is to be used by issue tracker in general
648//                    msg("status mod detected",0);
649                    if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
650                    else { $captcha_ok = ($this->_captcha_ok());}
651                    if ($captcha_ok)
652                    {   if (checkSecurityToken())
653                        {    $old_value = $issues[$issue_id]['status'];
654                             $issue_id  = htmlspecialchars(stripslashes($_REQUEST['issue_ID']));
655                             $project   = htmlspecialchars(stripslashes($_REQUEST['project']));
656                             $usr       = htmlspecialchars(stripslashes($_REQUEST['busr']));
657                             $value     = $_REQUEST['new_status'];
658                             $column    = 'status';
659                             $issues[$issue_id]['status'] = htmlspecialchars(stripslashes($_REQUEST['new_status']));
660//                             echo 'new status = '.$issues[$issue_id]['status'].'<br />';
661                            //save issue-file
662                            $xvalue     = io_saveFile($pfile,serialize($issues));
663
664                            if(($this->getConf('status_special')!=='') && (stripos($this->getConf('status_special'),$value) === false)) {
665                                                                                              // $project, $issue,             $old_value, $column, $new_value
666                                if($this->getConf('userinfo_email') >0) $this->_emailForIssueMod($project, $issues[$issue_id], $old_value, $column, $issues[$issue_id]['status']);
667                            }
668                            $this->_log_mods($project, $issues[$issue_id], $usr, $column, $old_value, $issues[$issue_id]['status']);
669                            msg($this->getLang('msg_statusmodtrue'),1);
670                        }
671                    }
672                 }
673/* Workaround to be stored ---------------------------------------------------*/
674                 elseif(isset($_REQUEST["mod_wround"]))
675                 {  // check if captcha is to be used by issue tracker in general
676                    if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
677                    else { $captcha_ok = ($this->_captcha_ok());}
678                    if ($captcha_ok)
679                    {   if (checkSecurityToken())
680                        {   // find issue and description
681                            if (@file_exists($pfile))
682                    	      {  $issues  = unserialize(@file_get_contents($pfile)); }
683                            else
684                    	      {  msg('Issue file not found !'.NL.$pfile,-1);
685                               return false; }
686
687                             // get comment file contents
688                             if($this->getConf('it_data')==false) $comments_file = DOKU_CONF."../data/meta/".$project."_".$_REQUEST['comment_issue_ID'].'.cmnts';
689                             else $comments_file = DOKU_CONF."../". $this->getConf('it_data').$project."_".$_REQUEST['comment_issue_ID'].'.cmnts';
690
691                             if (@file_exists($comments_file))  {  $comments  = unserialize(@file_get_contents($comments_file));  }
692                             else  {  $comments = array();  }
693                             $checkFlag=false;
694                             $comment_id = 0;
695                             $comments[$comment_id] = array();
696                             $comments[$comment_id]['id'] = "WA";
697                             $comments[$comment_id]['author'] = htmlspecialchars(stripslashes($_REQUEST['author']));
698                             $cur_date = date($this->getConf('d_format'));
699                             $comments[$comment_id]['timestamp'] = $cur_date;
700//                             $comments[$comment_id]['wround_mod'] = htmlspecialchars(stripslashes($_REQUEST['wround_mod']));
701                             $comments[$comment_id]['wround_mod'] = htmlspecialchars($_REQUEST['wround_mod']);
702                             //Create comments file
703                             $xvalue = io_saveFile($comments_file,serialize($comments));
704                             if($this->getConf('mail_add_comment') ===1) $this->_emailForMod($_REQUEST['project'],$issues[$_REQUEST['comment_issue_ID']], $comments[$comment_id], 'workaround');
705                             msg($this->getLang('msg_wroundtrue').'.',1);
706
707                          // update issues modification date
708                          if ($checkFlag === false)
709                          {   // inform user (or assignee) about update
710                              // update modified date
711                              $cur_date = date($this->getConf('d_format'));
712                              $issues[$_REQUEST['comment_issue_ID']]['modified'] = $cur_date;
713                              $xvalue = io_saveFile($pfile,serialize($issues));
714                              $anker_id = 'resolved_'. uniqid((double)microtime()*1000000,1);
715                          }
716                        }
717                     }
718                 }
719                 // Render
720                                                        // Array  , project name
721                 $Generated_Table = $this->_details_render($issues, $project);
722                 //$data->doc .= $Generated_Header.$Generated_Table.$Generated_feedback;
723        }
724/* scrolling next/previous issues --------------------------------------------*/
725        elseif (($data->data == 'issuelist_next') || ($data->data == 'issuelist_previous') || ($data->data == 'issuelist_filter') || ($data->data == 'issuelist_filterlink'))
726        {
727                 $data->preventDefault();
728                 $renderer->info['cache'] = false;
729                 $project = $this->itl_pjct;
730                 $itl_start = $this->itl_start;
731                 $step = $this->itl_step;
732                 if ($step == '') {$step=10;}
733                 $itl_next = $this->itl_next;
734                 $a = $this->itl_pjct;
735                 if ($this->getConf('multi_projects')==0) {
736                    $all = false;
737                 }
738                 else {
739                    $all = true;
740                 }
741
742                 // get issues file contents
743                  $all = true;
744                  $issues = $this->_get_issues($project, $all);
745
746                  // global sort of issues array
747                  $sort_key = $this->itl_sort;
748                  $issues = $this->_issues_globalsort($issues, $sort_key);
749
750                 if ($data->data == 'issuelist_next') {
751                    $start = $itl_next;
752                    if ($start<0)  { $start='0'; }
753                    elseif($start>count($issues)) {$start=count($issues)-step;}
754                    $next_start = $start + $step;
755                    if ($next_start>count($issues)) {
756                      $next_start=count($issues);
757                      $start = $next_start - $step;
758                      if ($start<0) { $start='0'; }
759                      }
760//                    echo 'start = '.$start.';  step = '.$step.';  next_start = '.$next_start.'<br />';
761                 }
762                 elseif ($data->data == 'issuelist_previous') {
763                    $start = $itl_start - $step;
764                    if ($start<0) { $start='0'; $next_start = $start + $step;}
765                    else $next_start = $itl_start;
766                 }
767                 elseif ($data->data == 'issuelist_filter') {
768                    $start = $itl_start;
769                    $next_start = $start + $step;
770                    if ($next_start>count($issues)) { $next_start=count($issues); }
771                 }
772                 elseif ($data->data == 'issuelist_filterlink') {
773                    $start = 0;
774                    $step = count($issues);
775                    $next_start = count($issues);
776                    if ($next_start>count($issues)) { $next_start=count($issues); }
777                 }
778
779                $filter = array();
780                $filter['status']    = $this->itl_stat;
781                $filter['severity']  = $this->itl_sev;
782                $filter['product']   = $this->itl_prod;
783                $filter['version']   = $this->itl_vers;
784                $filter['component'] = $this->itl_comp;
785                $filter['tblock']    = $this->itl_block;
786                $filter['assignee']  = $this->itl_assi;
787                $filter['reporter']  = $this->itl_reporter;
788                $filter['myissues']  = $this->itl_myis;
789                $filter['tblock']    = $this->itl_block;
790
791                if ($filter['severity']   == '') { $filter['severity']   = 'ALL' ;}
792                if ($filter['status']     == '') { $filter['status']     = 'ALL' ;}
793                if ($filter['product']    == '') { $filter['product']    = 'ALL' ;}
794                if ($filter['version']    == '') { $filter['version']    = 'ALL' ;}
795                if ($filter['component']  == '') { $filter['component']  = 'ALL' ;}
796                if ($filter['tblock']     == '') { $filter['tblock']     = false ;}
797                else { $filter['tblock']  = true ;}
798                if ($filter['assignee']   == '') { $filter['assignee']   = 'ALL' ;}
799                if ($filter['reporter']   == '') { $filter['reporter']   = 'ALL' ;}
800            	  if ($filter['myissues']   == '') { $filter['myissues']   = false ;}
801                else { $filter['myissues']= true ;}
802
803                if ($filter['myissues']      == '') {$filter['myissues'] = false;}
804                else {$filter['myissues'] = true;}
805
806                $Generated_Header  = '';
807                $Generated_Table   = $this->_table_render($this->project,$a,$step,$start,$next_start,$filter,$all);
808                $Generated_Scripts = $this->_scripts_render($project);
809        }
810        elseif ($data->data == 'showmodlog'){
811            global $auth;
812            $data->preventDefault();
813            $issue_id = $this->parameter;
814            $project = $this->project;
815            $Generated_Header  = '';
816            $Generated_Scripts = '';
817            $Generated_Report  = '';
818            $Generated_Message = '';
819
820            // get mod-log file contents
821            if($this->getConf('it_data')==false) $modfile = DOKU_CONF."../data/meta/".$project.'_'.$issue_id.'.mod-log';
822            else $modfile = DOKU_CONF."../". $this->getConf('it_data').$project.'_'.$issue_id.'.mod-log';
823            if (@file_exists($modfile))
824                {$mods  = unserialize(@file_get_contents($modfile));}
825            else
826                {msg('No Modification log file found for this issue',-1);
827                 return;}
828
829            $Generated_Table  .= '<h1>'.$this->getLang('h_modlog').$issue_id.'</h1>';
830            $Generated_Table  .= '<div class="dokuwiki"><table class="inline tbl_showmodlog">'.NL;
831            $Generated_Table  .= '<tr><th>Date</th><th>User</th><th>Field</th><th>old Value</th><th>new Value</th></tr>'.NL;
832
833            foreach($mods as $mod) {
834
835                if($rowEven==="it_roweven") $rowEven="it_rowodd";
836                else $rowEven="it_roweven";
837
838                $Generated_Table  .= '<tr class="'.$rowEven.'" >'.NL;
839                $Generated_Table  .= '  <td>'.date($this->getConf('d_format'),strtotime($this->_get_one_value($mod,'timestamp'))).'</td>'.NL;
840                $Generated_Table  .= '  <td>'.$this->_get_one_value($mod,'user').'</td>'.NL;
841                $Generated_Table  .= '  <td>'.$this->_get_one_value($mod,'field').'</td>'.NL;
842                $Generated_Table  .= '  <td>'.$this->_get_one_value($mod,'old_value').'</td>'.NL;
843
844                $__assigened       = $this->_get_one_value($mod,'new_value');
845                $__assigened       = $this->xs_format($__assigened);
846                if((stripos($this->_get_one_value($mod,'field'),'assign')!== false) && ($this->getConf('auth_ad_overflow') == false)) {
847
848                    $filter['grps']=$this->getConf('assign');
849                    $target = $auth->retrieveUsers(0,0,$filter);
850
851                    foreach($target as $_assignee)
852                    { if($_assignee['mail'] === $__assigened) {
853                        $__assigened = $_assignee['name'];
854                        break; }
855                    }
856                }
857                $Generated_Table  .= '  <td>'.$__assigened.'</td>'.NL;
858                $Generated_Table  .= '</tr>'.NL;
859            }
860
861            $Generated_Table  .= '</table></div>'.NL;
862            // build parameter for $_GET method
863            $pstring = sprintf("showid=%s&amp;project=%s", urlencode($issue_id), urlencode($project));
864            msg($ID,0);
865            $itl_item_title = '<a href="doku.php?id='.$ID.'&do=showcaselink&'.$pstring.'" title="'.$this->getLang('back').'">'.$this->getLang('back').'</a>';
866            $Generated_Table  .= $itl_item_title.NL;
867        }
868        elseif ($data->data == 'it_search'){
869            $data->preventDefault();
870            include('itsearch.php');
871        }
872/*        elseif ($data->data == 'savecfgelement'){
873          // add a new element to the config-matrix
874          $data->preventDefault();
875          $cfg_file = DOKU_PLUGIN."issuetracker/conf/it_matrix.cfg";
876          $new_element = array();
877          if (@file_exists($cfg_file)) { $new_element  = unserialize(@file_get_contents($cfg_file)); }
878
879          // elmnt_type | elmnt_name | rel_childs
880          $new_element[]= array(
881                                'elmnt_type' => $_POST['type1'] ,
882                                'elmnt_name' => $_POST['name1'] ,
883                                'rel_childs' => "");
884
885          //save cfg-matrix file
886          asort($new_element);
887          $xvalue = io_saveFile($cfg_file,serialize($new_element));
888          if($xvalue>0) msg("New element added to the config matrix.",1);
889          else          msg("New element cannot be added to the config matrix.",-1);
890          $backlink = str_replace("&do=savecfgelement","",$ID);
891          echo '<a href="'.DOKU_URL.'doku.php?id='.$backlink.'">back</a> <br/>';
892        }
893        elseif ($data->data == 'savecfgmatrix'){
894          $data->preventDefault();
895          msg("implement code to store the newly added relation of an element and its childs",0);
896          echo 'elmnt_type: '  .$_POST['type2'].'<br />';
897          echo 'elmnt_name: '  .$_POST['name2'].'<br />';
898          echo 'elmnt_childs 1: '.$_POST['childs_1'].'<br />';
899          echo 'elmnt_childs 2: '.$_POST['childs_2'].'<br />';
900          echo 'elmnt_childs 3: '.$_POST['childs_3'].'<br />';
901          echo 'elmnt_childs 4: '.$_POST['childs_4'].'<br />';
902          echo 'elmnt_childs 5: '.$_POST['childs_5'].'<br />';
903        }
904        elseif ($data->data == 'deletecfgelement'){
905          $data->preventDefault();
906//          msg("implement code to delete an existing element and all its references",0);
907//          echo 'elmnt_type: '.$_POST['type3'].'<br />';
908//          echo 'elmnt_name: '.$_POST['name3'].'<br />';
909          // open cfg-matrix
910          $data->preventDefault();
911          $cfg_file = DOKU_PLUGIN."issuetracker/conf/it_matrix.cfg";
912          $elements = array();
913          if (@file_exists($cfg_file)) { $elements  = unserialize(@file_get_contents($cfg_file)); }
914          else return;
915          // loop through matrix elements and delete all references + element themselves
916          foreach($elements as $key => &$item) {
917            if (($item['elmnt_type']===$_POST['type3']) & ($item['elmnt_name']===$_POST['name3'])) {
918                // delete completely from array
919                unset($elements[$key]);
920            }
921            if(stripos($item['rel_childs'],$_POST['name3'])!==false){
922              $temp = explode(",",$item['rel_childs']);
923              foreach($temp as $k => $i){
924                if($i===$_POST['name3']) unset($temp[$k]);
925              }
926              $item['rel_childs'] = implode(",",$temp);
927            }
928          }
929          //save cfg-matrix file
930          $xvalue = io_saveFile($cfg_file,serialize($elements));
931          if($xvalue>0) msg("Element completely deleted from config matrix.",1);
932          else          msg("Element cannot be deleted from config matrix.",-1);
933          $backlink = str_replace("&do=savecfgelement","",$ID);
934          echo '<a href="'.DOKU_URL.'doku.php?id='.$backlink.'">back</a> <br/>';
935        }
936*/
937        else return;
938
939        // Render
940        echo $Generated_Header.$Generated_Table.$Generated_Scripts.$Generated_Report.$Generated_Message;
941    }
942/******************************************************************************/
943/* Create table scripts
944*/
945    function _scripts_render($project)
946    {
947        // load status values from config into select control
948        $s_counter = 0;
949        $status = explode(',', $this->getConf('status')) ;
950        foreach ($status as $x_status)
951        {
952            $s_counter = $s_counter + 1;
953            $x_status = trim($x_status);
954            $STR_STATUS = $STR_STATUS . "case '".$x_status."':  val = ".$s_counter."; break;";
955            $pattern = $pattern . "|" .  $x_status;
956            $x_status_select = $x_status_select . "['".$x_status."','".$x_status."'],";
957        }
958
959        // Build string to load products select
960        $products = explode(',', $this->getConf('products')) ;
961        foreach ($products as $x_products)
962        {
963            $x_products = trim($x_products);
964            $x_products_select = $x_products_select . "['".$x_products."','".$x_products."'],";
965        }
966
967        // Build string to load severity select
968        $severity = explode(',', $this->getConf('severity')) ;
969        foreach ($severity as $x_severity)
970        {
971            $x_severity = trim($x_severity);
972            $x_severity_select = $x_severity_select . "['".$x_severity."','".$x_severity."'],";
973        }
974
975        // see issue 37: AUTH:AD switch to provide text input instead
976        // select with retriveing all_users from AD
977        if($this->getConf('auth_ad_overflow') == false) {
978            global $auth;
979            global $conf;
980            $filter['grps']  = $this->getConf('assign');
981            $target          = $auth->retrieveUsers(0,0,$filter);
982            $shw_assignee_as = $this->getConf('shw_assignee_as');
983            if(stripos("login, mail, name",$shw_assignee_as) === false) $shw_assignee_as = "login";
984//--------------------------------------------------------------------------------------------
985// Build 'assign to' list from a simple textfile
986        	  // 1. check if file exist else use configuration
987        	  if($this->getConf('assgnee_list')==="") {
988                foreach ($target as $key => $x_umail)
989                {       // show assignee by login, name, mail
990                        if($shw_assignee_as=='login') $x_umail_select = $x_umail_select . "['".$key."','".$x_umail['mail']."'],";
991                        else $x_umail_select = $x_umail_select . "['".$x_umail[$shw_assignee_as]."','".$x_umail['mail']."'],";
992                }
993            }
994            else{
995                $x_umail_select = __get_assignees_from_files($this->getConf('assgnee_list'));
996              }
997//--------------------------------------------------------------------------------------------
998
999            $x_umail_select .= "['',''],";
1000            $authAD_selector = "TableKit.Editable.selectInput('assigned',{}, [".$x_umail_select."]);";
1001        }
1002
1003        //hack if DOKU_BASE is not properly set
1004        if(strlen(DOKU_BASE) < strlen(DOKU_URL)) $BASE = DOKU_URL."lib/plugins/issuetracker/";
1005        else $BASE = DOKU_BASE."lib/plugins/issuetracker/";
1006
1007        return    "<script type=\"text/javascript\" src=\"".$BASE."prototype.js\"></script><script type=\"text/javascript\" src=\"".$BASE."fabtabulous.js\"></script>
1008        <script type=\"text/javascript\" src=\"".$BASE."tablekit.js\"></script>
1009        <script type=\"text/javascript\">
1010            TableKit.options.editAjaxURI = '".$BASE."edit.php';
1011            TableKit.Editable.selectInput('status',{}, [".$x_status_select."]);
1012            TableKit.Editable.selectInput('product',{}, [".$x_products_select."]);
1013            TableKit.Editable.selectInput('severity',{}, [".$x_severity_select."]);
1014            ".$authAD_selector."
1015            TableKit.Editable.multiLineInput('description');
1016            TableKit.Editable.multiLineInput('resolution');
1017            var _tabs = new Fabtabs('tabs');
1018            $$('a.next-tab').each(function(a) {
1019                Event.observe(a, 'click', function(e){
1020                    Event.stop(e);
1021                    var t = $(this.href.match(/#(\w.+)/)[1]+'-tab');
1022                    _tabs.show(t);
1023                    _tabs.menu.without(t).each(_tabs.hide.bind(_tabs));
1024                }.bindAsEventListener(a));
1025            });
1026        </script>";
1027    }
1028/******************************************************************************/
1029/* Create list of next/previous Issues
1030*/
1031    function _table_render($project,$a,$step,$start,$next_start,$filter,$all=false)
1032    {
1033        global $ID;
1034        $imgBASE       = DOKU_BASE."lib/plugins/issuetracker/images/";
1035        $style         = ' style="text-align:center; white-space:pre-wrap;">';
1036        $user_grp      = pageinfo();
1037        $noStatIMG     = $this->getConf('noStatIMG');
1038        $noSevIMG      = $this->getConf('noSevIMG');
1039
1040        // get issues file contents
1041        //$all = true;
1042        $issues = $this->_get_issues($project, $all);
1043        // global sort of issues array
1044        $sort_key = $this->itl_sort;
1045        $issues = $this->_issues_globalsort($issues, $sort_key);
1046        // global sort of issues array
1047        $sort_key = $this->itl_sort;
1048        $issues = $this->_issues_globalsort($issues, $sort_key);
1049        //
1050        $dynatable_id = "t_".uniqid((double)microtime()*1000000,1);
1051
1052        if ($start>count($issues)) $start=count($issues)-$step;
1053        if(array_key_exists('userinfo', $user_grp))
1054        {
1055            foreach ($user_grp['userinfo']['grps'] as $ugrp)
1056            {
1057                $user_grps = $user_grps . $ugrp;
1058            }
1059        }
1060        else
1061        {   $user_grps = 'all';  }
1062
1063        $ret = '<br /><br /><form class="issuetracker__form2" method="post" action="'.$_SERVER['REQUEST_URI'].'" accept-charset="'.$lang['encoding'].'"><p>';
1064        $ret .= formSecurityToken(false).'<input type="hidden" name="do" value="show" />';
1065
1066        // the user maybe member of different user groups
1067        // check if one of its assigned groups match with configuration
1068        $allowed_users = explode('|', $this->getConf('assign'));
1069        $cFlag = false;
1070        foreach ($allowed_users as $w)
1071        { // check if one of the assigned user roles does match with current user roles
1072
1073            if (strpos($user_grps,$w)!== false)
1074            {   $cFlag = true;
1075                break;  }
1076        }
1077        // members of defined groups allowed $user_grps changing issue contents
1078        if (($cFlag === true) || ($this->getConf('registered_users')== 0))
1079        {
1080            if(($this->getConf('multi_projects')!==0) && ($this->getConf('shw_project_col')!==0)) { $th_project = "<th id='project'>".$this->getLang('th_project')."</th>"; }
1081            $head = "<div class='itl__table'><table id='".$dynatable_id."' class='sortable editable resizable inline' width='100%'>".NL.
1082                    "<thead><tr>".NL.
1083                     $th_project.NL.
1084                    "<th class='".$this->getConf('listview_sort')."' id='id'>".$this->getLang('th_id')."</th>".NL.
1085                    "<th id='created'>"   .$this->getLang('th_created')   ."</th>".NL.
1086                    "<th id='product'>"   .$this->getLang('th_product')   ."</th>".NL.
1087                    "<th id='version'>"   .$this->getLang('th_version')   ."</th>".NL.
1088                    "<th id='severity'>"  .$this->getLang('th_severity')  ."</th>".NL.
1089                    "<th id='status'>"    .$this->getLang('th_status')    ."</th>".NL.
1090                    "<th id='user_name'>" .$this->getLang('th_user_name')  ."</th>".NL.
1091                    "<th id='title'>"     .$this->getLang('th_title')     ."</th>".NL.
1092                    "<th id='assigned'>"  .$this->getLang('th_assigned')  ."</th>".NL.
1093                    "<th id='resolution'>".$this->getLang('th_resolution')."</th>".NL.
1094                    "<th id='modified'>"  .$this->getLang('th_modified')  ."</th>".NL.
1095                    "</tr></thead>".NL;
1096            $body = '<tbody>'.NL;
1097
1098            // Note: The checked attribute is a boolean attribute.
1099            // It is enough if checked is mentioned to hook the checkbox !
1100            if($filter['myissues'] == '') { $filter['myissues'] = false; }
1101            else { $filter['myissues'] = true; }
1102            $max_vissible = $step;
1103
1104            for ($i=$next_start-1;$i>=0;$i=$i-1)
1105            {   // check start and end of rows to be displayed
1106                if($i>count($issues)) break;  // prevent the php-warning
1107                if(count($issues)> $i) {
1108                    $issue = $issues[$i];
1109                    $a_project    = strtolower($this->_get_one_value($issue,'project'));
1110                    $a_status     = strtolower($this->_get_one_value($issue,'status'));
1111                    $a_severity   = strtolower($this->_get_one_value($issue,'severity'));
1112                    $a_product    = strtoupper($this->_get_one_value($issue,'product'));
1113                    $a_version    = strtoupper($this->_get_one_value($issue,'version'));
1114                    $a_component  = strtoupper($this->_get_one_value($issue,'component'));
1115                    $a_tblock     = strtoupper($this->_get_one_value($issue,'tblock'));
1116                    $a_assignee   = strtoupper($this->_get_one_value($issue,'assignee'));
1117                    $a_reporter   = strtoupper($this->_get_one_value($issue,'user_name'));
1118
1119                    if ((($filter['status']    =='ALL') || (stristr($filter['status'],$a_status)          != false)) &&
1120                        (($filter['severity']  =='ALL') || (stristr($filter['severity'],$a_severity)      != false)) &&
1121                        (($filter['product']   =='ALL') || (stristr($filter['product'],$a_product)        != false)) &&
1122                        (($filter['version']   =='ALL') || (stristr($filter['version'],$a_version)        != false)) &&
1123                        (($filter['component'] =='ALL') || (stristr($filter['component'],$a_component)    != false)) &&
1124                        (($filter['assignee']  =='ALL') || (stristr($filter['assignee'],$a_assignee)      != false)) &&
1125                        (($filter['reporter']  =='ALL') || (stristr($filter['reporter'],$a_reporter)      != false)) &&
1126                        (($filter['tblock']  == false)   || (($a_tblock != false) && ($filter['tblock'] == true))) &&
1127                        (($data['myissues']  == false  ) || ($this->_find_myissues($issue, $user_grp) == true)))
1128                   {
1129
1130                        if ($y>=$step) break;
1131                        if ((stripos($this->getConf('status_special'),$a_status) !== false) && (stripos($filter['status'],$this->getConf('status_special')) === false)) continue;
1132                        $y=$y+1;
1133                        // check if status image or text to be displayed
1134                        if ($noStatIMG == false) {
1135                            $status_img = $imgBASE . implode('', explode(' ',$this->img_name_encode($a_status))).'.gif';
1136//                          if(!file_exists(str_replace("//", "/", DOKU_INC.$status_img)))  { $status_img = $imgBASE . 'status.gif' ;}
1137                            $status_img ='  class="it_center"><span style="display : none;">'.$a_status.'</span><img border="0" alt="'.$a_status.'" title="'.$a_status.'" style="margin-right:0.5em" vspace="1" align="middle" src="'.$status_img.'" width="16" height="16">';
1138                        }
1139                        else { $status_img = $style.strtoupper($a_status); }
1140                        // check if severity image or text to be displayed
1141                        if ($noSevIMG == false) {
1142                            $severity_img = $imgBASE . implode('', explode(' ',$this->img_name_encode($a_severity))).'.gif';
1143
1144//                          if(!file_exists(str_replace("//", "/", DOKU_INC.$severity_img)))  { $severity_img = $imgBASE . 'status.gif' ;}
1145                            $severity_img ='  class="it_center"><span style="display : none;">'.$a_severity.'</span><img border="0" alt="'.$a_severity.'" title="'.$a_severity.'" style="margin-right:0.5em" vspace="1" align="middle" src="'.$severity_img.'" width="16" height="16">';
1146                        }
1147                        else { $severity_img = $style.strtoupper($a_severity); }
1148
1149
1150                        $it_issue_username = $this->_get_one_value($issue,'user_name');
1151                        $a_project = $this->_get_one_value($issue,'project');
1152                        if(($this->getConf('multi_projects')!==0) && ($this->getConf('shw_project_col')!==0))
1153                        {   $td_project = '<td class="itl__td_standard">'.$a_project.'</td>'; }
1154                        elseif($this->getConf('multi_projects')!==0)
1155                        {   $td_project = ""; }
1156
1157                        // build parameter for $_GET method
1158//                            $pstring = sprintf("showid=%s&amp;project=%s", urlencode($this->_get_one_value($issue,'id')), urlencode($this->_get_one_value($issue,'project')));
1159                            $pstring = sprintf("showid=%s&amp;project=%s", urlencode($this->_get_one_value($issue,'id')), urlencode($a_project));
1160                            $itl_item_title = '<a href="doku.php?id='.$ID.'&do=showcaselink&'.$pstring.'" title="'.$this->_get_one_value($issue,'title').'">'.$this->_get_one_value($issue,'title').'</a>';
1161
1162                    if((($this->getConf('multi_projects')!==0) && ($this->getConf('shw_project_col')!==0)) || $project == $a_project  )
1163                    {   if($rowEven==="it_roweven") $rowEven="it_rowodd";
1164                        else $rowEven="it_roweven";
1165                        $body .= '<tr id = "'.$a_project.' '.$this->_get_one_value($issue,'id').'" class="'.$rowEven.'" >'.NL.
1166                                  $td_project.NL.
1167                                 '<td class="itl__td_standard">'.$this->_get_one_value($issue,'id').'</td>'.NL.
1168                                 '<td class="itl__td_date">'.date($this->getConf('d_format'),strtotime($this->_get_one_value($issue,'created'))).'</td>'.NL.
1169                                 '<td class="itl__td_standard">'.$this->_get_one_value($issue,'product').'</td>'.NL.
1170                                 '<td class="itl__td_standard">'.$this->_get_one_value($issue,'version').'</td>'.NL.
1171                                 '<td'.$severity_img.'</td>'.NL.
1172                                 '<td'.$status_img.'</td>'.NL.
1173                                 '<td class="canbreak itl__td_standard"><a href="mailto:'.$this->_get_one_value($issue,'user_mail').'">'.$it_issue_username.'</a></td>'.NL.
1174                                 '<td class="canbreak itl__td_standard">'.$itl_item_title.'</td>'.NL;
1175
1176                        // check how the assignee to be displayed: login, name or mail
1177                        $a_display = $this->_get_assignee($issue,'assigned');
1178                        $body .= '<td class="canbreak itl__td_standard"><a href="mailto:'.$this->_get_one_value($issue,'assigned').'">'.$a_display.'</a></td>'.NL.
1179                                 '<td class="canbreak itl__td_standard">'.$this->xs_format($this->_get_one_value($issue,'resolution')).'</td>'.NL.
1180                                 '<td class="itl__td_date">'.date($this->getConf('d_format'),strtotime($this->_get_one_value($issue,'modified'))).'</td>'.NL.
1181                                 '</tr>'.NL;
1182                    }
1183                  }
1184                }
1185            }
1186            $body .= '</tbody></table></div>';
1187        }
1188        else
1189        {
1190            //Build table header according settings or syntax
1191            if(strlen($this->it_th_cols)>0) {
1192              $configs = explode(',', strtolower($this->it_th_cols));
1193            }
1194            else {
1195              $configs = explode(',', $this->getConf('shwtbl_usr')) ;
1196            }
1197            if(($this->getConf('multi_projects')!==0) && ($this->getConf('shw_project_col')!==0))
1198            { $th_project = "<th id='project'>".$this->getLang('th_project')."</th>"; }
1199
1200            $reduced_header ='';
1201            $reduced_header = "<div class='itl__table'><table id='".$dynatable_id."' class='sortable resizable inline' width='100%'>".NL.
1202                    "<thead><tr>".NL.$th_project.NL."<th class='".$this->getConf('listview_sort')."' id='id'>".$this->getLang('th_id')."</th>".NL;
1203
1204            foreach ($configs as $config)
1205            {
1206                $reduced_header .= "<th id='".$config."'>".$this->getLang('th_'.$config)."</th>".NL;
1207            }
1208
1209            $reduced_header .= "</tr></thead>".NL;
1210
1211            //Build rows according settings
1212            $reduced_issues='';
1213            for ($i=$next_start-1;$i>=0;$i=$i-1)
1214            {   // check start and end of rows to be displayed
1215                if($i>count($issues)) break;  // prevent the php-warning
1216                if(count($issues)> $i) {
1217                        $issue = $issues[$i];
1218                        $a_project    = strtolower($this->_get_one_value($issue,'project'));
1219                        $a_status     = strtoupper($this->_get_one_value($issue,'status'))   ;
1220                        $a_severity   = strtoupper($this->_get_one_value($issue,'severity')) ;
1221                        $a_product    = strtoupper($this->_get_one_value($issue,'product'))  ;
1222                        $a_version    = strtoupper($this->_get_one_value($issue,'version'))  ;
1223                        $a_component  = strtoupper($this->_get_one_value($issue,'component'));
1224                        $a_tblock     = strtoupper($this->_get_one_value($issue,'tblock'))   ;
1225                        $a_assignee   = strtoupper($this->_get_one_value($issue,'assignee')) ;
1226                        $a_reporter   = strtoupper($this->_get_one_value($issue,'user_name'));
1227
1228                    if ((($filter['status']    =='ALL') || (stristr($filter['status'],$a_status)          != false)) &&
1229                        (($filter['severity']  =='ALL') || (stristr($filter['severity'],$a_severity)      != false)) &&
1230                        (($filter['product']   =='ALL') || (stristr($filter['product'],$a_product)        != false)) &&
1231                        (($filter['version']   =='ALL') || (stristr($filter['version'],$a_version)        != false)) &&
1232                        (($filter['component'] =='ALL') || (stristr($filter['component'],$a_component)    != false)) &&
1233                        (($filter['assignee']  =='ALL') || (stristr($filter['assignee'],$a_assignee)      != false)) &&
1234                        (($filter['reporter']  =='ALL') || (stristr($filter['reporter'],$a_reporter)      != false)) &&
1235                        (($filter['tblock']  == false)   || (($a_tblock != false) && ($filter['tblock'] == true))) &&
1236                        (($data['myissues']  == false  ) || ($this->_find_myissues($issue, $user_grp) == true)))
1237                    {
1238
1239                        if ((stripos($this->getConf('status_special'),$a_status) !== false) && (stripos($filter['status'],$this->getConf('status_special')) === false)) continue;
1240
1241                        if($this->getConf('multi_projects')!==0 || $project == $a_project  )
1242                        {     if ($y>=$step) break;
1243                              $y=$y+1;
1244
1245                              if($rowEven==="it_roweven") $rowEven="it_rowodd";
1246                              else $rowEven="it_roweven";
1247
1248                              $reduced_issues = $reduced_issues.'<tr id = "'.$a_project.' '.$this->_get_one_value($issue,'id').'" class="'.$rowEven.'" >'.
1249                                                                '<td'.$style.$this->_get_one_value($issue,'id').'</td>';
1250                              foreach ($configs as $config)
1251                              {
1252                                  $isval = $this->_get_one_value($issue,strtolower($config));
1253                                  // check if status image or text to be displayed
1254                                  if ($config == 'status')
1255                                  {
1256                                      if ($noStatIMG == false) {
1257                                          $status_img = $imgBASE . implode('', explode(' ',$this->img_name_encode($isval))).'.gif';
1258                                          $reduced_issues .='<td  class="it_center"><span style="display : none;">'.$a_status.'</span><img border="0" alt="'.$isval.'" title="'.$isval.'" style="margin-right:0.5em" vspace="1" align="middle" src="'.$status_img.'" width="16" height="16"></td>';
1259                                      }
1260                                      else { $reduced_issues .= '<td'.$style.$isval; }
1261                                  }
1262                                  // check if severity image or text to be displayed
1263                                  elseif ($config == 'severity')
1264                                  {
1265                                      if ($noSevIMG == false) {
1266                                          $severity_img = $imgBASE . implode('', explode(' ',$this->img_name_encode($isval))).'.gif';
1267                                          $reduced_issues .='<td  class="it_center"><span style="display : none;">'.$a_severity.'</span><img border="0" alt="'.$isval.'" title="'.$isval.'" style="margin-right:0.5em" vspace="1" align="middle" src="'.$severity_img.'" width="16" height="16"></td>';
1268                                      }
1269                                      else { $reduced_issues .= '<td'.$style.$isval.'</td>'; }
1270                                  }
1271                                  elseif ($config == 'title')
1272                                  {   // build parameter for $_GET method
1273          //                            $pstring = sprintf("showid=%s&amp;project=%s", urlencode($this->_get_one_value($issue,'id')), urlencode($this->_get_one_value($issue,'project')));
1274                                      $pstring = sprintf("showid=%s&amp;project=%s", urlencode($this->_get_one_value($issue,'id')), $a_project);
1275                                      $reduced_issues .='<td>'.
1276                                                        '<a href="doku.php?id='.$ID.'&do=showcaselink&'.$pstring.'" title="'.$isval.'">'.$isval.'</a></td>';
1277                                  }
1278                                  elseif ($config == 'created')
1279                                  {   $reduced_issues .='<td class="itl__td_date">'.date($this->getConf('d_format'),strtotime($this->_get_one_value($issue,'created'))).'</td>'.NL;
1280                                  }
1281                                  elseif ($config == 'modified')
1282                                  {   $reduced_issues .='<td class="itl__td_date">'.date($this->getConf('d_format'),strtotime($this->_get_one_value($issue,'modified'))).'</td>'.NL;
1283                                  }
1284                                  elseif ($config == 'resolution')
1285                                  {   $reduced_issues .='<td class="canbreak itl__td_standard">'.$this->xs_format($this->_get_one_value($issue,'resolution')).'</td>'.NL;
1286                                  }
1287                                  elseif ($config == 'description')
1288                                  {   $reduced_issues .='<td class="canbreak itl__td_standard">'.$this->xs_format($this->_get_one_value($issue,'description')).'</td>'.NL;
1289                                  }
1290                                  else
1291                                  {   $reduced_issues .= '<td'.$style.$isval.'</td>';
1292                                  }
1293                              }
1294                              $reduced_issues .= '</tr>';
1295                          }
1296                    }
1297                }
1298            }
1299
1300            $head = NL.$reduced_header.NL;
1301            $body = '<tbody>'.$reduced_issues.'</tbody></table></div>';
1302        }
1303
1304        if ($filter['product']==="") {$filter['product']='ALL';}
1305
1306            if($i<=0)
1307            {    $next_start = count($issues);
1308                 $start = $next_start - $step;
1309                 if($start<0) $start=0;
1310            }
1311            else {
1312                $start = $i;
1313                $next_start = $start + $step;
1314                if($next_start>count($issues)) $next_start = count($issues);
1315            }
1316// -----------------------------------------------------------------------------
1317// Control render
1318        if($this->itl_myis==false)  { $filter['myissues'] = ''; }
1319        else {$filter['myissues'] = "checked='true'";}
1320
1321        if($this->itl_block==false) { $filter['tblock'] = ''; }
1322        else $filter['tblock'] = "checked='true'";
1323
1324        $a_result = $this->_count_render($issues,$start,$step,$next_start,$filter,$project);
1325        $li_count =$a_result[1];
1326        $count = $a_result[0];
1327
1328        $ret = '<div>'.NL.
1329               '<script  type="text/javascript">'.NL.
1330               '        function changeAction(where) {'.NL.
1331               '           if(where==1) {'.NL.
1332               '              document.forms["myForm"].action = "doku.php?id=' . $ID . '&do=issuelist_previous";'.NL.
1333               '           }'.NL.
1334               '           else if(where==2){'.NL.
1335               '              document.forms["myForm"].action = "doku.php?id=' . $ID . '&do=issuelist_next";'.NL.
1336               '           }'.NL.
1337               '           else if(where==3){'.NL.
1338               '              document.forms["myForm"].action = "doku.php?id=' . $ID . '&do=issuelist_filter";'.NL.
1339               '           }'.NL.
1340               '           document.forms["myForm"].submit();'.NL.
1341               '        }'.NL.
1342               '     </script>'.NL.
1343               '<table class="itl__t1"><tbody>'.NL.
1344               '<tr class="itd__tables_tr">'.NL.
1345                  '<td colspan="4" align="left" valign="middle" height="40">'.NL.
1346                      '<label class="it__cir_projectlabel">'.sprintf($this->getLang('lbl_issueqty'),$project).$count.'</label>'.NL.
1347                  '</td>'.NL.
1348                  '<td class="itl__showdtls" rowspan="2" width="35%">'.$li_count.'</td>'.NL.
1349               '</tr>'.NL.
1350
1351               '<tr class="itd__tables_tr">'.NL.
1352               '   <td align ="left" valign="top" width="15%">'.NL;
1353
1354               $ret .= '   <p class="it__cir_projectlabel">'.'<label for="itl_step"           style="align:left;">'.$this->getLang('lbl_scroll')                                                 .'</label><br />'.NL;
1355                   if(stripos($this->getConf('ltdListFilters'),'Filter Severity')=== false)      $ret .= '<label for="itl_sev_filter"   style="align:left;">'.$this->getLang('lbl_filtersev')     .'</label><br />'.NL;
1356                   if(stripos($this->getConf('ltdListFilters'),'Filter Status')=== false)        $ret .= '<label for="itl_stat_filter"  style="align:left;">'.$this->getLang('lbl_filterstat')    .'</label><br />'.NL;
1357               $ret .= '</p><p class="it__cir_projectlabel">'.NL;
1358                   if(stripos($this->getConf('ltdListFilters'),'Filter Product')=== false)       $ret .= '<label for="itl__prod_filter" style="align:left;">'.$this->getLang('lbl_filterprod')    .'</label><br />'.NL;
1359                   if(stripos($this->getConf('ltdListFilters'),'Filter Version')=== false)       $ret .= '<label for="itl__vers_filter" style="align:left;">'.$this->getLang('lbl_filtervers')    .'</label><br />'.NL;
1360                   if(stripos($this->getConf('ltdListFilters'),'Filter Component')=== false)     $ret .= '<label for="itl__comp_filter" style="align:left;">'.$this->getLang('lbl_filtercomp')    .'</label><br />'.NL;
1361               $ret .= '</p><p class="it__cir_projectlabel">'.NL;
1362                   if(stripos($this->getConf('ltdListFilters'),'Filter Test blocking')=== false) $ret .= '<label for="itl__block_filter" style="align:left;">'.$this->getLang('lbl_filterblock')  .'</label><br />'.NL;
1363                   if(stripos($this->getConf('ltdListFilters'),'Filter Assignee')=== false)      $ret .= '<label for="itl__assi_filter" style="align:left;">'.$this->getLang('lbl_filterassi')    .'</label><br />'.NL;
1364                   if(stripos($this->getConf('ltdListFilters'),'Filter Reporter')=== false)      $ret .= '<label for="itl__user_filter" style="align:left;">'.$this->getLang('lbl_filterreporter').'</label><br />'.NL;
1365               $ret .= '</p><p class="it__cir_projectlabel">'.NL;
1366                   if(stripos($this->getConf('ltdListFilters'),'MyIssues')=== false)             $ret .= '<label for="itl_myis_filter"  style="align:left;">'.$this->getLang('cbx_myissues')      .'</label><br />'.NL;
1367                   if(stripos($this->getConf('ltdListFilters'),'Sort by')=== false)              $ret .= '<label for="it_glbl_sort"     style="align:left;">'.$this->getLang('lbl_sort')          .'</label>'.NL;
1368               $ret .= '</p></td>'.NL;
1369
1370               $ret .= '   <td align ="left" valign="top" width="20%">'.NL.
1371               '    <form name="myForm" action="" method="post">'.NL.
1372               '       <input                          type="hidden" name="itl_start"        id="itl_start"        value="'.$start.'"/>'.NL.
1373               '       <input                          type="hidden" name="itl_step"         id="itl_step"         value="'.$step.'"/>'.NL.
1374               '       <input                          type="hidden" name="itl_next"         id="itl_next"         value="'.$next_start.'"/>'.NL.
1375               '       <input                          type="hidden" name="itl_project"      id="itl_project"      value="'.$project.'"/>'.NL.
1376               '       <input                          type="hidden" name="it_th_cols"       id="it_th_cols"       value="'.$data['columns'].'"/>'.NL.
1377               '       <input class="itl__buttons"     type="button" name="showprevious"                           value="'.$this->getLang('btn_previuos').'" title="'.$this->getLang('btn_previuos_title').'" onClick="changeAction(1)"/>'.NL.
1378               '       <input class="itl__step_input"  type="text"   name="itl_step"         id="itl_step"         value="'.$step.'"/>'.NL.
1379               '       <input class="itl__buttons"     type="button" name="shownext"                               value="'.$this->getLang('btn_next').'"     title="'.$this->getLang('btn_next_title').'"     onClick="changeAction(2)"/><p>'.NL;
1380
1381                   if(stripos($this->getConf('ltdListFilters'),'Filter Severity')=== false)      $ret .= '<input class="itl__sev_filter"  type="text"      name="itl_sev_filter"   id="itl_sev_filter"   value="'.$filter['severity'].'"/><br />'.NL;
1382                   if(stripos($this->getConf('ltdListFilters'),'Filter Status')=== false)        $ret .= '<input class="itl__stat_filter" type="text"      name="itl_stat_filter"  id="itl_stat_filter"  value="'.$filter['status'].'"/><br />'.NL;
1383               $ret .= '</p><p>'.NL;
1384                   if(stripos($this->getConf('ltdListFilters'),'Filter Product')=== false)       $ret .= '<input class="itl__prod_filter" type="text"      name="itl__prod_filter" id="itl__prod_filter" value="'.$filter['product'].'"/><br />'.NL;
1385                   if(stripos($this->getConf('ltdListFilters'),'Filter Version')=== false)       $ret .= '<input class="itl__prod_filter" type="text"      name="itl__vers_filter" id="itl__vers_filter" value="'.$filter['version'].'"/><br />'.NL;
1386                   if(stripos($this->getConf('ltdListFilters'),'Filter Component')=== false)     $ret .= '<input class="itl__prod_filter" type="text"      name="itl__comp_filter" id="itl__comp_filter" value="'.$filter['component'].'"/><br />'.NL;
1387               $ret .= '</p><p>'.NL;
1388                   if(stripos($this->getConf('ltdListFilters'),'Filter Test blocking')=== false) $ret .= '<input                          type="checkbox"  name="itl__block_filter" id="itl__block_filter" '     .$filter['tblock'].' " /><br />'.NL;
1389                   if(stripos($this->getConf('ltdListFilters'),'Filter Assignee')=== false)      $ret .= '<input class="itl__prod_filter" type="text"      name="itl__assi_filter" id="itl__assi_filter" value="'.$filter['assignee'].'"/><br />'.NL;
1390                   if(stripos($this->getConf('ltdListFilters'),'Filter Reporter')=== false)      $ret .= '<input class="itl__prod_filter" type="text"      name="itl__user_filter" id="itl__user_filter" value="'.$filter['reporter'].'"/><br />'.NL;
1391               $ret .= '</p><p>'.NL;
1392                   if(stripos($this->getConf('ltdListFilters'),'MyIssues')=== false)             $ret .= '<input                          type="checkbox"  name="itl_myis_filter" id="itl_myis_filter" '         .$filter['myissues'].' value="'.$filter['myissues'].'" title="'.$this->getLang('cbx_myissues').'"/><br />'.NL;
1393                   if(stripos($this->getConf('ltdListFilters'),'Sort by')=== false)              $ret .= '<input class="itl__sev_filter"  type="text"      name="it_glbl_sort" id="it_glbl_sort" value="'.$glbl_sort.'"/><br />'.NL;
1394               $ret .= '</p><input class="itl__buttons" type="button" name="go" value="'.$this->getLang('btn_go').'" title="'.$this->getLang('btn_go').'" onClick="changeAction(3)"/><br />'.NL;
1395               $ret .= '</form>'.NL.
1396               '   </td>'.NL.
1397               '   <td width="2%">&nbsp;</td>'.NL.
1398               '   <td class="itl__showdtls" align ="left" width="40%">'.NL.
1399               '    <form  method="post" action="doku.php?id=' . $ID . '&do=showcase">'.NL.
1400               '       <label class="it__searchlabel">'.$this->getLang('lbl_showid').'</label>'.NL.
1401               '       <input class="itl__sev_filter"    type="text"   name="showid"          id="showid"          value="0"/>'.NL.
1402               '       <input                            type="hidden" name="project"         id="project"         value="'.$project.'"/>'.NL.
1403               '       <input                            type="hidden" name="itl_sev_filter"  id="itl_sev_filter"  value="'.$filter['severity'].'"/>'.NL.
1404               '       <input                            type="hidden" name="itl_stat_filter" id="itl_stat_filter" value="'.$filter['status'].'"/>'.NL.
1405               '       <input                            type="hidden" name="itl_myis_filter" id="itl_myis_filter" '.$filter['myissues'].' value="'.$filter['myissues'].'"/>'.NL.
1406               '       <input class="itl__showid_button" type="submit" name="showcase"        id="showcase"        value="'.$this->getLang('btn_showid').'"    title="'.$this->getLang('btn_showid_title').'"/>'.NL.
1407               '    </form><br />'.NL.
1408               '    <form  method="post" action="doku.php?id=' . $ID . '&do=it_search">'.NL.
1409               '       <label class="it__searchlabel">'.$this->getLang('lbl_search').'</label>'.NL.
1410               '       <input class="itl__sev_filter"    type="text"   name="it_str_search"   id="it_str_search"   value="'.$search.'"/>'.NL.
1411               '       <input                            type="hidden" name="project"         id="project"         value="'.$project.'"/>'.NL.
1412               '       <input class="itl__search_button" type="submit" name="searchcase"      id="searchcase"      value="'.$this->getLang('btn_search').'" title="'.$this->getLang('btn_search_title').'"/>'.NL.
1413               '    </form>'.NL.
1414               '   </td>'.NL.
1415               '</tr>'.NL.'</tbody>'.NL.'</table>'.NL.'</div>'.NL;
1416
1417         $usr  = '<span style="display:none;" id="currentuser">'.$user_grp['userinfo']['name'].'</span>' ; // to log issue mods
1418         $usr .= '<span style="display:none;" id="currentID">'.urlencode($ID).'</span>' ; // to log issue mods
1419         $a_lang  = '<span style="display:none;" name="table_kit_OK" id="table_kit_OK">'.$this->getLang('table_kit_OK').'</span>'; // for tablekit.js
1420         $a_lang .= '<span style="display:none;" name="table_kit_Cancel" id="table_kit_Cancel">'.$this->getLang('table_kit_Cancel').'</span>'; // for tablekit.js
1421
1422         $ret  = $a_lang.$usr.$ret.$head.$body;
1423        return $ret;
1424    }
1425/******************************************************************************
1426**  Details form
1427*/
1428                       // Array  , project name
1429 function _details_render($issues, $project) {
1430        // load issue details and display on page
1431        global $lang;
1432        global $auth;
1433        global $ID;
1434        $issue_id = $this->parameter;
1435        if (!$issue_id) { $issue_id = '0'; }
1436
1437/*      ------------------------------------------------------------------------
1438 *        introduced due to issue #159
1439 *      ------------------------------------------------------------------------
1440 *      - check ACL of current user for current ID
1441 *        (AUTH_READ permission is necessary at least)
1442 *        return $ret    where $ret is empty and finally no content will be displayed */
1443        if(auth_quickaclcheck($ID)<1) { return $ret; }
1444/*      - ignore function also if page content does not contain the IssueTracker
1445 *        syntax due to the function can be invoked just by action parameters
1446 *        what would bypass the DokuWiki ACL
1447 *        return $ret    where $ret is empty and finally no content will be displayed */
1448        $rawText = rawWiki($ID);
1449        if(stripos($rawText, "{{issuetracker>") == false) { return $ret; }
1450//      ------------------------------------------------------------------------
1451
1452
1453        if ($issue_id === false) return;
1454        $imgBASE = DOKU_BASE."lib/plugins/issuetracker/images/";
1455        $noStatIMG = $this->getConf('noStatIMG');
1456        $noSevIMG = $this->getConf('noSevIMG');
1457//        $user_grp = pageinfo();
1458
1459        // get issues file contents
1460        $issue = $this->get_issues_file_contents($project, $issue_id);
1461        if((!$issue) && (strlen($project)>1)) {
1462          sprintf("showid=%s&amp;project=%s", urlencode($issue[$issue_id]['id']), urlencode($project));
1463          sprintf($this->getLang('msg_inotexisting1'),$project,$issue_id,DOKU_URL,$ID);
1464//          msg("The issue does not exist at the given project. <br /> Project = $project <br /> Issue ID = $issue_id <br /> <a href='".DOKU_URL.'doku.php?id='.$ID."'> << back</a>");
1465          return false;
1466        }
1467        elseif(!$issue) {
1468          msg($this->getLang('msg_issuemissing').$issue_id.'<br /> <a href="'.DOKU_URL.'doku.php?id='.$ID.'"> << back</a>');
1469          return false;
1470        }
1471
1472        // get detail information from issue comment file
1473        if($this->getConf('it_data')==false) $cfile = DOKU_CONF."../data/meta/".$project."_".$issue_id.'.cmnts';
1474        else $cfile = DOKU_CONF."../". $this->getConf('it_data').$project."_".$issue_id.'.cmnts';
1475        if (@file_exists($cfile)) {$comments  = unserialize(@file_get_contents($cfile));}
1476        else {$comments = array();}
1477
1478        $a_severity = $issue[$issue_id]['severity'];
1479        $severity_img = $imgBASE . implode('', explode(' ',$this->img_name_encode($a_severity))).'.gif';
1480        $severity_img =' <img border="0" alt="'.$a_severity.'" title="'.$a_severity.'" style="margin-right:0.5em" vspace="1" align="middle" src="'.$severity_img.'" width="16" height="16"> ';
1481        $a_status = $issue[$issue_id]['status'];
1482        $status_img = $imgBASE . implode('', explode(' ',$this->img_name_encode($a_status))).'.gif';
1483        $status_img =' <img border="0" alt="'.$a_status.'" title="'.$a_status.'" style="margin-right:0.5em" vspace="1" align="middle" src="'.$status_img.'" width="16" height="16"> ';
1484        $a_product = $issue[$issue_id]['product'];
1485
1486        //---------------------------------------------------------------------------------------------------------------------
1487        // do not show personal contact details if issue details not viewed by admin/assignee nor the original reporter itself
1488        //---------------------------------------------------------------------------------------------------------------------
1489        $user_mail = pageinfo();  //to get mail address of reporter
1490        if($this->getConf('auth_ad_overflow') == false) {
1491            $filter['grps']=$this->getConf('assign');
1492            $target = $auth->retrieveUsers(0,0,$filter);
1493            $target2 = $this->array_implode($target);
1494            $target2 = implode($target2);
1495
1496            if((($user_mail['userinfo']['mail'] === $issue[$issue_id]['user_mail']) or
1497                 (strpos($target2,$user_mail['userinfo']['mail']) != false)) &&
1498                ($this->getConf('shw_mail_addr') === 1))
1499            {   $__assigened      = $this->_get_assignee($issue[$issue_id],'assigned');
1500                $__assigenedaddr  = $issue[$issue_id]['assigned'];
1501                $__reportedby     = $issue[$issue_id]['user_name'];
1502                $__reportedbyaddr = $issue[$issue_id]['user_mail'];
1503                $mail_allowed     = true;
1504            }
1505            elseif($user_mail['userinfo']['mail']  === $issue[$issue_id]['assigned'])
1506            {   $__assigenedaddr = $user_mail['userinfo']['mail'];
1507                $__assigened     = $user_mail['userinfo']['name'];
1508                $__reportedby     = $issue[$issue_id]['user_name'];
1509                $__reportedbyaddr = $issue[$issue_id]['user_mail'];
1510                $mail_allowed    = true;
1511            }
1512            else
1513            {   foreach($target as $_assignee)
1514                  { if($_assignee['mail'] === $user_mail['userinfo']['mail'])
1515                    {   $__assigened     = $_assignee['name'];
1516                        $mail_allowed    = false;
1517                        break;
1518                    }
1519                    if($_assignee['mail'] === $issue[$issue_id]['assigned'])
1520                    {   $__assigened     = $_assignee['name'];
1521                        $mail_allowed    = false;
1522                        break;
1523                    }
1524                  }
1525                $__reportedby     = $issue[$issue_id]['user_name'];
1526                $__reportedbyaddr = $issue[$issue_id]['user_mail'];
1527            }
1528        }
1529        else {  // auth_ad_overflow = true
1530                $__assigened      = $this->_get_assignee($issue[$issue_id],'assigned');
1531                $__assigenedaddr  = $issue[$issue_id]['assigned'];
1532
1533                if($this->getConf('shw_mail_addr') === 1) { $__reportedby = $issue[$issue_id]['user_mail']; }
1534                else                                      { $__reportedby = $issue[$issue_id]['user_name']; }
1535
1536                $__reportedbyaddr = $issue[$issue_id]['user_mail'];
1537                $mail_allowed     = true;
1538        }
1539
1540// scripts for xsEditor -------------------------------------------------------
1541$issue_edit_head .= '<span>
1542         <script type="text/javascript">
1543          function resizeBoxId(obj,size) {
1544              var arows = document.getElementById(obj).rows;
1545              document.getElementById(obj).rows = arows + size;
1546          }
1547
1548          function doHLine(tag1,obj)
1549          {
1550          textarea = document.getElementById(obj);
1551          	// Code for IE
1552          		if (document.selection)
1553          			{
1554          				textarea.focus();
1555          				var sel = document.selection.createRange();
1556          				//alert(sel.text);
1557          				sel.text = tag1 + sel.text;
1558          			}
1559             else
1560              {  // Code for Mozilla Firefox
1561          		var len = textarea.value.length;
1562          	  var start = textarea.selectionStart;
1563          		var end = textarea.selectionEnd;
1564
1565          		var scrollTop = textarea.scrollTop;
1566          		var scrollLeft = textarea.scrollLeft;
1567
1568                  var sel = textarea.value.substring(start, end);
1569          	      //alert(sel);
1570          		    var rep = tag1 + sel;
1571                  textarea.value =  textarea.value.substring(0,start) + rep + textarea.value.substring(end,len);
1572
1573          		textarea.scrollTop = scrollTop;
1574          		textarea.scrollLeft = scrollLeft;
1575          	}
1576          }
1577
1578          function doAddTags(tag1,tag2,obj)
1579          {
1580          textarea = document.getElementById(obj);
1581          	// Code for IE
1582          		if (document.selection)
1583          			{
1584          				textarea.focus();
1585          				var sel = document.selection.createRange();
1586          				//alert(sel.text);
1587          				sel.text = tag1 + sel.text + tag2;
1588          			}
1589             else
1590              {  // Code for Mozilla Firefox
1591          		var len = textarea.value.length;
1592          	    var start = textarea.selectionStart;
1593          		var end = textarea.selectionEnd;
1594
1595          		var scrollTop = textarea.scrollTop;
1596          		var scrollLeft = textarea.scrollLeft;
1597
1598                  var sel = textarea.value.substring(start, end);
1599          	    //alert(sel);
1600          		var rep = tag1 + sel + tag2;
1601                  textarea.value =  textarea.value.substring(0,start) + rep + textarea.value.substring(end,len);
1602
1603          		textarea.scrollTop = scrollTop;
1604          		textarea.scrollLeft = scrollLeft;
1605          	}
1606          }
1607
1608          function doList(tag1,tag2,obj){
1609          textarea = document.getElementById(obj);
1610
1611          // Code for IE
1612          		if (document.selection)
1613          			{
1614          				textarea.focus();
1615          				var sel = document.selection.createRange();
1616          				var list = sel.text.split("\n");
1617
1618          				for(i=0;i<list.length;i++)
1619          				{
1620          				list[i] = "[li]" + list[i] + "[/li]";
1621          				}
1622          				sel.text = tag1 + "\n" + list.join("\n") + "\n" + tag2;
1623
1624          			} else
1625          			// Code for Firefox
1626          			{
1627
1628          		var len = textarea.value.length;
1629          	  var start = textarea.selectionStart;
1630          		var end = textarea.selectionEnd;
1631          		var i;
1632
1633          		var scrollTop = textarea.scrollTop;
1634          		var scrollLeft = textarea.scrollLeft;
1635
1636              var sel = textarea.value.substring(start, end);
1637      	      //alert(sel);
1638
1639          		var list = sel.split("\n");
1640
1641          		for(i=0;i<list.length;i++)
1642          		{
1643          		list[i] = "[li]" + list[i] + "[/li]";
1644          		}
1645
1646          		var rep = tag1 + "\n" + list.join("\n") + "\n" +tag2;
1647          		textarea.value =  textarea.value.substring(0,start) + rep + textarea.value.substring(end,len);
1648
1649          		textarea.scrollTop = scrollTop;
1650          		textarea.scrollLeft = scrollLeft;
1651           }
1652          }
1653          function save_addinfo(){
1654            var a=0;
1655
1656          }
1657          </script></span>'.NL;
1658
1659$issue_edit_head .= '<span>
1660        <script type="text/javascript">
1661             function tab_open(blink_id, cell_ID)
1662              {   if (document.getElementById(blink_id).style.display == "block")
1663                  {   document.getElementById(blink_id).style.display = "none";
1664                      document.getElementById(cell_ID).style.backgroundPosition = "0px 0px";
1665                  }
1666                  else
1667                  {   document.getElementById(blink_id).style.display = "block";
1668                      document.getElementById(cell_ID).style.backgroundPosition = "0px -19px";
1669                  }
1670              }
1671             function span_open(blink_id)
1672              {   if (document.getElementById(blink_id).style.display == "block")
1673                  {   document.getElementById(blink_id).style.display = "none";
1674                  }
1675                  else
1676                  {   document.getElementById(blink_id).style.display = "block";
1677                  }
1678              }
1679        </script></span>'.NL;
1680
1681//--------------------------------------
1682// Tables for the Issue details view:
1683//--------------------------------------
1684$issue_edit_head .= '<script>
1685                      function updSeverity()
1686                      {   document.getElementById("severity").style.display="none";
1687                          document.getElementById("frm_severity").style.display="inline"; }
1688
1689                      function updStatus()
1690                      {   document.getElementById("status").style.display="none";
1691                          document.getElementById("frm_status").style.display="inline"; }
1692                    </script>';
1693
1694$issue_edit_head .= '<table class="itd__title" style="margin-bottom:0;">'.
1695                   '<tr>
1696                      <td colSpan="6" >
1697                      <p>
1698                        <font size="1"><i>&nbsp['.$issue[$issue_id]['id'].']&nbsp;&nbsp;</i></font>
1699                        <font size="3" color=#00008f>'.
1700                          '<b><i><h class="itd_formtitle">'.$issue[$issue_id]['title'].'</h></i></b>
1701                        </FONT>
1702                      </p>
1703                      </td>
1704                    </tr>'.
1705
1706                   '<tbody class="itd__details">'.
1707
1708                   '<tr class="itd_tr_standard">
1709                      <td class="it__left_indent"></td>
1710                      <td class="itd__col2">'.$this->getLang('lbl_reporter').'</td>'.NL;
1711
1712if(($user_mail['userinfo']['mail'] === $issue[$issue_id]['user_mail']) or (strpos($target2,$user_mail['userinfo']['mail']) != false) or ($this->getConf('registered_users')=== 0))
1713{$allowedUser = true;}
1714
1715if($allowedUser == true)
1716                        {$issue_edit_head .= '<td class="itd__col3"><a href="mailto:'.$__reportedbyaddr.'">'.$__reportedby.'</a></td>'.NL;}
1717else{$issue_edit_head .= '<td class="itd__col3">'.$__reportedby.'</td>'.NL;}
1718
1719$issue_edit_head .= '<td class="itd__col4"></td>
1720                      <td class="itd__col5">'.$this->getLang('th_created').':</td>
1721                      <td class="itd__col6">'.date($this->getConf('d_format'),strtotime($issue[$issue_id]['created'])).'</td>
1722                    </tr>'.
1723
1724                    '<tr class="itd_tr_standard">
1725                      <td class="it__left_indent"></td>
1726                      <td class="itd__col2">'.$this->getLang('th_assigned').':</td>'.NL;
1727if($allowedUser == true)
1728                        {$issue_edit_head .= '<td class="itd__col3"><a href="mailto:'.$__assigenedaddr.'">'.$__assigened.'</a></td>'.NL;}
1729else{$issue_edit_head .= '<td class="itd__col3">'.$__assigened.'</td>'.NL;}
1730
1731$issue_edit_head .= '<td class="itd__col4"></td>
1732                      <td class="itd__col5">'.$this->getLang('th_modified').':</td>
1733                      <td class="itd__col6">'.date($this->getConf('d_format'),strtotime($issue[$issue_id]['modified'])).'</td>
1734                    </tr>'.
1735
1736                   '<tr class="itd_tr_standard">
1737                      <td class="it__left_indent"></td>
1738                      <td class="itd__col2">'.$this->getLang('th_severity').':</td>
1739                      <td class="itd__col3"><span id="severity"';
1740
1741// --- #132 Feature Request: severity should be modifiable by admin/assignee ---
1742                      // check if current user is admin/assignee
1743                      if(strpos($target2,$user_mail['userinfo']['mail']) != false) {
1744$issue_edit_head .= ' onClick="updSeverity()">'.$severity_img.$issue[$issue_id]['severity'].'</span>'.NL;
1745                        // Build string to load severity select
1746                        $severity = explode(',', $this->getConf('severity')) ;
1747                        foreach ($severity as $x_severity)
1748                        {   $x_severity = trim($x_severity);
1749                            if(stripos($issue[$issue_id]['severity'],$x_severity) !==false) $x_severity_select = $x_severity_select . '<option selected="selected" style="color: blue;" value="'.$x_severity.'">'.$x_severity.'</option>';
1750                            else $x_severity_select = $x_severity_select . '<option value="'.$x_severity.'">'.$x_severity.'</option>'; }
1751
1752                      // built hidden form with select box of configured severity values
1753$issue_edit_head .= '<div class="frm_severity" id="frm_severity" style="display:none !important;">
1754                      <form method="post" accept-charset="'.$lang['encoding'].'>'.
1755                     '<input type="hidden" name="project" value="'.$project.'" />
1756                      <input type="hidden" name="issue_ID" value="'.$issue[$issue_id]['id'].'" />
1757                      <input type="hidden" name="mod_severity" value="1"/>
1758                      <input type="hidden" name="ausr" value="'.$user_mail['userinfo']['name'].'"/>
1759                      <select name="new_severity">'.$x_severity_select.'</select> '.NL;
1760                      if ($this->getConf('use_captcha')==1)
1761                      {   $helper = null;
1762              		        if(@is_dir(DOKU_PLUGIN.'captcha'))
1763              			         $helper = plugin_load('helper','captcha');
1764
1765              		        if(!is_null($helper) && $helper->isEnabled())
1766              			      {  $issue_edit_head .= '<span>'.$helper->getHTML().'</span>'; }
1767                      }
1768$issue_edit_head .= '<input type="submit" class="button" id="btnmod_severity" name="btnmod_severity" value="'.$this->getLang('btn_mod').'" title="'.$this->getLang('btn_mod_title').'");/>'.NL.
1769                      formSecurityToken(false).'</form></div>'.NL;
1770                      }
1771                      else $issue_edit_head .= '">'.$severity_img.$issue[$issue_id]['severity'].'</span>'.NL;
1772
1773$issue_edit_head .= ' </td>
1774                      <td class="itd__col4"></td>
1775                      <td class="itd__col5">'.$this->getLang('lbl_project').'</td>
1776                      <td class="itd__col6">'.$project.'</td>
1777                    </tr>';
1778
1779
1780$issue_edit_head .= '<tr class="itd_tr_standard">
1781                      <td class="it__left_indent"></td>
1782                      <td class="itd__col2">'.$this->getLang('th_status').':</td>
1783                      <td class="itd__col3"><span id="status"';
1784
1785// --- #132 Feature Request: severity should be modifiable by admin/assignee ---
1786                      // check if current user is admin/assignee
1787                      if(strpos($target2,$user_mail['userinfo']['mail']) != false) {
1788$issue_edit_head .= ' onClick="updStatus()">'.$status_img.$issue[$issue_id]['status'].'</span>'.NL;
1789                        // Build string to load severity select
1790                        $status = explode(',', $this->getConf('status')) ;
1791                        foreach ($status as $x_status)
1792                        {   $x_status = trim($x_status);
1793                            if(stripos($issue[$issue_id]['status'],$x_status) !==false) $x_status_select = $x_status_select . '<option selected="selected" style="color: blue;" value="'.$x_status.'">'.$x_status.'</option>';
1794                            else $x_status_select = $x_status_select . '<option value="'.$x_status.'">'.$x_status.'</option>'; }
1795                      // built hidden form with select box of configured status values
1796$issue_edit_head .= '<div class="frm_status" id="frm_status" style="display:none !important;">
1797                      <form method="post" accept-charset="'.$lang['encoding'].'>'.
1798                     '<input type="hidden" name="project" value="'.$project.'" />
1799                      <input type="hidden" name="issue_ID" value="'.$issue[$issue_id]['id'].'" />
1800                      <input type="hidden" name="mod_status" value="1"/>
1801                      <input type="hidden" name="busr" value="'.$user_mail['userinfo']['name'].'"/>
1802                      <select name="new_status">'.$x_status_select.'</select> '.NL;
1803                      if ($this->getConf('use_captcha')==1)
1804                      {   $helper = null;
1805              		        if(@is_dir(DOKU_PLUGIN.'captcha'))
1806              			         $helper = plugin_load('helper','captcha');
1807
1808              		        if(!is_null($helper) && $helper->isEnabled())
1809              			      {  $issue_edit_head .= '<span>'.$helper->getHTML().'</span>'; }
1810                      }
1811$issue_edit_head .= '<input type="submit" class="button" id="btnmod_status" name="btnmod_status" value="'.$this->getLang('btn_mod').'" title="'.$this->getLang('btn_mod_title').'");/>'.NL.
1812                      formSecurityToken(false).'</form></div>'.NL;
1813                      }
1814                      else $issue_edit_head .= '">'.$status_img.$issue[$issue_id]['status'].'</span>'.NL;
1815
1816$issue_edit_head .= ' </td>
1817                      <td class="itd__col4"></td>
1818                      <td class="itd__col5"></td>
1819                      <td class="itd__col6"></td>
1820                    </tr>
1821                    <tr class="itd_tr_standard">
1822                      <tr class="itd_tr_standard">
1823                      <td class="it__left_indent"></td>
1824                      <td class="itd__col2"></td>
1825                      <td class="itd__col3"></td>
1826                      <td class="itd__col4"></td>
1827                      <td class="itd__col5"></td>
1828                      <td class="itd__col6"></td>
1829                    </tr>
1830                    </tbody></table>'.NL;
1831
1832if(($mail_allowed === true) || ($this->getConf('registered_users')=== 0)) {
1833      $issue_edit_head .= '<form name="form77" method="post" accept-charset="'.$lang['encoding'].'">'.NL;
1834      $issue_edit_head .= formSecurityToken(false).
1835                           '<input type="hidden" name="project" value="'.$project.'" />
1836                            <input type="hidden" name="issue_ID" value="'.$issue[$issue_id]['id'].'" />
1837                            <input type="hidden" name="mod_add_data" value="1" />';
1838
1839      if($issue[$issue_id]['dev_start']   !="") $dev_start = date('d.M.Y',strtotime($issue[$issue_id]['dev_start']));
1840      if($issue[$issue_id]['dev_deadline']!="") $deadline  = date('d.M.Y',strtotime($issue[$issue_id]['dev_deadline']));
1841
1842      $issue_edit_head .= '<table class="itd__title" style="margin:0;padding-top: 1px;"><tbody class="itd__details">
1843                          <tr class="itd_tr_standard">
1844                            <td class="it__left_indent" style="margin-top: 3px;"></td>
1845                            <td class="itd__col2" style="padding-top: 3px;">'.$this->getLang('th_product').':</td>
1846                            <td class="itd__col3" style="padding-top: 3px;">'.$issue[$issue_id]['product'].'</td>
1847                            <td class="itd__col4" style="padding-top: 3px;"></td>
1848                            <td class="itd__col5" style="padding-top: 3px;">'.$this->getLang('th_begin').':</td>
1849                            <td class="itd__col6" style="padding-top: 3px;"><input type="text" class="itdtls_txt" name="dev_start" id="dev_start" value="'.$dev_start.'" /></td>
1850                          </tr>';
1851
1852      $issue_edit_head .= '<tr class="itd_tr_standard">
1853                            <td class="it__left_indent"></td>
1854                            <td class="itd__col2">'.$this->getLang('th_version').':</td>
1855                            <td class="itd__col3">'.$issue[$issue_id]['version'].'</td>
1856                            <td class="itd__col4"></td>
1857                            <td class="itd__col5">'.$this->getLang('th_deadline').':</td>
1858                            <td class="itd__col6"><input type="text" class="itdtls_txt" name="dev_deadline" id="dev_deadline" value="'.$deadline.'" /></td>
1859                          </tr>';
1860
1861      $issue_edit_head .= '<tr class="itd_tr_standard">
1862                            <td class="it__left_indent"></td>'.NL;
1863
1864                  /*--------------------------------------------------------------------*/
1865                  // load set of components defined by admin
1866                  /*--------------------------------------------------------------------*/
1867                  $STR_COMPONENTS = "";
1868                  $components = explode(',', $this->getConf('components')) ;
1869                  foreach ($components as $_component)
1870                  {
1871                      $_component = trim($_component);
1872                      if($issue[$issue_id]['component'] !== $_component) {
1873                          $STR_COMPONENTS .= '<option value="'.$_component.'" >'.$_component."</option>".NL;
1874                      }
1875                      else {
1876                          $STR_COMPONENTS .= '<option value="'.$_component.'" selected="selected" >'.$_component."</option>".NL;
1877                      }
1878                  }
1879                  $STR_COMPONENTS = '<option value=""></option>' .NL. $STR_COMPONENTS;
1880
1881      $issue_edit_head .= '
1882                            <td class="itd__col2">Component:</td>
1883                            <td class="itd__col3"><select name="new_component" id="new_component" class="itdtls_select" style="width:17em;font-size:95%">'.$STR_COMPONENTS.'</select></td>
1884                            <td class="itd__col4"></td>
1885                            <td class="itd__col5">'.$this->getLang('th_progress').':</td>
1886                            <td class="itd__col6"><input type="text" class="itdtls_txt" name="dev_progress" id="dev_progress" value="'.$issue[$issue_id]['dev_progress'].'" /></td>
1887                          </tr>'.NL;
1888
1889                          if($issue[$issue_id]['tblock']==false) { $cbx_tblock = ""; }
1890                          else $cbx_tblock = "checked='true'";
1891
1892      $issue_edit_head .= '<tr class="itd_tr_standard">
1893                            <td class="it__left_indent"></td>
1894                            <td class="itd__col2">'.$this->getLang('th_tversion').':</td>
1895                            <td class="itd__col3"><input type="text" class="itdtls_txt" name="trgt_version" id="trgt_version" value="'.$issue[$issue_id]['trgt_version'].'"  /></td>
1896                            <td class="itd__col4"></td>
1897                            <td class="itd__col5"></td>
1898                            <td class="itd__col6"></td>
1899                           </tr>'.NL;
1900      $issue_edit_head .= '<tr class="itd_tr_standard">
1901                            <td class="it__left_indent"></td>
1902                            <td class="itd__col2">'.$this->getLang('th_tblock').':</td>
1903                            <td class="itd__col3"><input type="checkbox" name="itl__block_filter" id="itl__block_filter" '.$cbx_tblock.' />&nbsp</td>
1904                            <td class="itd__col4"></td>
1905                            <td class="itd__col5">
1906                                <input class ="button"
1907                                 style ="font-size:8pt;"
1908                                 id    ="btn_upd_addinfo"
1909                                 name  ="btn_upd_addinfo"
1910                                 type  ="submit"
1911                                 value ="'.$this->getLang('btn_upd_addinfo').'"
1912                                 title ="'.$this->getLang('btn_upd_addinfo').'" />
1913                            </td>
1914                            <td class="itd__col6"></td>
1915                           </tr>
1916                           </table>'.NL;
1917      $issue_edit_head .= '
1918                           </form>'.NL;
1919}
1920else {  // user not allowed to modify the planning data
1921      if($issue[$issue_id]['dev_start']   !="") $dev_start = date('d.M.Y',strtotime($issue[$issue_id]['dev_start']));
1922      if($issue[$issue_id]['dev_deadline']!="") $deadline  = date('d.M.Y',strtotime($issue[$issue_id]['dev_deadline']));
1923
1924        $issue_edit_head .= '<table class="itd__title" style="margin:0;padding-top: 1px;"><tbody class="itd__details">
1925                            <tr class="itd_tr_standard">
1926                              <td class="it__left_indent" style="margin-top: 3px;"></td>
1927                              <td class="itd__col2" style="padding-top: 3px;">'.$this->getLang('th_product').':</td>
1928                              <td class="itd__col3" style="padding-top: 3px;">'.$issue[$issue_id]['product'].'</td>
1929                              <td class="itd__col4" style="padding-top: 3px;"></td>
1930                              <td class="itd__col5" style="padding-top: 3px;">'.$this->getLang('th_begin').':</td>
1931                              <td class="itd__col6" style="padding-top: 3px;">'.$dev_start.'</td>
1932                            </tr>';
1933
1934        $issue_edit_head .= '<tr class="itd_tr_standard">
1935                              <td class="it__left_indent"></td>
1936                              <td class="itd__col2">'.$this->getLang('th_version').':</td>
1937                              <td class="itd__col3">'.$issue[$issue_id]['version'].'</td>
1938                              <td class="itd__col4"></td>
1939                              <td class="itd__col5">'.$this->getLang('th_deadline').':</td>
1940                              <td class="itd__col6">'.$issue[$issue_id]['dev_deadline'].'</td>
1941                            </tr>';
1942
1943        $issue_edit_head .= '<tr class="itd_tr_standard">
1944                              <td class="it__left_indent"></td>
1945                              <td class="itd__col2">'.$this->getLang('th_components').':</td>
1946                              <td class="itd__col3">'.$deadline.'</td>
1947                              <td class="itd__col4"></td>
1948                              <td class="itd__col5">'.$this->getLang('th_progress').':</td>
1949                              <td class="itd__col6">'.$issue[$issue_id]['dev_progress'].'</td>
1950                            </tr>'.NL;
1951
1952                            if($issue[$issue_id]['tblock']!==false) { $cbx_tblock = $this->getLang('yes'); }
1953                            else $cbx_tblock = false;
1954
1955        $issue_edit_head .= '<tr class="itd_tr_standard">
1956                              <td class="it__left_indent"></td>
1957                              <td class="itd__col2">'.$this->getLang('th_tversion').':</td>
1958                              <td class="itd__col3">'.$issue[$issue_id]['trgt_version'].'</td>
1959                              <td class="itd__col4"></td>
1960                              <td class="itd__col5"></td>
1961                              <td class="itd__col6"></td>
1962                             </tr>'.NL;
1963        $issue_edit_head .= '<tr class="itd_tr_standard">
1964                              <td class="it__left_indent"></td>
1965                              <td class="itd__col2">'.$this->getLang('th_tblock').':</td>
1966                              <td class="itd__col3">'.$cbx_tblock.'</td>
1967                              <td class="itd__col4"></td>
1968                              <td class="itd__col5"></td>
1969                              <td class="itd__col6"></td>
1970                             </tr>
1971                             </table>'.NL;
1972}
1973
1974/*------------------------------------------------------------------------------
1975  #60: to view mod-log
1976------------------------------------------------------------------------------*/
1977            if($this->getConf('it_data')==false) $modfile = DOKU_CONF."../data/meta/".$project.'_'.$issue[$issue_id]['id'].'.mod-log';
1978            else $modfile = DOKU_CONF."../". $this->getConf('it_data').$project.'_'.$issue[$issue_id]['id'].'.mod-log';
1979            if (@file_exists($modfile)) {
1980              $pstring = sprintf("showid=%s&amp;project=%s", urlencode($issue[$issue_id]['id']), urlencode($project));
1981              $modlog_link = '<a style="font-size:8pt;" href="doku.php?id='.$ID.'&do=showmodlog&'.$pstring.'" title="'.$this->getLang('th_showmodlog').'">'.$this->getLang('th_showmodlog').'</a>';
1982              $issue_edit_head .= '<table class="itd__title modlog_link"><tr><td class="itd__modlog_link" style="width:100%;font-size:10pt !important;align:right;">['.$modlog_link.']</td></tr>'.NL;
1983              $issue_edit_head .= '</table>'.NL;
1984            }
1985/*----------------------------------------------------------------------------*/
1986
1987                  $alink_id++;
1988                  $blink_id = 'statanker_'.$alink_id;
1989                  $anker_id = 'anker_'.$alink_id;
1990                  $cell_ID = 'img_tab_open_reporterdtls_'.$blink_id;
1991$issue_client_details = '<table class="itd__tables" id="tbl_'.$anker_id.'"><tbody>
1992                        <tr>
1993                           <td class="itd_tables_tdh" colSpan="3">'.$this->getLang('lbl_reporterdtls').'</td>
1994                        </tr>
1995                        <tbody style="display : none;" id="'.$blink_id.'"><tr class="itd__tables_tr" style="width:100%;">
1996                           <td class="it__left_indent"></td>
1997                           <td class="itd_tables_tdc2">'.$this->getLang('lbl_reportername').'</td>
1998                           <td class="itd_tables_tdc3">'.$issue[$issue_id]['user_name'].'</td>
1999                        </tr>';
2000
2001                        //--------------------------------------------------------------------------------------------------------------
2002                        // do not show personal details if issue details diplayed by neigther admin/assignee nor the original user itself
2003                        //--------------------------------------------------------------------------------------------------------------
2004/*                        echo "current user = ".$user_mail['userinfo']['mail']."<br />".
2005                               "Reporting user = ".$issue[$issue_id]['user_mail']."<br />";
2006                          if($user_mail['userinfo']['mail'] === $issue[$issue_id]['user_mail']) {echo "current user = Reporting user <br /><br />";}
2007                             else {echo "current user != Reporting user <br /><br />";}
2008                          if(strpos($target2,$user_mail['userinfo']['mail']) != false) {echo "current user is a member of assignees <br /><br />";}
2009                             else {echo "current user is not a member of assignees <br /><br />";}
2010*/
2011//--------------------------------------------------------------------------------------------------------------
2012//create output for followers on registered users only
2013if(($user_mail['userinfo']['mail'] !== false))
2014{         $blink2_id = 'statanker2_'.$alink_id;
2015          $anker2_id = 'anker2_'.$alink_id;
2016          $tmp = explode(',', $issue[$issue_id]['add_user_mail']);
2017          $follower = 0;
2018$issue_addcontacts .='      <td class="itd_tables_tdc3">'.NL;
2019                            foreach($tmp as $email) {
2020                              //show only own mail address
2021                              if((strlen($email)>2) && (stripos($user_mail['userinfo']['mail'],$email)!==false)) {
2022                                  $issue_addcontacts .='<a href="mailto:'.$email.'">'.$email.'</a>, '.NL;
2023                                  $ademail .= $email;
2024                                  $follower++;
2025                              }
2026                              //admin/assignee to see all followers
2027                              elseif((strlen($email)>2) && (strpos($target2,$user_mail['userinfo']['mail']) != false)) {
2028                                  $issue_addcontacts .='<a href="mailto:'.$email.'">'.$email.'</a>, '.NL;
2029                                  $ademail .= $email;
2030                                  $follower++;
2031                              }
2032                              // to count follower
2033                              elseif(strlen($email)>2) $follower++;
2034                            }
2035                            if($follower==0) $follower='0';
2036                            $ademail = str_replace(',,',',',$ademail);
2037$issue_addcontacts .='      <span style="display : none;" id="'.$blink2_id.'">
2038                                 <form name="add_contact" method="post" accept-charset="'.$lang['encoding'].'">'
2039                                  .formSecurityToken(false).'
2040                                  <input type="hidden" name="project" value="'.$project.'" />
2041                                  <input type="hidden" name="issue_ID" value="'.$issue[$issue_id]['id'].'" />
2042                                  <input type="hidden" name="mod_contacts" value="1"/>
2043                                  <input type="text" style="width:95%; font-size: 9pt;" name="add_contact" value="'.$user_mail['userinfo']['mail'].'" /><br />';
2044                                  if ($this->getConf('use_captcha')==1)
2045                                    {   $helper = null;
2046                            		        if(@is_dir(DOKU_PLUGIN.'captcha'))
2047                            			         $helper = plugin_load('helper','captcha');
2048
2049                            		        if(!is_null($helper) && $helper->isEnabled())
2050                            			      {  $issue_addcontacts .= '<span>'.$helper->getHTML().'</span>'; }
2051                                    }
2052$issue_addcontacts .='            <input  type="submit" class="button" style="font-size:8pt;" id="btn_add_contact" name="btn_add_contact" value="'.$this->getLang('btn_add').'" title="'.$this->getLang('btn_add').'");/>
2053                                </form>
2054                              </span>
2055                            </td>'.NL;
2056$issue_addimg = '<img class="cmt_list_plus_img" alt="add" src="'.DOKU_BASE.'lib/plugins/issuetracker/images/blank.gif" id="'.$anker2_id.'" onClick="span_open(\''.$blink2_id.'\')" />
2057                 <p style="margin-top:-4px;"><span style="font-size:7pt;">'.sprintf($this->getLang('itd_follower'),$follower).'</span></p>';
2058}
2059//--------------------------------------------------------------------------------------------------------------
2060
2061                        if($allowedUser == true)
2062                        {
2063$issue_client_details .= '<tr class="itd__tables_tr">
2064                            <td class="it__left_indent"></td>
2065                            <td class="itd_tables_tdc2">'.$this->getLang('lbl_reportermail').'</td>
2066                            <td class="itd_tables_tdc3"><a href="mailto:'.$issue[$issue_id]['user_mail'].'">'.$issue[$issue_id]['user_mail'].'</a></td>
2067                          </tr>
2068                          <tr class="itd__tables_tr">
2069                            <td class="it__left_indent"></td>
2070                            <td class="itd_tables_tdc2">'.$this->getLang('lbl_reporterphone').'</td>
2071                            <td class="itd_tables_tdc3">'.$issue[$issue_id]['user_phone'].'</td>
2072                          </tr>';
2073                        }
2074$issue_client_details .=    '<tr class="itd__tables_tr">
2075                                <td class="it__left_indent"></td>
2076                                <td class="itd_tables_tdc2">'.$this->getLang('lbl_reporteradcontact').NL.
2077                                $issue_addimg.NL.
2078                                '</td>'.$issue_addcontacts.'
2079                             </tr>';
2080
2081$issue_client_details .= '</tbody><tr>'.NL.'
2082                            <td colspan="3" class="img_tab_open_comment" id="'.$cell_ID.'">'.NL.'
2083                                <div class="lnk_tab_open_comment" id="'.$cell_ID.'">
2084                                  <a id="'.$anker_id.'" onClick="tab_open(\''.$blink_id.'\',\''.$cell_ID.'\')">'.$this->getLang('gen_tab_open').'</a>
2085                                </div>'.NL.'
2086                            </td>
2087                            </tr>'.NL.'</tbody></table>';
2088
2089
2090                        $x_comment = $this->convertlabel($issue[$issue_id]['description']);
2091
2092/*------------------------------------------------------------------------------
2093 * Issue: 39, reported by lukas
2094 * hook-in to provide possibility of modifing the initial description
2095------------------------------------------------------------------------------*/
2096        // retrive some basic information
2097        $cur_date = date($this->getConf('d_format'));
2098        if($user_mail['userinfo']['mail']=='') {$u_mail_check ='unknown';}
2099        else {$u_mail_check = $user_mail['userinfo']['mail'];}
2100        $user_check = $this->getConf('registered_users');
2101
2102$issue_initial_description = '<table class="itd__tables"><tbody>
2103                                <tr>
2104                                  <td class="itd_tables_tdh" colSpan="2" >'.$this->getLang('lbl_initdescr').'</td>
2105                                </tr>
2106                                <tr class="itd__tables_tr">
2107                                  <td class="itd_comment_tr" colSpan="2" style="padding-left:0.45em;">'.$this->xs_format($x_comment).'</td>
2108                                </tr>';
2109
2110/* mod for edit description by ticket owner and admin/assignee ---------------*/
2111// check if current user is author of the comment and offer an edit button
2112            if(($user_mail['userinfo']['mail'] === $issue[$issue_id]['user_mail']) || (strpos($target2,$user_mail['userinfo']['mail']) != false))
2113            {     // add hidden edit toolbar and textarea
2114                  $alink_id++;
2115                  $blink_id = 'statanker_'.$alink_id;
2116                  $anker_id = 'anker_'.$alink_id;
2117
2118            $issue_initial_description .= '   <tr class="itd_edit_tr">
2119                                                 <td class="itd_edit_tr" colSpan="2" style="display : none;" id="'.$blink_id.'">';
2120
2121            if($this->getConf('wysiwyg')==true) {
2122                $issue_initial_description .= $this->it_wysiwyg_edit_toolbar($x_comment);
2123                $_textarea = '<textarea class="itd_textarea" id="description_mod" name="description_mod" style="display: none;"> </textarea><br />'.NL;
2124            }
2125            else {
2126                $issue_initial_description .= $this->it_xs_edit_toolbar('description_mod_'.$alink_id);
2127                $_textarea = '<textarea class="itd_textarea" id="description_mod_'.$alink_id.'" name="description_mod" type="text" cols="106" rows="7" value="">'.strip_tags($x_comment).'</textarea><br />'.NL;
2128            }
2129            $issue_initial_description .= '<form name="form1" method="post" accept-charset="'.$lang['encoding'].'">'.NL;
2130            $issue_initial_description .= formSecurityToken(false).
2131                                         '<input type="hidden" name="project" value="'.$project.'" />'.NL.
2132                                         '<input type="hidden" name="comment_issue_ID" value="'.$issue[$issue_id]['id'].'" />'.NL.
2133                                         '<input type="hidden" name="author"value="'.$u_mail_check.'" />'.NL.
2134                                         '<input type="hidden" name="timestamp" value="'.$cur_date.'" />'.NL.
2135                                         '<input type="hidden" name="mod_description" value="1"/>'.NL.
2136                                         $_textarea . '
2137                                          <span class="reply_close_link">
2138                                            <a href="javascript:resizeBoxId(\'description_mod_'.$alink_id.'\', -20)"><img src="'.$imgBASE.'reduce.png" title="reduce textarea" style="float:right;" /></a>
2139                                            <a href="javascript:resizeBoxId(\'description_mod_'.$alink_id.'\', +20)"><img src="'.$imgBASE.'enlarge.png" title="enlarge textarea" style="float:right;" /></a>
2140                                         </span>'.NL;
2141
2142
2143                                if ($this->getConf('use_captcha')==1)
2144                                {   $helper = null;
2145                        		        if(@is_dir(DOKU_PLUGIN.'captcha'))
2146                        			         $helper = plugin_load('helper','captcha');
2147
2148                        		        if(!is_null($helper) && $helper->isEnabled())
2149                        			      {  $issue_initial_description .= '<p>'.$helper->getHTML().'</p>'; }
2150                                }
2151                                $cell_ID = 'img_tab_open_comment'.$blink_id;
2152                                $cntrl_id  = 'ctrl_'.$alink_id;
2153$issue_initial_description .=  '<input  type="hidden" class="showid__option" name="showid" id="showid" size="10" value="'.$this->parameter.'"/>'.
2154                               '<fieldset class="minor_mod">'.
2155                               '<span style="width: 30em; text-align: left; float: left;" title="'.$this->getLang('minor_mod_cbx_title').'"><input type="checkbox" name="minor_mod" id="'.$cntrl_id.'" value="true" style="float: left;" /><label for="'.$cntrl_id.'">&nbsp;&nbsp;'.$this->getLang('minor_mod').'</label>'.
2156                               '<input  style="margin-left: 2em;" type="submit" class="button" id="btnmod_description" name="btnmod_description" value="'.$this->getLang('btn_mod').'" title="'.$this->getLang('btn_mod_title').'");/>'.'</span>'.
2157                               '</fieldset>'.
2158                               '</form>'.NL.'</td>'.NL.'</tr>'.NL.
2159                               '<tr>'.NL.'
2160                                   <td colspan="2" class="img_tab_open_comment" id="'.$cell_ID.'">'.NL.'
2161                                       <div class="lnk_tab_open_comment" id="'.$cell_ID.'">
2162                                         <a id="'.$anker_id.'" onClick="tab_open(\''.$blink_id.'\',\''.$cell_ID.'\')">'.$this->getLang('descr_tab_mod').'</a>
2163                                       </div>'.NL.'
2164                                   </td>'.NL.'
2165                                </tr>'.NL;
2166                }
2167$issue_initial_description .= '</tbody></table>';
2168/* END mod for edit description by ticket owner ----------------------------------*/
2169if((strpos($this->getConf('ltdReport'),'Symptom link 1')===false) || ($this->getConf('upload')>0)) {
2170  $issue_attachments = '<table class="itd__tables"><tbody>
2171                        <tr>
2172                          <td colspan="2" class="itd_tables_tdh">'.$this->getLang('lbl_symptlinks').'</td>
2173                        </tr>
2174                        <tr  class="itd__tables_tr">
2175                          <td class="itd_attachments_tr" colspan="2" style="padding-left:0.45em;">1. <a href="'.$issue[$issue_id]['attachment1'].'"><img border="0" alt="symptoms 1" style="margin-right:0.5em" vspace="1" align="middle" src="'.$imgBASE.'sympt.gif" width="16" height="16"></a><a title="'.$issue[$issue_id]['attachment1'].'" href="'.$issue[$issue_id]['attachment1'].'">'.$issue[$issue_id]['attachment1'].'</a></td>
2176                        </tr>'.NL;
2177  if(strpos($this->getConf('ltdReport'),'Symptom link 2')===false){
2178    $issue_attachments .= '<tr  class="itd__tables_tr">
2179                            <td class="itd_attachments_tr" colspan="2" style="padding-left:0.45em;">2. <a href="'.$issue[$issue_id]['attachment2'].'"><img border="0" alt="symptoms 2" style="margin-right:0.5em" vspace=1em align=absMiddle src="'.$imgBASE.'sympt.gif" width="16" height="16"></a><a title="'.$issue[$issue_id]['attachment2'].'" href="'.$issue[$issue_id]['attachment2'].'">'.$issue[$issue_id]['attachment2'].'</a></td>
2180                          </tr>'.NL;
2181  }
2182  if(strpos($this->getConf('ltdReport'),'Symptom link 3')===false){
2183    $issue_attachments .= '<tr  class="itd__tables_tr">
2184                            <td class="itd_attachments_tr" colspan="2" style="padding-left:0.45em;">3. <a href="'.$issue[$issue_id]['attachment3'].'"><img border="0" alt="symptoms 3" style="margin-right:0.5em" vspace="1" align="middle" src="'.$imgBASE.'sympt.gif" width="16" height="16"></a><a title="'.$issue[$issue_id]['attachment3'].'" href="'.$issue[$issue_id]['attachment3'].'">'.$issue[$issue_id]['attachment3'].'</a></td>
2185                          </tr>'.NL;
2186  }
2187  /* mod for edit symptom links by ticket owner and admin/assignee ---------------*/
2188  // check if current user is author of the comment and offer an edit button
2189              if(($user_mail['userinfo']['mail'] === $issue[$issue_id]['user_mail']) || (strpos($target2,$user_mail['userinfo']['mail']) != false)) {
2190                    // add hidden edit toolbar and textarea
2191                    $alink_id++;
2192                    $blink_id = 'statanker_'.$alink_id;
2193                    $anker_id = 'anker_'.$alink_id;
2194                    $cell_ID = 'img_tab_open_reporterdtls'.$blink_id;
2195  $issue_attachments .= '<tbody style="display : none;" id="'.$blink_id.'">
2196                          <tr><td colspan=2>'.NL.
2197                          '<form name="form1" method="post" accept-charset="'.$lang['encoding'].'" enctype="multipart/form-data">'.NL;
2198  $issue_attachments .= formSecurityToken(false).
2199                       '<input type="hidden" name="project" value="'.$project.'" />'.NL.
2200                       '<input type="hidden" name="comment_issue_ID" value="'.$issue[$issue_id]['id'].'" />'.NL.
2201                       '<input type="hidden" name="mod_symptomlinks" value="1"/>'.NL;
2202
2203                                  if ($this->getConf('use_captcha')==1)
2204                                  {   $helper = null;
2205                          		        if(@is_dir(DOKU_PLUGIN.'captcha'))
2206                          			         $helper = plugin_load('helper','captcha');
2207
2208                          		        if(!is_null($helper) && $helper->isEnabled())
2209                          			      {  $issue_attachments .= '<p>'.$helper->getHTML().'</p>'; }
2210                                  }
2211                  //Check config if hidden
2212                  if($this->getConf('upload')>0) {
2213                    if(strpos($this->getConf('ltdReport'),'Symptom link 1')!==false){
2214                        $issue_attachments .= ' <input type="hidden" class="it__cir_linput" name="attachment1" value="'.$issue[$issue_id]['attachment1'].'"/>'.NL;
2215                    }
2216                    else {
2217                        $issue_attachments .= '<span><input type="file" class="it__cir_linput" name="attachment1" value="'.$issue[$issue_id]['attachment1'].'"/></span><br />'.NL;
2218                    }
2219                    if(strpos($this->getConf('ltdReport'),'Symptom link 2')!==false){
2220                        $issue_attachments .= ' <input type="hidden" class="it__cir_linput" name="attachment2" value="'.$issue[$issue_id]['attachment2'].'"/>'.NL;
2221                    }
2222                    else {
2223                        $issue_attachments .= '<span><input type="file" class="it__cir_linput" name="attachment2" value="'.$issue[$issue_id]['attachment2'].'"/></span><br />'.NL;
2224                    }
2225                    if(strpos($this->getConf('ltdReport'),'Symptom link 3')!==false){
2226                        $issue_attachments .= ' <input type="hidden" class="it__cir_linput" name="attachment3" value="'.$issue[$issue_id]['attachment3'].'"/>'.NL;
2227                    }
2228                    else {
2229                        $issue_attachments .= '<span><input type="file" class="it__cir_linput" name="attachment3" value="'.$issue[$issue_id]['attachment3'].'"/></span><br/>'.NL;
2230                    }
2231                  }
2232  $issue_attachments .= '<input type="hidden" class="showid__option" name="showid" id="showid" size="10" value="'.$this->parameter.'"/>'.
2233                                 '<input  type="submit" class="button" id="btnmod_description" name="btnmod_description" style="float:right;" value="'.$this->getLang('btn_mod').'" title="'.$this->getLang('btn_mod_title').'");/>'.
2234                                 '</form>'.NL.'</td></tr></tbody><tr>'.NL.'
2235                              <td colspan="3" class="img_tab_open_comment" id="'.$cell_ID.'">'.NL.'
2236                                  <div class="lnk_tab_open_comment" id="'.$cell_ID.'">
2237                                    <a id="'.$anker_id.'" onClick="tab_open(\''.$blink_id.'\',\''.$cell_ID.'\')">'.$this->getLang('descr_tab_mod').'</a>
2238                                  </div>'.NL.'
2239                              </td>
2240                              </tr>'.NL.'</table>';
2241              }
2242  $issue_attachments .='</tbody></table>'.NL;
2243}
2244/* END mod for edit description by ticket owner ----------------------------------*/
2245
2246/* Workaround description --------------------------------------------------------*/
2247$issue_workaround ='<table class="itd__tables"><tbody>
2248                      <tr>
2249                        <td class="itd_tables_tdh" colSpan="2" >'.$this->getLang('lbl_workaround').'</td>
2250                      </tr>'.NL;
2251$issue_workaround .= '<tr  class="itd__tables_tr">
2252                          <td class="itd_comment_tr">'.NL;
2253                      // output workaround content
2254                      $x_id = "WA";
2255                      $x_workaround = $comments[0]['wround_mod'];
2256                      $x_workaround = $this->convertlabel($x_workaround);
2257$issue_workaround .= $this->xs_format($x_workaround).NL.'</td></tr>'.NL;
2258
2259//create output for followers on registered users only
2260if(($user_mail['userinfo']['mail'] === $issue[$issue_id]['user_mail']) || (strpos($target2,$user_mail['userinfo']['mail']) != false))
2261{                   // add hidden edit toolbar and textarea
2262                      $alink_id++;
2263                      $blink_id = 'statanker_'.$alink_id;
2264                      $anker_id = 'anker_'.$alink_id;
2265
2266                    $issue_workaround .= '   <tr class="itd_edit_tr">
2267                                                 <td class="itd_edit_tr" colSpan="2" style="display : none;" id="'.$blink_id.'">';
2268
2269                    $issue_workaround .= $this->it_xs_edit_toolbar('wround_mod_'.$alink_id);
2270
2271                    $issue_workaround .= '<form name="wround_form" method="post" accept-charset="'.$lang['encoding'].'">'.NL;
2272
2273                    $issue_workaround .= formSecurityToken(false).
2274                                         '<input type="hidden" name="mod_wround" value="1" />'.NL.
2275                                         '<input type="hidden" name="project" value="'.$project.'" />'.NL.
2276                                         '<input type="hidden" name="comment_file" value="'.$cfile.'" />'.NL.
2277                                         '<input type="hidden" name="comment_issue_ID" value="'.$issue[$issue_id]['id'].'" />'.NL.
2278                                         '<input type="hidden" name="author" value="'.$user_mail['userinfo']['mail'].'" />'.NL.
2279                                         '<input type="hidden" name="timestamp" value="'.$cur_date.'" />'.NL.
2280                                         '<textarea class="itd_textarea" id="wround_mod_'.$alink_id.'" name="wround_mod" type="text" cols="106" rows="7" value="">'.strip_tags($x_workaround).'</textarea><br />
2281                                          <span class="reply_close_link">
2282                                            <a href="javascript:resizeBoxId(\'wround_mod_'.$alink_id.'\', -20)"><img src="'.$imgBASE.'reduce.png" title="reduce textarea" style="float:right;" /></a>
2283                                            <a href="javascript:resizeBoxId(\'wround_mod_'.$alink_id.'\', +20)"><img src="'.$imgBASE.'enlarge.png" title="enlarge textarea" style="float:right;" /></a>
2284                                          </span>'.NL;
2285
2286                    if ($this->getConf('use_captcha')==1)
2287                    {   $helper = null;
2288            		        if(@is_dir(DOKU_PLUGIN.'captcha'))
2289            			         $helper = plugin_load('helper','captcha');
2290
2291            		        if(!is_null($helper) && $helper->isEnabled())
2292            			      {  $issue_workaround .= '<p>'.$helper->getHTML().'</p>'; }
2293                    }
2294                    $cell_ID = 'img_tab_open_comment'.$blink_id;
2295                    $cntrl_id  = 'ctrl_'.$alink_id;
2296
2297$issue_workaround .= '<input  type="hidden" class="showid__option" name="showid" id="showid" size="10" value="'.$this->parameter.'"/>'.
2298                       '<fieldset class="minor_mod">'.
2299                               '<span style="width: 30em; text-align: left; float: left;"  title="'.$this->getLang('minor_mod_cbx_title').'"><input type="checkbox" name="minor_mod" value="true" id="'.$cntrl_id.'" value="true" style="float: left;" /><label for="'.$cntrl_id.'">&nbsp;&nbsp;'.$this->getLang('minor_mod').'</label>'.
2300                               '<input style="margin-left: 2em;" type="submit" class="button" id="store_workaround" name="store_workaround"  value="'.$this->getLang('btn_mod').'" title="'.$this->getLang('btn_mod_title').'");/>'.'</span>'.
2301                       '</fieldset>'.
2302                       '</form>'.NL.'</td>'.NL.'</tr>'.NL.
2303                       '<tr>'.NL.'
2304                           <td colspan="2" class="img_tab_open_comment" id="'.$cell_ID.'">'.NL.'
2305                               <div class="lnk_tab_open_comment" id="'.$cell_ID.'">
2306                                 <a id="'.$anker_id.'" onClick="tab_open(\''.$blink_id.'\',\''.$cell_ID.'\')">'.$this->getLang('descr_tab_mod').'</a>
2307                               </div>'.NL.'
2308                           </td>'.NL.'
2309                        </tr>'.NL;
2310}
2311$issue_workaround .='</tbody></table>'.NL;
2312
2313/* END of Workaround description --------------------------------------------------------*/
2314
2315$issue_comments_log ='<table class="itd__tables"><tbody>
2316                      <tr>
2317                        <td class="itd_tables_tdh" colSpan="2" >'.$this->getLang('lbl_cmts_wlog').'</td>
2318                      </tr>';
2319              // loop through the comments
2320              if ($comments!=false) {
2321                  foreach ($comments as $a_comment)
2322                  {     if($this->_get_one_value($a_comment,'id') === 'WA') continue;
2323                        $x_id = $this->_get_one_value($a_comment,'id');
2324                        $x_comment = $this->_get_one_value($a_comment,'comment');
2325                        $x_comment = $this->convertlabel($x_comment);
2326
2327                        //----------------------------------------------------------------------------------------------------------------
2328                        // do not show personal details if issue details diplayed by neigther admin/assignee nor the original user itself
2329                        //----------------------------------------------------------------------------------------------------------------
2330                        if((($user_mail['userinfo']['mail'] === $issue[$issue_id]['user_mail'])
2331                            or (strpos($target2,$user_mail['userinfo']['mail']) != false)
2332                            or ($user_mail['userinfo']['mail'] === $this->_get_one_value($a_comment,'author')))
2333                            && ($this->getConf('shw_mail_addr')===1) && ($this->getConf('auth_ad_overflow') == false))
2334                        {   $x_mail = '<a href="mailto:'.$this->_get_one_value($a_comment,'author').'">'.$this->_get_one_value($a_comment,'author').'</a>'; }
2335                        // show mailto with name instead user mail address
2336                        elseif((($user_mail['userinfo']['mail'] === $issue[$issue_id]['user_mail'])
2337                            or (strpos($target2,$user_mail['userinfo']['mail']) != false)
2338                            or ($user_mail['userinfo']['mail'] === $this->_get_one_value($a_comment,'author')))
2339                            && ($this->getConf('shw_mail_addr')===0) && ($this->getConf('auth_ad_overflow') == false))
2340                            {
2341                              $compare = $this->_get_one_value($a_comment,'author');
2342                              $dw_users = $auth->retrieveUsers();
2343                              foreach($dw_users as $mail_adr)
2344                              { if($mail_adr['mail']==$compare)
2345                                {   $tmp_name = $mail_adr['name'];
2346                                    break;
2347                                }
2348                              }
2349                              if($tmp_name==false) $tmp_name = $compare;
2350                              $x_mail= '<a href="mailto:'.$compare.'">'.$tmp_name.'</a>';
2351                            }
2352                        elseif($this->getConf('auth_ad_overflow') == true) {
2353                            $x_mail = '<a href="mailto:'.$this->_get_one_value($a_comment,'author').'">'.$this->_get_one_value($a_comment,'author').'</a>'; }
2354                        else {
2355                            // here it is necessary for others to know if issue reporter, follower or assignee is commenting
2356                            // implement the function to differenciate between these roles
2357                            // => check mail address with reporter, follower and assignee/admin group else it is a foreigner
2358                            $role       = $this->_get_one_value($a_comment,'author');
2359                            if ($issue[$issue_id]['user_mail'] === $role)
2360                                $x_mail = '<i> ('.$this->getLang('dtls_reporter_hidden').') </i>';
2361                            elseif (stripos($issue['add_user_mail'],$role) != false)
2362                                $x_mail = '<i> ('.$this->getLang('dtls_follower_hidden').') </i>';
2363                            elseif (stripos($target2,$role) != false)
2364                                $x_mail = '<i> ('.$this->getLang('dtls_assignee_hidden').') </i>';
2365                            else
2366                                $x_mail = '<i> ('.$this->getLang('dtls_foreigner_hidden').') </i>';
2367                        }
2368
2369                        if($this->_get_one_value($a_comment,'mod_timestamp')) { $insert_lbl = '<label class="cmt_mod_exclamation">!</label>';}
2370                        else $insert_lbl ='';
2371
2372                        $issue_comments_log .= '<tr  class="itd__tables_tr">
2373                                                  <td class="itd_comment_trh"><label name="a'.$x_id.'" id="a'.$x_id.'">['.$this->_get_one_value($a_comment,'id').'] </label>&nbsp;&nbsp;&nbsp;
2374                                                                            <label>'.date($this->getConf('d_format'),strtotime($this->_get_one_value($a_comment,'timestamp'))).' </label>&nbsp;&nbsp;&nbsp;'.NL.'
2375                                                                            <label>'.$x_mail.'</label>'.NL;
2376                        if($this->_get_one_value($a_comment,'mod_timestamp')) {
2377                        $issue_comments_log .= '                            <label class="cmt_mod_label" >&nbsp;&nbsp;[modified: '.date($this->getConf('d_format'),strtotime($this->_get_one_value($a_comment,'mod_timestamp'))).']&nbsp;'.$insert_lbl.'&nbsp;</label>&nbsp;&nbsp;&nbsp;'.NL;
2378                        }
2379
2380                        $issue_comments_log .= '  </td>'.NL;
2381                        $issue_comments_log .= '</tr>
2382                                                <tr  class="itd__tables_tr">
2383                                                  <td class="itd_comment_tr">';
2384
2385                        // delete button for comments
2386                        if(($user_mail['userinfo']['mail'] === $this->_get_one_value($a_comment,'author')) or (strpos($target2,$user_mail['userinfo']['mail']) != false))
2387                        {   $issue_comments_log .= '<form name="form1" method="post" accept-charset="'.$lang['encoding'].'">'.NL;
2388                            $issue_comments_log .= formSecurityToken(false).
2389                                                 '<input type="hidden" name="project" value="'.$project.'"/>'.NL.
2390                                                 '<input type="hidden" name="comment_file" value="'.$cfile.'"/>'.NL.
2391                                                 '<input type="hidden" name="comment_issue_ID" value="'.$issue[$issue_id]['id'].'"/>'.NL.
2392                                                 '<input type="hidden" name="author" value="'.$u_mail_check.'"/>'.NL.
2393                                                 '<input type="hidden" name="del_cmnt" value="TRUE"/>'.NL.
2394                                                 '<input type="hidden" name="comment_id" value="'.$this->_get_one_value($a_comment,'id').'"/>'.NL.
2395                                                 '<input class="cmt_del_img" type="image" src="'.DOKU_BASE.'lib/plugins/issuetracker/images/dot.gif" alt="Del" title="'.$this->getLang('del_title').'" />'.
2396                                                 '</form>'.NL;
2397                       }
2398                       // output comment content
2399                       $issue_comments_log .= $this->xs_format($x_comment).NL.'</td></tr>'.NL;
2400        //--------------------------------------------------------------------------------------------------------------
2401        // only admin/assignees and reporter are allowed to add comments if only user edit option is set
2402        //--------------------------------------------------------------------------------------------------------------
2403        // retrive some basic information
2404        $cur_date = date($this->getConf('d_format'));
2405        if($user_mail['userinfo']['mail']=='') {$u_mail_check ='unknown';}
2406        elseif($this->getConf('shw_mail_addr')===0) {$u_mail_check =$user_mail['userinfo']['name'];}
2407        else {$u_mail_check = $user_mail['userinfo']['mail'];}
2408        $user_check = $this->getConf('registered_users');
2409
2410/*------------------------------------------------------------------------------
2411 *   Modify comment                                                           */
2412                // check if current user is author of the comment and offer an edit button
2413                if(($allowedUser == true) or ($this->getConf('auth_ad_overflow') == true))
2414                {     // add hidden edit toolbar and textarea
2415                      $alink_id++;
2416                      $blink_id = 'statanker_'.$alink_id;
2417                      $anker_id = 'anker_'.$alink_id;
2418
2419                    $issue_comments_log .= '   <tr class="itd_edit_tr">
2420                                                 <td class="itd_edit_tr" colSpan="2" style="display : none;" id="'.$blink_id.'">';
2421
2422                    $issue_comments_log .= $this->it_xs_edit_toolbar('comment_mod_'.$alink_id);
2423
2424                    $issue_comments_log .= '<form name="form1" method="post" accept-charset="'.$lang['encoding'].'">'.NL;
2425
2426                    $issue_comments_log .= formSecurityToken(false).
2427                                         '<input type="hidden" name="project" value="'.$project.'" />'.NL.
2428                                         '<input type="hidden" name="comment_file" value="'.$cfile.'" />'.NL.
2429                                         '<input type="hidden" name="comment_issue_ID" value="'.$issue[$issue_id]['id'].'" />'.NL.
2430                                         '<input type="hidden" name="author"value="'.$user_mail['userinfo']['mail'].'" />'.NL.
2431                                         '<input type="hidden" name="timestamp" value="'.$cur_date.'" />'.NL.
2432                                         '<input type="hidden" name="comment_id" value="'.$this->_get_one_value($a_comment,'id').'" />'.NL.
2433                                         '<textarea class="itd_textarea" id="comment_mod_'.$alink_id.'" name="comment_mod" type="text" cols="106" rows="7" value="">'.strip_tags($x_comment).'</textarea><br />
2434                                          <span class="reply_close_link">
2435                                            <a href="javascript:resizeBoxId(\'comment_mod_'.$alink_id.'\', -20)"><img src="'.$imgBASE.'reduce.png" title="reduce textarea" style="float:right;" /></a>
2436                                            <a href="javascript:resizeBoxId(\'comment_mod_'.$alink_id.'\', +20)"><img src="'.$imgBASE.'enlarge.png" title="enlarge textarea" style="float:right;" /></a>
2437                                          </span>'.NL;
2438
2439                    if ($this->getConf('use_captcha')==1)
2440                    {   $helper = null;
2441            		        if(@is_dir(DOKU_PLUGIN.'captcha'))
2442            			         $helper = plugin_load('helper','captcha');
2443
2444            		        if(!is_null($helper) && $helper->isEnabled())
2445            			      {  $issue_comments_log .= '<p>'.$helper->getHTML().'</p>'; }
2446                    }
2447                    $cell_ID = 'img_tab_open_comment'.$blink_id;
2448                    $cntrl_id  = 'ctrl_'.$alink_id;
2449                    // check if only registered users are allowed to modify comments
2450                    // ¦ perm — the user's permissions related to the current page ($ID)
2451$issue_comments_log .= '<input  type="hidden" class="showid__option" name="showid" id="showid" size="10" value="'.$this->parameter.'"/>'.
2452                       '<fieldset class="minor_mod">'.
2453                               '<span style="width: 30em; text-align: left; float: left;"  title="'.$this->getLang('minor_mod_cbx_title').'"><input type="checkbox" name="minor_mod" value="true" id="'.$cntrl_id.'" value="true" style="float: left;" /><label for="'.$cntrl_id.'">&nbsp;&nbsp;'.$this->getLang('minor_mod').'</label>'.
2454                               '<input style="margin-left: 2em;"  type="submit" class="button" id="btnmod_description" name="btnmod_description"  value="'.$this->getLang('btn_mod').'" title="'.$this->getLang('btn_mod_title').'");/>'.'</span>'.
2455                       '</fieldset>'.
2456                       '</form>'.NL.'</td>'.NL.'</tr>'.NL.
2457                       '<tr>'.NL.'
2458                           <td colspan="2" class="img_tab_open_comment" id="'.$cell_ID.'">'.NL.'
2459                               <div class="lnk_tab_open_comment" id="'.$cell_ID.'">
2460                                 <a id="'.$anker_id.'" onClick="tab_open(\''.$blink_id.'\',\''.$cell_ID.'\')">'.$this->getLang('cmt_tab_mod').'</a>
2461                               </div>'.NL.'
2462                           </td>'.NL.'
2463                        </tr>'.NL;
2464                }
2465            }
2466        }
2467        $issue_comments_log .='</tbody></table>';
2468
2469/*   end Modify comment
2470------------------------------------------------------------------------------*/
2471
2472        //--------------------------------------------------------------------------------------------------------------
2473        // only admin/assignees and reporter are allowed to add comments if only user edit option is set
2474        //--------------------------------------------------------------------------------------------------------------
2475        // retrive some basic information
2476        $cur_date = date($this->getConf('d_format'));
2477        if(strlen($user_mail['userinfo']['mail']) == 0) {$u_mail_check ='unknown';}
2478        else {$u_mail_check = $user_mail['userinfo']['mail'];}
2479        $user_check = $this->getConf('registered_users');
2480        $u_name = $user_mail['userinfo']['name'];
2481        //2011-12-02: bwenz code proposal (Issue 11)
2482        $x_resolution = $this->convertlabel($issue[$issue_id]['resolution']);
2483//        if(!$x_resolution) { $x_resolution = "&nbsp;"; }
2484
2485        $_cFlag = false;
2486        if($user_check == 0)
2487            { $_cFlag = true;  }
2488        elseif(($user_check == 1) && ($user_mail['perm'] > 1))
2489            { $_cFlag = true;  }
2490
2491        if($_cFlag === true) {
2492
2493
2494// mod for editor ---------------------------------------------------------------------
2495                  $alink_id++;
2496                  $blink_id = 'statanker_'.$alink_id;
2497                  $anker_id = 'anker_'.$alink_id;
2498$issue_add_comment .='<table class="itd__tables">'.
2499                      '<tr>'.
2500                        '<td class="itd_tables_tdh cmts_adcmt" colSpan="2" >'.$this->getLang('lbl_cmts_adcmt').'</td>
2501                      </tr><tr class="itd_edit_tr"><td class="itd_edit_tr" colSpan="2" style="display : none;" id="'.$blink_id.'">';
2502$issue_add_comment .= $this->it_xs_edit_toolbar('comment_'.$alink_id);
2503// mod for editor ---------------------------------------------------------------------
2504
2505$issue_add_comment .= '<form name="form1" method="post" accept-charset="'.$lang['encoding'].'">'.NL;
2506
2507$issue_add_comment .= formSecurityToken(false).
2508                     '<input type="hidden" name="project" value="'.$project.'" />'.NL.
2509                     '<input type="hidden" name="comment_file" value="'.$cfile.'" />'.NL.
2510                     '<input type="hidden" name="comment_issue_ID" value="'.$issue[$issue_id]['id'].'" />'.NL.
2511                     '<input type="hidden" name="author" value="'.$u_mail_check.'" />'.NL.
2512                     '<input type="hidden" name="timestamp" value="'.$cur_date.'" />'.NL.
2513                     '<textarea class="itd_textarea" id="comment_'.$alink_id.'" name="comment" type="text" cols="106" rows="7" value=""></textarea><br>
2514                      <span class="reply_close_link">
2515                        <a href="javascript:resizeBoxId(\'comment_'.$alink_id.'\', -20)"><img src="'.$imgBASE.'reduce.png" title="reduce textarea" style="float:right;" /></a>
2516                        <a href="javascript:resizeBoxId(\'comment_'.$alink_id.'\', +20)"><img src="'.$imgBASE.'enlarge.png" title="enlarge textarea" style="float:right;" /></a>
2517                      </span>'.NL;
2518
2519
2520                      if ($this->getConf('use_captcha')==1)
2521                      {   $helper = null;
2522              		        if(@is_dir(DOKU_PLUGIN.'captcha'))
2523              			         $helper = plugin_load('helper','captcha');
2524
2525              		        if(!is_null($helper) && $helper->isEnabled())
2526              			      {  $issue_add_comment .= '<p>'.$helper->getHTML().'</p>'; }
2527                      }
2528                      $cell_ID = 'img_tab_open_comment'.$blink_id;
2529                      // check if only registered users are allowed to add comments
2530                      // ¦ perm — the user's permissions related to the current page ($ID)
2531                      $issue_add_comment .= '<input  type="hidden" class="showid__option" name="showid" id="showid" size="10" value="'.$this->parameter.'"/>'.NL.
2532                                            '<input class="button" id="showcase" type="submit" name="showcase" value="'.$this->getLang('btn_add').'" title="'.$this->getLang('btn_add_title').'");/>'.NL.
2533                                            '</form>'.NL.'</td>'.NL.'</tr>'.NL.
2534                                            '<tr>'.NL.'
2535                                                <td colspan="2" class="img_tab_open_comment" id="'.$cell_ID.'">'.NL.'
2536                                                    <div class="lnk_tab_open_comment" id="'.$cell_ID.'">
2537                                                      <a id="'.$anker_id.'" onClick="tab_open(\''.$blink_id.'\',\''.$cell_ID.'\')">'.$this->getLang('cmt_tab_open').'</a>
2538                                                    </div>'.NL.'
2539                                                </td>'.NL.'
2540                                             </tr></table>'.NL;
2541
2542                  $alink_id++;
2543                  $blink_id = 'statanker_'.$alink_id;
2544                  $anker_id = 'anker_'.$alink_id;
2545
2546$issue_edit_resolution ='<table class="itd__tables">
2547                         <tr>
2548                            <td class="itd_tables_tdh" colSpan="2" >'.$this->getLang('th_resolution').'</td>
2549                        </tr>';
2550$issue_edit_resolution .= '<tr class="itd__tables_tr">
2551                            <td class="itd_comment_tr" colSpan="2" style="padding-left:0.45em;">'.$this->xs_format($x_resolution).'</td>
2552                          </tr>
2553                          <tr class="itd_edit_tr"><td class="itd_edit_tr" colSpan="2" style="display : none;" id="'.$blink_id.'">';
2554
2555/*------------------------------------------------------------------------------
2556 * extension based on Issue: 39, reported by lukas
2557 * hook-in to provide possibility of modifing the last comment
2558------------------------------------------------------------------------------*/
2559/*    - if user = commentor of last comment then provide edit text area
2560        pre-loaded with button and last comment content for mofification
2561 *    - upon diff of former comment and textarea store it as comment
2562 *    - highlight current comment as modified (optional)
2563------------------------------------------------------------------------------*/
2564
2565// mod for editor ---------------------------------------------------------------------
2566$issue_edit_resolution .= $this->it_xs_edit_toolbar('x_resolution');
2567// mod for editor ---------------------------------------------------------------------
2568
2569$issue_edit_resolution .= '<form name="edit_resolution" method="post" action="'.$_SERVER['REQUEST_URI'].'" accept-charset="'.$lang['encoding'].'">'.NL;
2570$issue_edit_resolution .= formSecurityToken(false).
2571                          '<input type="hidden" name="project"value="'.$project.'"/>'.NL.
2572                          '<input type="hidden" name="comment_issue_ID" value="'.$issue[$issue_id]['id'].'"/>'.NL.
2573                          '<input type="hidden" name="usr" value="'.$u_name.'"/>'.NL.
2574                          '<input type="hidden" name="add_resolution" value="1"/>'.NL;
2575
2576$issue_edit_resolution .= "<textarea class='itd_textarea' id='x_resolution' name='x_resolution' type='text' cols='106' rows='7' value=''>".strip_tags($x_resolution)."</textarea><br>".
2577                          '<span class="reply_close_link">
2578                            <a href="javascript:resizeBoxId(\'x_resolution\', -20)"><img src="'.$imgBASE.'reduce.png" title="reduce textarea" style="float:right;" /></a>
2579                            <a href="javascript:resizeBoxId(\'x_resolution\', +20)"><img src="'.$imgBASE.'enlarge.png" title="enlarge textarea" style="float:right;" /></a>
2580                          </span>'.NL;
2581
2582
2583                      if ($this->getConf('use_captcha')==1)
2584                      {   $helper = null;
2585              		        if(@is_dir(DOKU_PLUGIN.'captcha'))
2586              			         $helper = plugin_load('helper','captcha');
2587
2588              		        if(!is_null($helper) && $helper->isEnabled())
2589              			      {  $issue_edit_resolution .= '<p>'.$helper->getHTML().'</p>'; }
2590                      }
2591
2592                      $cell_ID = 'img_tab_open_comment'.$blink_id;
2593
2594$issue_edit_resolution .= '<input  type="hidden" class="showid__option" name="showid" id="showid" size="10" value="'.$this->parameter.'"/>'.
2595                      '<input class="button" id="store_resolution" type="submit" name="store_resolution" value="'.$this->getLang('btn_add').'" title="'.$this->getLang('btn_add_title').'");/>'.
2596                      '</form>'.NL.'</td>'.NL.'</tr>'.NL.
2597                      '<tr>'.NL.'
2598                          <td colspan="2" class="img_tab_open_comment" id="'.$cell_ID.'">'.NL.'
2599                              <div class="lnk_tab_open_comment" id="'.$cell_ID.'">
2600                                <a id="'.$anker_id.'" onClick="tab_open(\''.$blink_id.'\',\''.$cell_ID.'\')">'.$this->getLang('rsl_tab_open').'</a>
2601                              </div>'.NL.'
2602                          </td>'.NL.'
2603                       </tr></table>'.NL;
2604        }
2605        // the user maybe registered within group "all" but the registered flag is turned on
2606        // eigther the user has to be moved into group "user" or the flag to be switched off
2607        elseif(($user_mail['perm'] < 2) && (strlen($user_mail['userinfo']['mail'])>1)) {
2608            $issue_edit_resolution ='<table class="itd__tables">
2609                                     <tr>
2610                                        <td class="itd_tables_tdh" colSpan="2" >'.$this->getLang('th_resolution').'</td>
2611                                    </tr>';
2612            $issue_edit_resolution .= '<tr class="itd__tables_tr">
2613                                        <td class="itd_resolution_tr" colSpan="2" style="padding-left:0.45em;">'.$this->xs_format($x_resolution).'</td>
2614                                      </tr></table>'.NL;
2615
2616            $wmsg = $this->getLang('lbl_lessPermission');
2617            $issue_edit_resolution .= '<div class="it__standard_feedback">'.$wmsg.'</div>';
2618        }
2619        else {
2620            $issue_edit_resolution ='<table class="itd__tables">
2621                                     <tr>
2622                                        <td class="itd_tables_tdh" colSpan="2" >'.$this->getLang('th_resolution').'</td>
2623                                    </tr>';
2624            $issue_edit_resolution .= '<tr>
2625                                        <td class="itd_comment_tr">'.$this->xs_format($x_resolution).'</td>
2626                                      </tr></table>'.NL;
2627
2628            $wmsg = $this->getLang('lbl_please').'<a href="?do=login&amp class="action login" accesskey="" rel="nofollow" style="color:blue;text-decoration:underline;" title="Login">'.$this->getLang('lbl_signin');
2629            $issue_edit_resolution .= '<div class="it__standard_feedback">'.$wmsg.'</div>';
2630        }
2631
2632
2633        //2011-12-02: bwenz code proposal (Issue 11)
2634//        $ret = $issue_edit_head . $issue_client_details . $issue_initial_description . $issue_attachments . $issue_comments_log . $issue_add_comment;
2635        $usr = '<span style="display:none;" id="currentuser">'.$user_grp['userinfo']['name'].'</span>' ;  //to log issue mods
2636        $ret = $usr.$issue_edit_head . $issue_client_details . $issue_initial_description . $issue_attachments . $issue_workaround . $issue_comments_log . $issue_add_comment . $issue_edit_resolution;
2637
2638        return $ret;
2639    }
2640
2641/******************************************************************************/
2642/******************************************************************************/
2643/* send an e-mail to user due to issue resolution
2644*/
2645    function _emailForRes($project,$issue)
2646    {       if($this->getConf('userinfo_email') ===0) return;
2647
2648            if ($this->getConf('mail_templates')==1) {
2649                // load user html mail template
2650                $sFilename = DOKU_PLUGIN.'issuetracker/mailtemplate/issue_resolved_mail.html';
2651                $bodyhtml = file_get_contents($sFilename);
2652            }
2653
2654            $subject = sprintf($this->getLang('issue_resolved_subject'),$issue['id'], $project);
2655            $subject = mb_encode_mimeheader($subject, "UTF-8", "Q" );
2656            $pstring = sprintf("showid=%s&project=%s", urlencode($issue['id']), urlencode($project));
2657            global $ID;
2658            $body = $this->getLang('issuemod_head').chr(10).chr(10).
2659                    $this->getLang('issue_resolved_intro').chr(10).
2660                    $this->getLang('issuemod_issueid').$issue['id'].chr(10).
2661                    $this->getLang('issuemod_status').$issue['status'].chr(10).
2662                    $this->getLang('issuemod_product').$issue['product'].chr(10).
2663                    $this->getLang('issuemod_version').$issue['version'].chr(10).chr(10).
2664                    $this->getLang('issue_resolved_text').$this->xs_format($issue['resolution']).chr(10).chr(10).
2665                    $this->getLang('issuemod_see').DOKU_URL.'doku.php?id='.$ID.'&do=showcaselink&'.$pstring.chr(10).chr(10).
2666                    $this->getLang('issuemod_br').chr(10).$project.$this->getLang('issuemod_end');
2667
2668            $body = html_entity_decode($body);
2669
2670            if ($this->getConf('mail_templates')==1) $bodyhtml = $this->replace_bodyhtml($bodyhtml, $pstring, $project, $issue, NULL);
2671
2672            $from=$this->getConf('email_address') ;
2673
2674            $to=$issue['user_mail'];
2675            if($to==='') $to=$this->getConf('email_address');
2676
2677            $cc=$issue['add_user_mail'].', '.$issue['assigned'];
2678            if(stripos($to.$cc,$issue['assigned'])==false) $cc .=', '.$issue['assigned'];
2679
2680            if ($this->getConf('mail_templates')==1) {
2681              $headers = "Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable";
2682              $this->mail_send_html($to, $subject, $body, $bodyhtml, $from, $cc, $bcc='', $headers, $params=null);
2683            }
2684            else {
2685              mail_send($to, $subject, $body, $from, $cc, $bcc='', $headers=null, $params=null);
2686            }
2687    }
2688/******************************************************************************/
2689/* send an e-mail to user due to issue modificaion
2690*/
2691    function _emailForIssueMod($project, $issue, $old_value, $column, $new_value)
2692    {
2693//        if ($conf['plugin']['issuetracker']['userinfo_email']==1)
2694        {   global $ID;
2695            global $lang;
2696            global $conf;
2697            if($new_value == '') $new_value = $this->getLang('it__none');
2698            if($old_value == '') $old_value = $this->getLang('it__none');
2699
2700            if ($this->getConf('mail_templates')==1) {
2701                // load user html mail template
2702                $sFilename            = DOKU_PLUGIN.'issuetracker/mailtemplate/edit_issuemod_mail.html';
2703                $bodyhtml             = file_get_contents($sFilename);
2704                $comment              = array();
2705                $comment["field"]     = $column;
2706                $comment["old_value"] = $old_value;
2707                $comment["new_value"] = $new_value;
2708                $comment["timestamp"] = date($this->getConf('d_format'));
2709                $user_mail            = pageinfo();
2710                $comment["author"]    = $user_mail['userinfo']['mail'];
2711            }
2712            //issuemod_subject = 'Issue #%s on %s: %s';
2713            $subject = sprintf($this->getLang('issuemod_subject'), $issue['id'], $project, $this->getLang('th_'.$column));
2714            $subject = mb_encode_mimeheader($subject, "UTF-8", "Q" );
2715            $pstring = sprintf("showid=%s&project=%s", urlencode($issue['id']), urlencode($project));
2716
2717            //issuemod_changes = The issue changed on %s from %s to %s.
2718            $changes = sprintf($this->getLang('issuemod_changes'),$this->getLang('th_'.$column), $old_value, $new_value);
2719
2720            $body = chr(10).$this->getLang('issuemod_head').chr(10).chr(10).
2721                    $this->getLang('issuemod_intro').chr(10).
2722                    $changes.chr(10).chr(10).
2723                    $this->getLang('issuemod_title').$issue['title'].chr(10).
2724                    $this->getLang('issuemod_issueid').$issue['id'].chr(10).
2725                    $this->getLang('issuemod_product').$issue['product'].chr(10).
2726                    $this->getLang('issuemod_version').$issue['version'].chr(10).
2727                    $this->getLang('issuemod_severity').$issue['severity'].chr(10).
2728                    $this->getLang('issuemod_status').$issue['status'].chr(10).
2729                    $this->getLang('issuemod_creator').$issue['user_name'].chr(10).
2730                    $this->getLang('issuemod_assignee').$issue['assigned'].chr(10).
2731                    $this->getLang('issuenew_descr').$issue['description'].chr(10).
2732                    $this->getLang('issuemod_see').DOKU_URL.'doku.php?id='.$ID.'&do=showcaselink&'.$pstring.chr(10).chr(10).
2733                    $this->getLang('issuemod_br').chr(10).$this->getLang('issuemod_end');
2734            $body = html_entity_decode($body);
2735            if ($this->getConf('mail_templates')==1) $bodyhtml = $this->replace_bodyhtml($bodyhtml, $pstring, $project, $issue, $comment);
2736
2737            $from=$this->getConf('email_address'). "\r\n";
2738
2739            $user_mail = pageinfo();
2740            if($user_mail['userinfo']['mail']===$issue['user_mail']) $to=$issue['assigned'];
2741            elseif($user_mail['userinfo']['mail']===$issue['assigned']) $to=$issue['user_mail'];
2742            else $to=$issue['user_mail'].', '.$issue['assigned'];
2743            if($to==='') $to=$this->getConf('email_address');
2744
2745            $cc=$issue['add_user_mail'];
2746            if ($this->getConf('mail_templates')==1) {
2747              $this->mail_send_html($to, $subject, $body, $bodyhtml, $from, $cc, $bcc='', $headers, $params=null);
2748            }
2749            else {
2750              mail_send($to, $subject, $body, $from, $cc, $bcc='', $headers=null, $params=null);
2751            }
2752        }
2753    }
2754/******************************************************************************/
2755/* send an e-mail to user due to issue modificaion
2756*/
2757    function _emailForMod($project,$issue,$comment,$reason)
2758    {       if($this->getConf('userinfo_email') ===0) return;
2759            global $ID;
2760
2761            if ($this->getConf('mail_templates')==1) {
2762                // load user html mail template
2763                $sFilename = DOKU_PLUGIN.'issuetracker/mailtemplate/cmnt_mod_mail.html';
2764                $bodyhtml = file_get_contents($sFilename);
2765            }
2766            if($reason     =='new')        { $subject = sprintf($this->getLang('cmnt_new_subject'),$issue['id'], $project). "\r\n"; }
2767            elseif($reason =='delete')     { $subject = sprintf($this->getLang('cmnt_del_subject'),$issue['id'], $project). "\r\n"; }
2768            elseif($reason =='workaround') { $subject = sprintf($this->getLang('cmnt_wa_subject') ,$issue['id'], $project). "\r\n"; }
2769            else {                           $subject = sprintf($this->getLang('cmnt_mod_subject'),$issue['id'], $project). "\r\n"; }
2770
2771            $subject = mb_encode_mimeheader($subject, "UTF-8", "Q" );
2772            $pstring = sprintf("showid=%s&project=%s", urlencode($issue['id']), urlencode($project));
2773
2774            if($reason =='delete') {
2775              $body2     = $this->getLang('cmt_del_intro').chr(10).chr(13);
2776              $bodyhtml = str_ireplace("%%bodyhtml2%%",$this->getLang('cmt_del_intro'),$bodyhtml);
2777            }
2778            elseif($reason =='workaround') {
2779              $body2 = $this->getLang('issuemod_intro').chr(10).chr(13);
2780              $bodyhtml = str_ireplace("%%bodyhtml2%%",$this->getLang('issuemod_intro'),$bodyhtml);
2781              $body3 = $this->getLang('issuemod_cmntauthor').$comment['author'].chr(10).
2782                       $this->getLang('issuemod_date').date($this->getConf('d_format'),strtotime($comment['timestamp'])).chr(10).
2783                       $this->getLang('issuemod_cmnt').chr(10).$this->xs_format($comment['wround_mod']).chr(10).chr(10);
2784            }else {
2785              $body2 = $this->getLang('issuemod_intro').chr(10).chr(13);
2786              $bodyhtml = str_ireplace("%%bodyhtml2%%",$this->getLang('issuemod_intro'),$bodyhtml);
2787              $body3 = $this->getLang('issuemod_cmntauthor').$comment['author'].chr(10).
2788                       $this->getLang('issuemod_date').date($this->getConf('d_format'),strtotime($comment['timestamp'])).chr(10).
2789                       $this->getLang('issuemod_cmnt').chr(10).$this->xs_format($comment['comment']).chr(10).chr(10);
2790            }
2791
2792            $body = $this->getLang('issuemod_head').chr(10).chr(10).
2793                    $body2.
2794                    $this->getLang('issuemod_title').$issue['title'].chr(10).
2795                    $this->getLang('issuemod_issueid').$issue['id'].chr(10).
2796                    $this->getLang('issuemod_product').$issue['product'].chr(10).
2797                    $this->getLang('issuemod_version').$issue['version'].chr(10).
2798                    $this->getLang('issuemod_severity').$issue['severity'].chr(10).
2799                    $this->getLang('issuemod_status').$issue['status'].chr(10).
2800                    $this->getLang('issuemod_creator').$issue['user_name'].chr(10).
2801                    $this->getLang('issuemod_assignee').$issue['assigned'].chr(10).
2802                    $body3.
2803                    $this->getLang('issuemod_see').DOKU_URL.'doku.php?id='.$ID.'&do=showcaselink&'.$pstring.chr(10).chr(10).
2804                    $this->getLang('issuemod_br').chr(10).$project.$this->getLang('issuemod_end'). "\r\n";
2805
2806            $body = html_entity_decode($body);
2807
2808            if ($this->getConf('mail_templates')==1) $bodyhtml = $this->replace_bodyhtml($bodyhtml, $pstring, $project, $issue, $comment);
2809
2810            $from=$this->getConf('email_address'). "\r\n";
2811
2812            $user_mail = pageinfo();
2813            if($user_mail['userinfo']['mail']===$issue['user_mail']) $to=$issue['assigned'];
2814            elseif($user_mail['userinfo']['mail']===$issue['assigned']) $to=$issue['user_mail'];
2815            else $to=$issue['user_mail'].', '.$issue['assigned'];
2816            if(strlen($to)<3) $to=$this->getConf('email_address');
2817
2818            $cc=$issue['add_user_mail'];
2819            if ($this->getConf('mail_templates')==1) {