* Copyright 2010 (c) Fusionforge Team
* Copyright 2011, Franck Villaume - Capgemini
* Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
- * Copyright 2014,2016-2017, Franck Villaume - TrivialDev
+ * Copyright 2014,2016-2017,2021, Franck Villaume - TrivialDev
* Copyright 2016-2017, Stéphane-Eymeric Bredthauer - TrivialDev
* http://fusionforge.org
*
require_once $gfcommon.'tracker/ArtifactWorkflow.class.php';
require_once $gfcommon.'tracker/EffortUnitFactory.class.php';
require_once $gfcommon.'include/utils_crossref.php';
-require_once $gfcommon.'include/UserManager.class.php';
require_once $gfcommon.'widget/WidgetLayoutManager.class.php';
class ArtifactTypeHtml extends ArtifactType {
$params['submenu'] = $HTML->subMenu($labels, $links, $attr);
site_project_header($params);
- if ($this)
- plugin_hook("blocks", "tracker_".$this->getName());
-
+ if ($this) {
+ plugin_hook('blocks', 'tracker_'.$this->getName());
+ }
}
function footer($params = array()) {
$elementLi[] = array('content' => util_make_link('/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&add_canned=1', _('Manage Canned Responses'), array('title'=>_('Create/change generic response messages for the tracker.'))));
$elementLi[] = array('content' => util_make_link('/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&clone_tracker=1', _('Apply Template Tracker'), array('title'=>_('Duplicate parameters and fields from a template trackers in this one.'))));
$elementLi[] = array('content' => util_make_link('/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&delete=1', _('Delete'), array('title'=>_('Permanently delete this tracker.'))));
+ $hook_params = array('group_id' => $group_id, 'atid' => $this->getID());
+ plugin_hook_by_reference("admin_tracker_add_actions", $hook_params);
+ if (isset($hook_params['result'])) {
+ foreach($hook_params['result'] as $action => $values) {
+ $elementLi[] = array('content' => util_make_link('/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID()."&$action=1", $values['text'], array('title'=>$values['description'])));
+ }
+ }
echo $HTML->html_list($elementLi);
}
/**
* renderExtraFields - ???
*
- * @param array $selected
- * @param bool $show_100 Display the specific '100' value. Default is false.
- * @param string $text_100 Label displayed for the '100' value. Default is 'none'
- * @param bool $show_any
- * @param string $text_any
- * @param array $types
- * @param bool $status_show_100 Force display of the '100' value if needed. Default is false.
- * @param string $mode QUERY, DISPLAY, UPDATE, NEW
+ * @param array $selected
+ * @param bool $show_100 Display the specific '100' value. Default is false.
+ * @param string $text_100 Label displayed for the '100' value. Default is 'none'
+ * @param bool $show_any
+ * @param string $text_any
+ * @param array $types
+ * @param bool $status_show_100 Force display of the '100' value if needed. Default is false.
+ * @param string $mode QUERY, DISPLAY, UPDATE, NEW
*/
function renderExtraFields($selected = array(),
$show_100 = false, $text_100 = 'none',
$post_name = '';
$i=$keys[$k];
- if (!isset($selected[$efarr[$i]['extra_field_id']]))
+ if (!isset($selected[$efarr[$i]['extra_field_id']])) {
$selected[$efarr[$i]['extra_field_id']] = '';
-
+ }
$value = $selected[$efarr[$i]['extra_field_id']];
$type = $efarr[$i]['field_type'];
"<a href=\"\\1\" target=\"_blank\">\\1</a>", $value);
} elseif ($type == ARTIFACT_EXTRAFIELDTYPE_RELATION || $type == ARTIFACT_EXTRAFIELDTYPE_PARENT) {
// Convert artifact id to links.
- $value = preg_replace_callback('/\b(\d+)\b/', create_function('$matches', 'return _artifactid2url($matches[1], \'title\');'), $value);
+ $callback = function ($matches) { return _artifactid2url($matches, 'title'); };
+ $value = preg_replace_callback('/\b(\d+)\b/', $callback, $value);
} elseif ($type == ARTIFACT_EXTRAFIELDTYPE_DATETIME && $value!='') {
$value = date('Y-m-d H:i', $value);
} elseif ($type == ARTIFACT_EXTRAFIELDTYPE_EFFORT) {
}
}
- if (!isset($selected[$efarr[$i]['extra_field_id']]))
+ if (!isset($selected[$efarr[$i]['extra_field_id']])) {
$selected[$efarr[$i]['extra_field_id']] = '';
-
+ }
if ($status_show_100) {
$efarr[$i]['show100'] = $status_show_100;
}
- $allowed=false;
+ $allowed = false;
if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT ||
$efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX ||
$str = $this->renderIntegerField($efarr[$i]['extra_field_id'], $selected[$efarr[$i]['extra_field_id']], $efarr[$i]['attribute1'], $efarr[$i]['attribute2'], $attrs);
}
if ($mode == 'QUERY') {
- $post_name = ' <i>'._('(%% for wildcards)').'</i> ';
+ $post_name = ' '.html_e('em', array(), _('(%% for wildcards)')).' ';
}
} elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXTAREA) {
$str = $this->renderTextArea($efarr[$i]['extra_field_id'], $selected[$efarr[$i]['extra_field_id']], $efarr[$i]['attribute1'], $efarr[$i]['attribute2'], $attrs);
if ($mode == 'QUERY') {
- $post_name = ' <i>'._('(%% for wildcards)').'</i>';
+ $post_name = ' '.html_e('em', array(), _('(%% for wildcards)'));
}
} elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
} elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RELATION) {
$str = $this->renderRelationField($efarr[$i]['extra_field_id'], $selected[$efarr[$i]['extra_field_id']], $efarr[$i]['attribute1'], $efarr[$i]['attribute2'], $attrs);
if ($mode == 'UPDATE' || $mode == 'NEW') {
- $post_name = $HTML->getEditFieldPic(_('Click to edit'), $alt = _('Click to edit'), array('onclick'=>"switch2edit(this, 'show$i', 'edit$i')"));
+ $post_name = $HTML->getEditFieldPic(_('Click to edit'), _('Click to edit'), array('onclick'=>"switch2edit(this, 'show$i', 'edit$i')"));
}
} elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_PARENT) {
$str = $this->renderParentField($efarr[$i]['extra_field_id'], $selected[$efarr[$i]['extra_field_id']], $efarr[$i]['attribute1'], $efarr[$i]['attribute2'], $attrs);
if ($mode == 'UPDATE' || $mode == 'NEW') {
- $post_name = $HTML->getEditFieldPic(_('Click to edit'), $alt = _('Click to edit'), array('onclick'=>"switch2edit(this, 'show$i', 'edit$i')"));
+ $post_name = $HTML->getEditFieldPic(_('Click to edit'), _('Click to edit'), array('onclick'=>"switch2edit(this, 'show$i', 'edit$i')"));
}
} elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_DATETIME) {
$str = $this->renderDatetime($efarr[$i]['extra_field_id'], $selected[$efarr[$i]['extra_field_id']], $attrs);
$str = $this->renderMultiReleaseField($efarr[$i]['extra_field_id'], $selected[$efarr[$i]['extra_field_id']], $efarr[$i]['show100'], $efarr[$i]['show100label'], $show_any, $text_any,false, $attrs);
} elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_DATERANGE) {
if ($mode == 'QUERY') {
- $post_name = ' <i>'._('(YYYY-MM-DD YYYY-MM-DD Format)').'</i>';
+ $post_name = ' '.html_e('em', array(), _('(YYYY-MM-DD YYYY-MM-DD Format)'));
}
$str = $this->renderDateRange($efarr[$i]['extra_field_id'], $selected[$efarr[$i]['extra_field_id']], $attrs);
} elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_EFFORT) {
$str = $this->renderEffort($efarr[$i]['extra_field_id'], $selected[$efarr[$i]['extra_field_id']], $efarr[$i]['attribute1'], $efarr[$i]['attribute2'], $attrs);
} elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_EFFORTRANGE) {
$str = $this->renderEffortRange($efarr[$i]['extra_field_id'], $selected[$efarr[$i]['extra_field_id']], $efarr[$i]['attribute1'], $efarr[$i]['attribute2'], $attrs);
+ } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SLA) {
+ $str = $this->renderSLAField($efarr[$i]['extra_field_id'], $selected[$efarr[$i]['extra_field_id']], $attrs);
}
$template = str_replace('{$PostName:'.$efarr[$i]['field_name'].'}', $post_name, $template);
$template = str_replace('{$'.$efarr[$i]['field_name'].'}', $str, $template);
$return = '';
- $taskcount = db_numrows($ah->getRelatedTasks());
- db_result_reset($ah->getRelatedTasks());
+ $tasks = $ah->getRelatedTasks();
+ $taskcount = db_numrows($tasks);
if (forge_check_perm('tracker_admin', $ah->ArtifactType->Group->getID())) {
$is_admin=true;
(($is_admin) ? $title_arr[]=_('Remove Relation') : '');
$return .= $HTML->listTableTop($title_arr);
- for ($i = 0; $i < $taskcount; $i++) {
- $taskinfo = db_fetch_array_by_row($ah->getRelatedTasks(), $i);
+ while ($taskinfo = db_fetch_array($tasks)) {
$totalPercentage += $taskinfo['percent_complete'];
$taskid = $taskinfo['project_task_id'];
$projectid = $taskinfo['group_project_id'];
- $groupid = $taskinfo['group_id'];
if (forge_check_perm('pm', $projectid, 'read')) {
$summary = util_unconvert_htmlspecialchars($taskinfo['summary']);
$startdate = date(_('Y-m-d H:i'), $taskinfo['start_date']);
return $return;
}
- function renderFiles($group_id, $ah) {
+ function renderFiles($group_id, $ah, $formid = null) {
global $HTML;
$file_list =& $ah->getFiles();
$count=count($file_list);
$return .= '<td>'.util_display_user($file->getSubmittedUnixName(), $file->getSubmittedBy(), $file->getSubmittedRealName()).'</td>';
$return .= '<td>'.util_make_link('/tracker/download.php/'.$group_id.'/'. $this->getID().'/'. $ah->getID() .'/'.$file->getID().'/'.$file->getName(), htmlspecialchars($file->getName())).'</td>';
if (forge_check_perm('tracker', $this->getID(), 'tech')) {
- $return .= '<td><input type="checkbox" name="delete_file[]" value="'. $file->getID() .'">'._('Delete').'</td>';
+ $return .= '<td><input type="checkbox" name="delete_file[]" '.(($formid) ? 'form="'.$formid.'"' : '').' value="'. $file->getID() .'">'._('Delete').'</td>';
}
$return .= '</tr>';
}
* @param string $mode Display mode (QUERY OR DISPLAY OR NEW)
* @return string HTML template.
*/
- function generateRenderHTML($types=array(), $mode) {
+ function generateRenderHTML($types, $mode) {
if ($mode == 'NEW') {
$efarr = $this->getExtraFields($types, false, false);
} else {
$keys=array_keys($efarr);
$count=count($keys);
- if ($count == 0) return '';
-
+ if ($count == 0) {
+ return '';
+ }
for ($k=0; $k<$count; $k++) {
$i=$keys[$k];
}
}
if ($aef->isAutoAssign()) {
- $autoAssignTo = UserManager::instance()->getUserById($aefe->getAutoAssignto());
+ $autoAssignTo = user_get_object($aefe->getAutoAssignto());
$opt_attrs[$i]=array_merge(isset($opt_attrs[$i]) ? $opt_attrs[$i] : array(), array('data-autoassignto'=>'{"id":'.$aefe->getAutoAssignto().', "name":"'.$autoAssignTo->getRealName().' ('.$autoAssignTo->getUnixName().')"}'));
}
}
}
$fpFactory = new FRSPackageFactory($this->getGroup());
- $packages = $fpFactory->getFRSs(true);
- uasort($packages, 'compareObjectName');
- foreach ($packages as $package) {
- $releases = $package->getReleases(false);
- uasort($releases, 'compareObjectName');
- foreach ($releases as $release) {
- $optGroup[] = $package->getName();
- $releasesArray[$release->getID()] = $release->getName();
+ if ($fpFactory && is_object($fpFactory) && !$fpFactory->isError()) {
+ $packages = $fpFactory->getFRSs(true);
+ uasort($packages, 'compareObjectName');
+ foreach ($packages as $package) {
+ $releases = $package->getReleases(false);
+ uasort($releases, 'compareObjectName');
+ foreach ($releases as $release) {
+ $optGroup[] = $package->getName();
+ $releasesArray[$release->getID()] = $release->getName();
+ }
}
- }
- $keys = array_keys($releasesArray);
- $vals = array_values($releasesArray);
- return html_build_select_box_from_arrays($keys, $vals, 'extra_fields['.$extra_field_id.']', $checked, $show_100, $text_100, $show_any, $text_any, $allowed, $attrs, $releasesAttrs, array(), $optGroup);
+ $keys = array_keys($releasesArray);
+ $vals = array_values($releasesArray);
+ return html_build_select_box_from_arrays($keys, $vals, 'extra_fields['.$extra_field_id.']', $checked, $show_100, $text_100, $show_any, $text_any, $allowed, $attrs, $releasesAttrs, array(), $optGroup);
+ } else {
+ global $HTML;
+ return $HTML->error_msg(_('Unable to get FRS Package Factory'));
+ }
}
/**
* @param string $text_100 What $string to call the '100 row'
* @param bool $show_any
* @param string $text_any
+ * @param bool $allowed
* @param array $attrs Array of other attributes
* @return string HTML code using radio buttons
*/
$dependency = '';
if (!empty($aefChildren)) {
$cElmntArr = $aefe->getChildrenElements();
- if (!empty($cElmntArr))
- {
+ if (!empty($cElmntArr)) {
foreach ($cElmntArr as $key=>$cElmnt) {
$childField = new ArtifactExtraField($this, $key);
$dependency .= (empty($dependency) ? '':', ').'{"field":'.$key.', "elmnt": ['.implode(', ', $cElmnt).']}';
}
}
if ($aef->isAutoAssign()) {
- $autoAssignTo = UserManager::instance()->getUserById($aefe->getAutoAssignto());
+ $autoAssignTo = user_get_object($aefe->getAutoAssignto());
$radios_attrs[$i]=array_merge(isset($radios_attrs[$i]) ? $radios_attrs[$i] : array(), array('data-autoassignto'=>'{"id":'.$aefe->getAutoAssignto().', "name":"'.$autoAssignTo->getRealName().' ('.$autoAssignTo->getUnixName().')"}'));
}
}
* @param array $checked The items that should be checked
* @param bool|string $show_100 Whether to show the '100 row'
* @param string $text_100 What to call the '100 row'
+ * @param bool $allowed
* @param array $attrs Array of other attributes
* @return string radio buttons
*/
* @param array $checked The items that should be checked
* @param bool|string $show_100 Whether to show the '100 row'
* @param string $text_100 What to call the '100 row'
+ * @param bool $allowed
* @param array $attrs Array of other attributes
* @return string radio multiselectbox
*/
if (isset($attrs['form'])) {
$attrsTxt['form'] = $attrs['form'];
}
- $html_contents = preg_replace_callback('/\b(\d+)\b/', create_function('$matches', 'return _artifactid2url($matches[1], \'title\');'), $contents);
+ $callback = function ($matches) { return _artifactid2url($matches, 'title'); };
+ $html_contents = preg_replace_callback('/\b(\d+)\b/', $callback, $contents);
$edit_contents = $this->renderTextField ($extra_field_id, $contents, $size, $maxlength, $attrsTxt);
return html_e('div',array_merge(array('id'=>'edit'.$extra_field_id, 'style'=>'display: none', 'title'=>_('Tip: Enter a space-separated list of artifact ids ([#NNN] also accepted)')), $attrs), $edit_contents)
.html_e('div',array_merge(array('id'=>'show'.$extra_field_id, 'style'=>'display: block'), $attrs), $html_contents);
$attrsTxt['pattern']='^\d*$';
}
// Convert artifact id to links.
- $html_contents = preg_replace_callback('/\b(\d+)\b/', create_function('$matches', 'return _artifactid2url($matches[1], \'title\');'), $contents);
+ $callback = function ($matches) { return _artifactid2url($matches, 'title'); };
+ $html_contents = preg_replace_callback('/\b(\d+)\b/', $callback, $contents);
$edit_contents = $this->renderTextField ($extra_field_id, $contents, $size, $maxlength, $attrsTxt);
return html_e('div',array_merge(array('id'=>'edit'.$extra_field_id, 'style'=>'display: none', 'title'=>_('Tip: Enter a space-separated list of artifact ids ([#NNN] also accepted)')), $attrs), $edit_contents)
.html_e('div',array_merge(array('id'=>'show'.$extra_field_id, 'style'=>'display: block'), $attrs), $html_contents);
}
/**
- * renderFormulaField - this function builds a formula field (RO).
+ * renderFormulaField - this function builds a formula field (RO).
*
- * @param string $contents The data for this field.
- * @return string
+ * @param string $contents The data for this field.
+ * @return string
*/
function renderFormulaField($contents) {
return $contents;
}
/**
- * renderSLAField - this function builds a formula field (RO).
+ * renderSLAField - this function builds a formula field (RO).
*
- * @param int $extra_field_id The ID of this field.
- * @param string $contents The data for this field.
- * @return string
+ * @param int $extra_field_id The ID of this field.
+ * @param string $contents The data for this field.
+ * @param $ef
+ * @return string
*/
function renderSLAField($extra_field_id, $contents, $ef) {
global $aid;
} elseif ($ef['alias'] == 'response_time') {
// Implement Response SLA: Time from create to first comment.
$messages = $artifact->getMessageObjects();
- if (count($messages) > 0) {
+ if (!empty($messages)) {
$message = $messages[count($messages) - 1];
$current_time = $message->getAddDate();
$timer_is_running = false;
if ($remaining >= 0) {
$value = gmdate("G\h i", $remaining);
} else {
- $value = '<b>-' . gmdate("G\h i", -$remaining) . "</b>";
+ $value = html_e('strong', array(), '-' . gmdate("G\h i", -$remaining));
}
if (!$timer_is_running) {
if ($remaining >= 0) {
$value = gmdate("G\h i", $remaining);
} else {
- $value = '<b>-' . gmdate("G\h i", -$remaining) . "</b>";
+ $value = html_e('strong', array(), '-' . gmdate("G\h i", -$remaining));
}
if ($artifact->getStatusID() == 2) {
if ($remaining >= 0) {
}
}
- function lastModifierBox($name='last_modified_by[]', $checked='xzxz', $show_100=true, $text_100='none', $extra_id='-1', $extra_name='', $multiple=false) {
+ function lastModifierBox($name = 'last_modified_by[]', $checked = 'xzxz', $show_100 = true, $text_100 = 'none', $extra_id = '-1', $extra_name = '', $multiple = false) {
if ($text_100=='none'){
$text_100=_('Nobody');
}
$result = $this->getLastModifiers();
- $ids =& util_result_column_to_array($result,0);
- $names =& util_result_column_to_array($result,1);
+ $ids =& util_result_column_to_array($result, 0);
+ $names =& util_result_column_to_array($result, 1);
if ($extra_id != '-1') {
- $ids[]=$extra_id;
- $names[]=$extra_name;
+ $ids[] = $extra_id;
+ $names[] = $extra_name;
}
if ($multiple) {
/**
* statusBox - show the statuses - automatically shows the "custom statuses" if they exist
*
- * @return string HTML code
+ * @param string $name
+ * @param string $checked
+ * @param bool $show_100
+ * @param string $text_100
+ * @param array $attrs
+ * @return string HTML code
*/
function statusBox($name = 'status_id', $checked = 'xzxz', $show_100 = false, $text_100 = 'none', $attrs = array()) {
if ($text_100=='none'){
/**
* priorityBox - show the priorities
*
- * @return string HTML code
+ * @param string $name
+ * @param string $checked_val
+ * @param bool $nochange
+ * @param array $attrs
+ * @param bool $show_any
+ * @return string HTML code
*/
function priorityBox($name = 'priority', $checked_val = '3', $nochange = false, $attrs = array(), $show_any = false){
return html_build_priority_select_box($name, $checked_val, $nochange, $attrs, $show_any);
});
});
-
-
-
- $("img[name='addparent']").click(function(){
+ $("img.addparent").click(function(){
$.ajax({
type: 'POST',
url: 'index.php',
$("div#show"+answer['parent_efid']).html(answer['parent_link']);
$("input#parent_id").val('');
$("div.addparent").addClass('hide');
+ $("img.removeparent").click(function(){
+ removeParent($(this).data("id"));
+ });
}
return true;
}
});
});
-
- $("img[name='addchild']").click(function(){
+ $("img.addchild").click(function(){
$.ajax({
type: 'POST',
url: 'index.php',
} else {
$("table.children").replaceWith(answer['children']);
$("input#child_id").val('');
+ $("img.removechild").click(function(){
+ removeChild($(this).data("id"));
+ });
}
return true;
}
});
+ $("img.removeparent").click(function(){
+ removeParent($(this).data("id"));
+ });
+
+ function removeParent(id) {
+ $.ajax({
+ type: 'POST',
+ url: 'index.php',
+ data: 'rtype=ajax&function=remove_parent&group_id='+groupId+'&atid='+atId+'&aid='+$("input#aid").val()+'&parent_id='+id,
+ async: false,
+ dataType: 'json',
+ success: function(answer){
+ if(answer['message']) {
+ showMessage(answer['message'], 'error');
+ } else {
+ $("table#parent"+id).remove();
+ $("div.addparent").removeClass('hide');
+ }
+ return true;
+ }
+ });
+ };
+
+ $("img.removechild").click(function(){
+ removeChild($(this).data("id"));
+ });
+
+ function removeChild(id) {
+ $.ajax({
+ type: 'POST',
+ url: 'index.php',
+ data: 'rtype=ajax&function=remove_child&group_id='+groupId+'&atid='+atId+'&aid='+$("input#aid").val()+'&child_id='+id,
+ async: false,
+ dataType: 'json',
+ success: function(answer){
+ if(answer['message']) {
+ showMessage(answer['message'], 'error');
+ } else {
+ $("span#child"+id).remove();
+ }
+ return true;
+ }
+ });
+ };
$(".autoassign[name^='extra_fields']").change(function(){
if ($(this).prop('tagName') == 'SELECT') {
var elmnts = $(this).children('option:selected');