From 6854cb3f4d8219cf1829e32122eb2502a916eae9 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 1 Feb 2020 09:05:48 +0100 Subject: initial checkin --- scripts/details.php | 768 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 768 insertions(+) create mode 100644 scripts/details.php (limited to 'scripts/details.php') diff --git a/scripts/details.php b/scripts/details.php new file mode 100644 index 0000000..421a68a --- /dev/null +++ b/scripts/details.php @@ -0,0 +1,768 @@ +can_view_task($task_details)) { + Flyspray::show_error( $user->isAnon() ? 102 : 101, false); +} else{ + + require_once(BASEDIR . '/includes/events.inc.php'); + + if($proj->prefs['use_effort_tracking']){ + require_once(BASEDIR . '/includes/class.effort.php'); + $effort = new effort($task_id,$user->id); + $effort->populateDetails(); + $page->assign('effort',$effort); + } + + $page->uses('task_details'); + + // Send user variables to the template + $page->assign('assigned_users', $task_details['assigned_to']); + $page->assign('old_assigned', implode(' ', $task_details['assigned_to'])); + $page->assign('tags', $task_details['tags']); + + $page->setTitle(sprintf('FS#%d : %s', $task_details['task_id'], $task_details['item_summary'])); + + + if ((Get::val('edit') || (Post::has('item_summary') && !isset($_SESSION['SUCCESS']))) && $user->can_edit_task($task_details)) { + + if(isset($move) && $move==1){ + if( !$user->perms('modify_all_tasks', $toproject->id)){ + Flyspray::show_error('invalidtargetproject'); + } + } + + $result = $db->query(' + SELECT g.project_id, u.user_id, u.user_name, u.real_name, g.group_id, g.group_name + FROM {users} u + JOIN {users_in_groups} uig ON u.user_id = uig.user_id + JOIN {groups} g ON g.group_id = uig.group_id + WHERE (g.show_as_assignees = 1 OR g.is_admin = 1) + AND (g.project_id = 0 OR g.project_id = ?) + AND u.account_enabled = 1 + ORDER BY g.project_id ASC, g.group_name ASC, u.user_name ASC', + ($proj->id ? $proj->id : -1) + ); // FIXME: -1 is a hack. when $proj->id is 0 the query fails + + $userlist = array(); + $userids = array(); + while ($row = $db->fetchRow($result)) { + if( !in_array($row['user_id'], $userids) ){ + $userlist[$row['group_id']][] = array( + 0 => $row['user_id'], + 1 => sprintf('%s (%s)', $row['user_name'], $row['real_name']), + 2 => $row['project_id'], + 3 => $row['group_name'] + ); + $userids[]=$row['user_id']; + } else{ + # user is probably in a global group with assignee permission listed, so no need to show second time in a project group. + } + } + + if (is_array(Post::val('rassigned_to'))) { + $page->assign('assignees', Post::val('rassigned_to')); + } else { + $assignees = $db->query('SELECT user_id FROM {assigned} WHERE task_id = ?', $task_details['task_id']); + $page->assign('assignees', $db->fetchCol($assignees)); + } + $page->assign('userlist', $userlist); + + # Build the select arrays, for 'move task' or normal taskedit + # Then in the template just use tpl_select($xxxselect); + + # keep last selections + $catselected=Req::val('product_category', $task_details['product_category']); + $osselected=Req::val('operating_system', $task_details['operating_system']); + $ttselected=Req::val('task_type', $task_details['task_type']); + $stselected=Req::val('item_status', $task_details['item_status']); + $repverselected=Req::val('reportedver', $task_details['product_version']); + $dueverselected=Req::val('closedby_version', $task_details['closedby_version']); + if(isset($move) && $move==1){ + # get global categories + $gcats=$proj->listCategories(0); + if( count($gcats)>0){ + foreach($gcats as $cat){ + $gcatopts[]=array('value'=>$cat['category_id'], 'label'=>$cat['category_name']); + if($catselected==$cat['category_id']){ + $gcatopts[count($gcatopts)-1]['selected']=1; + } + } + #$catsel['options'][]=array('optgroup'=>1, 'label'=>L('categoriesglobal'), 'options'=>$gcatopts); + $catsel['options'][]=array('optgroup'=>1, 'label'=>L('globaloptions'), 'options'=>$gcatopts); + } + # get project categories + $pcats=$proj->listCategories($proj->id); + if( count($pcats)>0){ + foreach($pcats as $cat){ + $pcatopts[]=array('value'=>$cat['category_id'], 'label'=>$cat['category_name']); + if($catselected==$cat['category_id']){ + $pcatopts[count($pcatopts)-1]['selected']=1; + } + } + #$catsel['options'][]=array('optgroup'=>1, 'label'=>L('categoriesproject').' '.$proj->prefs['project_title'], 'options'=>$pcatopts); + $catsel['options'][]=array('optgroup'=>1, 'label'=>L('currentproject').' '.$proj->prefs['project_title'], 'options'=>$pcatopts); + } + # get target categories + $tcats=$toproject->listCategories($toproject->id); + if( count($tcats)>0){ + foreach($tcats as $cat){ + $tcatopts[]=array('value'=>$cat['category_id'], 'label'=>$cat['category_name']); + if($catselected==$cat['category_id']){ + $tcatopts[count($tcatopts)-1]['selected']=1; + } + } + #$catsel['options'][]=array('optgroup'=>1, 'label'=>L('categoriestarget').' '.$toproject->prefs['project_title'], 'options'=>$tcatopts); + $catsel['options'][]=array('optgroup'=>1, 'label'=>L('targetproject').' '.$toproject->prefs['project_title'], 'options'=>$tcatopts); + } + + + # get global task statuses + $resgst=$db->query("SELECT status_id, status_name, list_position, show_in_list FROM {list_status} WHERE project_id=0 ORDER BY list_position"); + $gsts=$db->fetchAllArray($resgst); + if(count($gsts)>0){ + foreach($gsts as $gst){ + $gstopts[]=array('value'=>$gst['status_id'], 'label'=>$gst['status_name']); + if($stselected==$gst['status_id']){ + $gstopts[count($gstopts)-1]['selected']=1; + } + if($gst['show_in_list']==0){ + $gstopts[count($gstopts)-1]['disabled']=1; + } + } + $statussel['options'][]=array('optgroup'=>1, 'label'=>L('globaloptions'), 'options'=>$gstopts); + } + # get current project task statuses + $rescst=$db->query("SELECT status_id, status_name, list_position, show_in_list FROM {list_status} WHERE project_id=? ORDER BY list_position", array($proj->id)); + $csts=$db->fetchAllArray($rescst); + if(count($csts)>0){ + foreach($csts as $cst){ + $cstopts[]=array('value'=>$cst['status_id'], 'label'=>$cst['status_name']); + if($stselected==$cst['status_id']){ + $cstopts[count($cstopts)-1]['selected']=1; + } + if($cst['show_in_list']==0){ + $cstopts[count($cstopts)-1]['disabled']=1; + } + } + $statussel['options'][]=array('optgroup'=>1, 'label'=>L('currentproject').' '.$proj->prefs['project_title'], 'options'=>$cstopts); + } + # get target project task statuses + $restst=$db->query("SELECT status_id, status_name, list_position, show_in_list FROM {list_status} WHERE project_id=? ORDER BY list_position", array($toproject->id)); + $tsts=$db->fetchAllArray($restst); + if(count($tsts)>0){ + foreach($tsts as $tst){ + $tstopts[]=array('value'=>$tst['status_id'], 'label'=>$tst['status_name']); + if($stselected==$tst['status_id']){ + $tstopts[count($tstopts)-1]['selected']=1; + } + if($tst['show_in_list']==0){ + $tstopts[count($tstopts)-1]['disabled']=1; + } + } + $statussel['options'][]=array('optgroup'=>1, 'label'=>L('targetproject').' '.$toproject->prefs['project_title'], 'options'=>$tstopts); + } + + + # get list global tasktypes + $resgtt=$db->query("SELECT tasktype_id, tasktype_name, list_position, show_in_list FROM {list_tasktype} WHERE project_id=0 ORDER BY list_position"); + $gtts=$db->fetchAllArray($resgtt); + if(count($gtts)>0){ + foreach($gtts as $gtt){ + $gttopts[]=array('value'=>$gtt['tasktype_id'], 'label'=>$gtt['tasktype_name']); + if($ttselected==$gtt['tasktype_id']){ + $gttopts[count($gttopts)-1]['selected']=1; + } + } + $tasktypesel['options'][]=array('optgroup'=>1, 'label'=>L('globaloptions'), 'options'=>$gttopts); + } + # get current project tasktypes + $resctt=$db->query("SELECT tasktype_id, tasktype_name, list_position, show_in_list FROM {list_tasktype} WHERE project_id=? ORDER BY list_position", array($proj->id)); + $ctts=$db->fetchAllArray($resctt); + if(count($ctts)>0){ + foreach($ctts as $ctt){ + $cttopts[]=array('value'=>$ctt['tasktype_id'], 'label'=>$ctt['tasktype_name']); + if($ttselected==$ctt['tasktype_id']){ + $cttopts[count($cttopts)-1]['selected']=1; + } + } + $tasktypesel['options'][]=array('optgroup'=>1, 'label'=>L('currentproject').' '.$proj->prefs['project_title'], 'options'=>$cttopts); + } + # get target project tasktypes + $resttt=$db->query("SELECT tasktype_id, tasktype_name, list_position, show_in_list FROM {list_tasktype} WHERE project_id=? ORDER BY list_position", array($toproject->id)); + $ttts=$db->fetchAllArray($resttt); + if(count($ttts)>0){ + foreach($ttts as $ttt){ + $tttopts[]=array('value'=>$ttt['tasktype_id'], 'label'=>$ttt['tasktype_name']); + if($ttselected==$ttt['tasktype_id']){ + $tttopts[count($tttopts)-1]['selected']=1; + } + } + $tasktypesel['options'][]=array('optgroup'=>1, 'label'=>L('targetproject').' '.$toproject->prefs['project_title'], 'options'=>$tttopts); + } + + + # allow unset (0) value (field os_id currently defined with NOT NULL by flyspray-install.xml, so must use 0 instead null) + $osfound=0; + $ossel['options'][]=array('value'=>0, 'label'=>L('undecided')); + # get global operating systems + $resgos=$db->query("SELECT os_id, os_name, list_position, show_in_list FROM {list_os} WHERE project_id=0 AND show_in_list=1 ORDER BY list_position"); + $goses=$db->fetchAllArray($resgos); + if(count($goses)>0){ + foreach($goses as $gos){ + $gosopts[]=array('value'=>$gos['os_id'], 'label'=>$gos['os_name']); + if($osselected==$gos['os_id']){ + $gosopts[count($gosopts)-1]['selected']=1; + $osfound=1; + } + } + $ossel['options'][]=array('optgroup'=>1, 'label'=>L('globaloptions'), 'options'=>$gosopts); + } + # get current project operating systems + $rescos=$db->query("SELECT os_id, os_name, list_position, show_in_list FROM {list_os} WHERE project_id=? AND show_in_list=1 ORDER BY list_position", array($proj->id)); + $coses=$db->fetchAllArray($rescos); + if(count($coses)>0){ + foreach($coses as $cos){ + $cosopts[]=array('value'=>$cos['os_id'], 'label'=>$cos['os_name']); + if($osselected==$cos['os_id']){ + $cosopts[count($cosopts)-1]['selected']=1; + $osfound=1; + } + } + $ossel['options'][]=array('optgroup'=>1, 'label'=>L('currentproject').' '.$proj->prefs['project_title'], 'options'=>$cosopts); + } + # get target project operating systems + $restos=$db->query("SELECT os_id, os_name, list_position, show_in_list FROM {list_os} WHERE project_id=? AND show_in_list=1 ORDER BY list_position", array($toproject->id)); + $toses=$db->fetchAllArray($restos); + if(count($toses)>0){ + foreach($toses as $tos){ + $tosopts[]=array('value'=>$tos['os_id'], 'label'=>$tos['os_name']); + if($osselected==$tos['os_id']){ + $tosopts[count($tosopts)-1]['selected']=1; + $osfound=1; + } + } + $ossel['options'][]=array('optgroup'=>1, 'label'=>L('targetproject').' '.$toproject->prefs['project_title'], 'options'=>$tosopts); + } + # keep existing operating_system entry choosable even if would not currently selectable by current settings + if($osfound==0 && $task_details['operating_system']>0){ + # get operating_system of that existing old entry, even if show_in_list=0 or other project + $resexistos=$db->query(" + SELECT os.os_id, os.os_name, os.list_position, os.show_in_list, os.project_id, p.project_id AS p_project_id FROM {list_os} os + LEFT JOIN {projects} p ON p.project_id=os.project_id + WHERE os.os_id=?", array($task_details['operating_system'])); + $existos=$db->fetchRow($resexistos); + if($existos['project_id']==$proj->id){ + $existosgrouplabel=$proj->prefs['project_title'].': existing reported version'; + } elseif($existos['project_id']==$toproject->id){ + $existosgrouplabel=$toproject->prefs['project_title'].': existing reported version'; + } else{ + # maybe version_id from other/hidden/forbidden/deleted project, so only show project_id as hint. + # if user has view permission of this other project, then showing project_title would be ok -> extra sql required + $existosgrouplabel='existing os of project '.($existos['p_project_id']->id); + } + $existosopts[]=array('value'=>$task_details['operating_system'], 'label'=>$existos['os_name']); + if($osselected==$task_details['operating_system']){ + $existosopts[count($existosopts)-1]['selected']=1; + } + + #$ossel['options'][]=array('optgroup'=>1, 'label'=>$existosgrouplabel, 'options'=>$existosopts); + # put existing at beginning + $ossel['options']=array_merge(array(array('optgroup'=>1, 'label'=>$existosgrouplabel, 'options'=>$existosopts)), $ossel['options']); + } + + + + # get list global reported versions + # FIXME/TODO: Should we use 'show_in_list' list setting here to filter them out here? Or distinguish between editor/projectmanager/admin roles? + # FIXME/TODO: All Flyspray version up to 1.0-rc8 only versions with tense=2 were shown for edit. + # But what if someone edits an old tasks (maybe reopened an old closed), and that old task is connected with an old reported version (tense=1) + # Or that {list_version} entry has now show_in_list=0 set ? + # In both cases that version would not be selectable for editing the task, although it is the correct reported version. + $reportedversionfound=0; + $repversel['options'][]=array('value'=>0, 'label'=>L('undecided')); + $resgrepver=$db->query("SELECT version_id, version_name, list_position, show_in_list FROM {list_version} + WHERE project_id=0 + AND version_tense=2 + AND show_in_list=1 + ORDER BY list_position"); + $grepvers=$db->fetchAllArray($resgrepver); + if(count($grepvers)>0){ + foreach($grepvers as $grepver){ + $grepveropts[]=array('value'=>$grepver['version_id'], 'label'=>$grepver['version_name']); + if($repverselected==$grepver['version_id']){ + $grepveropts[count($grepveropts)-1]['selected']=1; + $reportedversionfound=1; + } + } + $repversel['options'][]=array('optgroup'=>1, 'label'=>L('globaloptions'), 'options'=>$grepveropts); + } + # get current project reported versions + $rescrepver=$db->query("SELECT version_id, version_name, list_position, show_in_list FROM {list_version} + WHERE project_id=? + AND version_tense=2 + AND show_in_list=1 + ORDER BY list_position", array($proj->id)); + $crepvers=$db->fetchAllArray($rescrepver); + if(count($crepvers)>0){ + foreach($crepvers as $crepver){ + $crepveropts[]=array('value'=>$crepver['version_id'], 'label'=>$crepver['version_name']); + if($repverselected==$crepver['version_id']){ + $crepveropts[count($crepveropts)-1]['selected']=1; + $reportedversionfound=1; + } + } + $repversel['options'][]=array('optgroup'=>1, 'label'=>L('currentproject').' '.$proj->prefs['project_title'], 'options'=>$crepveropts); + } + # get target project reported versions + $restrepver=$db->query("SELECT version_id, version_name, list_position, show_in_list FROM {list_version} + WHERE project_id=? + AND version_tense=2 + AND show_in_list=1 + ORDER BY list_position", array($toproject->id)); + $trepvers=$db->fetchAllArray($restrepver); + if(count($trepvers)>0){ + foreach($trepvers as $trepver){ + $trepveropts[]=array('value'=>$trepver['version_id'], 'label'=>$trepver['version_name']); + if($repverselected==$trepver['version_id']){ + $trepveropts[count($trepveropts)-1]['selected']=1; + $reportedversionfound=1; + } + } + $repversel['options'][]=array('optgroup'=>1, 'label'=>L('targetproject').' '.$toproject->prefs['project_title'], 'options'=>$trepveropts); + } + # keep existing reportedversion(product_version) choosable even if would not currently selectable by current settings + if($reportedversionfound==0 && $task_details['product_version']>0){ + # get version_name of that existing old entry, even if tense is past or show_in_list=0 or other project + $resexistrepver=$db->query(" + SELECT v.version_id, v.version_name, v.list_position, v.show_in_list, v.project_id, p.project_id AS p_project_id FROM {list_version} v + LEFT JOIN {projects} p ON p.project_id=v.project_id + WHERE v.version_id=?", array($task_details['product_version'])); + $existrepver=$db->fetchRow($resexistrepver); + if($existrepver['project_id']==$proj->id){ + $existgrouplabel=$proj->prefs['project_title'].': existing reported version'; + } elseif($existrepver['project_id']==$toproject->id){ + $existgrouplabel=$toproject->prefs['project_title'].': existing reported version'; + } else{ + # maybe version_id from other/hidden/forbidden/deleted project, so only show project_id as hint. + # if user has view permission of this other project, then showing project_title would be ok -> extra sql required + $existgrouplabel='existing reported version of project '.($existrepver['p_project_id']); + } + $existrepveropts[]=array('value'=>$task_details['product_version'], 'label'=>$existrepver['version_name']); + if($repverselected==$task_details['product_version']){ + $existrepveropts[count($existrepveropts)-1]['selected']=1; + } + + #$repversel['options'][]=array('optgroup'=>1, 'label'=>$existgrouplabel, 'options'=>$existrepveropts); + # put existing at beginning + $repversel['options']=array_merge(array(array('optgroup'=>1, 'label'=>$existgrouplabel, 'options'=>$existrepveropts)), $repversel['options']); + } + + + # get list global due versions + # FIXME/TODO: Should we use 'show_in_list' list setting here to filter them out here? Or distinguish between editor/projectmanager/admin roles? + $dueversel['options'][]=array('value'=>0, 'label'=>L('undecided')); + $resgduever=$db->query("SELECT version_id, version_name, list_position, show_in_list FROM {list_version} + WHERE project_id=0 + AND version_tense=3 + AND show_in_list=1 + ORDER BY list_position"); + $gduevers=$db->fetchAllArray($resgduever); + if(count($gduevers)>0){ + foreach($gduevers as $gduever){ + $gdueveropts[]=array('value'=>$gduever['version_id'], 'label'=>$gduever['version_name']); + if($dueverselected==$gduever['version_id']){ + $gdueveropts[count($gdueveropts)-1]['selected']=1; + } + } + $dueversel['options'][]=array('optgroup'=>1, 'label'=>L('globaloptions'), 'options'=>$gdueveropts); + } + # get current project due versions + $rescduever=$db->query("SELECT version_id, version_name, list_position, show_in_list FROM {list_version} + WHERE project_id=? + AND version_tense=3 + AND show_in_list=1 + ORDER BY list_position", array($proj->id)); + $cduevers=$db->fetchAllArray($rescduever); + if(count($cduevers)>0){ + foreach($cduevers as $cduever){ + $cdueveropts[]=array('value'=>$cduever['version_id'], 'label'=>$cduever['version_name']); + if($dueverselected==$cduever['version_id']){ + $cdueveropts[count($cdueveropts)-1]['selected']=1; + } + } + $dueversel['options'][]=array('optgroup'=>1, 'label'=>L('currentproject').' '.$proj->prefs['project_title'], 'options'=>$cdueveropts); + } + # get target project due versions + $restduever=$db->query("SELECT version_id, version_name, list_position, show_in_list FROM {list_version} + WHERE project_id=? + AND version_tense=3 + AND show_in_list=1 + ORDER BY list_position", array($toproject->id)); + $tduevers=$db->fetchAllArray($restduever); + if(count($tduevers)>0){ + foreach($tduevers as $tduever){ + $tdueveropts[]=array('value'=>$tduever['version_id'], 'label'=>$tduever['version_name']); + if($dueverselected==$tduever['version_id']){ + $tdueveropts[count($tdueveropts)-1]['selected']=1; + } + } + $dueversel['options'][]=array('optgroup'=>1, 'label'=>L('targetproject').' '.$toproject->prefs['project_title'], 'options'=>$tdueveropts); + } + + + }else{ + # just the normal merged global/project categories + $cats=$proj->listCategories(); + if( count($cats)>0){ + foreach($cats as $cat){ + $catopts[]=array('value'=>$cat['category_id'], 'label'=>$cat['category_name']); + if($catselected==$cat['category_id']){ + $catopts[count($catopts)-1]['selected']=1; + } + } + $catsel['options']=$catopts; + } + + # just the normal merged global/project statuses + $sts=$proj->listTaskStatuses(); + if( count($sts)>0){ + foreach($sts as $st){ + $stopts[]=array('value'=>$st['status_id'], 'label'=>$st['status_name']); + if($stselected==$st['status_id']){ + $stopts[count($stopts)-1]['selected']=1; + } + } + $statussel['options']=$stopts; + } + + # just the normal merged global/project tasktypes + $tts=$proj->listTaskTypes(); + if( count($tts)>0){ + foreach($tts as $tt){ + $ttopts[]=array('value'=>$tt['tasktype_id'], 'label'=>$tt['tasktype_name']); + if($ttselected==$tt['tasktype_id']){ + $ttopts[count($ttopts)-1]['selected']=1; + } + } + $tasktypesel['options']=$ttopts; + } + + # just the normal merged global/project os + $osses=$proj->listOs(); + # also allow unsetting operating system entry + $osopts[]=array('value'=>0, 'label'=>L('undecided')); + if( count($osses)>0){ + foreach($osses as $os){ + $osopts[]=array('value'=>$os['os_id'], 'label'=>$os['os_name']); + if($osselected==$os['os_id']){ + $osopts[count($osopts)-1]['selected']=1; + } + } + $ossel['options']=$osopts; + } + + # just the normal merged global/project reported version + $repversions=$proj->listVersions(false, 2, $task_details['product_version']); + # also allow unsetting dueversion system entry + $repveropts[]=array('value'=>0, 'label'=>L('undecided')); + if( count($repversions)>0){ + foreach($repversions as $repver){ + $repveropts[]=array('value'=>$repver['version_id'], 'label'=>$repver['version_name']); + if($repverselected==$repver['version_id']){ + $repveropts[count($repveropts)-1]['selected']=1; + } + } + $repversel['options']=$repveropts; + } + + # just the normal merged global/project dueversion + $dueversions=$proj->listVersions(false, 3); # future (tense=3) with 'shown_in_list' set + # also allow unsetting dueversion system entry + $dueveropts[]=array('value'=>0, 'label'=>L('undecided')); + if( count($dueversions)>0){ + foreach($dueversions as $duever){ + $dueveropts[]=array('value'=>$duever['version_id'], 'label'=>$duever['version_name']); + if($dueverselected==$duever['version_id']){ + $dueveropts[count($dueveropts)-1]['selected']=1; + } + } + $dueversel['options']=$dueveropts; + } + } + $catsel['name']='product_category'; + $catsel['attr']['id']='category'; + $page->assign('catselect', $catsel); + + $statussel['name']='item_status'; + $statussel['attr']['id']='status'; + $page->assign('statusselect', $statussel); + + $tasktypesel['name']='task_type'; + $tasktypesel['attr']['id']='tasktype'; + $page->assign('tasktypeselect', $tasktypesel); + + $ossel['name']='operating_system'; + $ossel['attr']['id']='os'; + $page->assign('osselect', $ossel); + + $repversel['name']='reportedver'; + $repversel['attr']['id']='reportedver'; + $page->assign('reportedversionselect', $repversel); + + $dueversel['name']='closedby_version'; + $dueversel['attr']['id']='dueversion'; + $page->assign('dueversionselect', $dueversel); + + # user tries to move a task to a different project: + if(isset($move) && $move==1){ + $page->assign('move', 1); + $page->assign('toproject', $toproject); + } + $page->pushTpl('details.edit.tpl'); + } else { + $prev_id = $next_id = 0; + + if (isset($_SESSION['tasklist']) && ($id_list = $_SESSION['tasklist']) + && ($i = array_search($task_id, $id_list)) !== false) { + $prev_id = isset($id_list[$i - 1]) ? $id_list[$i - 1] : ''; + $next_id = isset($id_list[$i + 1]) ? $id_list[$i + 1] : ''; + } + + // Sub-Tasks + $subtasks = $db->query('SELECT t.*, p.project_title + FROM {tasks} t + LEFT JOIN {projects} p ON t.project_id = p.project_id + WHERE t.supertask_id = ?', + array($task_id)); + $subtasks_cleaned = Flyspray::weedOutTasks($user, $db->fetchAllArray($subtasks)); + + for($i=0;$iquery('SELECT * + FROM {list_category} + WHERE lft < ? AND rgt > ? AND project_id = ? AND lft != 1 + ORDER BY lft ASC', + array($task_details['lft'], $task_details['rgt'], $task_details['cproj'])); + // Check for task dependencies that block closing this task + $check_deps = $db->query('SELECT t.*, s.status_name, r.resolution_name, d.depend_id, p.project_title + FROM {dependencies} d + LEFT JOIN {tasks} t on d.dep_task_id = t.task_id + LEFT JOIN {list_status} s ON t.item_status = s.status_id + LEFT JOIN {list_resolution} r ON t.resolution_reason = r.resolution_id + LEFT JOIN {projects} p ON t.project_id = p.project_id + WHERE d.task_id = ?', array($task_id)); + $check_deps_cleaned = Flyspray::weedOutTasks($user, $db->fetchAllArray($check_deps)); + + + for($i=0;$iquery('SELECT t.*, s.status_name, r.resolution_name, d.depend_id, p.project_title + FROM {dependencies} d + LEFT JOIN {tasks} t on d.task_id = t.task_id + LEFT JOIN {list_status} s ON t.item_status = s.status_id + LEFT JOIN {list_resolution} r ON t.resolution_reason = r.resolution_id + LEFT JOIN {projects} p ON t.project_id = p.project_id + WHERE d.dep_task_id = ?', array($task_id)); + $check_blocks_cleaned = Flyspray::weedOutTasks($user, $db->fetchAllArray($check_blocks)); + + + for($i=0;$iquery("SELECT * + FROM {admin_requests} + WHERE task_id = ? AND resolved_by = 0", + array($task_id)); + + // Get info on the dependencies again + $open_deps = $db->query('SELECT COUNT(*) - SUM(is_closed) + FROM {dependencies} d + LEFT JOIN {tasks} t on d.dep_task_id = t.task_id + WHERE d.task_id = ?', array($task_id)); + + $watching = $db->query('SELECT COUNT(*) + FROM {notifications} + WHERE task_id = ? AND user_id = ?', + array($task_id, $user->id)); + + // Check if task has been reopened some time + $reopened = $db->query('SELECT COUNT(*) + FROM {history} + WHERE task_id = ? AND event_type = 13', + array($task_id)); + + // Check for cached version + $cached = $db->query("SELECT content, last_updated + FROM {cache} + WHERE topic = ? AND type = 'task'", + array($task_details['task_id'])); + $cached = $db->fetchRow($cached); + + // List of votes + $get_votes = $db->query('SELECT u.user_id, u.user_name, u.real_name, v.date_time + FROM {votes} v + LEFT JOIN {users} u ON v.user_id = u.user_id + WHERE v.task_id = ? + ORDER BY v.date_time DESC', + array($task_id)); + + if ($task_details['last_edited_time'] > $cached['last_updated'] || !defined('FLYSPRAY_USE_CACHE')) { + $task_text = TextFormatter::render($task_details['detailed_desc'], 'task', $task_details['task_id']); + } else { + $task_text = TextFormatter::render($task_details['detailed_desc'], 'task', $task_details['task_id'], $cached['content']); + } + + $page->assign('prev_id', $prev_id); + $page->assign('next_id', $next_id); + $page->assign('task_text', $task_text); + $page->assign('subtasks', $subtasks_cleaned); + $page->assign('deps', $check_deps_cleaned); + $page->assign('parent', $db->fetchAllArray($parent)); + $page->assign('blocks', $check_blocks_cleaned); + $page->assign('votes', $db->fetchAllArray($get_votes)); + $page->assign('penreqs', $db->fetchAllArray($get_pending)); + $page->assign('d_open', $db->fetchOne($open_deps)); + $page->assign('watched', $db->fetchOne($watching)); + $page->assign('reopened', $db->fetchOne($reopened)); + $page->pushTpl('details.view.tpl'); + + /////////////// + // tabbed area + + // Comments + cache + $sql = $db->query('SELECT * FROM {comments} c + LEFT JOIN {cache} ca ON (c.comment_id = ca.topic AND ca.type = ?) + WHERE task_id = ? + ORDER BY date_added ASC', + array('comm', $task_id)); + $page->assign('comments', $db->fetchAllArray($sql)); + + // Comment events + $sql = get_events($task_id, ' AND (event_type = 3 OR event_type = 14)'); + $comment_changes = array(); + while ($row = $db->fetchRow($sql)) { + $comment_changes[$row['event_date']][] = $row; + } + $page->assign('comment_changes', $comment_changes); + + // Comment attachments + $attachments = array(); + $sql = $db->query('SELECT * + FROM {attachments} a, {comments} c + WHERE c.task_id = ? AND a.comment_id = c.comment_id', + array($task_id)); + while ($row = $db->fetchRow($sql)) { + $attachments[$row['comment_id']][] = $row; + } + $page->assign('comment_attachments', $attachments); + + // Comment links + $links = array(); + $sql = $db->query('SELECT * + FROM {links} l, {comments} c + WHERE c.task_id = ? AND l.comment_id = c.comment_id', + array($task_id)); + while ($row = $db->fetchRow($sql)) { + $links[$row['comment_id']][] = $row; + } + $page->assign('comment_links', $links); + + // Relations, notifications and reminders + $sql = $db->query('SELECT t.*, r.*, s.status_name, res.resolution_name + FROM {related} r + LEFT JOIN {tasks} t ON (r.related_task = t.task_id AND r.this_task = ? OR r.this_task = t.task_id AND r.related_task = ?) + LEFT JOIN {list_status} s ON t.item_status = s.status_id + LEFT JOIN {list_resolution} res ON t.resolution_reason = res.resolution_id + WHERE t.task_id is NOT NULL AND is_duplicate = 0 AND ( t.mark_private = 0 OR ? = 1 ) + ORDER BY t.task_id ASC', + array($task_id, $task_id, $user->perms('manage_project'))); + $related_cleaned = Flyspray::weedOutTasks($user, $db->fetchAllArray($sql)); + $page->assign('related', $related_cleaned); + + $sql = $db->query('SELECT t.*, r.*, s.status_name, res.resolution_name + FROM {related} r + LEFT JOIN {tasks} t ON r.this_task = t.task_id + LEFT JOIN {list_status} s ON t.item_status = s.status_id + LEFT JOIN {list_resolution} res ON t.resolution_reason = res.resolution_id + WHERE is_duplicate = 1 AND r.related_task = ? + ORDER BY t.task_id ASC', + array($task_id)); + $duplicates_cleaned = Flyspray::weedOutTasks($user, $db->fetchAllArray($sql)); + $page->assign('duplicates', $duplicates_cleaned); + + $sql = $db->query('SELECT * + FROM {notifications} n + LEFT JOIN {users} u ON n.user_id = u.user_id + WHERE n.task_id = ?', array($task_id)); + $page->assign('notifications', $db->fetchAllArray($sql)); + + $sql = $db->query('SELECT * + FROM {reminders} r + LEFT JOIN {users} u ON r.to_user_id = u.user_id + WHERE task_id = ? + ORDER BY reminder_id', array($task_id)); + $page->assign('reminders', $db->fetchAllArray($sql)); + + $page->pushTpl('details.tabs.tpl'); + + if ($user->perms('view_comments') || $proj->prefs['others_view'] || ($user->isAnon() && $task_details['task_token'] && Get::val('task_token') == $task_details['task_token'])) { + $page->pushTpl('details.tabs.comment.tpl'); + } + + $page->pushTpl('details.tabs.related.tpl'); + + if ($user->perms('manage_project')) { + $page->pushTpl('details.tabs.notifs.tpl'); + $page->pushTpl('details.tabs.remind.tpl'); + } + + if ($proj->prefs['use_effort_tracking']) { + $page->pushTpl('details.tabs.efforttracking.tpl'); + } + + $page->pushTpl('details.tabs.history.tpl'); + + } # endif can_edit_task + +} # endif can_view_task +?> -- cgit v1.2.3-70-g09d2