'Taggic',
'email' => 'Taggic@t-online.de',
'date' => '2016-06-02',
'name' => 'Issue comments (action plugin component)',
'desc' => 'to display details of a dedicated issue.',
'url' => 'https://www.dokuwiki.org/plugin:issuetracker',
);
}
/******************************************************************************
** Register its handlers with the dokuwiki's event controller
*/
function register(Doku_Event_Handler $controller) {
$controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, '_handle_act', array());
$controller->register_hook('TPL_ACT_UNKNOWN', 'BEFORE', $this, 'output', array());
//HTML_UPDATEPROFILEFORM_OUTPUT
$controller->register_hook( 'AUTH_USER_CHANGE',
'BEFORE',
$this,
'handle_usermod_before',
array());
$controller->register_hook( 'AUTH_USER_CHANGE',
'AFTER',
$this,
'handle_usermod_after',
array());
// $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, '_hookjs');
}
/******************************************************************************/
/**
* Hook js script into page headers.
*/
function _hookjs(&$event, $param) {
$css=DOKU_URL."lib/plugins/issuetracker/datepick/jsDatePick_ltr.css";
$jquery=DOKU_URL."lib/plugins/issuetracker/datepick/jquery.1.4.2.js";
$datepicker=DOKU_URL."lib/plugins/issuetracker/datepick/jsDatePick.min.1.3.js";
$event->data["link"][] = array (
"rel" => "stylesheet",
"media" => "all",
"type" => "text/css",
"href" => $css
);
$event->data["script"][] = array ( "type" => "text/javascript",
"charset" => "utf-8",
"_data" => "",
"src" => $jquery
);
$event->data["script"][] = array ( "type" => "text/javascript",
"charset" => "utf-8",
"_data" => "",
"src" => $datepicker
);
$event->data["script"][] = array ( "type" => "text/javascript",
"charset" => "utf-8",
"_data" => "
window.onload = function(){
new JsDatePick({
useMode:2,
target:'dev_start',
dateFormat:'%d.%M.%Y'
});
new JsDatePick({
useMode:2,
target:'dev_deadline',
dateFormat:'%d.%M.%Y'
});
};",
"src" => ""
);
}
/******************************************************************************
** Handle the action
*/
function _handle_act(&$event, $param) {
if (($event->data === 'showcase') || ($event->data === 'store_resolution') || ($event->data === 'store_workaround')){
$this->parameter = $_POST['showid'];
$this->project = $_POST['itl_project'];
}
elseif ($event->data === 'showcaselink') {
$this->parameter = $_GET['showid'];
$this->project = $_GET['project'];
}
elseif($event->data === 'btn_add_contact') {
$this->project = $_POST['project'];
$this->issue_ID = $_POST['issue_ID'];
$this->add_contact = $_POST['add_contact'];
}
elseif($event->data === 'btn_upd_addinfo') {
$this->project = $_POST['project'];
$this->parameter = $_POST['issue_ID'];
$this->new_component = $_POST['new_component'];
$this->trgt_version = $_POST['trgt_version'];
$this->itl_block = $_POST['itl__block_filter'];
$this->dev_start = $_POST['dev_start'];
$this->dev_deadline = $_POST['dev_deadline'];
$this->dev_progress = $_POST['dev_progress'];
}
elseif ($event->data === 'it_search') {
$this->parameter = $_POST['it_str_search'];
$this->project = $_POST['itl_project'];
}
elseif ($event->data === 'issuelist_next') {
$this->itl_start = $_POST['itl_start'];
$this->itl_step = $_POST['itl_step'];
$this->itl_next = $_POST['itl_next'];
$this->itl_pjct = $_POST['itl_project'];
$this->itl_sort = $_POST['it_glbl_sort'];
$this->itl_stat = $_POST['itl_stat_filter'];
$this->itl_sev = $_POST['itl_sev_filter'];
$this->itl_prod = $_POST['itl__prod_filter'];
$this->itl_vers = $_POST['itl__vers_filter'];
$this->itl_comp = $_POST['itl__comp_filter'];
$this->itl_block = $_POST['itl__block_filter'];
$this->itl_assi = $_POST['itl__assi_filter'];
$this->itl_reporter= $_POST['itl__user_filter'];
$this->itl_myis = $_POST['itl_myis_filter'];
$this->project = $_POST['itl_project'];
$this->it_th_cols = $_POST['it_th_cols'];
}
elseif ($event->data === 'issuelist_previous') {
$this->itl_start = $_POST['itl_start'];
$this->itl_step = $_POST['itl_step'];
$this->itl_next = $_POST['itl_next'];
$this->itl_pjct = $_POST['itl_project'];
$this->itl_sort = $_POST['it_glbl_sort'];
$this->itl_stat = $_POST['itl_stat_filter'];
$this->itl_sev = $_POST['itl_sev_filter'];
$this->itl_prod = $_POST['itl__prod_filter'];
$this->itl_vers = $_POST['itl__vers_filter'];
$this->itl_comp = $_POST['itl__comp_filter'];
$this->itl_block = $_POST['itl__block_filter'];
$this->itl_assi = $_POST['itl__assi_filter'];
$this->itl_reporter= $_POST['itl__user_filter'];
$this->itl_myis = $_POST['itl_myis_filter'];
$this->project = $_POST['itl_project'];
$this->it_th_cols = $_POST['it_th_cols'];
}
elseif ($event->data === 'issuelist_filter') {
$this->itl_start = $_POST['itl_start'];
$this->itl_step = $_POST['itl_step'];
$this->itl_next = $_POST['itl_next'];
$this->itl_pjct = $_POST['itl_project'];
$this->itl_sort = $_POST['it_glbl_sort'];
$this->itl_stat = $_POST['itl_stat_filter'];
$this->itl_sev = $_POST['itl_sev_filter'];
$this->itl_prod = $_POST['itl__prod_filter'];
$this->itl_vers = $_POST['itl__vers_filter'];
$this->itl_comp = $_POST['itl__comp_filter'];
$this->itl_block = $_POST['itl__block_filter'];
$this->itl_assi = $_POST['itl__assi_filter'];
$this->itl_reporter= $_POST['itl__user_filter'];
$this->itl_myis = $_POST['itl_myis_filter'];
$this->project = $_POST['itl_project'];
$this->it_th_cols = $_POST['it_th_cols'];
}
elseif ($event->data === 'issuelist_filterlink') {
$this->itl_start = $_GET['itl_start'];
$this->itl_step = $_GET['itl_step'];
$this->itl_next = $_GET['itl_next'];
$this->itl_pjct = $_GET['itl_project'];
$this->itl_sort = $_GET['it_glbl_sort'];
$this->itl_stat = $_GET['itl_stat_filter'];
$this->itl_sev = $_GET['itl_sev_filter'];
$this->itl_prod = $_GET['itl__prod_filter'];
$this->itl_vers = $_GET['itl__vers_filter'];
$this->itl_comp = $_GET['itl__comp_filter'];
$this->itl_block = $_GET['itl__block_filter'];
$this->itl_assi = $_GET['itl__assi_filter'];
$this->itl_reporter= $_GET['itl__user_filter'];
$this->itl_myis = $_GET['itl_myis_filter'];
$this->project = $_GET['itl_project'];
$this->it_th_cols = $_POST['it_th_cols'];
}
elseif ($event->data === 'showmodlog') {
$this->parameter = $_GET['showid'];
$this->project = $_GET['project'];
}
elseif ($event->data === 'savecfgelement') {
$this->parameter = "addcfgelement";
$this->elmnt_name = $_POST['name1'];
$this->elmnt_type = $_POST['type1'];
}
elseif ($event->data === 'savecfgmatrix') {
$this->parameter = "cfgmatrix";
$this->elmnt_type = $_POST['type2'];
$this->elmnt_name = $_POST['name2'];
$this->elmnt_childs = $_POST['childs2'];
}
elseif ($event->data === 'deletecfgelement') {
$this->parameter = "deletecfgelement";
$this->elmnt_type = $_POST['type3'];
$this->elmnt_name = $_POST['name3'];
}
else return;
$event->preventDefault(); // https://www.dokuwiki.org/devel:events#event_object
}
/******************************************************************************
** format string for comment label
*/
function convertlabel($txt){
$len = strlen($txt);
$res = "";
$tmp = explode(chr(10),$txt);
foreach($tmp as $line) {
if((stripos($line,'ul]')!==false) || (stripos($line,'ol]')!==false) || (stripos($line,'li]')!==false)) {
$res .= $line;
}
else $res .= $line." ";
}
return $res;
}
/******************************************************************************/
/* improved implode needed
*/
function array_implode($arrays, &$target = array())
{
foreach ($arrays as $item) {
if (is_array($item)) {
$this->array_implode($item, $target);
} else {
$target[] = $item;
}
}
return $target;
}
/******************************************************************************
** Generate output
*/
function output(&$data) {
global $ID;
if (($data->data == 'showcase') || ($data->data == 'showcaselink') || ($data->data == 'store_resolution') || ($data->data == 'store_workaround')) {
$data->preventDefault();
// if ($mode == 'xhtml'){
$renderer->info['cache'] = false;
$issue_id = $this->parameter;
$project = $this->project;
$user_grp = pageinfo();
$usr = $user_grp['userinfo']['name'] ; //to log issue mods
$Generated_Header = '';
$Generated_Message = '';
// get issues file contents
if($this->getConf('it_data')==false) $pfile = DOKU_CONF."../data/meta/".$project.'.issues';
else $pfile = DOKU_CONF."../". $this->getConf('it_data').$project.'.issues';
if (is_file($pfile))
{ $issues = unserialize(@file_get_contents($pfile));}
elseif(strlen($project)>1)
{// promt error message that issue with ID does not exist
echo '
'.sprintf($this->getLang('msg_pfilemissing'), $project) . '
';
}
// showcase can refer to multiple issues in the event of multi-project tuned on
// 1. check if multiproject is on
if(($data->data == 'showcase') && ($this->getConf('multi_projects')!== false)) {
// 2. get list of projects and issues
$issues = $this->_get_issues($project, true);
// 3. filter for related issue id
foreach($issues as $issue) {
if($issue['id']==$issue_id) {
$tmp[] = $issue;
$pstring = sprintf("showid=%s&project=%s", urlencode($issue['id']), urlencode($issue['project']));
$p = $p + 1;
$referrer = "p".$p;
$itl_item_title .= ''.$issue['project'].':  '.
''.$issue['title'].' ';
}
}
$issues = $tmp;
if(count($issues)>1) {
// list issues
echo $this->getLang('msg_showCase') . ' ';
echo $itl_item_title;
return;
}
elseif(count($issues)===1) {
// just one issue but of which project ?
$project = $issue['project'];
}
}
//If comment to be deleted
elseif ($_REQUEST['del_cmnt']==='TRUE') {
// check if captcha is to be used by issue tracker in general
if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
else { $captcha_ok = ($this->_captcha_ok());}
if ($captcha_ok)
{ if (checkSecurityToken())
{ // get comment file contents
if($this->getConf('it_data')==false) $comments_file = DOKU_CONF."../data/meta/".$project."_".$_REQUEST['comment_issue_ID'].'.cmnts';
else $comments_file = DOKU_CONF."../". $this->getConf('it_data').$project."_".$_REQUEST['comment_issue_ID'].'.cmnts';
if (@file_exists($comments_file)) { $comments = unserialize(@file_get_contents($comments_file)); }
else { $txt='Comments file does not exist.'; }
// delete fieldset from $comments array
$comment_id = htmlspecialchars(stripslashes($_REQUEST['comment_id']));
$comment_id = htmlspecialchars($_REQUEST['comment_id']);
//$comments[$comment_id]
unset($comments[$comment_id]);
// store comments to file
$xvalue = io_saveFile($comments_file,serialize($comments));
if($this->getConf('mail_modify_comment') ===1) $this->_emailForMod($_REQUEST['project'],$issues[$_REQUEST['comment_issue_ID']], $comments[$comment_id],'delete');
//sprintf($format, $num
msg(sprintf($this->getLang('msg_commentdeltrue'),$comment_id),1);
// $Generated_Header = ''.sprintf($this->getLang('msg_commentdeltrue'),$comment_id).'
';
}
}
}
//Comment to be added or modified
elseif ((isset($_REQUEST['comment'])) || (isset($_REQUEST['comment_id'])))
{ if ((($_REQUEST['comment']) || (isset($_REQUEST['comment_id']))) && (isset($_REQUEST['comment_issue_ID'])))
{
// check if captcha is to be used by issue tracker in general
if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
else { $captcha_ok = ($this->_captcha_ok());}
if (@file_exists($pfile))
{ $issues = unserialize(@file_get_contents($pfile)); }
else
{ msg('Issue file not found !'.NL.$pfile,-1);
return false; }
if ($captcha_ok)
{
if (checkSecurityToken())
{ // get comment file contents
if($this->getConf('it_data')==false) $comments_file = DOKU_CONF."../data/meta/".$project."_".$_REQUEST['comment_issue_ID'].'.cmnts';
else $comments_file = DOKU_CONF."../". $this->getConf('it_data').$project."_".$_REQUEST['comment_issue_ID'].'.cmnts';
if (@file_exists($comments_file)) { $comments = unserialize(@file_get_contents($comments_file)); }
else { $comments = array(); }
$checkFlag=false;
//Add new comment to the comment file
$comment_id=count($comments);
// check if comment content already exist
foreach ($comments as $value)
{ if ($value['id'] >= $comment_id) { $comment_id=$value['id'] + 1; }
if ($_REQUEST['comment'] === $value['comment'])
{ msg($this->getLang('msg_commentfalse').'.',-1);
// $Generated_Header = ''.$this->getLang('msg_commentfalse').'
';
$checkFlag=true;
}
}
//If comment to be modified
if (($checkFlag === false) && (isset($_REQUEST['comment_id'])))
{ $comment_id = htmlspecialchars(stripslashes($_REQUEST['comment_id']));
if ($_REQUEST['comment_mod'] === $comments[$comment_id]['comment'])
{ msg($this->getLang('msg_commentfalse').$comment_id.'.',-1);
// $Generated_Header = ''.$this->getLang('msg_commentmodfalse').$comment_id.'
';
$checkFlag=true;
}
else
{ $cur_date = date($this->getConf('d_format'));
$comments[$comment_id]['mod_timestamp'] = $cur_date;
// $comments[$comment_id]['comment'] = htmlspecialchars(stripslashes($_REQUEST['comment_mod']));
$comments[$comment_id]['comment'] = htmlspecialchars($_REQUEST['comment_mod']);
// $Generated_Header = ''.$this->getLang('msg_commentmodtrue').$comment_id.'.
';
//Create comments file
$xvalue = io_saveFile($comments_file,serialize($comments));
if(($this->getConf('mail_modify_comment') ===1) && ($_REQUEST['minor_mod']!=="true")) $this->_emailForMod($_REQUEST['project'],$issues[$_REQUEST['comment_issue_ID']], $comments[$comment_id], 'modify');
msg($this->getLang('msg_commenttrue').$comment_id.'.',1);
// $Generated_Header = ''.$this->getLang('msg_commenttrue').$comment_id.'.
';
}
}
//If comment to be added
elseif ($checkFlag === false)
{ $comments[$comment_id]['id'] = $comment_id;
$comments[$comment_id]['author'] = htmlspecialchars(stripslashes($_REQUEST['author']));
$cur_date = date($this->getConf('d_format'));
$comments[$comment_id]['timestamp'] = $cur_date;
// $comments[$comment_id]['comment'] = htmlspecialchars(stripslashes($_REQUEST['comment']));
$comments[$comment_id]['comment'] = htmlspecialchars($_REQUEST['comment']);
//Create comments file
$xvalue = io_saveFile($comments_file,serialize($comments));
if($this->getConf('mail_add_comment') ===1) $this->_emailForMod($_REQUEST['project'],$issues[$_REQUEST['comment_issue_ID']], $comments[$comment_id], 'new');
msg($this->getLang('msg_commenttrue').$comment_id.'.',1);
// $Generated_Header = ''.$this->getLang('msg_commenttrue').$comment_id.'.
';
}
// update issues modification date
if ($checkFlag === false)
{ // inform user (or assignee) about update
// update modified date
$cur_date = date($this->getConf('d_format'));
$issues[$_REQUEST['comment_issue_ID']]['modified'] = $cur_date;
$xvalue = io_saveFile($pfile,serialize($issues));
// if($this->getConf('mail_modify_comment') ===1) $this->_emailForMod($_REQUEST['project'],$issues[$_REQUEST['comment_issue_ID']], $comments[$comment_id], 'modify');
$anker_id = 'resolved_'. uniqid((double)microtime()*1000000,1);
}
}
}
}
}
elseif (isset($_REQUEST['mod_add_data']))
{
$old_value = 'Planning info modified: '.
'Component: '.$issues[$issue_id]['component'].' '.
'Target version: '.$issues[$issue_id]['trgt_version'].' '.
'Test blocking: '.$issues[$issue_id]['tblock'].' '.
'Begin: '.$issues[$issue_id]['dev_start'].' '.
'Deadline: '.$issues[$issue_id]['dev_deadline'].' '.
'Progress: '.$issues[$issue_id]['dev_progress'];
$issues[$issue_id]['component'] = $_REQUEST['new_component'];
$issues[$issue_id]['trgt_version'] = $_REQUEST['trgt_version'];
$issues[$issue_id]['tblock'] = $_REQUEST['itl__block_filter'];
$issues[$issue_id]['dev_start'] = $_REQUEST['dev_start'];
$issues[$issue_id]['dev_deadline'] = $_REQUEST['dev_deadline'];
$issues[$issue_id]['dev_progress'] = $_REQUEST['dev_progress'];
//save issue-file
$xvalue = io_saveFile($pfile,serialize($issues));
$new_value = 'Planning info modified: '.
'Component: '.$issues[$issue_id]['component'].' '.
'Target version: '.$issues[$issue_id]['trgt_version'].' '.
'Test blocking: '.$issues[$issue_id]['tblock'].' '.
'Begin: '.$issues[$issue_id]['dev_start'].' '.
'Deadline: '.$issues[$issue_id]['dev_deadline'].' '.
'Progress: '.$issues[$issue_id]['dev_progress'];
// echo $issue_id.' ... '.$old_value.' '.' '.$new_value.' ';
$this->_log_mods($project, $issues[$issue_id], $usr, 'planning data', $old_value, $new_value);
}
elseif (isset($_REQUEST['mod_description']))
{
// check if captcha is to be used by issue tracker in general
if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
else { $captcha_ok = ($this->_captcha_ok());}
if ($captcha_ok)
{ if (checkSecurityToken())
{ // find issue and description
$issue_id = trim($_REQUEST['comment_issue_ID']);
$cFlag = false;
foreach ($issues as $value)
{ $ist = $value['id'];
if ($value['id'] == $issue_id)
{ $cFlag = true;
break;}
}
if ($cFlag === true)
{ $old_value = $issues[$issue_id]['description'];
// $issues[$issue_id]['description'] = htmlspecialchars(stripslashes($_REQUEST['description_mod']));
$issues[$issue_id]['description'] = htmlspecialchars($_REQUEST['description_mod']);
//save issue-file
$xvalue = io_saveFile($pfile,serialize($issues));
if(($this->getConf('mail_modify__description') ===1) && ($_REQUEST['minor_mod']!=="true")) $this->_emailForDscr($_REQUEST['project'], $issues[$issue_id]);
$this->_log_mods($project, $issues[$issue_id], $usr, 'description mod', $old_value, $issues[$issue_id]['description']);
msg($this->getLang('msg_descrmodtrue'),1);
// $Generated_Header = ''.$this->getLang('msg_descrmodtrue').$issue_id.'
';
}
else { msg("Issue with ID: $issue_id not found.",-1); }
}
}
}
elseif(isset($_REQUEST['mod_contacts']))
{ // check if captcha is to be used by issue tracker in general
if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
else { $captcha_ok = ($this->_captcha_ok());}
if ($captcha_ok)
{ if (checkSecurityToken())
{ // find issue and description
$issue_id = trim($_REQUEST['issue_ID']);
$a1 = $_REQUEST['add_contact'];
$a1 = preg_replace("/ +/", ',', $a1);
$a1 = preg_replace('/;/',',',$a1);
$a1 = preg_replace('/,+/',',',$a1);
$xvalue = false;
//check if register or unregister a follower
if((strlen($a1)>0) && (stripos($issues[$issue_id]['add_user_mail'],$a1) === false)) {
$issues[$issue_id]['add_user_mail'] .= ",".$a1;
//save issue-file
$xvalue = io_saveFile($pfile,serialize($issues));
if($xvalue!==false) { msg(sprintf($this->getLang('msg_addFollower_true'),$issue_id).$a1,1);}
$this->_log_mods($project, $issues[$issue_id], $usr, 'follower added', '', $a1);
}
// delete mail address from followers
elseif((strlen($a1)>0) && (stripos($issues[$issue_id]['add_user_mail'],$a1) !== false)) {
$tmp = explode(',', $issues[$issue_id]['add_user_mail']);
foreach($tmp as $email) {
if (stripos($email,$a1) === false) $ret_mails .= $email.',';
}
//save issue-file
$issues[$issue_id]['add_user_mail'] = $ret_mails;
$xvalue = io_saveFile($pfile,serialize($issues));
if($xvalue!==false) { msg(sprintf($this->getLang('msg_rmvFollower_true'),$issue_id).$a1,1);}
$this->_log_mods($project, $issues[$issue_id], $usr, 'follower deleted', $a1, '');
}
if($xvalue===false) { msg(sprintf($this->getLang('msg_addFollower_failed'),$issue_id).$a1,-1); }
}
}
}
elseif(isset($_REQUEST['mod_symptomlinks']))
{
// check if captcha is to be used by issue tracker in general
if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
else { $captcha_ok = ($this->_captcha_ok());}
if ($captcha_ok)
{ if (checkSecurityToken())
{ // find issue and description
$issue_id = trim($_REQUEST['comment_issue_ID']);
$cFlag = false;
foreach ($issues as $value)
{ if ($value['id'] == $issue_id)
{ $cFlag = true;
break;}
}
if ($cFlag === true) {
// *****************************************************************************
// upload a symptom file
// *****************************************************************************
$mime_type1 = $_FILES['attachment1']['type'];
if(($this->getConf('upload')> 0) && (strlen($mime_type1)>1)) {
$Generated_Header = $this->_symptom_file_upload($issues,$issue_id,'attachment1');
}
$mime_type2 = $_FILES['attachment2']['type'];
if(($this->getConf('upload')> 0) && (strlen($mime_type2)>1)) {
$Generated_Header = $this->_symptom_file_upload($issues,$issue_id,'attachment2');
}
$mime_type3 = $_FILES['attachment3']['type'];
if(($this->getConf('upload')> 0) && (strlen($mime_type3)>1)) {
$Generated_Header = $this->_symptom_file_upload($issues,$issue_id,'attachment3');
}
//save issue-file
$xvalue = io_saveFile($pfile,serialize($issues));
$new_value = $issues[$issue_id]['attachment1'].' '.$issues[$issue_id]['attachment2'].' '.$issues[$issue_id]['attachment3'];
$this->_log_mods($project, $issues[$issue_id], $usr, 'symptom links', $old_value, $new_value);
}
else { msg("Issue with ID: $issue_id not found.",-1); }
}
}
}
elseif (isset($_REQUEST['add_resolution']))
{ $renderer->info['cache'] = false;
if (@file_exists($pfile))
{ $issues = unserialize(@file_get_contents($pfile)); }
else
{ msg('Issue file not found !'.NL.$pfile,-1);
return false; }
// check if captcha is to be used by issue tracker in general
if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
else { $captcha_ok = ($this->_captcha_ok());}
if ($captcha_ok)
{ if (checkSecurityToken())
{ //Add resolution text to the issue file and set the issue to solved
$issue_id = trim($_REQUEST['comment_issue_ID']);
$cFlag = false;
foreach ($issues as $value)
{ $ist = $value['id'];
if ($value['id'] == $issue_id)
{ $cFlag = true;
break;}
}
if ($cFlag === true)
{ $old_value = $issues[$issue_id]['resolution'];
// $issues[$issue_id]['resolution'] = htmlspecialchars(stripslashes($_REQUEST['x_resolution']));
$issues[$issue_id]['resolution'] = htmlspecialchars($_REQUEST['x_resolution']);
$issues[$issue_id]['status'] = $this->getLang('issue_resolved_status');
$xuser = $issues[$issue_id]['user_mail'];
$xdescription = $issues[$issue_id]['description'];
//save issue-file
$xvalue = io_saveFile($pfile,serialize($issues));
$anker_id = 'resolved_'. uniqid((double)microtime()*1000000,1);
if($this->getConf('mail_modify_resolution') ===1) $this->_emailForRes($_REQUEST['project'], $issues[$_REQUEST['comment_issue_ID']]);
// $Generated_Message = ''.$this->getLang('msg_resolution_true').$issue_id.'
';
msg($this->getLang('msg_resolution_true').$issue_id.'.',1);
$usr = $_POST['usr'];
$this->_log_mods($project, $issues[$issue_id], $usr, 'resolution', $old_value, $issues[$issue_id]['resolution']);
}
else { msg("Issue with ID: $issue_id not found.",-1); }
}
}
}
elseif(isset($_REQUEST['mod_severity']))
{ // check if captcha is to be used by issue tracker in general
// msg("severity mod detected",0);
if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
else { $captcha_ok = ($this->_captcha_ok());}
if ($captcha_ok)
{ if (checkSecurityToken())
{ $old_value = $issues[$issue_id]['severity'];
$issue_id = htmlspecialchars(stripslashes($_REQUEST['issue_ID']));
$project = htmlspecialchars(stripslashes($_REQUEST['project']));
$usr = htmlspecialchars(stripslashes($_REQUEST['ausr']));
$column = 'severity';
$issues[$issue_id]['severity'] = htmlspecialchars(stripslashes($_REQUEST['new_severity']));
// echo 'new severity = '.$issues[$issue_id]['severity'].' ';
//save issue-file
$xvalue = io_saveFile($pfile,serialize($issues)); // $project, $issue, $old_value, $column, $new_value
if($this->getConf('userinfo_email') >0) $this->_emailForIssueMod($project, $issues[$issue_id], $old_value, $column, $issues[$issue_id]['severity']);
$this->_log_mods($project, $issues[$issue_id], $usr, $column, $old_value, $issues[$issue_id]['severity']);
msg($this->getLang('msg_severitymodtrue'),1);
}
}
}
elseif(isset($_REQUEST['mod_status']))
{ // check if captcha is to be used by issue tracker in general
// msg("status mod detected",0);
if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
else { $captcha_ok = ($this->_captcha_ok());}
if ($captcha_ok)
{ if (checkSecurityToken())
{ $old_value = $issues[$issue_id]['status'];
$issue_id = htmlspecialchars(stripslashes($_REQUEST['issue_ID']));
$project = htmlspecialchars(stripslashes($_REQUEST['project']));
$usr = htmlspecialchars(stripslashes($_REQUEST['busr']));
$value = $_REQUEST['new_status'];
$column = 'status';
$issues[$issue_id]['status'] = htmlspecialchars(stripslashes($_REQUEST['new_status']));
// echo 'new status = '.$issues[$issue_id]['status'].' ';
//save issue-file
$xvalue = io_saveFile($pfile,serialize($issues));
if(($this->getConf('status_special')!=='') && (stripos($this->getConf('status_special'),$value) === false)) {
// $project, $issue, $old_value, $column, $new_value
if($this->getConf('userinfo_email') >0) $this->_emailForIssueMod($project, $issues[$issue_id], $old_value, $column, $issues[$issue_id]['status']);
}
$this->_log_mods($project, $issues[$issue_id], $usr, $column, $old_value, $issues[$issue_id]['status']);
msg($this->getLang('msg_statusmodtrue'),1);
}
}
}
/* Workaround to be stored ---------------------------------------------------*/
elseif(isset($_REQUEST["mod_wround"]))
{ // check if captcha is to be used by issue tracker in general
if ($this->getConf('use_captcha') === 0) { $captcha_ok = 1;}
else { $captcha_ok = ($this->_captcha_ok());}
if ($captcha_ok)
{ if (checkSecurityToken())
{ // find issue and description
if (@file_exists($pfile))
{ $issues = unserialize(@file_get_contents($pfile)); }
else
{ msg('Issue file not found !'.NL.$pfile,-1);
return false; }
// get comment file contents
if($this->getConf('it_data')==false) $comments_file = DOKU_CONF."../data/meta/".$project."_".$_REQUEST['comment_issue_ID'].'.cmnts';
else $comments_file = DOKU_CONF."../". $this->getConf('it_data').$project."_".$_REQUEST['comment_issue_ID'].'.cmnts';
if (@file_exists($comments_file)) { $comments = unserialize(@file_get_contents($comments_file)); }
else { $comments = array(); }
$checkFlag=false;
$comment_id = 0;
$comments[$comment_id] = array();
$comments[$comment_id]['id'] = "WA";
$comments[$comment_id]['author'] = htmlspecialchars(stripslashes($_REQUEST['author']));
$cur_date = date($this->getConf('d_format'));
$comments[$comment_id]['timestamp'] = $cur_date;
// $comments[$comment_id]['wround_mod'] = htmlspecialchars(stripslashes($_REQUEST['wround_mod']));
$comments[$comment_id]['wround_mod'] = htmlspecialchars($_REQUEST['wround_mod']);
//Create comments file
$xvalue = io_saveFile($comments_file,serialize($comments));
if($this->getConf('mail_add_comment') ===1) $this->_emailForMod($_REQUEST['project'],$issues[$_REQUEST['comment_issue_ID']], $comments[$comment_id], 'workaround');
msg($this->getLang('msg_wroundtrue').'.',1);
// update issues modification date
if ($checkFlag === false)
{ // inform user (or assignee) about update
// update modified date
$cur_date = date($this->getConf('d_format'));
$issues[$_REQUEST['comment_issue_ID']]['modified'] = $cur_date;
$xvalue = io_saveFile($pfile,serialize($issues));
$anker_id = 'resolved_'. uniqid((double)microtime()*1000000,1);
}
}
}
}
// Render
// Array , project name
$Generated_Table = $this->_details_render($issues, $project);
//$data->doc .= $Generated_Header.$Generated_Table.$Generated_feedback;
}
/* scrolling next/previous issues --------------------------------------------*/
elseif (($data->data == 'issuelist_next') || ($data->data == 'issuelist_previous') || ($data->data == 'issuelist_filter') || ($data->data == 'issuelist_filterlink'))
{
$data->preventDefault();
$renderer->info['cache'] = false;
$project = $this->itl_pjct;
$itl_start = $this->itl_start;
$step = $this->itl_step;
if ($step == '') {$step=10;}
$itl_next = $this->itl_next;
$a = $this->itl_pjct;
if ($this->getConf('multi_projects')==0) {
$all = false;
}
else {
$all = true;
}
// get issues file contents
$all = true;
$issues = $this->_get_issues($project, $all);
// global sort of issues array
$sort_key = $this->itl_sort;
$issues = $this->_issues_globalsort($issues, $sort_key);
if ($data->data == 'issuelist_next') {
$start = $itl_next;
if ($start<0) { $start='0'; }
elseif($start>count($issues)) {$start=count($issues)-step;}
$next_start = $start + $step;
if ($next_start>count($issues)) {
$next_start=count($issues);
$start = $next_start - $step;
if ($start<0) { $start='0'; }
}
// echo 'start = '.$start.'; step = '.$step.'; next_start = '.$next_start.' ';
}
elseif ($data->data == 'issuelist_previous') {
$start = $itl_start - $step;
if ($start<0) { $start='0'; $next_start = $start + $step;}
else $next_start = $itl_start;
}
elseif ($data->data == 'issuelist_filter') {
$start = $itl_start;
$next_start = $start + $step;
if ($next_start>count($issues)) { $next_start=count($issues); }
}
elseif ($data->data == 'issuelist_filterlink') {
$start = 0;
$step = count($issues);
$next_start = count($issues);
if ($next_start>count($issues)) { $next_start=count($issues); }
}
$filter = array();
$filter['status'] = $this->itl_stat;
$filter['severity'] = $this->itl_sev;
$filter['product'] = $this->itl_prod;
$filter['version'] = $this->itl_vers;
$filter['component'] = $this->itl_comp;
$filter['tblock'] = $this->itl_block;
$filter['assignee'] = $this->itl_assi;
$filter['reporter'] = $this->itl_reporter;
$filter['myissues'] = $this->itl_myis;
$filter['tblock'] = $this->itl_block;
if ($filter['severity'] == '') { $filter['severity'] = 'ALL' ;}
if ($filter['status'] == '') { $filter['status'] = 'ALL' ;}
if ($filter['product'] == '') { $filter['product'] = 'ALL' ;}
if ($filter['version'] == '') { $filter['version'] = 'ALL' ;}
if ($filter['component'] == '') { $filter['component'] = 'ALL' ;}
if ($filter['tblock'] == '') { $filter['tblock'] = false ;}
else { $filter['tblock'] = true ;}
if ($filter['assignee'] == '') { $filter['assignee'] = 'ALL' ;}
if ($filter['reporter'] == '') { $filter['reporter'] = 'ALL' ;}
if ($filter['myissues'] == '') { $filter['myissues'] = false ;}
else { $filter['myissues']= true ;}
if ($filter['myissues'] == '') {$filter['myissues'] = false;}
else {$filter['myissues'] = true;}
$Generated_Header = '';
$Generated_Table = $this->_table_render($this->project,$a,$step,$start,$next_start,$filter,$all);
$Generated_Scripts = $this->_scripts_render($project);
}
elseif ($data->data == 'showmodlog'){
global $auth;
$data->preventDefault();
$issue_id = $this->parameter;
$project = $this->project;
$Generated_Header = '';
$Generated_Scripts = '';
$Generated_Report = '';
$Generated_Message = '';
// get mod-log file contents
if($this->getConf('it_data')==false) $modfile = DOKU_CONF."../data/meta/".$project.'_'.$issue_id.'.mod-log';
else $modfile = DOKU_CONF."../". $this->getConf('it_data').$project.'_'.$issue_id.'.mod-log';
if (@file_exists($modfile))
{$mods = unserialize(@file_get_contents($modfile));}
else
{msg('No Modification log file found for this issue',-1);
return;}
$Generated_Table .= ''.$this->getLang('h_modlog').$issue_id.' ';
$Generated_Table .= ''.NL;
$Generated_Table .= 'Date User Field old Value new Value '.NL;
foreach($mods as $mod) {
if($rowEven==="it_roweven") $rowEven="it_rowodd";
else $rowEven="it_roweven";
$Generated_Table .= ''.NL;
$Generated_Table .= ' '.date($this->getConf('d_format'),strtotime($this->_get_one_value($mod,'timestamp'))).' '.NL;
$Generated_Table .= ' '.$this->_get_one_value($mod,'user').' '.NL;
$Generated_Table .= ' '.$this->_get_one_value($mod,'field').' '.NL;
$Generated_Table .= ' '.$this->_get_one_value($mod,'old_value').' '.NL;
$__assigened = $this->_get_one_value($mod,'new_value');
$__assigened = $this->xs_format($__assigened);
if((stripos($this->_get_one_value($mod,'field'),'assign')!== false) && ($this->getConf('auth_ad_overflow') == false)) {
$filter['grps']=$this->getConf('assign');
$target = $auth->retrieveUsers(0,0,$filter);
foreach($target as $_assignee)
{ if($_assignee['mail'] === $__assigened) {
$__assigened = $_assignee['name'];
break; }
}
}
$Generated_Table .= ' '.$__assigened.' '.NL;
$Generated_Table .= ' '.NL;
}
$Generated_Table .= '
'.NL;
// build parameter for $_GET method
$pstring = sprintf("showid=%s&project=%s", urlencode($issue_id), urlencode($project));
msg($ID,0);
$itl_item_title = ''.$this->getLang('back').' ';
$Generated_Table .= $itl_item_title.NL;
}
elseif ($data->data == 'it_search'){
$data->preventDefault();
include('itsearch.php');
}
/* elseif ($data->data == 'savecfgelement'){
// add a new element to the config-matrix
$data->preventDefault();
$cfg_file = DOKU_PLUGIN."issuetracker/conf/it_matrix.cfg";
$new_element = array();
if (@file_exists($cfg_file)) { $new_element = unserialize(@file_get_contents($cfg_file)); }
// elmnt_type | elmnt_name | rel_childs
$new_element[]= array(
'elmnt_type' => $_POST['type1'] ,
'elmnt_name' => $_POST['name1'] ,
'rel_childs' => "");
//save cfg-matrix file
asort($new_element);
$xvalue = io_saveFile($cfg_file,serialize($new_element));
if($xvalue>0) msg("New element added to the config matrix.",1);
else msg("New element cannot be added to the config matrix.",-1);
$backlink = str_replace("&do=savecfgelement","",$ID);
echo 'back ';
}
elseif ($data->data == 'savecfgmatrix'){
$data->preventDefault();
msg("implement code to store the newly added relation of an element and its childs",0);
echo 'elmnt_type: ' .$_POST['type2'].' ';
echo 'elmnt_name: ' .$_POST['name2'].' ';
echo 'elmnt_childs 1: '.$_POST['childs_1'].' ';
echo 'elmnt_childs 2: '.$_POST['childs_2'].' ';
echo 'elmnt_childs 3: '.$_POST['childs_3'].' ';
echo 'elmnt_childs 4: '.$_POST['childs_4'].' ';
echo 'elmnt_childs 5: '.$_POST['childs_5'].' ';
}
elseif ($data->data == 'deletecfgelement'){
$data->preventDefault();
// msg("implement code to delete an existing element and all its references",0);
// echo 'elmnt_type: '.$_POST['type3'].' ';
// echo 'elmnt_name: '.$_POST['name3'].' ';
// open cfg-matrix
$data->preventDefault();
$cfg_file = DOKU_PLUGIN."issuetracker/conf/it_matrix.cfg";
$elements = array();
if (@file_exists($cfg_file)) { $elements = unserialize(@file_get_contents($cfg_file)); }
else return;
// loop through matrix elements and delete all references + element themselves
foreach($elements as $key => &$item) {
if (($item['elmnt_type']===$_POST['type3']) & ($item['elmnt_name']===$_POST['name3'])) {
// delete completely from array
unset($elements[$key]);
}
if(stripos($item['rel_childs'],$_POST['name3'])!==false){
$temp = explode(",",$item['rel_childs']);
foreach($temp as $k => $i){
if($i===$_POST['name3']) unset($temp[$k]);
}
$item['rel_childs'] = implode(",",$temp);
}
}
//save cfg-matrix file
$xvalue = io_saveFile($cfg_file,serialize($elements));
if($xvalue>0) msg("Element completely deleted from config matrix.",1);
else msg("Element cannot be deleted from config matrix.",-1);
$backlink = str_replace("&do=savecfgelement","",$ID);
echo 'back ';
}
*/
else return;
// Render
echo $Generated_Header.$Generated_Table.$Generated_Scripts.$Generated_Report.$Generated_Message;
}
/******************************************************************************/
/* Create table scripts
*/
function _scripts_render($project)
{
// load status values from config into select control
$s_counter = 0;
$status = explode(',', $this->getConf('status')) ;
foreach ($status as $x_status)
{
$s_counter = $s_counter + 1;
$x_status = trim($x_status);
$STR_STATUS = $STR_STATUS . "case '".$x_status."': val = ".$s_counter."; break;";
$pattern = $pattern . "|" . $x_status;
$x_status_select = $x_status_select . "['".$x_status."','".$x_status."'],";
}
// Build string to load products select
$products = explode(',', $this->getConf('products')) ;
foreach ($products as $x_products)
{
$x_products = trim($x_products);
$x_products_select = $x_products_select . "['".$x_products."','".$x_products."'],";
}
// Build string to load severity select
$severity = explode(',', $this->getConf('severity')) ;
foreach ($severity as $x_severity)
{
$x_severity = trim($x_severity);
$x_severity_select = $x_severity_select . "['".$x_severity."','".$x_severity."'],";
}
// see issue 37: AUTH:AD switch to provide text input instead
// select with retriveing all_users from AD
if($this->getConf('auth_ad_overflow') == false) {
global $auth;
global $conf;
$filter['grps'] = $this->getConf('assign');
$target = $auth->retrieveUsers(0,0,$filter);
$shw_assignee_as = $this->getConf('shw_assignee_as');
if(stripos("login, mail, name",$shw_assignee_as) === false) $shw_assignee_as = "login";
//--------------------------------------------------------------------------------------------
// Build 'assign to' list from a simple textfile
// 1. check if file exist else use configuration
if($this->getConf('assgnee_list')==="") {
foreach ($target as $key => $x_umail)
{ // show assignee by login, name, mail
if($shw_assignee_as=='login') $x_umail_select = $x_umail_select . "['".$key."','".$x_umail['mail']."'],";
else $x_umail_select = $x_umail_select . "['".$x_umail[$shw_assignee_as]."','".$x_umail['mail']."'],";
}
}
else{
$x_umail_select = __get_assignees_from_files($this->getConf('assgnee_list'));
}
//--------------------------------------------------------------------------------------------
$x_umail_select .= "['',''],";
$authAD_selector = "TableKit.Editable.selectInput('assigned',{}, [".$x_umail_select."]);";
}
//hack if DOKU_BASE is not properly set
if(strlen(DOKU_BASE) < strlen(DOKU_URL)) $BASE = DOKU_URL."lib/plugins/issuetracker/";
else $BASE = DOKU_BASE."lib/plugins/issuetracker/";
return "
";
}
/******************************************************************************/
/* Create list of next/previous Issues
*/
function _table_render($project,$a,$step,$start,$next_start,$filter,$all=false)
{
global $ID;
$imgBASE = DOKU_BASE."lib/plugins/issuetracker/images/";
$style = ' style="text-align:center; white-space:pre-wrap;">';
$user_grp = pageinfo();
$noStatIMG = $this->getConf('noStatIMG');
$noSevIMG = $this->getConf('noSevIMG');
// get issues file contents
//$all = true;
$issues = $this->_get_issues($project, $all);
// global sort of issues array
$sort_key = $this->itl_sort;
$issues = $this->_issues_globalsort($issues, $sort_key);
// global sort of issues array
$sort_key = $this->itl_sort;
$issues = $this->_issues_globalsort($issues, $sort_key);
//
$dynatable_id = "t_".uniqid((double)microtime()*1000000,1);
if ($start>count($issues)) $start=count($issues)-$step;
if(array_key_exists('userinfo', $user_grp))
{
foreach ($user_grp['userinfo']['grps'] as $ugrp)
{
$user_grps = $user_grps . $ugrp;
}
}
else
{ $user_grps = 'all'; }
$ret = ''.NL;
$issue_edit_head .= formSecurityToken(false).
'
';
if($issue[$issue_id]['dev_start'] !="") $dev_start = date('d.M.Y',strtotime($issue[$issue_id]['dev_start']));
if($issue[$issue_id]['dev_deadline']!="") $deadline = date('d.M.Y',strtotime($issue[$issue_id]['dev_deadline']));
$issue_edit_head .= ''.NL;
$issue_edit_head .= '
'.NL;
}
else { // user not allowed to modify the planning data
if($issue[$issue_id]['dev_start'] !="") $dev_start = date('d.M.Y',strtotime($issue[$issue_id]['dev_start']));
if($issue[$issue_id]['dev_deadline']!="") $deadline = date('d.M.Y',strtotime($issue[$issue_id]['dev_deadline']));
$issue_edit_head .= '
'.$this->getLang('th_product').':
'.$issue[$issue_id]['product'].'
'.$this->getLang('th_begin').':
'.$dev_start.'
';
$issue_edit_head .= '
'.$this->getLang('th_version').':
'.$issue[$issue_id]['version'].'
'.$this->getLang('th_deadline').':
'.$issue[$issue_id]['dev_deadline'].'
';
$issue_edit_head .= '
'.$this->getLang('th_components').':
'.$deadline.'
'.$this->getLang('th_progress').':
'.$issue[$issue_id]['dev_progress'].'
'.NL;
if($issue[$issue_id]['tblock']!==false) { $cbx_tblock = $this->getLang('yes'); }
else $cbx_tblock = false;
$issue_edit_head .= '
'.$this->getLang('th_tversion').':
'.$issue[$issue_id]['trgt_version'].'
'.NL;
$issue_edit_head .= '
'.$this->getLang('th_tblock').':
'.$cbx_tblock.'
'.NL;
}
/*------------------------------------------------------------------------------
#60: to view mod-log
------------------------------------------------------------------------------*/
if($this->getConf('it_data')==false) $modfile = DOKU_CONF."../data/meta/".$project.'_'.$issue[$issue_id]['id'].'.mod-log';
else $modfile = DOKU_CONF."../". $this->getConf('it_data').$project.'_'.$issue[$issue_id]['id'].'.mod-log';
if (@file_exists($modfile)) {
$pstring = sprintf("showid=%s&project=%s", urlencode($issue[$issue_id]['id']), urlencode($project));
$modlog_link = ''.$this->getLang('th_showmodlog').' ';
$issue_edit_head .= '['.$modlog_link.'] '.NL;
$issue_edit_head .= '
'.NL;
}
/*----------------------------------------------------------------------------*/
$alink_id++;
$blink_id = 'statanker_'.$alink_id;
$anker_id = 'anker_'.$alink_id;
$cell_ID = 'img_tab_open_reporterdtls_'.$blink_id;
$issue_client_details = '
'.$this->getLang('lbl_reporterdtls').'
'.$this->getLang('lbl_reportername').'
'.$issue[$issue_id]['user_name'].'
';
//--------------------------------------------------------------------------------------------------------------
// do not show personal details if issue details diplayed by neigther admin/assignee nor the original user itself
//--------------------------------------------------------------------------------------------------------------
/* echo "current user = ".$user_mail['userinfo']['mail']." ".
"Reporting user = ".$issue[$issue_id]['user_mail']." ";
if($user_mail['userinfo']['mail'] === $issue[$issue_id]['user_mail']) {echo "current user = Reporting user ";}
else {echo "current user != Reporting user ";}
if(strpos($target2,$user_mail['userinfo']['mail']) != false) {echo "current user is a member of assignees ";}
else {echo "current user is not a member of assignees ";}
*/
//--------------------------------------------------------------------------------------------------------------
//create output for followers on registered users only
if(($user_mail['userinfo']['mail'] !== false))
{ $blink2_id = 'statanker2_'.$alink_id;
$anker2_id = 'anker2_'.$alink_id;
$tmp = explode(',', $issue[$issue_id]['add_user_mail']);
$follower = 0;
$issue_addcontacts .=' '.NL;
foreach($tmp as $email) {
//show only own mail address
if((strlen($email)>2) && (stripos($user_mail['userinfo']['mail'],$email)!==false)) {
$issue_addcontacts .=''.$email.' , '.NL;
$ademail .= $email;
$follower++;
}
//admin/assignee to see all followers
elseif((strlen($email)>2) && (strpos($target2,$user_mail['userinfo']['mail']) != false)) {
$issue_addcontacts .=''.$email.' , '.NL;
$ademail .= $email;
$follower++;
}
// to count follower
elseif(strlen($email)>2) $follower++;
}
if($follower==0) $follower='0';
$ademail = str_replace(',,',',',$ademail);
$issue_addcontacts .='
'
.formSecurityToken(false).'
';
if ($this->getConf('use_captcha')==1)
{ $helper = null;
if(@is_dir(DOKU_PLUGIN.'captcha'))
$helper = plugin_load('helper','captcha');
if(!is_null($helper) && $helper->isEnabled())
{ $issue_addcontacts .= ''.$helper->getHTML().' '; }
}
$issue_addcontacts .='
'.NL;
$issue_addimg = '
'.sprintf($this->getLang('itd_follower'),$follower).'
';
}
//--------------------------------------------------------------------------------------------------------------
if($allowedUser == true)
{
$issue_client_details .= '
'.$this->getLang('lbl_reportermail').'
'.$issue[$issue_id]['user_mail'].'
'.$this->getLang('lbl_reporterphone').'
'.$issue[$issue_id]['user_phone'].'
';
}
$issue_client_details .= '
'.$this->getLang('lbl_reporteradcontact').NL.
$issue_addimg.NL.
' '.$issue_addcontacts.'
';
$issue_client_details .= ''.NL.'
'.NL.'
';
$x_comment = $this->convertlabel($issue[$issue_id]['description']);
/*------------------------------------------------------------------------------
* Issue: 39, reported by lukas
* hook-in to provide possibility of modifing the initial description
------------------------------------------------------------------------------*/
// retrive some basic information
$cur_date = date($this->getConf('d_format'));
if($user_mail['userinfo']['mail']=='') {$u_mail_check ='unknown';}
else {$u_mail_check = $user_mail['userinfo']['mail'];}
$user_check = $this->getConf('registered_users');
$issue_initial_description = '';
/* END mod for edit description by ticket owner ----------------------------------*/
if((strpos($this->getConf('ltdReport'),'Symptom link 1')===false) || ($this->getConf('upload')>0)) {
$issue_attachments = '';
}
$issue_attachments .=''.NL;
}
/* END mod for edit description by ticket owner ----------------------------------*/
/* Workaround description --------------------------------------------------------*/
$issue_workaround =''.NL;
/* END of Workaround description --------------------------------------------------------*/
$issue_comments_log ='
'.$this->getLang('lbl_cmts_wlog').'
';
// loop through the comments
if ($comments!=false) {
foreach ($comments as $a_comment)
{ if($this->_get_one_value($a_comment,'id') === 'WA') continue;
$x_id = $this->_get_one_value($a_comment,'id');
$x_comment = $this->_get_one_value($a_comment,'comment');
$x_comment = $this->convertlabel($x_comment);
//----------------------------------------------------------------------------------------------------------------
// do not show personal details if issue details diplayed by neigther admin/assignee nor the original user itself
//----------------------------------------------------------------------------------------------------------------
if((($user_mail['userinfo']['mail'] === $issue[$issue_id]['user_mail'])
or (strpos($target2,$user_mail['userinfo']['mail']) != false)
or ($user_mail['userinfo']['mail'] === $this->_get_one_value($a_comment,'author')))
&& ($this->getConf('shw_mail_addr')===1) && ($this->getConf('auth_ad_overflow') == false))
{ $x_mail = ''.$this->_get_one_value($a_comment,'author').' '; }
// show mailto with name instead user mail address
elseif((($user_mail['userinfo']['mail'] === $issue[$issue_id]['user_mail'])
or (strpos($target2,$user_mail['userinfo']['mail']) != false)
or ($user_mail['userinfo']['mail'] === $this->_get_one_value($a_comment,'author')))
&& ($this->getConf('shw_mail_addr')===0) && ($this->getConf('auth_ad_overflow') == false))
{
$compare = $this->_get_one_value($a_comment,'author');
$dw_users = $auth->retrieveUsers();
foreach($dw_users as $mail_adr)
{ if($mail_adr['mail']==$compare)
{ $tmp_name = $mail_adr['name'];
break;
}
}
if($tmp_name==false) $tmp_name = $compare;
$x_mail= ''.$tmp_name.' ';
}
elseif($this->getConf('auth_ad_overflow') == true) {
$x_mail = ''.$this->_get_one_value($a_comment,'author').' '; }
else {
// here it is necessary for others to know if issue reporter, follower or assignee is commenting
// implement the function to differenciate between these roles
// => check mail address with reporter, follower and assignee/admin group else it is a foreigner
$role = $this->_get_one_value($a_comment,'author');
if ($issue[$issue_id]['user_mail'] === $role)
$x_mail = ' ('.$this->getLang('dtls_reporter_hidden').') ';
elseif (stripos($issue['add_user_mail'],$role) != false)
$x_mail = ' ('.$this->getLang('dtls_follower_hidden').') ';
elseif (stripos($target2,$role) != false)
$x_mail = ' ('.$this->getLang('dtls_assignee_hidden').') ';
else
$x_mail = ' ('.$this->getLang('dtls_foreigner_hidden').') ';
}
if($this->_get_one_value($a_comment,'mod_timestamp')) { $insert_lbl = '! ';}
else $insert_lbl ='';
$issue_comments_log .= '
'.NL;
$issue_comments_log .= '
'.NL;
//--------------------------------------------------------------------------------------------------------------
// only admin/assignees and reporter are allowed to add comments if only user edit option is set
//--------------------------------------------------------------------------------------------------------------
// retrive some basic information
$cur_date = date($this->getConf('d_format'));
if($user_mail['userinfo']['mail']=='') {$u_mail_check ='unknown';}
elseif($this->getConf('shw_mail_addr')===0) {$u_mail_check =$user_mail['userinfo']['name'];}
else {$u_mail_check = $user_mail['userinfo']['mail'];}
$user_check = $this->getConf('registered_users');
/*------------------------------------------------------------------------------
* Modify comment */
// check if current user is author of the comment and offer an edit button
if(($allowedUser == true) or ($this->getConf('auth_ad_overflow') == true))
{ // add hidden edit toolbar and textarea
$alink_id++;
$blink_id = 'statanker_'.$alink_id;
$anker_id = 'anker_'.$alink_id;
$issue_comments_log .= '
';
$issue_comments_log .= $this->it_xs_edit_toolbar('comment_mod_'.$alink_id);
$issue_comments_log .= ''.NL;
$issue_comments_log .= formSecurityToken(false).
' '.NL.
' '.NL.
' '.NL.
' '.NL.
' '.NL.
' '.NL.
'
'.NL;
if ($this->getConf('use_captcha')==1)
{ $helper = null;
if(@is_dir(DOKU_PLUGIN.'captcha'))
$helper = plugin_load('helper','captcha');
if(!is_null($helper) && $helper->isEnabled())
{ $issue_comments_log .= ''.$helper->getHTML().'
'; }
}
$cell_ID = 'img_tab_open_comment'.$blink_id;
$cntrl_id = 'ctrl_'.$alink_id;
// check if only registered users are allowed to modify comments
// ¦ perm  the user's permissions related to the current page ($ID)
$issue_comments_log .= ' '.
''.
' '.$this->getLang('minor_mod').' '.
' '.' '.
' '.
' '.NL.' '.NL.' '.NL.
''.NL.'
'.NL.'
'.NL;
}
}
}
$issue_comments_log .='
';
/* end Modify comment
------------------------------------------------------------------------------*/
//--------------------------------------------------------------------------------------------------------------
// only admin/assignees and reporter are allowed to add comments if only user edit option is set
//--------------------------------------------------------------------------------------------------------------
// retrive some basic information
$cur_date = date($this->getConf('d_format'));
if(strlen($user_mail['userinfo']['mail']) == 0) {$u_mail_check ='unknown';}
else {$u_mail_check = $user_mail['userinfo']['mail'];}
$user_check = $this->getConf('registered_users');
$u_name = $user_mail['userinfo']['name'];
//2011-12-02: bwenz code proposal (Issue 11)
$x_resolution = $this->convertlabel($issue[$issue_id]['resolution']);
// if(!$x_resolution) { $x_resolution = " "; }
$_cFlag = false;
if($user_check == 0)
{ $_cFlag = true; }
elseif(($user_check == 1) && ($user_mail['perm'] > 1))
{ $_cFlag = true; }
if($_cFlag === true) {
// mod for editor ---------------------------------------------------------------------
$alink_id++;
$blink_id = 'statanker_'.$alink_id;
$anker_id = 'anker_'.$alink_id;
$issue_add_comment .=''.NL;
$alink_id++;
$blink_id = 'statanker_'.$alink_id;
$anker_id = 'anker_'.$alink_id;
$issue_edit_resolution =''.NL;
}
// the user maybe registered within group "all" but the registered flag is turned on
// eigther the user has to be moved into group "user" or the flag to be switched off
elseif(($user_mail['perm'] < 2) && (strlen($user_mail['userinfo']['mail'])>1)) {
$issue_edit_resolution ='
'.$this->getLang('th_resolution').'
';
$issue_edit_resolution .= '
'.$this->xs_format($x_resolution).'
'.NL;
$wmsg = $this->getLang('lbl_lessPermission');
$issue_edit_resolution .= ''.$wmsg.'
';
}
else {
$issue_edit_resolution ='
'.$this->getLang('th_resolution').'
';
$issue_edit_resolution .= '
'.NL;
$wmsg = $this->getLang('lbl_please').''.$this->getLang('lbl_signin');
$issue_edit_resolution .= ''.$wmsg.'
';
}
//2011-12-02: bwenz code proposal (Issue 11)
// $ret = $issue_edit_head . $issue_client_details . $issue_initial_description . $issue_attachments . $issue_comments_log . $issue_add_comment;
$usr = ''.$user_grp['userinfo']['name'].' ' ; //to log issue mods
$ret = $usr.$issue_edit_head . $issue_client_details . $issue_initial_description . $issue_attachments . $issue_workaround . $issue_comments_log . $issue_add_comment . $issue_edit_resolution;
return $ret;
}
/******************************************************************************/
/******************************************************************************/
/* send an e-mail to user due to issue resolution
*/
function _emailForRes($project,$issue)
{ if($this->getConf('userinfo_email') ===0) return;
if ($this->getConf('mail_templates')==1) {
// load user html mail template
$sFilename = DOKU_PLUGIN.'issuetracker/mailtemplate/issue_resolved_mail.html';
$bodyhtml = file_get_contents($sFilename);
}
$subject = sprintf($this->getLang('issue_resolved_subject'),$issue['id'], $project);
$subject = mb_encode_mimeheader($subject, "UTF-8", "Q" );
$pstring = sprintf("showid=%s&project=%s", urlencode($issue['id']), urlencode($project));
global $ID;
$body = $this->getLang('issuemod_head').chr(10).chr(10).
$this->getLang('issue_resolved_intro').chr(10).
$this->getLang('issuemod_issueid').$issue['id'].chr(10).
$this->getLang('issuemod_status').$issue['status'].chr(10).
$this->getLang('issuemod_product').$issue['product'].chr(10).
$this->getLang('issuemod_version').$issue['version'].chr(10).chr(10).
$this->getLang('issue_resolved_text').$this->xs_format($issue['resolution']).chr(10).chr(10).
$this->getLang('issuemod_see').DOKU_URL.'doku.php?id='.$ID.'&do=showcaselink&'.$pstring.chr(10).chr(10).
$this->getLang('issuemod_br').chr(10).$project.$this->getLang('issuemod_end');
$body = html_entity_decode($body);
if ($this->getConf('mail_templates')==1) $bodyhtml = $this->replace_bodyhtml($bodyhtml, $pstring, $project, $issue, NULL);
$from=$this->getConf('email_address') ;
$to=$issue['user_mail'];
if($to==='') $to=$this->getConf('email_address');
$cc=$issue['add_user_mail'].', '.$issue['assigned'];
if(stripos($to.$cc,$issue['assigned'])==false) $cc .=', '.$issue['assigned'];
if ($this->getConf('mail_templates')==1) {
$headers = "Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable";
$this->mail_send_html($to, $subject, $body, $bodyhtml, $from, $cc, $bcc='', $headers, $params=null);
}
else {
mail_send($to, $subject, $body, $from, $cc, $bcc='', $headers=null, $params=null);
}
}
/******************************************************************************/
/* send an e-mail to user due to issue modificaion
*/
function _emailForIssueMod($project, $issue, $old_value, $column, $new_value)
{
// if ($conf['plugin']['issuetracker']['userinfo_email']==1)
{ global $ID;
global $lang;
global $conf;
if($new_value == '') $new_value = $this->getLang('it__none');
if($old_value == '') $old_value = $this->getLang('it__none');
if ($this->getConf('mail_templates')==1) {
// load user html mail template
$sFilename = DOKU_PLUGIN.'issuetracker/mailtemplate/edit_issuemod_mail.html';
$bodyhtml = file_get_contents($sFilename);
$comment = array();
$comment["field"] = $column;
$comment["old_value"] = $old_value;
$comment["new_value"] = $new_value;
$comment["timestamp"] = date($this->getConf('d_format'));
$user_mail = pageinfo();
$comment["author"] = $user_mail['userinfo']['mail'];
}
//issuemod_subject = 'Issue #%s on %s: %s';
$subject = sprintf($this->getLang('issuemod_subject'), $issue['id'], $project, $this->getLang('th_'.$column));
$subject = mb_encode_mimeheader($subject, "UTF-8", "Q" );
$pstring = sprintf("showid=%s&project=%s", urlencode($issue['id']), urlencode($project));
//issuemod_changes = The issue changed on %s from %s to %s.
$changes = sprintf($this->getLang('issuemod_changes'),$this->getLang('th_'.$column), $old_value, $new_value);
$body = chr(10).$this->getLang('issuemod_head').chr(10).chr(10).
$this->getLang('issuemod_intro').chr(10).
$changes.chr(10).chr(10).
$this->getLang('issuemod_title').$issue['title'].chr(10).
$this->getLang('issuemod_issueid').$issue['id'].chr(10).
$this->getLang('issuemod_product').$issue['product'].chr(10).
$this->getLang('issuemod_version').$issue['version'].chr(10).
$this->getLang('issuemod_severity').$issue['severity'].chr(10).
$this->getLang('issuemod_status').$issue['status'].chr(10).
$this->getLang('issuemod_creator').$issue['user_name'].chr(10).
$this->getLang('issuemod_assignee').$issue['assigned'].chr(10).
$this->getLang('issuenew_descr').$issue['description'].chr(10).
$this->getLang('issuemod_see').DOKU_URL.'doku.php?id='.$ID.'&do=showcaselink&'.$pstring.chr(10).chr(10).
$this->getLang('issuemod_br').chr(10).$this->getLang('issuemod_end');
$body = html_entity_decode($body);
if ($this->getConf('mail_templates')==1) $bodyhtml = $this->replace_bodyhtml($bodyhtml, $pstring, $project, $issue, $comment);
$from=$this->getConf('email_address'). "\r\n";
$user_mail = pageinfo();
if($user_mail['userinfo']['mail']===$issue['user_mail']) $to=$issue['assigned'];
elseif($user_mail['userinfo']['mail']===$issue['assigned']) $to=$issue['user_mail'];
else $to=$issue['user_mail'].', '.$issue['assigned'];
if($to==='') $to=$this->getConf('email_address');
$cc=$issue['add_user_mail'];
if ($this->getConf('mail_templates')==1) {
$this->mail_send_html($to, $subject, $body, $bodyhtml, $from, $cc, $bcc='', $headers, $params=null);
}
else {
mail_send($to, $subject, $body, $from, $cc, $bcc='', $headers=null, $params=null);
}
}
}
/******************************************************************************/
/* send an e-mail to user due to issue modificaion
*/
function _emailForMod($project,$issue,$comment,$reason)
{ if($this->getConf('userinfo_email') ===0) return;
global $ID;
if ($this->getConf('mail_templates')==1) {
// load user html mail template
$sFilename = DOKU_PLUGIN.'issuetracker/mailtemplate/cmnt_mod_mail.html';
$bodyhtml = file_get_contents($sFilename);
}
if($reason =='new') { $subject = sprintf($this->getLang('cmnt_new_subject'),$issue['id'], $project). "\r\n"; }
elseif($reason =='delete') { $subject = sprintf($this->getLang('cmnt_del_subject'),$issue['id'], $project). "\r\n"; }
elseif($reason =='workaround') { $subject = sprintf($this->getLang('cmnt_wa_subject') ,$issue['id'], $project). "\r\n"; }
else { $subject = sprintf($this->getLang('cmnt_mod_subject'),$issue['id'], $project). "\r\n"; }
$subject = mb_encode_mimeheader($subject, "UTF-8", "Q" );
$pstring = sprintf("showid=%s&project=%s", urlencode($issue['id']), urlencode($project));
if($reason =='delete') {
$body2 = $this->getLang('cmt_del_intro').chr(10).chr(13);
$bodyhtml = str_ireplace("%%bodyhtml2%%",$this->getLang('cmt_del_intro'),$bodyhtml);
}
elseif($reason =='workaround') {
$body2 = $this->getLang('issuemod_intro').chr(10).chr(13);
$bodyhtml = str_ireplace("%%bodyhtml2%%",$this->getLang('issuemod_intro'),$bodyhtml);
$body3 = $this->getLang('issuemod_cmntauthor').$comment['author'].chr(10).
$this->getLang('issuemod_date').date($this->getConf('d_format'),strtotime($comment['timestamp'])).chr(10).
$this->getLang('issuemod_cmnt').chr(10).$this->xs_format($comment['wround_mod']).chr(10).chr(10);
}else {
$body2 = $this->getLang('issuemod_intro').chr(10).chr(13);
$bodyhtml = str_ireplace("%%bodyhtml2%%",$this->getLang('issuemod_intro'),$bodyhtml);
$body3 = $this->getLang('issuemod_cmntauthor').$comment['author'].chr(10).
$this->getLang('issuemod_date').date($this->getConf('d_format'),strtotime($comment['timestamp'])).chr(10).
$this->getLang('issuemod_cmnt').chr(10).$this->xs_format($comment['comment']).chr(10).chr(10);
}
$body = $this->getLang('issuemod_head').chr(10).chr(10).
$body2.
$this->getLang('issuemod_title').$issue['title'].chr(10).
$this->getLang('issuemod_issueid').$issue['id'].chr(10).
$this->getLang('issuemod_product').$issue['product'].chr(10).
$this->getLang('issuemod_version').$issue['version'].chr(10).
$this->getLang('issuemod_severity').$issue['severity'].chr(10).
$this->getLang('issuemod_status').$issue['status'].chr(10).
$this->getLang('issuemod_creator').$issue['user_name'].chr(10).
$this->getLang('issuemod_assignee').$issue['assigned'].chr(10).
$body3.
$this->getLang('issuemod_see').DOKU_URL.'doku.php?id='.$ID.'&do=showcaselink&'.$pstring.chr(10).chr(10).
$this->getLang('issuemod_br').chr(10).$project.$this->getLang('issuemod_end'). "\r\n";
$body = html_entity_decode($body);
if ($this->getConf('mail_templates')==1) $bodyhtml = $this->replace_bodyhtml($bodyhtml, $pstring, $project, $issue, $comment);
$from=$this->getConf('email_address'). "\r\n";
$user_mail = pageinfo();
if($user_mail['userinfo']['mail']===$issue['user_mail']) $to=$issue['assigned'];
elseif($user_mail['userinfo']['mail']===$issue['assigned']) $to=$issue['user_mail'];
else $to=$issue['user_mail'].', '.$issue['assigned'];
if(strlen($to)<3) $to=$this->getConf('email_address');
$cc=$issue['add_user_mail'];
if ($this->getConf('mail_templates')==1) {
$this->mail_send_html($to, $subject, $body, $bodyhtml, $from, $cc, $bcc='', $headers, $params=null);
}
else {
mail_send($to, $subject, $body, $from, $cc, $bcc='', $headers=null, $params=null);
}
}
/******************************************************************************/
/* send an e-mail to user due to issue modificaion on Descriptions
*/
function _emailForDscr($project,$issue)
{ if($this->getConf('userinfo_email') ===0) return;
global $ID;
if ($this->getConf('mail_templates')==1) {
// load user html mail template
$sFilename = DOKU_PLUGIN.'issuetracker/mailtemplate/issue_descr_mail.html';
$bodyhtml = file_get_contents($sFilename);
}
$subject = sprintf($this->getLang('issuedescrmod_subject'),$issue['id'], $project). "\r\n";
$subject = mb_encode_mimeheader($subject, "UTF-8", "Q" );
$pstring = sprintf("showid=%s&project=%s", urlencode($issue['id']), urlencode($project));
global $ID;
$body = $this->getLang('issuemod_head').chr(10).chr(10).
$this->getLang('issuemod_intro').chr(10).chr(13).
$this->getLang('issuemod_title').$issue['title'].chr(10).
$this->getLang('issuemod_issueid').$issue['id'].chr(10).
$this->getLang('issuemod_product').$issue['product'].chr(10).
$this->getLang('issuemod_version').$issue['version'].chr(10).
$this->getLang('issuemod_severity').$issue['severity'].chr(10).
$this->getLang('issuemod_status').$issue['status'].chr(10).
$this->getLang('issuemod_creator').$issue['user_name'].chr(10).
$this->getLang('issuemod_assignee').$issue['assigned'].chr(10).chr(10).
$this->getLang('issuemod_date').date($this->getConf('d_format'),strtotime($comment['timestamp'])).chr(10).chr(10).
$this->getLang('th_description').chr(10).$issue['description'].chr(10).chr(10).
$this->getLang('issuemod_see').DOKU_URL.'doku.php?id='.$ID.'&do=showcaselink&'.$pstring.chr(10).chr(10).
$this->getLang('issuemod_br').chr(10).$project.$this->getLang('issuemod_end'). "\r\n";
if ($this->getConf('mail_templates')==1) $bodyhtml = $this->replace_bodyhtml($bodyhtml, $pstring, $project, $issue, $comment);
$body = html_entity_decode($body);
$from=$this->getConf('email_address'). "\r\n";
$user_mail = pageinfo();
if($user_mail['userinfo']['mail']===$issue['user_mail']) $to=$issue['assigned']. "\r\n";
elseif($user_mail['userinfo']['mail']===$issue['assigned']) $to=$issue['user_mail']. "\r\n";
else $to=$issue['user_mail'].', '.$issue['assigned']. "\r\n";
$cc=$issue['add_user_mail']. "\r\n";
if ($this->getConf('mail_templates')==1) {
$this->mail_send_html($to, $subject, $body, $bodyhtml, $from, $cc, $bcc='', $headers, $params=null);
}
else {
mail_send($to, $subject, $body, $from, $cc, $bcc='', $headers=null, $params=null);
}
}
/******************************************************************************/
/***********************************
* HTML Mail functions
*
* Sends HTML-formatted mail
* By Lin Junjie (mail [dot] junjie [at] gmail [dot] com)
*
***********************************/
function mail_send_html($to, $subject, $body, $bodyhtml, $from='', $cc='', $bcc='', $header='', $params=null){
if(defined('MAILHEADER_ASCIIONLY')){
$subject = utf8_deaccent($subject);
$subject = utf8_strip($subject);
}
if(!defined('MAILHEADER_EOL')) define('MAILHEADER_EOL',"\n");
if(!utf8_isASCII($subject)) {
$subject = '=?UTF-8?Q?'.mail_quotedprintable_encode($subject,0).'?=';
// Spaces must be encoded according to rfc2047. Use the "_" shorthand
$subject = preg_replace('/ /', '_', $subject);
}
$header = '';
$usenames = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? false : true;
$random_hash = md5(date('r', time())); // added
$to = mail_encode_address($to,'',$usenames);
$header .= mail_encode_address($from,'From');
$header .= mail_encode_address($cc,'Cc');
$header .= mail_encode_address($bcc,'Bcc');
$header .= 'MIME-Version: 1.0'.MAILHEADER_EOL;
$header .= "Content-Type: multipart/alternative; boundary=PHP-alt-".$random_hash.MAILHEADER_EOL;
$header = trim($header);
$body = mail_quotedprintable_encode($body,0);
$bodyhtml = mail_quotedprintable_encode($bodyhtml,0);
$message = "--PHP-alt-".$random_hash."\r\n".
"Content-Type: text/plain; charset=UTF-8"."\n".
"Content-Transfer-Encoding: quoted-printable"."\n\n".
$body."\n\n".
"--PHP-alt-".$random_hash."\r\n".
"Content-Type: text/html; charset=UTF-8"."\n".
"Content-Transfer-Encoding: quoted-printable"."\n\n".
$bodyhtml."\n".
"--PHP-alt-".$random_hash."--";
if($params == null){
return @mail($to,$subject,$message,$header);
}else{
return @mail($to,$subject,$message,$header,$params);
}
}
/******************************************************************************/
function replace_bodyhtml($bodyhtml, $pstring, $project, $issue, $comment) {
global $ID;
// echo "ID = ". $ID . " ";
$bodyhtml = str_ireplace("%%_SEE%%",DOKU_URL.'doku.php?id='.$ID.'&do=showcaselink&'.$pstring,$bodyhtml);
$bodyhtml = str_ireplace("%%issuemod_head%%",$this->getLang('issuemod_head'),$bodyhtml);
$bodyhtml = str_ireplace("%%issuemod_intro%%",$this->getLang('issuemod_intro'),$bodyhtml);
$bodyhtml = str_ireplace("%%issuemod_issueid%%",$this->getLang('issuemod_issueid'),$bodyhtml);
$bodyhtml = str_ireplace("%%ID%%",$issue['id'],$bodyhtml);
$bodyhtml = str_ireplace("%%issuemod_title%%",$this->getLang('issuemod_title'),$bodyhtml);
$bodyhtml = str_ireplace("%%TITEL%%",$issue['title'],$bodyhtml);
$bodyhtml = str_ireplace("%%issuemod_status%%",$this->getLang('issuemod_status'),$bodyhtml);
$bodyhtml = str_ireplace("%%STATUS%%",$issue['status'],$bodyhtml);
$bodyhtml = str_ireplace("%%th_project%%",$this->getLang('th_project'),$bodyhtml);
$bodyhtml = str_ireplace("%%PROJECT%%",$project,$bodyhtml);
$bodyhtml = str_ireplace("%%issuemod_product%%",$this->getLang('issuemod_product'),$bodyhtml);
$bodyhtml = str_ireplace("%%PRODUCT%%",$issue['product'],$bodyhtml);
$bodyhtml = str_ireplace("%%issuemod_version%%",$this->getLang('issuemod_version'),$bodyhtml);
$bodyhtml = str_ireplace("%%VERSION%%",$issue['version'],$bodyhtml);
$bodyhtml = str_ireplace("%%issuemod_severity%%",$this->getLang('issuemod_severity'),$bodyhtml);
$bodyhtml = str_ireplace("%%SEVERITY%%",$issue['severity'],$bodyhtml);
$bodyhtml = str_ireplace("%%issuemod_creator%%",$this->getLang('issuemod_creator'),$bodyhtml);
$bodyhtml = str_ireplace("%%CREATOR%%",$issue['user_name'],$bodyhtml);
$bodyhtml = str_ireplace("%%CREATOR_MAIL%%",$issue['user_mail'],$bodyhtml);
$bodyhtml = str_ireplace("%%th_assigned%%",$this->getLang('th_assigned'),$bodyhtml);
$bodyhtml = str_ireplace("%%ASSIGNED%%",$issue['assigned'],$bodyhtml);
$bodyhtml = str_ireplace("%%th_created%%",$this->getLang('th_created'),$bodyhtml);
$bodyhtml = str_ireplace("%%CREATED%%",$issue['created'],$bodyhtml);
$bodyhtml = str_ireplace("%%issueassigned_head%%",$lang['issueassigned_head'],$bodyhtml);
$bodyhtml = str_ireplace("%%issueassigned_intro%%",$lang['issueassigned_intro'],$bodyhtml);
$bodyhtml = str_ireplace("%%issue_resolved_intro%%",$this->getLang('issue_resolved_intro'),$bodyhtml);
$bodyhtml = str_ireplace("%%issue_resolved_text%%",$this->getLang('issue_resolved_text'),$bodyhtml);
$frmt_res = str_ireplace(chr(10)," ",$issue['resolution']);
$bodyhtml = str_ireplace("%%RESOLUTION%%",$this->xs_format($frmt_res),$bodyhtml);
$bodyhtml = str_ireplace("%%TIMESTAMP%%",date($this->getConf('d_format')),$bodyhtml);
$user_grp = pageinfo();
$usr = $user_grp['userinfo']['name'] ;
$bodyhtml = str_ireplace("%%RESOLVER%%",$usr,$bodyhtml);
$bodyhtml = str_ireplace("%%MOD_BY%%",$usr,$bodyhtml);
$bodyhtml = str_ireplace("%%issuedescrmod_subject%%",sprintf($this->getLang('issuedescrmod_subject'),$issue['id'], $project),$bodyhtml);
$bodyhtml = str_ireplace("%%th_description%%",$this->getLang('th_description'),$bodyhtml);
$frmt_descr = str_ireplace(chr(10)," ",$issue['description']);
$bodyhtml = str_ireplace("%%DESCRIPTION%%",$this->xs_format($frmt_descr),$bodyhtml);
// if($comment) {
$bodyhtml = str_ireplace("%%lbl_cmts_wlog%%",$this->getLang('lbl_cmts_wlog'),$bodyhtml);
$bodyhtml = str_ireplace("%%CMNT_ID%%",$comment['id'],$bodyhtml);
$bodyhtml = str_ireplace("%%EDIT_AUTHOR%%",$comment['author'],$bodyhtml);
$bodyhtml = str_ireplace("%%CMNT_AUTHOR%%",$comment['author'],$bodyhtml);
$bodyhtml = str_ireplace("%%CMNT_TIMESTAMP%%",date($this->getConf('d_format'),strtotime($comment['timestamp'])),$bodyhtml);
$frmt_cmnt = str_ireplace(chr(10)," ",$comment['comment']);
$bodyhtml = str_ireplace("%%COMMENT%%",$this->xs_format($frmt_cmnt),$bodyhtml);
$bodyhtml = str_ireplace("%%FIELD%%",str_ireplace(chr(10)," ",$comment["field"]),$bodyhtml);
$bodyhtml = str_ireplace("%%OLD_VALUE%%",$this->xs_format(str_ireplace(chr(10)," ",$comment["old_value"])),$bodyhtml);
$bodyhtml = str_ireplace("%%NEW_VALUE%%",$this->xs_format(str_ireplace(chr(10)," ",$comment["new_value"])),$bodyhtml);
// }
$bodyhtml = str_ireplace("%%issuemod_br%%",$this->getLang('issuemod_br'),$bodyhtml);
$bodyhtml = str_ireplace("%%issuemod_end%%",$this->getLang('issuemod_end'),$bodyhtml);
// echo $bodyhtml;
return $bodyhtml;
}
/******************************************************************************/
/* pic-up a single value
*/
function _get_one_value($issue, $key) {
// echo $key. " => " . $issue . " ";
if (@array_key_exists($key,$issue)) return $issue[$key];
else return '';
}
/******************************************************************************/
/* elaborate the display string of assignee (login, name or mail)
*/
function _get_assignee($issue, $key) {
if (array_key_exists($key,$issue)) {
global $auth;
global $conf;
$filter['grps'] = $this->getConf('assign');
$usr_array = $auth->retrieveUsers(0,0,$filter);
$shw_assignee_as = trim($this->getConf('shw_assignee_as'));
if(stripos("login, mail, name",$shw_assignee_as) === false) $shw_assignee_as = "login";
foreach ($usr_array as $u_key => $usr)
{ if($usr['mail']==$issue[$key])
{ if ($shw_assignee_as == 'login') { return $u_key; }
elseif($shw_assignee_as == 'mail') { return $usr['mail']; }
else { return $usr['name']; }
}
}
}
if(stripos("mail",$shw_assignee_as) !== false) { return $issue[$key]; }
else
{ $b_display = explode("@",$issue[$key]);
return $b_display[0];
}
}
/******************************************************************************/
/* Captcha OK
*/
function _captcha_ok()
{
$helper = null;
if(@is_dir(DOKU_PLUGIN.'captcha')) $helper = plugin_load('helper','captcha');
if(!is_null($helper) && $helper->isEnabled()) { return $helper->check(); }
return ($this->getConf('use_captcha'));
}
/******************************************************************************/
/* Create count output
*/
function _count_render($issues,$start,$step,$next_start,$filter,$project)
{ global $ID;
$count = array();
foreach ($issues as $issue)
{
if(($issue['project'] !== $project) && ($this->getConf('multi_projects')==0)) {
continue;
}
elseif ((strcasecmp($filter['product'],'ALL')===0) || (stristr($filter['product'],$this->_get_one_value($issue,'product'))!= false))
{ $status = trim($this->_get_one_value($issue,'status'));
$a_count = $a_count + 1;
if (($status != '') && (stripos($this->getConf('status_special'),$status)===false))
{ if ($this->_get_one_value($count,strtoupper($status))=='')
{$count[strtoupper($status)] = array(1,$status);}
else
{$count[strtoupper($status)][0] += 1;}
}
}
}
$rendered_count = ''.'
';
foreach ($count as $value)
{
//http://www.fristercons.de/fcon/doku.php?id=issuetracker:issuelist&do=showcaselink&showid=19&project=fcon_project
// $ID.'&do=issuelist_filter&itl_sev_filter='.$value[1]
$rendered_count .= ''.$value[1].' '.$value[0].' ';
}
$rendered_count .= '
';
$ret_array = array($a_count,$rendered_count);
return $ret_array;
}
/******************************************************************************/
/* replace simple formats used by editor buttons
*/
function xs_format($x_comment)
{ // bold , italic, underline, etc.
$x_comment = preg_replace('/\[([bius])\]/i', '<\\1>', $x_comment);
$x_comment = preg_replace('/\[\/([bius])\]/i', '\\1>', $x_comment);
$x_comment = preg_replace('/\[ol\]/i', '', $x_comment);
$x_comment = preg_replace('/\[\/ol\]/i', ' ', $x_comment);
$x_comment = preg_replace('/\[ul\]/i', '', $x_comment);
$x_comment = preg_replace('/\[\/ul\]/i', ' ', $x_comment);
$x_comment = preg_replace('/\[li\]/i', '', $x_comment);
$x_comment = preg_replace('/\[\/li\]/i', ' ', $x_comment);
$x_comment = preg_replace('/\[sup\]/i', '', $x_comment);
$x_comment = preg_replace('/\[\/sup\]/i', ' ', $x_comment);
$x_comment = preg_replace('/\[sub\]/i', '', $x_comment);
$x_comment = preg_replace('/\[\/sub\]/i', ' ', $x_comment);
$x_comment = preg_replace('/\[hr\]/i', ' ', $x_comment);
$x_comment = preg_replace('/\[blockquote\]/i', '', $x_comment);
$x_comment = preg_replace('/\[\/blockquote\]/i', ' ', $x_comment);
$x_comment = preg_replace('/\[code\]/i', '', $x_comment);
$x_comment = preg_replace('/\[\/code\]/i', '
', $x_comment);
$x_comment = preg_replace('/\[red\]/i', '', $x_comment);
$x_comment = preg_replace('/\[\/red\]/i', ' ', $x_comment);
$x_comment = preg_replace('/\[grn\]/i', '', $x_comment);
$x_comment = preg_replace('/\[\/grn\]/i', ' ', $x_comment);
$x_comment = preg_replace('/\[bgy\]/i', '', $x_comment);
$x_comment = preg_replace('/\[\/bgy\]/i', ' ', $x_comment);
$x_comment = preg_replace('/\[blu\]/i', '', $x_comment);
$x_comment = preg_replace('/\[\/blu\]/i', ' ', $x_comment);
$urlsuch[]="/([^]_a-z0-9-=\"'\/])((https?|ftp):\/\/|www\.)([^ \r\n\(\)\^\$!`\"'\|\[\]\{\}<>]*)/si";
$urlsuch[]="/^((https?|ftp):\/\/|www\.)([^ \r\n\(\)\^\$!`\"'\|\[\]\{\}<>]*)/si";
$urlreplace[]="\\1[link]\\2\\4[/link]";
$urlreplace[]="[link]\\1\\3[/link]";
$x_comment = preg_replace($urlsuch, $urlreplace, $x_comment);
$x_comment = preg_replace("/\[link\]www.(.*?)\[\/link\]/si", " www.\\1 ", $x_comment);
$x_comment = preg_replace("/\[link=www.(.*?)\](.*?)\[\/link\]/si", "\\2 ", $x_comment);
$x_comment = preg_replace("/\[link\](\:.*?)\[\/link\]/si", "\\1 ", $x_comment);
$x_comment = preg_replace("/\[link=(\:.*?)\]\[\/link\]/si", "\\1 ", $x_comment);
$x_comment = preg_replace("/\[link=(\:.*?)\](.*?)\[\/link\]/si", "\\2 ", $x_comment);
$x_comment = preg_replace("/\[link\](.*?)\[\/link\]/si", "\\1 ", $x_comment);
$x_comment = preg_replace("/\[link=(.*?)\](.*?)\[\/link\]/si", "\\2 ", $x_comment);
$x_comment = preg_replace("/\[img\](http.*?)\[\/img\]/si", " ", $x_comment);
$x_comment = preg_replace("/\[img=(http.*?)\](.*?)\[\/img\]/si", " ", $x_comment);
$x_comment = preg_replace("/\[img\](file.*?)\[\/img\]/si", " ", $x_comment);
$x_comment = preg_replace("/\[img=(file.*?)\](.*?)\[\/img\]/si", " ", $x_comment);
$x_comment = preg_replace("/\[img\](\:.*?)\[\/img\]/si", " ", $x_comment);
$x_comment = preg_replace("/\[img=(\:.*?)\](.*?)\[\/img\]/si", " ", $x_comment);
$x_comment = preg_replace("/\[img\](.*?)\[\/img\]/si", " ", $x_comment);
$x_comment = preg_replace("/\[img=(.*?)\](.*?)\[\/img\]/si", " ", $x_comment);
/*---------------------------------------------------------------------------------
* think about parsing content by dokuwiki renderer for dokuwiki syntax recognition
* $x_comment = p_render('xhtml',p_get_instructions($x_comment),$info);
* take care to strip IssueTracker syntax to prevent endless loop
---------------------------------------------------------------------------------*/
return $x_comment;
}
/******************************************************************************/
/* return html-code for edit toolbar
*/
function it_wysiwyg_edit_toolbar($xa_comment) {
$sFilename = DOKU_BASE."lib/plugins/issuetracker/wysiwyg_editor.js";
$it_edit_tb .= '';
$sFilename = DOKU_PLUGIN.'issuetracker/wysiwyg_editor.html';
$it_edit_tb .= file_get_contents($sFilename);
$it_edit_tb = str_ireplace("%%DOKU_BASE%%",DOKU_BASE,$it_edit_tb);
$trans=get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES);
$trans=array_flip($trans);
$x_comment=strtr($xa_comment, $trans);
$it_edit_tb = str_ireplace('
',$x_comment,$it_edit_tb);
return $it_edit_tb;
}
function it_xs_edit_toolbar($type) {
$imgBASE = DOKU_BASE."lib/plugins/issuetracker/images/";
$it_edit_tb = '".NL;
return $it_edit_tb;
}
/******************************************************************************/
function get_issues_file_contents($project, $issue_id) {
if($this->getConf('it_data')==false) $pfile = DOKU_CONF."../data/meta/".$project.'.issues';
else $pfile = DOKU_CONF."../". $this->getConf('it_data').$project.'.issues';
if ((@file_exists($pfile)) && (strlen($project)>1))
{ $issue = unserialize(@file_get_contents($pfile));
// check if ID exist
$cFlag = false;
foreach ($issue as $issue_item) {
if ($issue_item['id'] == $issue_id) {
$cFlag = true;
return $issue;
break;
}
}
if ($cFlag === false) {
// promt error message that issue with this ID does not exist
$Generated_Header = ''.$this->getLang('msg_issuemissing').$issue_id.'.
';
// echo $Generated_Header;
return;
}
}
else
{ // promt error message that issue with ID does not exist
$Generated_Header = ''.sprintf($this->getLang('msg_pfilemissing'),$pfile).'
';
// echo $Generated_Header;
return;
}
}
/******************************************************************************/
/* sort the issues array according the selected key */
function _issues_globalsort($issues, $sort_key) {
/* $tmp = Array();
foreach($issues as &$ma) $tmp[] = &$ma[$sort_key];
array_multisort($tmp, $issues); */
foreach ($issues as $key => $row) {
$down[$key] = $row['id'];
$up[$key] = $row[$sort_key];
}
if($up) { @array_multisort($up, constant($this->getConf('global_sort')), $down, SORT_ASC, $issues); }
return $issues;
}
/******************************************************************************/
/* log issue modificaions
* who changed what and when per issue
*/
function _log_mods($project, $issue, $usr, $column, $old_value, $new_value)
{ global $conf;
// get mod-log file contents
$issue_id = $issue['id'];
if($this->getConf('it_data')==false) $modfile = DOKU_CONF."../data/meta/".$project.'_'.$issue_id.'.mod-log';
else $modfile = DOKU_CONF."../". $this->getConf('it_data').$project.'_'.$issue_id.'.mod-log';
if (@file_exists($modfile))
{$mods = unserialize(@file_get_contents($modfile));}
else
{$mods = array();}
$cur_date = date($this->getConf('d_format'));
$mod_id = count($mods);
if($new_value=='') $new_value = $this->getLang('mod_valempty');
$mods[$mod_id]['timestamp'] = $cur_date;
$mods[$mod_id]['user'] = $usr;
$mods[$mod_id]['field'] = $column;
$mods[$mod_id]['old_value'] = $old_value;
$mods[$mod_id]['new_value'] = $new_value;
// Save issues file contents
$fh = fopen($modfile, 'w');
fwrite($fh, serialize($mods));
fclose($fh);
}
/******************************************************************************/
/* replace special characters in file names like German "Umlaute"
*/
function img_name_encode($f_name) {
$umlaute = explode(',',$this->getLang('umlaute'));
$replace = explode(',',$this->getLang('conv_umlaute'));
if((count($umlaute)>1) && (count($replace)>1)) $f_name = str_replace($umlaute, $replace, $f_name);
//preg_replace($umlaute, $replace, $f_name);
$f_name = strtolower($f_name);
return $f_name;
}
/******************************************************************************/
/*******************************************************************************
* The eventhandlers to catch profile updates (e-mail address)
*******************************************************************************/
/* -------------------------------------------------------------------------- */
function handle_usermod_before(&$event, $param)
{ if($this->getConf('profile_updt')==false) return;
if($this->getConf('it_data')==false) $filename = DOKU_CONF."../data/meta/it_eventcheck.txt";
else $filename = DOKU_CONF."../". $this->getConf('it_data').'it_eventcheck.txt';
if (!$handle = fopen($filename, 'w')) {
msg("IssueTracker: Failed to create the eventcheck file.",-1);
return;
}
// search dokuwiki user-db for client and e-mail address before change
// store it for AFTER event comparison
global $auth;
$user = array();
$user['microtime_start'] = microtime(true);
$user['client'] = $event->data['params'][0];
$usr_info = $auth->getUserData($user['client']);
$user['name'] = $usr_info['name'];
$user['mail'] = $usr_info['mail'];
fwrite($handle, serialize($user));
// fwrite($handle, $eve);
fclose($handle);
}
/* -------------------------------------------------------------------------- */
function handle_usermod_after(&$event, $param)
{ //$filename = DOKU_INC . 'it_eventcheck.txt';
if($this->getConf('profile_updt')==false) return;
if($this->getConf('it_data')==false) $filename = DOKU_CONF."../data/meta/it_eventcheck.txt";
else $filename = DOKU_CONF."../". $this->getConf('it_data').'it_eventcheck.txt';
global $auth;
$result .= "* function handle_usermod_after".chr(10);
$user = array();
$user['client'] = $event->data['params'][0];
$usr_info = $auth->getUserData($user['client']);
$user['name'] = $usr_info['name'];
$user['mail'] = $usr_info['mail'];
$user_before = unserialize(@file_get_contents($filename));
$result .= ' --- BEFORE --- | --- AFTER ---'.chr(10);
$result .= $user_before['client'].' <= ? => '. $user['client'].chr(10);
$result .= $user_before['name'] .' <= ? => '. $user['name'].chr(10);
$result .= $user_before['mail'] .' <= ? => '. $user['mail'].chr(10);
if(($user_before['mail'] !== false) && ($user_before['mail'] !== $user['mail'])) {
$result .= 'DIFF in mail => update issues, comments and modlog'.chr(10);
$this->_update_it_files($user_before, $user);
// finally the eventcheck will contain the values and resulting action info
if (!$handle = fopen($filename, 'a')) {
msg("IssueTracker: Failed to write into eventcheck file.",-1);
return;
}
$perf = 'IssueTracker updates took '.microtime(true) - $user['microtime_start'].' seconds';
$result .= chr(10).chr(10).$perf.chr(10);
fwrite($handle, $result);
fclose($handle);
if($perf>0) msg($perf,0);
}
else $result .= chr(10).chr(10).'NO diff in mail => do nothing';
$handle = fopen($filename, 'a');
fwrite($handle, $result);
fclose($handle);
}
/* -------------------------------------------------------------------------- */
// replace user mail address after modification of user profile
function _update_it_files($user_before, $user) {
global $conf;
if($this->getConf('profile_updt')==false) return;
//$filename = DOKU_INC . 'it_eventcheck.txt';
if($this->getConf('it_data')==false) $filename = DOKU_CONF."../data/meta/it_eventcheck.txt";
else $filename = DOKU_CONF."../". $this->getConf('it_data').'it_eventcheck.txt';
// create array of related files
if($this->getConf('it_data')==false) $path = DOKU_CONF."../data/meta/";
else $path = DOKU_CONF."../".$this->getConf('it_data');
$file_array = $this->_file_list($path, '.issues.cmnts.mod-log');
$result .= "* function _update_it_files".chr(10);
if((strlen($user_before['mail'])<1) ) {
$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.";
}
elseif(strlen($user['mail'])<1) {
$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.";
}
else {
$result = chr(10).chr(10)."Loop thorugh IssueTracker data files.".chr(10);
// loop through all files
foreach($file_array as $file) {
$parts = explode(".", $file);
$extension = end($parts);
$pfile = $path.'/'.$file;
if (@file_exists($pfile)) {
switch ($extension) {
case "issues":
// get issues file contents
$issues = unserialize(@file_get_contents($pfile));
foreach($issues as &$issue) {
// search for old_mail and replace by new_mail
if($issue['user_mail'] == $user_before['mail']) {
$issue['user_name'] = $user['name'];
$issue['user_mail'] = $user['mail'];
$result .= 'Issue ID '.$issue['id'].': author field successfully updated'.chr(10);
$upd_issues++;
}
// delete mail address from followers
if((stripos($issue['add_user_mail'],$user_before['mail']) !== false)) {
$tmp = explode(',', $issues[$issue_id]['add_user_mail']);
foreach($tmp as $email) {
if (stripos($email,$user_before['mail']) === false) $ret_mails .= $email.',';
else {
$ret_mails .= $user['mail'].',';
$result .= 'Issue ID '.$issue['id'].': follower field successfully updated.'.chr(10);
$upd_folllowers++;
}
}
}
if($issue['assigned']==$user_before['mail']) {
$issue['assigned'] = $user['mail'];
$result .= 'Issue ID '.$issue['id'].': assignee field successfully updated.'.chr(10);
$upd_assignments++;
}
}
// store issue file
$xvalue = io_saveFile($pfile,serialize($issues));
case "cmnts":
// get comments file contents
$comments = unserialize(@file_get_contents($pfile));
foreach($comments as &$comment) {
if($comment['author'] == $user_before['mail']) {
$comment['author'] = $user['mail']; // search for old_mail and replace by new_mail
$result .= '('.$file.') Comment #'.$comment['id'].': author field successfully updated.'.chr(10);
$upd_comments++;
}
}
$xvalue = io_saveFile($pfile,serialize($comments));
case "mod-log":
// loop through all mod-log files
$mods = unserialize(@file_get_contents($pfile));
foreach($mods as &$mod) {
if($mod['new_value'] == $user_before['mail']) {
$mod['new_value'] = $user['mail']; // search for old_mail and replace by new_mail
$result .= '('.$file.') modification logfile successfully updated.'.chr(10);
$upd_modlog_entries++;
}
}
$xvalue = io_saveFile($pfile,serialize($mods));
}
}
else msg('File: '.$pfile.'does not exist',-1);
}
}
// provide user-feedback & log ---------------------------------
if($this->getConf('it_data')==false) $filename = DOKU_CONF."../data/meta/it_eventcheck.txt";
else $filename = DOKU_CONF."../". $this->getConf('it_data').'it_eventcheck.txt';
if (!$handle = fopen($filename, 'a')) {
msg("IssueTracker: Failed to write into eventcheck file.",-1);
return;
}
if(($upd_issues>0) && ($conf['allowdebug']!= false)) {
msg('IssueTracker: '.$upd_issues." issue creator entries updated",0);
}
$result .= chr(10).'IssueTracker: '.intval($upd_issues)." issue creator entries updated".chr(10);
if(($upd_folllowers>0) && ($conf['allowdebug']!= false)) {
msg('IssueTracker: '.$upd_folllowers." follower entries updated",0);
}
$result .= 'IssueTracker: '.intval($upd_folllowers)." follower entries updated".chr(10);
if(($upd_assignments>0) && ($conf['allowdebug']!= false)) {
msg('IssueTracker: '.$upd_assignments." assignments updated",0);
}
$result .= 'IssueTracker: '.intval($upd_assignments)." assignments updated".chr(10);
if(($upd_comments>0) && ($conf['allowdebug']!= false)) {
msg('IssueTracker: '.$upd_comments." comment author entries updated",0);
}
$result .= 'IssueTracker: '.intval($upd_comments)." comment author entries updated".chr(10);
if(($upd_modlog_entries>0) && ($conf['allowdebug']!= false)) {
msg('IssueTracker: '.$upd_modlog_entries." mod-log entries updated",0);
}
$result .= 'IssueTracker: '.intval($upd_modlog_entries)." mod-log entries updated".chr(10);
$result .= chr(10).chr(10);
if($conf['allowdebug']!= false) $result .= 'allowdebug = true'.chr(10);
else $result .= 'allowdebug = false'.chr(10);
$handle = fopen($filename, 'a');
fwrite($handle, $result);
fclose($handle);
return;
}
/* -------------------------------------------------------------------------- */
// list all files with defined file-extension within a directory
// does not read sub-directories
function _file_list($dir, $type) {
$dh = opendir($dir);
$files = array();
while (($file = readdir($dh)) !== false) {
$flag = false;
if($file !== '.' && $file !== '..') {
// --- get the current file extension ---------------------
$parts = explode(".", $file);
if (is_array($parts) && count($parts) > 1) {
$extension = end($parts);
if (stripos($type,$extension)!==false) {
$files[] = $file;
$a = $file.chr(10);
}
}
//---------------------------------------------------------
}
}
return $files;
}
/******************************************************************************/
/* upload a file if valid on mime type and file extension
*/
function _symptom_file_upload(&$issues, $issue_id, $attachment_id) {
global $conf;
if($this->getConf('it_data')==false) $target_path = "data/meta/";
else $target_path = $this->getConf('it_data');
$ip_block_path = $target_path."ipblock";
$target_path .= 'symptoms/';
if(!is_dir(DOKU_CONF."../".$target_path)) { mkdir(DOKU_CONF."../".$target_path, 0777); }
$valid_file_extensions = array();
$valid_mimetypes = array();
$mimetypes = getMimeTypes();
foreach($mimetypes as $key => $value) {
$valid_file_extensions[] = $key;
$valid_mimetypes[] = $value;
}
if($this->getConf('ip_blocked') == 1){
$ip_blocked_sec = $this->getConf('ip_blockd_time')*60;
// search folder ipblock
if(is_dir(DOKU_INC.$ip_block_path)) {
$path = openDir(DOKU_INC.$ip_block_path);
while(false !== ($filename = readdir($path))){
if($filename != "." && $filename != ".."){
// delete aged ipblocks
if(file_exists(DOKU_INC.$ip_block_path.'/'.$filename)) {
$t_check = filemtime(DOKU_INC.$ip_block_path.'/'.$filename)+$ip_blocked_sec;
if($t_check <= time()) { @unlink(DOKU_INC.$ip_block_path.'/'.$filename); }
}
}
}
closedir($path);
}
else {
mkdir(DOKU_INC.$ip_block_path.'/', 0777);
}
$ip_addr = $_SERVER['REMOTE_ADDR'];
if($ip_addr == "") {
if(getenv(HTTP_X_FORWARDED_FOR)) { $ip_addr = getenv('HTTP_X_FORWARD_FOR'); }
else { $ip_addr = getenv('REMOTE_ADDR'); }
}
if($ip_addr != ""){
// check if ip already known
if(file_exists(DOKU_INC.$ip_block_path.'/'.$ip_addr)) {
// check upload attampts (to be larger than 3)
$iplog = fopen(DOKU_INC.$ip_block_path.'/'.$ip_addr, "r");
$attachments_left=fread($iplog, filesize(DOKU_INC.$ip_block_path.'/'.$ip_addr));
fclose($iplog);
if($attachments_left<1) {
$error_code = 1;
$t_check = intval((filemtime(DOKU_INC.$ip_block_path.'/'.$filename)+$ip_blocked_sec-time())/60);
msg(sprintf($this->getLang('wmsg9'), $t_check),-1);
}
}
else $attachments_left = 3;
}
}
if(isset($error_code)){
$t_check = intval((filemtime(DOKU_INC.$ip_block_path.'/'.$filename)+$ip_blocked_sec-time())/60);
$Generated_Header = ''.sprintf($this->getLang('wmsg9'), $t_check).'
';
$renderer->doc .= $Generated_Header;
return;
}
// get file extension
$mime_type = $_FILES[$attachment_id]['type'];
$file_extension = strrchr($_FILES[$attachment_id]['name'],'.'); // last occurance of dot to detect extension
$file_dot_extension = strtolower($file_extension);
$file_extension = str_replace(".", "", strtolower($file_dot_extension));
$error_flag = 0;
// check validity of file extension
if(!in_array($file_extension, $valid_file_extensions)) {
$error_flag = 1;
$Generated_Header .= ''.$this->getLang('wmsg7').' (File: '.$_FILES[$attachment_id]['name'].' ) ';
}
// check mime type
if((!in_array($mime_type, $valid_mimetypes)) && (!in_array("!".$mime_type, $valid_mimetypes)) ) {
$error_flag = 1;
$Generated_Header .= ''.$this->getLang('wmsg8').' (File: '.$_FILES[$attachment_id]['name'].', Mime-Type: '.$mime_type.' ) ';
}
// check file-size
if($_FILES[$attachment_id]['size'] > ($this->getConf('max_fsize'))){
$error_flag = 1;
$Generated_Header .= ''.sprintf($this->getLang('wmsg6'), $this->getConf('max_fsize')).' (File: '.$_FILES[$attachment_id]['name'].' ) ';
}
// -----------------------------------------------------------------------------
if($error_flag > 0) {
echo $Generated_Header = ''.$Generated_Header.'
';
}
else {
//$safe_filename = preg_replace(array("/\s+/", "/[^-\.\w]+/"),array("_", ""),trim(basename( $_FILES[$attachment_id]['name'])));
// delete all other characters beside the following defined
$safe_filename = preg_replace('#[^A-Za-z0-9_.-]#', '',trim(basename( $_FILES[$attachment_id]['name'])));
$target_path = $target_path . $issue_id . '_sympt_' . $safe_filename;
if(move_uploaded_file($_FILES[$attachment_id]['tmp_name'], DOKU_INC.$target_path)) {
$attachments_left = $attachments_left-1;
$issues[$issue_id][$attachment_id] = DOKU_URL.$target_path;
// msg("The file ".$safe_filename." has been successfully uploaded to ".DOKU_URL.$target_path,1);
msg("The file ".$safe_filename." has been successfully uploaded.",1);
} else{
// msg("There was an error uploading the file to ".DOKU_URL.$target_path." \n, please try again!",-1);
msg("There was an error uploading the file, please try again!",-1);
}
// -----------------------------------------------------------------------------
// block ip
if($this->getConf('ip_blocked') == 1) {
$ip_addr=$_SERVER['REMOTE_ADDR'];
if($ip_addr==""){
if(getenv(HTTP_X_FORWARDED_FOR)) { $ip_addr = getenv('HTTP_X_FORWARD_FOR'); }
else { $ip_addr = getenv('REMOTE_ADDR'); }
}
if(!is_dir(DOKU_INC.$ip_block_path) && ($ip_addr != "")) {
@mkdir(DOKU_INC.$ip_block_path.'/', 0777);
$iplog = fopen(DOKU_INC.$ip_block_path.'/'.$ip_addr, "w+");
fwrite($iplog, $attachments_left);
fclose($iplog);
}
elseif($ip_addr != ""){
$iplog = fopen(DOKU_INC.$ip_block_path.'/'.$ip_addr, "w+");
fwrite($iplog, $attachments_left);
fclose($iplog);
}
}
}
// -----------------------------------------------------------------------------
return $Generated_Header;
}
/******************************************************************************/
/*
* Check for MyIssues
*
* Check if the issue is related to the current user
* the user maybe the issue reporter, assignee or registered as follower
* it will return true/false
*
* @author Taggic
* @param array $issue the single issue
* @param array $user the current user info
* @return bool (true / false)
*
*/
function _find_myissues($issue, $user) {
// current user is issue reporter
if($user['userinfo']['mail'] === $issue['user_mail']) return true;
// current user is assigned to this issue
if($user['userinfo']['mail'] === $issue['assigned']) return true;
// current user is registered as follower within the comments log of actual issue
if(stristr($issue['add_user_mail'],$user['userinfo']['mail']) !== false) return true;
// else return false
return false;
}
/******************************************************************************/
function __find_projects($path) {
if(!is_dir($path)) return false; // prevent the php-warning
if ($handle=opendir($path)) {
while (false!==($file=readdir($handle))) {
if ($file<>"." AND $file<>"..") {
if (is_file($path.'/'.$file)) {
$ext = explode('.',$file);
$last = count($ext) - 1;
if ($ext[$last] == 'issues') {
$projects .= ','.substr($file,0,strlen($file)-strlen('.issues'));
}
}
}
}
}
return $projects;
}
/******************************************************************************/
/*
* Load all issues into an array
*
* Check if multi_project is set to true
* Load current $project or all projects of it_data_store
* Return the issues array
*
* @author Taggic
* @param string $project delivers the project name; used if $all = false
* @param bool $all determines if all projects to be retrieved
* @return array $issues result: is an array of issues
*
*/
function _get_issues($project, $all = false) {
// detect the IssueTracker data store (path)
if($this->getConf('it_data')==false) $it_datastore = DOKU_CONF."../data/meta/";
else $it_datastore = DOKU_CONF."../". $this->getConf('it_data');
// check if last sign is a slash
$i = strrchr ($it_datastore, chr(47)); // chr(47) = "/"
$j = strrchr ($it_datastore, chr(92)); // chr(92) = "\"
if(($i !== strlen($it_datastore)) && ($i !== strlen($it_datastore))) { $it_datastore .= chr(47); }
if(($this->getConf('multi_projects')!==false) && ($all !== false)) {
// loop through it_datastore and list all .issues files
$xprojects = $this->__find_projects($it_datastore);
$x_projects = explode(',',$xprojects);
$issues = array();
$tmp = array();
foreach ($x_projects as $project)
{ $project = trim($project);
if(is_file($it_datastore.$project.'.issues') == true) {
$tmp = unserialize(@file_get_contents($it_datastore.$project.'.issues'));
// loop through the field and add project to each row
foreach($tmp as &$tmps)
{ $tmps['project'] = $project; }
$issues = array_merge($issues, $tmp);
$tmp = array();
}
}
}
else {
// get issues from single project file
if($this->getConf('it_data')==false) $pfile = $it_datastore.$project.'.issues';
else $pfile = $it_datastore.$project.'.issues';
if (@file_exists($pfile))
{$issues = unserialize(@file_get_contents($pfile));}
else
{$issues = array();
msg("project = $pfile not found",-1);
}
}
// $arr1 = $this->array_msort($issues, array('project'=>SORT_DESC, 'id'=>SORT_ASC));
$arr1 = $this->array_msort($issues, array('project'=>SORT_DESC));
return $arr1;
}
/******************************************************************************/
function array_msort($array, $cols)
{
$colarr = array();
foreach ($cols as $col => $order) {
$colarr[$col] = array();
foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
}
$eval = 'array_multisort(';
foreach ($cols as $col => $order) {
$eval .= '$colarr[\''.$col.'\'],'.$order.',';
}
$eval = substr($eval,0,-1).');';
eval($eval);
$ret = array();
foreach ($colarr as $col => $arr) {
foreach ($arr as $k => $v) {
$k = substr($k,1);
if (!isset($ret[$k])) $ret[$k] = $array[$k];
$ret[$k][$col] = $array[$k][$col];
}
}
return $ret;
}
/******************************************************************************/
}