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&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> '. 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&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&project=%s", urlencode($this->_get_one_value($issue,'id')), urlencode($this->_get_one_value($issue,'project'))); 1159 $pstring = sprintf("showid=%s&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&project=%s", urlencode($this->_get_one_value($issue,'id')), urlencode($this->_get_one_value($issue,'project'))); 1274 $pstring = sprintf("showid=%s&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%"> </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&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> ['.$issue[$issue_id]['id'].'] </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.' /> </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&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.'"> '.$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.'"> '.$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> 2374 <label>'.date($this->getConf('d_format'),strtotime($this->_get_one_value($a_comment,'timestamp'))).' </label> '.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" > [modified: '.date($this->getConf('d_format'),strtotime($this->_get_one_value($a_comment,'mod_timestamp'))).'] '.$insert_lbl.' </label> '.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.'"> '.$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 = " "; } 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& 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) { 2820 $this->mail_send_html($to, $subject, $body, $bodyhtml, $from, $cc, $bcc='', $headers, $params=null); 2821 } 2822 else { 2823 mail_send($to, $subject, $body, $from, $cc, $bcc='', $headers=null, $params=null); 2824 } 2825 } 2826/******************************************************************************/ 2827/* send an e-mail to user due to issue modificaion on Descriptions 2828*/ 2829 function _emailForDscr($project,$issue) 2830 { if($this->getConf('userinfo_email') ===0) return; 2831 global $ID; 2832 2833 if ($this->getConf('mail_templates')==1) { 2834 // load user html mail template 2835 $sFilename = DOKU_PLUGIN.'issuetracker/mailtemplate/issue_descr_mail.html'; 2836 $bodyhtml = file_get_contents($sFilename); 2837 } 2838 $subject = sprintf($this->getLang('issuedescrmod_subject'),$issue['id'], $project). "\r\n"; 2839 $subject = mb_encode_mimeheader($subject, "UTF-8", "Q" ); 2840 $pstring = sprintf("showid=%s&project=%s", urlencode($issue['id']), urlencode($project)); 2841 global $ID; 2842 2843 $body = $this->getLang('issuemod_head').chr(10).chr(10). 2844 $this->getLang('issuemod_intro').chr(10).chr(13). 2845 $this->getLang('issuemod_title').$issue['title'].chr(10). 2846 $this->getLang('issuemod_issueid').$issue['id'].chr(10). 2847 $this->getLang('issuemod_product').$issue['product'].chr(10). 2848 $this->getLang('issuemod_version').$issue['version'].chr(10). 2849 $this->getLang('issuemod_severity').$issue['severity'].chr(10). 2850 $this->getLang('issuemod_status').$issue['status'].chr(10). 2851 $this->getLang('issuemod_creator').$issue['user_name'].chr(10). 2852 $this->getLang('issuemod_assignee').$issue['assigned'].chr(10).chr(10). 2853 $this->getLang('issuemod_date').date($this->getConf('d_format'),strtotime($comment['timestamp'])).chr(10).chr(10). 2854 $this->getLang('th_description').chr(10).$issue['description'].chr(10).chr(10). 2855 $this->getLang('issuemod_see').DOKU_URL.'doku.php?id='.$ID.'&do=showcaselink&'.$pstring.chr(10).chr(10). 2856 $this->getLang('issuemod_br').chr(10).$project.$this->getLang('issuemod_end'). "\r\n"; 2857 2858 if ($this->getConf('mail_templates')==1) $bodyhtml = $this->replace_bodyhtml($bodyhtml, $pstring, $project, $issue, $comment); 2859 2860 $body = html_entity_decode($body); 2861 $from=$this->getConf('email_address'). "\r\n"; 2862 2863 $user_mail = pageinfo(); 2864 if($user_mail['userinfo']['mail']===$issue['user_mail']) $to=$issue['assigned']. "\r\n"; 2865 elseif($user_mail['userinfo']['mail']===$issue['assigned']) $to=$issue['user_mail']. "\r\n"; 2866 else $to=$issue['user_mail'].', '.$issue['assigned']. "\r\n"; 2867 2868 $cc=$issue['add_user_mail']. "\r\n"; 2869 if ($this->getConf('mail_templates')==1) { 2870 $this->mail_send_html($to, $subject, $body, $bodyhtml, $from, $cc, $bcc='', $headers, $params=null); 2871 } 2872 else { 2873 mail_send($to, $subject, $body, $from, $cc, $bcc='', $headers=null, $params=null); 2874 } 2875 } 2876/******************************************************************************/ 2877 /*********************************** 2878 * HTML Mail functions 2879 * 2880 * Sends HTML-formatted mail 2881 * By Lin Junjie (mail [dot] junjie [at] gmail [dot] com) 2882 * 2883 ***********************************/ 2884 function mail_send_html($to, $subject, $body, $bodyhtml, $from='', $cc='', $bcc='', $header='', $params=null){ 2885 if(defined('MAILHEADER_ASCIIONLY')){ 2886 $subject = utf8_deaccent($subject); 2887 $subject = utf8_strip($subject); 2888 } 2889 2890 if(!defined('MAILHEADER_EOL')) define('MAILHEADER_EOL',"\n"); 2891 if(!utf8_isASCII($subject)) { 2892 $subject = '=?UTF-8?Q?'.mail_quotedprintable_encode($subject,0).'?='; 2893 // Spaces must be encoded according to rfc2047. Use the "_" shorthand 2894 $subject = preg_replace('/ /', '_', $subject); 2895 } 2896 2897 $header = ''; 2898 2899 $usenames = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? false : true; 2900 2901 $random_hash = md5(date('r', time())); // added 2902 2903 $to = mail_encode_address($to,'',$usenames); 2904 $header .= mail_encode_address($from,'From'); 2905 $header .= mail_encode_address($cc,'Cc'); 2906 $header .= mail_encode_address($bcc,'Bcc'); 2907 $header .= 'MIME-Version: 1.0'.MAILHEADER_EOL; 2908 $header .= "Content-Type: multipart/alternative; boundary=PHP-alt-".$random_hash.MAILHEADER_EOL; 2909 $header = trim($header); 2910 2911 2912 $body = mail_quotedprintable_encode($body,0); 2913 $bodyhtml = mail_quotedprintable_encode($bodyhtml,0); 2914 2915 $message = "--PHP-alt-".$random_hash."\r\n". 2916 "Content-Type: text/plain; charset=UTF-8"."\n". 2917 "Content-Transfer-Encoding: quoted-printable"."\n\n". 2918 $body."\n\n". 2919 "--PHP-alt-".$random_hash."\r\n". 2920 "Content-Type: text/html; charset=UTF-8"."\n". 2921 "Content-Transfer-Encoding: quoted-printable"."\n\n". 2922 $bodyhtml."\n". 2923 "--PHP-alt-".$random_hash."--"; 2924 2925 if($params == null){ 2926 return @mail($to,$subject,$message,$header); 2927 }else{ 2928 return @mail($to,$subject,$message,$header,$params); 2929 } 2930 } 2931 2932/******************************************************************************/ 2933 function replace_bodyhtml($bodyhtml, $pstring, $project, $issue, $comment) { 2934 global $ID; 2935// echo "ID = ". $ID . "<br />"; 2936 $bodyhtml = str_ireplace("%%_SEE%%",DOKU_URL.'doku.php?id='.$ID.'&do=showcaselink&'.$pstring,$bodyhtml); 2937 $bodyhtml = str_ireplace("%%issuemod_head%%",$this->getLang('issuemod_head'),$bodyhtml); 2938 $bodyhtml = str_ireplace("%%issuemod_intro%%",$this->getLang('issuemod_intro'),$bodyhtml); 2939 2940 $bodyhtml = str_ireplace("%%issuemod_issueid%%",$this->getLang('issuemod_issueid'),$bodyhtml); 2941 $bodyhtml = str_ireplace("%%ID%%",$issue['id'],$bodyhtml); 2942 $bodyhtml = str_ireplace("%%issuemod_title%%",$this->getLang('issuemod_title'),$bodyhtml); 2943 $bodyhtml = str_ireplace("%%TITEL%%",$issue['title'],$bodyhtml); 2944 $bodyhtml = str_ireplace("%%issuemod_status%%",$this->getLang('issuemod_status'),$bodyhtml); 2945 $bodyhtml = str_ireplace("%%STATUS%%",$issue['status'],$bodyhtml); 2946 $bodyhtml = str_ireplace("%%th_project%%",$this->getLang('th_project'),$bodyhtml); 2947 $bodyhtml = str_ireplace("%%PROJECT%%",$project,$bodyhtml); 2948 $bodyhtml = str_ireplace("%%issuemod_product%%",$this->getLang('issuemod_product'),$bodyhtml); 2949 $bodyhtml = str_ireplace("%%PRODUCT%%",$issue['product'],$bodyhtml); 2950 $bodyhtml = str_ireplace("%%issuemod_version%%",$this->getLang('issuemod_version'),$bodyhtml); 2951 $bodyhtml = str_ireplace("%%VERSION%%",$issue['version'],$bodyhtml); 2952 $bodyhtml = str_ireplace("%%issuemod_severity%%",$this->getLang('issuemod_severity'),$bodyhtml); 2953 $bodyhtml = str_ireplace("%%SEVERITY%%",$issue['severity'],$bodyhtml); 2954 $bodyhtml = str_ireplace("%%issuemod_creator%%",$this->getLang('issuemod_creator'),$bodyhtml); 2955 $bodyhtml = str_ireplace("%%CREATOR%%",$issue['user_name'],$bodyhtml); 2956 $bodyhtml = str_ireplace("%%CREATOR_MAIL%%",$issue['user_mail'],$bodyhtml); 2957 $bodyhtml = str_ireplace("%%th_assigned%%",$this->getLang('th_assigned'),$bodyhtml); 2958 $bodyhtml = str_ireplace("%%ASSIGNED%%",$issue['assigned'],$bodyhtml); 2959 $bodyhtml = str_ireplace("%%th_created%%",$this->getLang('th_created'),$bodyhtml); 2960 $bodyhtml = str_ireplace("%%CREATED%%",$issue['created'],$bodyhtml); 2961 $bodyhtml = str_ireplace("%%issueassigned_head%%",$lang['issueassigned_head'],$bodyhtml); 2962 $bodyhtml = str_ireplace("%%issueassigned_intro%%",$lang['issueassigned_intro'],$bodyhtml); 2963 2964 $bodyhtml = str_ireplace("%%issue_resolved_intro%%",$this->getLang('issue_resolved_intro'),$bodyhtml); 2965 $bodyhtml = str_ireplace("%%issue_resolved_text%%",$this->getLang('issue_resolved_text'),$bodyhtml); 2966 $frmt_res = str_ireplace(chr(10),"<br />",$issue['resolution']); 2967 $bodyhtml = str_ireplace("%%RESOLUTION%%",$this->xs_format($frmt_res),$bodyhtml); 2968 $bodyhtml = str_ireplace("%%TIMESTAMP%%",date($this->getConf('d_format')),$bodyhtml); 2969 2970 $user_grp = pageinfo(); 2971 $usr = $user_grp['userinfo']['name'] ; 2972 $bodyhtml = str_ireplace("%%RESOLVER%%",$usr,$bodyhtml); 2973 $bodyhtml = str_ireplace("%%MOD_BY%%",$usr,$bodyhtml); 2974 $bodyhtml = str_ireplace("%%issuedescrmod_subject%%",sprintf($this->getLang('issuedescrmod_subject'),$issue['id'], $project),$bodyhtml); 2975 $bodyhtml = str_ireplace("%%th_description%%",$this->getLang('th_description'),$bodyhtml); 2976 $frmt_descr = str_ireplace(chr(10),"<br />",$issue['description']); 2977 $bodyhtml = str_ireplace("%%DESCRIPTION%%",$this->xs_format($frmt_descr),$bodyhtml); 2978 2979 2980// if($comment) { 2981 $bodyhtml = str_ireplace("%%lbl_cmts_wlog%%",$this->getLang('lbl_cmts_wlog'),$bodyhtml); 2982 $bodyhtml = str_ireplace("%%CMNT_ID%%",$comment['id'],$bodyhtml); 2983 $bodyhtml = str_ireplace("%%EDIT_AUTHOR%%",$comment['author'],$bodyhtml); 2984 $bodyhtml = str_ireplace("%%CMNT_AUTHOR%%",$comment['author'],$bodyhtml); 2985 $bodyhtml = str_ireplace("%%CMNT_TIMESTAMP%%",date($this->getConf('d_format'),strtotime($comment['timestamp'])),$bodyhtml); 2986 $frmt_cmnt = str_ireplace(chr(10),"<br />",$comment['comment']); 2987 $bodyhtml = str_ireplace("%%COMMENT%%",$this->xs_format($frmt_cmnt),$bodyhtml); 2988 $bodyhtml = str_ireplace("%%FIELD%%",str_ireplace(chr(10),"<br />",$comment["field"]),$bodyhtml); 2989 $bodyhtml = str_ireplace("%%OLD_VALUE%%",$this->xs_format(str_ireplace(chr(10),"<br />",$comment["old_value"])),$bodyhtml); 2990 $bodyhtml = str_ireplace("%%NEW_VALUE%%",$this->xs_format(str_ireplace(chr(10),"<br />",$comment["new_value"])),$bodyhtml); 2991// } 2992 $bodyhtml = str_ireplace("%%issuemod_br%%",$this->getLang('issuemod_br'),$bodyhtml); 2993 $bodyhtml = str_ireplace("%%issuemod_end%%",$this->getLang('issuemod_end'),$bodyhtml); 2994 2995// echo $bodyhtml; 2996 2997 return $bodyhtml; 2998 } 2999/******************************************************************************/ 3000/* pic-up a single value 3001*/ 3002 function _get_one_value($issue, $key) { 3003// echo $key. " => " . $issue . "<br />"; 3004 if (@array_key_exists($key,$issue)) return $issue[$key]; 3005 else return ''; 3006 } 3007/******************************************************************************/ 3008/* elaborate the display string of assignee (login, name or mail) 3009*/ 3010 function _get_assignee($issue, $key) { 3011 if (array_key_exists($key,$issue)) { 3012 global $auth; 3013 global $conf; 3014 3015 $filter['grps'] = $this->getConf('assign'); 3016 $usr_array = $auth->retrieveUsers(0,0,$filter); 3017 $shw_assignee_as = trim($this->getConf('shw_assignee_as')); 3018 3019 if(stripos("login, mail, name",$shw_assignee_as) === false) $shw_assignee_as = "login"; 3020 foreach ($usr_array as $u_key => $usr) 3021 { if($usr['mail']==$issue[$key]) 3022 { if ($shw_assignee_as == 'login') { return $u_key; } 3023 elseif($shw_assignee_as == 'mail') { return $usr['mail']; } 3024 else { return $usr['name']; } 3025 } 3026 } 3027 } 3028 if(stripos("mail",$shw_assignee_as) !== false) { return $issue[$key]; } 3029 else 3030 { $b_display = explode("@",$issue[$key]); 3031 return $b_display[0]; 3032 } 3033 } 3034/******************************************************************************/ 3035/* Captcha OK 3036*/ 3037 function _captcha_ok() 3038 { 3039 $helper = null; 3040 if(@is_dir(DOKU_PLUGIN.'captcha')) $helper = plugin_load('helper','captcha'); 3041 3042 if(!is_null($helper) && $helper->isEnabled()) { return $helper->check(); } 3043 3044 return ($this->getConf('use_captcha')); 3045 } 3046 3047/******************************************************************************/ 3048/* Create count output 3049*/ 3050 function _count_render($issues,$start,$step,$next_start,$filter,$project) 3051 { global $ID; 3052 $count = array(); 3053 foreach ($issues as $issue) 3054 { 3055 if(($issue['project'] !== $project) && ($this->getConf('multi_projects')==0)) { 3056 continue; 3057 } 3058 elseif ((strcasecmp($filter['product'],'ALL')===0) || (stristr($filter['product'],$this->_get_one_value($issue,'product'))!= false)) 3059 { $status = trim($this->_get_one_value($issue,'status')); 3060 $a_count = $a_count + 1; 3061 if (($status != '') && (stripos($this->getConf('status_special'),$status)===false)) 3062 { if ($this->_get_one_value($count,strtoupper($status))=='') 3063 {$count[strtoupper($status)] = array(1,$status);} 3064 else 3065 {$count[strtoupper($status)][0] += 1;} 3066 } 3067 } 3068 } 3069 $rendered_count = '<div class="itl__count_div">'.'<table class="itl__count_tbl">'; 3070 foreach ($count as $value) 3071 { 3072 //http://www.fristercons.de/fcon/doku.php?id=issuetracker:issuelist&do=showcaselink&showid=19&project=fcon_project 3073 // $ID.'&do=issuelist_filter&itl_sev_filter='.$value[1] 3074 $rendered_count .= '<tr><td><a href="'.DOKU_URL.'doku.php?id='.$ID.'&do=issuelist_filterlink'.'&itl_start='.$start.'&itl_step='.$step.'&itl_next='.$next_start.'&itl_stat_filter='.$value[1].'&itl_sev_filter='.$filter['severity'].'&itl__prod_filter='.$filter['product'].'&itl_project='.$project.'" >'.$value[1].'</a> </td><td> '.$value[0].'</td></tr>'; 3075 } 3076 $rendered_count .= '</table></div>'; 3077 $ret_array = array($a_count,$rendered_count); 3078 return $ret_array; 3079 } 3080/******************************************************************************/ 3081/* replace simple formats used by editor buttons 3082*/ 3083 function xs_format($x_comment) 3084 { // bold , italic, underline, etc. 3085 $x_comment = preg_replace('/\[([bius])\]/i', '<\\1>', $x_comment); 3086 $x_comment = preg_replace('/\[\/([bius])\]/i', '</\\1>', $x_comment); 3087 3088 $x_comment = preg_replace('/\[ol\]/i', '<ol>', $x_comment); 3089 $x_comment = preg_replace('/\[\/ol\]/i', '</ol>', $x_comment); 3090 3091 $x_comment = preg_replace('/\[ul\]/i', '<ul>', $x_comment); 3092 $x_comment = preg_replace('/\[\/ul\]/i', '</ul>', $x_comment); 3093 3094 $x_comment = preg_replace('/\[li\]/i', '<li>', $x_comment); 3095 $x_comment = preg_replace('/\[\/li\]/i', '</li>', $x_comment); 3096 3097 $x_comment = preg_replace('/\[sup\]/i', '<sup>', $x_comment); 3098 $x_comment = preg_replace('/\[\/sup\]/i', '</sup>', $x_comment); 3099 3100 $x_comment = preg_replace('/\[sub\]/i', '<sub>', $x_comment); 3101 $x_comment = preg_replace('/\[\/sub\]/i', '</sub>', $x_comment); 3102 3103 $x_comment = preg_replace('/\[hr\]/i', '<hr>', $x_comment); 3104 3105 $x_comment = preg_replace('/\[blockquote\]/i', '<blockquote>', $x_comment); 3106 $x_comment = preg_replace('/\[\/blockquote\]/i', '</blockquote>', $x_comment); 3107 3108 $x_comment = preg_replace('/\[code\]/i', '<div class="it_code"><code>', $x_comment); 3109 $x_comment = preg_replace('/\[\/code\]/i', '</code></div>', $x_comment); 3110 3111 $x_comment = preg_replace('/\[red\]/i', '<span style="color:red;">', $x_comment); 3112 $x_comment = preg_replace('/\[\/red\]/i', '</span>', $x_comment); 3113 3114 $x_comment = preg_replace('/\[grn\]/i', '<span style="color:green;">', $x_comment); 3115 $x_comment = preg_replace('/\[\/grn\]/i', '</span>', $x_comment); 3116 3117 $x_comment = preg_replace('/\[bgy\]/i', '<span style="background:yellow;">', $x_comment); 3118 $x_comment = preg_replace('/\[\/bgy\]/i', '</span>', $x_comment); 3119 3120 $x_comment = preg_replace('/\[blu\]/i', '<span style="color:blue;">', $x_comment); 3121 $x_comment = preg_replace('/\[\/blu\]/i', '</span>', $x_comment); 3122 3123 $urlsuch[]="/([^]_a-z0-9-=\"'\/])((https?|ftp):\/\/|www\.)([^ \r\n\(\)\^\$!`\"'\|\[\]\{\}<>]*)/si"; 3124 $urlsuch[]="/^((https?|ftp):\/\/|www\.)([^ \r\n\(\)\^\$!`\"'\|\[\]\{\}<>]*)/si"; 3125 $urlreplace[]="\\1[link]\\2\\4[/link]"; 3126 $urlreplace[]="[link]\\1\\3[/link]"; 3127 $x_comment = preg_replace($urlsuch, $urlreplace, $x_comment); 3128 $x_comment = preg_replace("/\[link\]www.(.*?)\[\/link\]/si", "<a target=\"_blank\" href=\"http://www.\\1\">www.\\1</a>", $x_comment); 3129 $x_comment = preg_replace("/\[link=www.(.*?)\](.*?)\[\/link\]/si", "<a target=\"_blank\" href=\"http://www.\\1\">\\2</a>", $x_comment); 3130 $x_comment = preg_replace("/\[link\](\:.*?)\[\/link\]/si", "<a target=\"_blank\" href=\"doku.php?id=\\1\">\\1</a>", $x_comment); 3131 $x_comment = preg_replace("/\[link=(\:.*?)\]\[\/link\]/si", "<a target=\"_blank\" href=\"doku.php?id=\\1\">\\1</a>", $x_comment); 3132 $x_comment = preg_replace("/\[link=(\:.*?)\](.*?)\[\/link\]/si", "<a target=\"_blank\" href=\"doku.php?id=\\1\">\\2</a>", $x_comment); 3133 $x_comment = preg_replace("/\[link\](.*?)\[\/link\]/si", "<a target=\"_blank\" href=\"\\1\">\\1</a>", $x_comment); 3134 $x_comment = preg_replace("/\[link=(.*?)\](.*?)\[\/link\]/si", "<a target=\"_blank\" href=\"\\1\">\\2</a>", $x_comment); 3135 3136 $x_comment = preg_replace("/\[img\](http.*?)\[\/img\]/si", "<img src=\"\\1\"title=\"\\1\" alt=\"\\1\" style=\"max-width:850px;\" \/>", $x_comment); 3137 $x_comment = preg_replace("/\[img=(http.*?)\](.*?)\[\/img\]/si", "<img src=\"\\1\" title=\"\\2\" alt=\"\\1\" style=\"max-width:850px;\" \/>", $x_comment); 3138 $x_comment = preg_replace("/\[img\](file.*?)\[\/img\]/si", "<img src=\"\\1\" title=\"\\1\" alt=\"\\1\" style=\"max-width:850px;\" \/>", $x_comment); 3139 $x_comment = preg_replace("/\[img=(file.*?)\](.*?)\[\/img\]/si", "<img src=\"\\1\" title=\"\\2\" alt=\"\\1\" style=\"max-width:850px;\" \/>", $x_comment); 3140 $x_comment = preg_replace("/\[img\](\:.*?)\[\/img\]/si", "<img src=\"". DOKU_URL . "lib/exe/fetch.php?media=\\1\" title=\"\\1\" alt=\"\\1\" style=\"max-width:850px;\" \/>", $x_comment); 3141 $x_comment = preg_replace("/\[img=(\:.*?)\](.*?)\[\/img\]/si", "<img src=\"". DOKU_URL . "lib/exe/fetch.php?media=\\1\" title=\"\\2\" alt=\"\\1\" style=\"max-width:850px;\" \/>", $x_comment); 3142 $x_comment = preg_replace("/\[img\](.*?)\[\/img\]/si", "<img src=\"\\1\" title=\"\\1\" style=\"max-width:850px;\" \/>", $x_comment); 3143 $x_comment = preg_replace("/\[img=(.*?)\](.*?)\[\/img\]/si", "<img src=\"\\1\" title=\"\\2\" style=\"max-width:850px;\" \/>", $x_comment); 3144 3145 3146/*--------------------------------------------------------------------------------- 3147* think about parsing content by dokuwiki renderer for dokuwiki syntax recognition 3148* $x_comment = p_render('xhtml',p_get_instructions($x_comment),$info); 3149* take care to strip IssueTracker syntax to prevent endless loop 3150---------------------------------------------------------------------------------*/ 3151 3152 return $x_comment; 3153 } 3154/******************************************************************************/ 3155/* return html-code for edit toolbar 3156*/ 3157 function it_wysiwyg_edit_toolbar($xa_comment) { 3158 $sFilename = DOKU_BASE."lib/plugins/issuetracker/wysiwyg_editor.js"; 3159 $it_edit_tb .= '<script type="text/javascript" src="'.$sFilename.'"></script>'; 3160 $sFilename = DOKU_PLUGIN.'issuetracker/wysiwyg_editor.html'; 3161 $it_edit_tb .= file_get_contents($sFilename); 3162 $it_edit_tb = str_ireplace("%%DOKU_BASE%%",DOKU_BASE,$it_edit_tb); 3163 $trans=get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES); 3164 $trans=array_flip($trans); 3165 $x_comment=strtr($xa_comment, $trans); 3166 3167 3168 $it_edit_tb = str_ireplace('<p> </p>',$x_comment,$it_edit_tb); 3169 return $it_edit_tb; 3170 } 3171 3172 function it_xs_edit_toolbar($type) { 3173 $imgBASE = DOKU_BASE."lib/plugins/issuetracker/images/"; 3174 $it_edit_tb = '<div class="it_edittoolbar">'.NL; 3175 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."bold.png\" name=\"btnBold\" title=\"Bold\" onClick=\"doAddTags('[b]','[/b]','$type')\">".NL; 3176 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."italic.png\" name=\"btnItalic\" title=\"Italic\" onClick=\"doAddTags('[i]','[/i]','$type')\">".NL; 3177 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."underline.png\" name=\"btnUnderline\" title=\"Underline\" onClick=\"doAddTags('[u]','[/u]','$type')\">".NL; 3178 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."strikethrough.png\" name=\"btnStrike\" title=\"Strike through\" onClick=\"doAddTags('[s]','[/s]','$type')\">".NL; 3179 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."subscript.png\" name=\"btnSubscript\" title=\"Subscript\" onClick=\"doAddTags('[sub]','[/sub]','$type')\">".NL; 3180 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."superscript.png\" name=\"btnSuperscript\" title=\"Superscript\" onClick=\"doAddTags('[sup]','[/sup]','$type')\">".NL; 3181 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."hr.png\" name=\"btnLine\" title=\"hLine\" onClick=\"doHLine('[hr]','$type')\">".NL; 3182 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."ordered.png\" name=\"btn_o_List\" title=\"Ordered List\" onClick=\"doList('[ol]','[/ol]','$type')\">".NL; 3183 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."unordered.png\" name=\"btn_u_List\" title=\"Unordered List\" onClick=\"doList('[ul]','[/ul]','$type')\">".NL; 3184 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."quote.png\" name=\"btnQuote\" title=\"Quote\" onClick=\"doAddTags('[blockquote]','[/blockquote]','$type')\">".NL; 3185 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."code.png\" name=\"btnCode\" title=\"Code\" onClick=\"doAddTags('[code]','[/code]','$type')\">".NL; 3186 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."pen_red.png\" name=\"btnRed\" title=\"Red\" onClick=\"doAddTags('[red]','[/red]','$type')\">".NL; 3187 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."pen_green.png\" name=\"btnGreen\" title=\"Green\" onClick=\"doAddTags('[grn]','[/grn]','$type')\">".NL; 3188 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."pen_blue.png\" name=\"btnBlue\" title=\"Blue\" onClick=\"doAddTags('[blu]','[/blu]','$type')\">".NL; 3189 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."bg_yellow.png\" name=\"btn_bgYellow\" title=\"bgYellow\" onClick=\"doAddTags('[bgy]','[/bgy]','$type')\">".NL; 3190 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."link.png\" name=\"btn_link\" title=\"Link\" onClick=\"doAddTags('[link]','[/link]','$type')\">".NL; 3191 $it_edit_tb .= "<img class=\"xseditor_button\" src=\"".$imgBASE."img.png\" name=\"btn_img\" title=\"Image - max width 850px\" onClick=\"doAddTags('[img]','[/img]','$type')\">".NL; 3192 $it_edit_tb .= "<a href=\"http://www.imageshack.us/\" target=\"_blank\"><<img class=\"xseditor_button\" src=\"".$imgBASE."imageshack.png\" name=\"btn_ishack\" title=\"ImageShack upload (ext TaC !)\">></a>".NL; 3193 $it_edit_tb .= "<br></div>".NL; 3194 return $it_edit_tb; 3195 } 3196/******************************************************************************/ 3197 function get_issues_file_contents($project, $issue_id) { 3198 if($this->getConf('it_data')==false) $pfile = DOKU_CONF."../data/meta/".$project.'.issues'; 3199 else $pfile = DOKU_CONF."../". $this->getConf('it_data').$project.'.issues'; 3200 if ((@file_exists($pfile)) && (strlen($project)>1)) 3201 { $issue = unserialize(@file_get_contents($pfile)); 3202 // check if ID exist 3203 $cFlag = false; 3204 foreach ($issue as $issue_item) { 3205 if ($issue_item['id'] == $issue_id) { 3206 $cFlag = true; 3207 return $issue; 3208 break; 3209 } 3210 } 3211 if ($cFlag === false) { 3212 // promt error message that issue with this ID does not exist 3213 $Generated_Header = '<div class="it__negative_feedback">'.$this->getLang('msg_issuemissing').$issue_id.'.</div><br />'; 3214// echo $Generated_Header; 3215 return; 3216 } 3217 } 3218 else 3219 { // promt error message that issue with ID does not exist 3220 $Generated_Header = '<div class="it__negative_feedback">'.sprintf($this->getLang('msg_pfilemissing'),$pfile).'</div><br />'; 3221// echo $Generated_Header; 3222 return; 3223 } 3224 } 3225/******************************************************************************/ 3226/* sort the issues array according the selected key */ 3227 function _issues_globalsort($issues, $sort_key) { 3228/* $tmp = Array(); 3229 foreach($issues as &$ma) $tmp[] = &$ma[$sort_key]; 3230 array_multisort($tmp, $issues); */ 3231 foreach ($issues as $key => $row) { 3232 $down[$key] = $row['id']; 3233 $up[$key] = $row[$sort_key]; 3234 } 3235 if($up) { @array_multisort($up, constant($this->getConf('global_sort')), $down, SORT_ASC, $issues); } 3236 return $issues; 3237 } 3238/******************************************************************************/ 3239/* log issue modificaions 3240 * who changed what and when per issue 3241*/ 3242 function _log_mods($project, $issue, $usr, $column, $old_value, $new_value) 3243 { global $conf; 3244 // get mod-log file contents 3245 $issue_id = $issue['id']; 3246 if($this->getConf('it_data')==false) $modfile = DOKU_CONF."../data/meta/".$project.'_'.$issue_id.'.mod-log'; 3247 else $modfile = DOKU_CONF."../". $this->getConf('it_data').$project.'_'.$issue_id.'.mod-log'; 3248 if (@file_exists($modfile)) 3249 {$mods = unserialize(@file_get_contents($modfile));} 3250 else 3251 {$mods = array();} 3252 $cur_date = date($this->getConf('d_format')); 3253 $mod_id = count($mods); 3254 if($new_value=='') $new_value = $this->getLang('mod_valempty'); 3255 $mods[$mod_id]['timestamp'] = $cur_date; 3256 $mods[$mod_id]['user'] = $usr; 3257 $mods[$mod_id]['field'] = $column; 3258 $mods[$mod_id]['old_value'] = $old_value; 3259 $mods[$mod_id]['new_value'] = $new_value; 3260 // Save issues file contents 3261 $fh = fopen($modfile, 'w'); 3262 fwrite($fh, serialize($mods)); 3263 fclose($fh); 3264 } 3265/******************************************************************************/ 3266/* replace special characters in file names like German "Umlaute" 3267*/ 3268 function img_name_encode($f_name) { 3269 $umlaute = explode(',',$this->getLang('umlaute')); 3270 $replace = explode(',',$this->getLang('conv_umlaute')); 3271 if((count($umlaute)>1) && (count($replace)>1)) $f_name = str_replace($umlaute, $replace, $f_name); 3272 //preg_replace($umlaute, $replace, $f_name); 3273 3274 $f_name = strtolower($f_name); 3275 return $f_name; 3276 } 3277/******************************************************************************/ 3278 3279/******************************************************************************* 3280* The eventhandlers to catch profile updates (e-mail address) 3281*******************************************************************************/ 3282/* -------------------------------------------------------------------------- */ 3283 function handle_usermod_before(&$event, $param) 3284 { if($this->getConf('profile_updt')==false) return; 3285 if($this->getConf('it_data')==false) $filename = DOKU_CONF."../data/meta/it_eventcheck.txt"; 3286 else $filename = DOKU_CONF."../". $this->getConf('it_data').'it_eventcheck.txt'; 3287 3288 if (!$handle = fopen($filename, 'w')) { 3289 msg("IssueTracker: Failed to create the eventcheck file.",-1); 3290 return; 3291 } 3292 // search dokuwiki user-db for client and e-mail address before change 3293 // store it for AFTER event comparison 3294 global $auth; 3295 $user = array(); 3296 $user['microtime_start'] = microtime(true); 3297 $user['client'] = $event->data['params'][0]; 3298 $usr_info = $auth->getUserData($user['client']); 3299 $user['name'] = $usr_info['name']; 3300 $user['mail'] = $usr_info['mail']; 3301 3302 fwrite($handle, serialize($user)); 3303// fwrite($handle, $eve); 3304 3305 fclose($handle); 3306 } 3307/* -------------------------------------------------------------------------- */ 3308 function handle_usermod_after(&$event, $param) 3309 { //$filename = DOKU_INC . 'it_eventcheck.txt'; 3310 if($this->getConf('profile_updt')==false) return; 3311 if($this->getConf('it_data')==false) $filename = DOKU_CONF."../data/meta/it_eventcheck.txt"; 3312 else $filename = DOKU_CONF."../". $this->getConf('it_data').'it_eventcheck.txt'; 3313 3314 global $auth; 3315 $result .= "* function handle_usermod_after".chr(10); 3316 $user = array(); 3317 $user['client'] = $event->data['params'][0]; 3318 $usr_info = $auth->getUserData($user['client']); 3319 $user['name'] = $usr_info['name']; 3320 $user['mail'] = $usr_info['mail']; 3321 3322 $user_before = unserialize(@file_get_contents($filename)); 3323 $result .= ' --- BEFORE --- | --- AFTER ---'.chr(10); 3324 $result .= $user_before['client'].' <= ? => '. $user['client'].chr(10); 3325 $result .= $user_before['name'] .' <= ? => '. $user['name'].chr(10); 3326 $result .= $user_before['mail'] .' <= ? => '. $user['mail'].chr(10); 3327 3328 if(($user_before['mail'] !== false) && ($user_before['mail'] !== $user['mail'])) { 3329 $result .= 'DIFF in mail => update issues, comments and modlog'.chr(10); 3330 $this->_update_it_files($user_before, $user); 3331 // finally the eventcheck will contain the values and resulting action info 3332 if (!$handle = fopen($filename, 'a')) { 3333 msg("IssueTracker: Failed to write into eventcheck file.",-1); 3334 return; 3335 } 3336 $perf = 'IssueTracker updates took '.microtime(true) - $user['microtime_start'].' seconds'; 3337 $result .= chr(10).chr(10).$perf.chr(10); 3338 fwrite($handle, $result); 3339 fclose($handle); 3340 if($perf>0) msg($perf,0); 3341 } 3342 else $result .= chr(10).chr(10).'NO diff in mail => do nothing'; 3343 3344 $handle = fopen($filename, 'a'); 3345 fwrite($handle, $result); 3346 fclose($handle); 3347 3348 } 3349/* -------------------------------------------------------------------------- */ 3350// replace user mail address after modification of user profile 3351 function _update_it_files($user_before, $user) { 3352 global $conf; 3353 3354 if($this->getConf('profile_updt')==false) return; 3355 //$filename = DOKU_INC . 'it_eventcheck.txt'; 3356 if($this->getConf('it_data')==false) $filename = DOKU_CONF."../data/meta/it_eventcheck.txt"; 3357 else $filename = DOKU_CONF."../". $this->getConf('it_data').'it_eventcheck.txt'; 3358 // create array of related files 3359 if($this->getConf('it_data')==false) $path = DOKU_CONF."../data/meta/"; 3360 else $path = DOKU_CONF."../".$this->getConf('it_data'); 3361 $file_array = $this->_file_list($path, '.issues.cmnts.mod-log'); 3362 3363 $result .= "* function _update_it_files".chr(10); 3364 3365 if((strlen($user_before['mail'])<1) ) { 3366 $result .= "Can't update IssueTracker records due to missing old mail value. \nThis may lead into troubles for the just updated user. \nBetter to turn back the changes same way (except on passwords) and use the Update Profile action of your template."; 3367 } 3368 elseif(strlen($user['mail'])<1) { 3369 $result .= "Can't update IssueTracker records due to missing new user mail value. \nThis may lead into troubles for the just updated user. \nBetter to turn back the changes same way (except on passwords or user deletion) and use the Update Profile action of your template."; 3370 } 3371 else { 3372 $result = chr(10).chr(10)."Loop thorugh IssueTracker data files.".chr(10); 3373 // loop through all files 3374 foreach($file_array as $file) { 3375 $parts = explode(".", $file); 3376 $extension = end($parts); 3377 $pfile = $path.'/'.$file; 3378 3379 if (@file_exists($pfile)) { 3380 switch ($extension) { 3381 case "issues": 3382 // get issues file contents 3383 $issues = unserialize(@file_get_contents($pfile)); 3384 foreach($issues as &$issue) { 3385 // search for old_mail and replace by new_mail 3386 if($issue['user_mail'] == $user_before['mail']) { 3387 $issue['user_name'] = $user['name']; 3388 $issue['user_mail'] = $user['mail']; 3389 $result .= 'Issue ID '.$issue['id'].': author field successfully updated'.chr(10); 3390 $upd_issues++; 3391 } 3392 // delete mail address from followers 3393 if((stripos($issue['add_user_mail'],$user_before['mail']) !== false)) { 3394 $tmp = explode(',', $issues[$issue_id]['add_user_mail']); 3395 foreach($tmp as $email) { 3396 if (stripos($email,$user_before['mail']) === false) $ret_mails .= $email.','; 3397 else { 3398 $ret_mails .= $user['mail'].','; 3399 $result .= 'Issue ID '.$issue['id'].': follower field successfully updated.'.chr(10); 3400 $upd_folllowers++; 3401 } 3402 } 3403 } 3404 if($issue['assigned']==$user_before['mail']) { 3405 $issue['assigned'] = $user['mail']; 3406 $result .= 'Issue ID '.$issue['id'].': assignee field successfully updated.'.chr(10); 3407 $upd_assignments++; 3408 } 3409 } 3410 // store issue file 3411 $xvalue = io_saveFile($pfile,serialize($issues)); 3412 3413 case "cmnts": 3414 // get comments file contents 3415 $comments = unserialize(@file_get_contents($pfile)); 3416 foreach($comments as &$comment) { 3417 if($comment['author'] == $user_before['mail']) { 3418 $comment['author'] = $user['mail']; // search for old_mail and replace by new_mail 3419 $result .= '('.$file.') Comment #'.$comment['id'].': author field successfully updated.'.chr(10); 3420 $upd_comments++; 3421 } 3422 } 3423 $xvalue = io_saveFile($pfile,serialize($comments)); 3424 3425 case "mod-log": 3426 // loop through all mod-log files 3427 $mods = unserialize(@file_get_contents($pfile)); 3428 foreach($mods as &$mod) { 3429 if($mod['new_value'] == $user_before['mail']) { 3430 $mod['new_value'] = $user['mail']; // search for old_mail and replace by new_mail 3431 $result .= '('.$file.') modification logfile successfully updated.'.chr(10); 3432 $upd_modlog_entries++; 3433 } 3434 } 3435 $xvalue = io_saveFile($pfile,serialize($mods)); 3436 } 3437 } 3438 else msg('File: '.$pfile.'does not exist',-1); 3439 } 3440 } 3441 3442 // provide user-feedback & log --------------------------------- 3443 if($this->getConf('it_data')==false) $filename = DOKU_CONF."../data/meta/it_eventcheck.txt"; 3444 else $filename = DOKU_CONF."../". $this->getConf('it_data').'it_eventcheck.txt'; 3445 3446 if (!$handle = fopen($filename, 'a')) { 3447 msg("IssueTracker: Failed to write into eventcheck file.",-1); 3448 return; 3449 } 3450 3451 if(($upd_issues>0) && ($conf['allowdebug']!= false)) { 3452 msg('IssueTracker: '.$upd_issues." issue creator entries updated",0); 3453 } 3454 $result .= chr(10).'IssueTracker: '.intval($upd_issues)." issue creator entries updated".chr(10); 3455 3456 if(($upd_folllowers>0) && ($conf['allowdebug']!= false)) { 3457 msg('IssueTracker: '.$upd_folllowers." follower entries updated",0); 3458 } 3459 $result .= 'IssueTracker: '.intval($upd_folllowers)." follower entries updated".chr(10); 3460 3461 if(($upd_assignments>0) && ($conf['allowdebug']!= false)) { 3462 msg('IssueTracker: '.$upd_assignments." assignments updated",0); 3463 } 3464 $result .= 'IssueTracker: '.intval($upd_assignments)." assignments updated".chr(10); 3465 3466 if(($upd_comments>0) && ($conf['allowdebug']!= false)) { 3467 msg('IssueTracker: '.$upd_comments." comment author entries updated",0); 3468 } 3469 $result .= 'IssueTracker: '.intval($upd_comments)." comment author entries updated".chr(10); 3470 3471 if(($upd_modlog_entries>0) && ($conf['allowdebug']!= false)) { 3472 msg('IssueTracker: '.$upd_modlog_entries." mod-log entries updated",0); 3473 } 3474 $result .= 'IssueTracker: '.intval($upd_modlog_entries)." mod-log entries updated".chr(10); 3475 $result .= chr(10).chr(10); 3476 if($conf['allowdebug']!= false) $result .= 'allowdebug = true'.chr(10); 3477 else $result .= 'allowdebug = false'.chr(10); 3478 3479 $handle = fopen($filename, 'a'); 3480 fwrite($handle, $result); 3481 fclose($handle); 3482 3483 return; 3484 } 3485/* -------------------------------------------------------------------------- */ 3486 // list all files with defined file-extension within a directory 3487 // does not read sub-directories 3488 function _file_list($dir, $type) { 3489 $dh = opendir($dir); 3490 $files = array(); 3491 while (($file = readdir($dh)) !== false) { 3492 $flag = false; 3493 if($file !== '.' && $file !== '..') { 3494 // --- get the current file extension --------------------- 3495 $parts = explode(".", $file); 3496 if (is_array($parts) && count($parts) > 1) { 3497 $extension = end($parts); 3498 if (stripos($type,$extension)!==false) { 3499 $files[] = $file; 3500 $a = $file.chr(10); 3501 } 3502 } 3503 //--------------------------------------------------------- 3504 } 3505 } 3506 return $files; 3507 } 3508/******************************************************************************/ 3509/* upload a file if valid on mime type and file extension 3510*/ 3511 function _symptom_file_upload(&$issues, $issue_id, $attachment_id) { 3512 global $conf; 3513 if($this->getConf('it_data')==false) $target_path = "data/meta/"; 3514 else $target_path = $this->getConf('it_data'); 3515 $ip_block_path = $target_path."ipblock"; 3516 $target_path .= 'symptoms/'; 3517 if(!is_dir(DOKU_CONF."../".$target_path)) { mkdir(DOKU_CONF."../".$target_path, 0777); } 3518 3519 $valid_file_extensions = array(); 3520 $valid_mimetypes = array(); 3521 $mimetypes = getMimeTypes(); 3522 3523 foreach($mimetypes as $key => $value) { 3524 $valid_file_extensions[] = $key; 3525 $valid_mimetypes[] = $value; 3526 } 3527 3528 if($this->getConf('ip_blocked') == 1){ 3529 $ip_blocked_sec = $this->getConf('ip_blockd_time')*60; 3530 3531 // search folder ipblock 3532 if(is_dir(DOKU_INC.$ip_block_path)) { 3533 $path = openDir(DOKU_INC.$ip_block_path); 3534 while(false !== ($filename = readdir($path))){ 3535 if($filename != "." && $filename != ".."){ 3536 // delete aged ipblocks 3537 if(file_exists(DOKU_INC.$ip_block_path.'/'.$filename)) { 3538 $t_check = filemtime(DOKU_INC.$ip_block_path.'/'.$filename)+$ip_blocked_sec; 3539 if($t_check <= time()) { @unlink(DOKU_INC.$ip_block_path.'/'.$filename); } 3540 } 3541 } 3542 } 3543 closedir($path); 3544 } 3545 else { 3546 mkdir(DOKU_INC.$ip_block_path.'/', 0777); 3547 } 3548 3549 $ip_addr = $_SERVER['REMOTE_ADDR']; 3550 if($ip_addr == "") { 3551 if(getenv(HTTP_X_FORWARDED_FOR)) { $ip_addr = getenv('HTTP_X_FORWARD_FOR'); } 3552 else { $ip_addr = getenv('REMOTE_ADDR'); } 3553 } 3554 3555 if($ip_addr != ""){ 3556 // check if ip already known 3557 if(file_exists(DOKU_INC.$ip_block_path.'/'.$ip_addr)) { 3558 // check upload attampts (to be larger than 3) 3559 $iplog = fopen(DOKU_INC.$ip_block_path.'/'.$ip_addr, "r"); 3560 $attachments_left=fread($iplog, filesize(DOKU_INC.$ip_block_path.'/'.$ip_addr)); 3561 fclose($iplog); 3562 if($attachments_left<1) { 3563 $error_code = 1; 3564 $t_check = intval((filemtime(DOKU_INC.$ip_block_path.'/'.$filename)+$ip_blocked_sec-time())/60); 3565 msg(sprintf($this->getLang('wmsg9'), $t_check),-1); 3566 } 3567 } 3568 else $attachments_left = 3; 3569 } 3570 } 3571 3572 if(isset($error_code)){ 3573 $t_check = intval((filemtime(DOKU_INC.$ip_block_path.'/'.$filename)+$ip_blocked_sec-time())/60); 3574 $Generated_Header = '<div class="it__negative_feedback">'.sprintf($this->getLang('wmsg9'), $t_check).'</div>'; 3575 $renderer->doc .= $Generated_Header; 3576 return; 3577 } 3578 3579 // get file extension 3580 $mime_type = $_FILES[$attachment_id]['type']; 3581 $file_extension = strrchr($_FILES[$attachment_id]['name'],'.'); // last occurance of dot to detect extension 3582 $file_dot_extension = strtolower($file_extension); 3583 $file_extension = str_replace(".", "", strtolower($file_dot_extension)); 3584 $error_flag = 0; 3585 3586 // check validity of file extension 3587 if(!in_array($file_extension, $valid_file_extensions)) { 3588 $error_flag = 1; 3589 $Generated_Header .= '<span>'.$this->getLang('wmsg7').' (File: <b>'.$_FILES[$attachment_id]['name'].'</b>)</span><br>'; 3590 } 3591 // check mime type 3592 if((!in_array($mime_type, $valid_mimetypes)) && (!in_array("!".$mime_type, $valid_mimetypes)) ) { 3593 $error_flag = 1; 3594 $Generated_Header .= '<span>'.$this->getLang('wmsg8').' (File: <b>'.$_FILES[$attachment_id]['name'].', Mime-Type: '.$mime_type.'</b>)</span><br>'; 3595 } 3596 // check file-size 3597 if($_FILES[$attachment_id]['size'] > ($this->getConf('max_fsize'))){ 3598 $error_flag = 1; 3599 $Generated_Header .= '<span>'.sprintf($this->getLang('wmsg6'), $this->getConf('max_fsize')).' (File: <b>'.$_FILES[$attachment_id]['name'].'</b>)</span><br>'; 3600 } 3601// ----------------------------------------------------------------------------- 3602 if($error_flag > 0) { 3603 echo $Generated_Header = '<div class="it__negative_feedback">'.$Generated_Header.'</div>'; 3604 } 3605 else { 3606 //$safe_filename = preg_replace(array("/\s+/", "/[^-\.\w]+/"),array("_", ""),trim(basename( $_FILES[$attachment_id]['name']))); 3607 // delete all other characters beside the following defined 3608 $safe_filename = preg_replace('#[^A-Za-z0-9_.-]#', '',trim(basename( $_FILES[$attachment_id]['name']))); 3609 $target_path = $target_path . $issue_id . '_sympt_' . $safe_filename; 3610 if(move_uploaded_file($_FILES[$attachment_id]['tmp_name'], DOKU_INC.$target_path)) { 3611 $attachments_left = $attachments_left-1; 3612 $issues[$issue_id][$attachment_id] = DOKU_URL.$target_path; 3613// msg("The file ".$safe_filename." has been successfully uploaded to ".DOKU_URL.$target_path,1); 3614 msg("The file ".$safe_filename." has been successfully uploaded.",1); 3615 } else{ 3616// msg("There was an error uploading the file to ".DOKU_URL.$target_path." \n, please try again!",-1); 3617 msg("There was an error uploading the file, please try again!",-1); 3618 } 3619// ----------------------------------------------------------------------------- 3620 // block ip 3621 if($this->getConf('ip_blocked') == 1) { 3622 $ip_addr=$_SERVER['REMOTE_ADDR']; 3623 if($ip_addr==""){ 3624 if(getenv(HTTP_X_FORWARDED_FOR)) { $ip_addr = getenv('HTTP_X_FORWARD_FOR'); } 3625 else { $ip_addr = getenv('REMOTE_ADDR'); } 3626 } 3627 if(!is_dir(DOKU_INC.$ip_block_path) && ($ip_addr != "")) { 3628 @mkdir(DOKU_INC.$ip_block_path.'/', 0777); 3629 $iplog = fopen(DOKU_INC.$ip_block_path.'/'.$ip_addr, "w+"); 3630 fwrite($iplog, $attachments_left); 3631 fclose($iplog); 3632 } 3633 elseif($ip_addr != ""){ 3634 $iplog = fopen(DOKU_INC.$ip_block_path.'/'.$ip_addr, "w+"); 3635 fwrite($iplog, $attachments_left); 3636 fclose($iplog); 3637 } 3638 } 3639 } 3640// ----------------------------------------------------------------------------- 3641 return $Generated_Header; 3642 } 3643/******************************************************************************/ 3644/* 3645 * Check for MyIssues 3646 * 3647 * Check if the issue is related to the current user 3648 * the user maybe the issue reporter, assignee or registered as follower 3649 * it will return true/false 3650 * 3651 * @author Taggic <taggic@t-online.de> 3652 * @param array $issue the single issue 3653 * @param array $user the current user info 3654 * @return bool (true / false) 3655 * 3656 */ 3657 3658 function _find_myissues($issue, $user) { 3659 // current user is issue reporter 3660 if($user['userinfo']['mail'] === $issue['user_mail']) return true; 3661 3662 // current user is assigned to this issue 3663 if($user['userinfo']['mail'] === $issue['assigned']) return true; 3664 3665 // current user is registered as follower within the comments log of actual issue 3666 if(stristr($issue['add_user_mail'],$user['userinfo']['mail']) !== false) return true; 3667 3668 // else return false 3669 return false; 3670 } 3671/******************************************************************************/ 3672 function __find_projects($path) { 3673 if(!is_dir($path)) return false; // prevent the php-warning 3674 if ($handle=opendir($path)) { 3675 while (false!==($file=readdir($handle))) { 3676 if ($file<>"." AND $file<>"..") { 3677 if (is_file($path.'/'.$file)) { 3678 $ext = explode('.',$file); 3679 $last = count($ext) - 1; 3680 if ($ext[$last] == 'issues') { 3681 $projects .= ','.substr($file,0,strlen($file)-strlen('.issues')); 3682 } 3683 } 3684 } 3685 } 3686 } 3687 return $projects; 3688 } 3689/******************************************************************************/ 3690/* 3691 * Load all issues into an array 3692 * 3693 * Check if multi_project is set to true 3694 * Load current $project or all projects of it_data_store 3695 * Return the issues array 3696 * 3697 * @author Taggic <taggic@t-online.de> 3698 * @param string $project delivers the project name; used if $all = false 3699 * @param bool $all determines if all projects to be retrieved 3700 * @return array $issues result: is an array of issues 3701 * 3702 */ 3703 3704 function _get_issues($project, $all = false) { 3705 // detect the IssueTracker data store (path) 3706 if($this->getConf('it_data')==false) $it_datastore = DOKU_CONF."../data/meta/"; 3707 else $it_datastore = DOKU_CONF."../". $this->getConf('it_data'); 3708 3709 // check if last sign is a slash 3710 $i = strrchr ($it_datastore, chr(47)); // chr(47) = "/" 3711 $j = strrchr ($it_datastore, chr(92)); // chr(92) = "\" 3712 if(($i !== strlen($it_datastore)) && ($i !== strlen($it_datastore))) { $it_datastore .= chr(47); } 3713 3714 if(($this->getConf('multi_projects')!==false) && ($all !== false)) { 3715 // loop through it_datastore and list all .issues files 3716 $xprojects = $this->__find_projects($it_datastore); 3717 $x_projects = explode(',',$xprojects); 3718 $issues = array(); 3719 $tmp = array(); 3720 3721 foreach ($x_projects as $project) 3722 { $project = trim($project); 3723 if(is_file($it_datastore.$project.'.issues') == true) { 3724 $tmp = unserialize(@file_get_contents($it_datastore.$project.'.issues')); 3725 3726 // loop through the field and add project to each row 3727 foreach($tmp as &$tmps) 3728 { $tmps['project'] = $project; } 3729 3730 $issues = array_merge($issues, $tmp); 3731 $tmp = array(); 3732 } 3733 } 3734 } 3735 else { 3736 // get issues from single project file 3737 if($this->getConf('it_data')==false) $pfile = $it_datastore.$project.'.issues'; 3738 else $pfile = $it_datastore.$project.'.issues'; 3739 3740 if (@file_exists($pfile)) 3741 {$issues = unserialize(@file_get_contents($pfile));} 3742 else 3743 {$issues = array(); 3744 msg("project = $pfile not found",-1); 3745 } 3746 } 3747// $arr1 = $this->array_msort($issues, array('project'=>SORT_DESC, 'id'=>SORT_ASC)); 3748 $arr1 = $this->array_msort($issues, array('project'=>SORT_DESC)); 3749 return $arr1; 3750 } 3751/******************************************************************************/ 3752 function array_msort($array, $cols) 3753 { 3754 $colarr = array(); 3755 foreach ($cols as $col => $order) { 3756 $colarr[$col] = array(); 3757 foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); } 3758 } 3759 $eval = 'array_multisort('; 3760 foreach ($cols as $col => $order) { 3761 $eval .= '$colarr[\''.$col.'\'],'.$order.','; 3762 } 3763 $eval = substr($eval,0,-1).');'; 3764 eval($eval); 3765 $ret = array(); 3766 foreach ($colarr as $col => $arr) { 3767 foreach ($arr as $k => $v) { 3768 $k = substr($k,1); 3769 if (!isset($ret[$k])) $ret[$k] = $array[$k]; 3770 $ret[$k][$col] = $array[$k][$col]; 3771 } 3772 } 3773 return $ret; 3774 } 3775/******************************************************************************/ 3776}