Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ITIL template field twig ui #16366

Merged
merged 3 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ The present file will list all changes made to the project; according to the
- `CommonITILActor::getActors()` signature changed. The `$items_id` parameter must strictly be an integer.
- The `date_mod` property for historical entries returned by `Log::getHistoryData` is no longer formatted based on the user's preferences.
- `Rule::dropdownRulesMatch()` has been made protected.
- `ITILTemplateField::showForITILTemplate()` method is no longer abstract.

#### Deprecated
- Usage of `GLPI_USE_CSRF_CHECK` constant.
Expand Down
169 changes: 168 additions & 1 deletion src/ITILTemplateField.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
* ---------------------------------------------------------------------
*/

use Glpi\Application\View\TemplateRenderer;
use Glpi\Search\SearchOption;

/**
* ITILTemplateMandatoryField Class
*
Expand Down Expand Up @@ -117,7 +120,171 @@ abstract public static function getExcludedFields();
*
* @return void
**/
abstract public static function showForITILTemplate(ITILTemplate $tt, $withtemplate = 0);
public static function showForITILTemplate(ITILTemplate $tt, $withtemplate = 0)
{
/**
* @var \DBmysql $DB
* @var array $CFG_GLPI
*/
global $DB, $CFG_GLPI;

$ID = $tt->fields['id'];

if (!$tt->getFromDB($ID) || !$tt->can($ID, READ)) {
return false;
}
$canedit = $tt->canEdit($ID);
$fields = $tt->getAllowedFieldsNames(false);
$fields = array_diff_key($fields, static::getExcludedFields());
$simplified_fields = $tt->getSimplifiedInterfaceFields();
$both_interfaces_label = sprintf(__('%1$s + %2$s'), __('Simplified interface'), __('Standard interface'));
$display_options = [
'relative_dates' => true,
'comments' => true,
'html' => true
];
$itil_class = static::$itiltype;
$searchOption = SearchOption::getOptionsForItemtype($itil_class);
$itil_object = new $itil_class();
$rand = mt_rand();

$crtiteria = [
'SELECT' => ['id', 'num'],
'FROM' => static::getTable(),
'WHERE' => [static::$items_id => $ID]
];
if (is_subclass_of(static::class, ITILTemplatePredefinedField::class)) {
$crtiteria['SELECT'][] = 'value';
}
$iterator = $DB->request($crtiteria);
$entries = [];

$numrows = count($iterator);

$used = [];
foreach ($iterator as $data) {
if (!array_key_exists($data['num'], $fields)) {
// Ignore deleted/unavailable fields
continue;
}
$interface_label = in_array($data['num'], $simplified_fields, false) ? $both_interfaces_label : __('Standard interface');
$entry = [
'itemtype' => static::class,
'id' => $data['id'],
'name' => $fields[$data['num']],
'interface' => $interface_label,
];
if (is_subclass_of(static::class, ITILTemplatePredefinedField::class)) {
$display_datas[$searchOption[$data['num']]['field']] = $data['value'];
$value_label = $itil_object->getValueToDisplay(
$searchOption[$data['num']],
$display_datas,
$display_options
);
$entry['value'] = $value_label;
}
$entries[] = $entry;
$used[$data['num']] = $data['num'];
}

$fields_dropdown_values = [];
foreach ($fields as $k => $field) {
$is_simple_field = in_array($k, $simplified_fields, false);
$label = sprintf(__('%1$s (%2$s)'), $field, $is_simple_field ? $both_interfaces_label : __('Standard interface'));
$fields_dropdown_values[$k] = $label;
}

if (is_subclass_of(static::class, ITILTemplatePredefinedField::class)) {
$fields_dropdown_values = array_replace([
-1 => Dropdown::EMPTY_VALUE
], $fields_dropdown_values);
}

if ($canedit) {
$extra_form_html = '';
if (is_subclass_of(static::class, ITILTemplatePredefinedField::class)) {
$embedded_ma_params = [
'id_field' => '__VALUE__',
'itemtype' => static::$itiltype,
'inline' => true,
'submitname' => _sx('button', 'Add'),
'options' => [
'relative_dates' => 1,
'with_time' => 1,
'with_days' => 0,
'with_specific_date' => 0,
'itemlink_as_string' => 1,
'entity' => $tt->getEntityID()
]
];
$extra_form_html = Ajax::updateItemOnSelectEvent(
"dropdown_num{$rand}",
"show_massiveaction_field",
$CFG_GLPI["root_doc"] . "/ajax/dropdownMassiveActionField.php",
$embedded_ma_params,
false
);
$extra_form_html .= "<div id='show_massiveaction_field'></div>";
}

$twig_params = [
'form_url' => static::getFormURL(),
'items_id_field' => static::$items_id,
'itemtype_name' => static::getTypeName(),
'used' => $used,
'id' => $ID,
'fields' => $fields_dropdown_values,
'extra_form_html' => $extra_form_html,
'rand' => $rand,
'show_submit' => !is_subclass_of(static::class, ITILTemplatePredefinedField::class)
];
echo TemplateRenderer::getInstance()->renderFromStringTemplate(<<<TWIG
{% import 'components/form/fields_macros.html.twig' as fields %}
{% import 'components/form/basic_inputs_macros.html.twig' as inputs %}
<div>
<form name="itiltemplatehidden_form{{ rand }}" method="post" action="{{ form_url }}" data-submit-once>
{{ inputs.hidden('_glpi_csrf_token', csrf_token()) }}
{{ inputs.hidden(items_id_field, id) }}
<div class="d-flex justify-content-center flex-wrap">
{{ fields.dropdownArrayField('num', 0, fields, null, {
no_label: true,
used: used,
add_field_attribs: {
'aria-label': itemtype_name
},
rand: rand
}) }}
{{ extra_form_html|raw }}
{% if show_submit %}
<div class="ms-2">{{ inputs.submit('add', _x('button', 'Add')) }}</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cconard96 _x() will not be detected by xgettext here.

I suggest to move this template into a dedicated Twig file. You could, inside this file, include components/datatable.html.twig, in order to have a single call to TemplateRenderer::getInstance()->display() inside the current method.

{% endif %}
</div>
</form>
</div>
TWIG, $twig_params);
}

$columns = [
'name' => __('Name'),
'interface' => __("Profile's interface")
];
if (is_subclass_of(static::class, ITILTemplatePredefinedField::class)) {
$columns['value'] = __('Value');
}
TemplateRenderer::getInstance()->display('components/datatable.html.twig', [
'is_tab' => true,
'nofilter' => true,
'columns' => $columns,
'entries' => $entries,
'total_number' => count($entries),
'filtered_number' => count($entries),
'showmassiveactions' => $canedit,
'massiveactionparams' => [
'num_displayed' => min($_SESSION['glpilist_limit'], $numrows),
'container' => 'mass' . static::class . $rand
],
]);
}


/**
Expand Down
111 changes: 2 additions & 109 deletions src/ITILTemplateHiddenField.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
* ---------------------------------------------------------------------
*/

use Glpi\Application\View\TemplateRenderer;

/**
* ITILTemplateHiddenField Class
*
Expand Down Expand Up @@ -148,113 +150,4 @@ public static function getExcludedFields()
175 => 175, // ticket's tasks (template)
];
}


/**
* Print the hidden fields
*
* @since 0.83
*
* @param ITILTemplate $tt ITIL Template
* @param integer $withtemplate Template or basic item (default 0)
*
* @return void
**/
public static function showForITILTemplate(ITILTemplate $tt, $withtemplate = 0)
{
/** @var \DBmysql $DB */
global $DB;

$ID = $tt->fields['id'];

if (!$tt->getFromDB($ID) || !$tt->can($ID, READ)) {
return false;
}
$canedit = $tt->canEdit($ID);
$ttm = new static();
$fields = $tt->getAllowedFieldsNames(false);
$fields = array_diff_key($fields, self::getExcludedFields());
$rand = mt_rand();

$iterator = $DB->request([
'FROM' => static::getTable(),
'WHERE' => [static::$items_id => $ID]
]);

$numrows = count($iterator);

$hiddenfields = [];
$used = [];
foreach ($iterator as $data) {
$hiddenfields[$data['id']] = $data;
$used[$data['num']] = $data['num'];
}

if ($canedit) {
echo "<div class='firstbloc'>";
echo "<form name='changeproblem_form$rand' id='changeproblem_form$rand' method='post'
action='" . $ttm->getFormURL() . "'>";

echo "<table class='tab_cadre_fixe'>";
echo "<tr class='tab_bg_2'><th colspan='2'>" . __('Add a hidden field') . "</th></tr>";
echo "<tr class='tab_bg_2'><td class='right'>";
echo "<input type='hidden' name='" . static::$items_id . "' value='$ID'>";
Dropdown::showFromArray('num', $fields, ['used' => $used]);
echo "</td><td class='center'>";
echo "&nbsp;<input type='submit' name='add' value=\"" . _sx('button', 'Add') .
"\" class='btn btn-primary'>";
echo "</td></tr>";
echo "</table>";
Html::closeForm();
echo "</div>";
}

echo "<div class='spaced'>";
if ($canedit && $numrows) {
Html::openMassiveActionsForm('mass' . $ttm->getType() . $rand);
$massiveactionparams = ['num_displayed' => min($_SESSION['glpilist_limit'], $numrows),
'container' => 'mass' . $ttm->getType() . $rand
];
Html::showMassiveActions($massiveactionparams);
}
echo "<table class='tab_cadre_fixehov'>";
echo "<tr class='noHover'><th colspan='2'>";
echo static::getTypeName(count($iterator));
echo "</th></tr>";
if ($numrows) {
$header_begin = "<tr>";
$header_top = '';
$header_bottom = '';
$header_end = '';
if ($canedit) {
$header_top .= "<th width='10'>";
$header_top .= Html::getCheckAllAsCheckbox('mass' . $ttm->getType() . $rand) . "</th>";
$header_bottom .= "<th width='10'>";
$header_bottom .= Html::getCheckAllAsCheckbox('mass' . $ttm->getType() . $rand) . "</th>";
}
$header_end .= "<th>" . __('Name') . "</th>";
$header_end .= "</tr>";
echo $header_begin . $header_top . $header_end;

foreach ($hiddenfields as $data) {
echo "<tr class='tab_bg_2'>";
if ($canedit) {
echo "<td>" . Html::getMassiveActionCheckBox($ttm->getType(), $data["id"]) . "</td>";
}
echo "<td>" . $fields[$data['num']] . "</td>";
echo "</tr>";
}
echo $header_begin . $header_bottom . $header_end;
} else {
echo "<tr><th colspan='2'>" . __('No item found') . "</th></tr>";
}

echo "</table>";
if ($canedit && $numrows) {
$massiveactionparams['ontop'] = false;
Html::showMassiveActions($massiveactionparams);
Html::closeForm();
}
echo "</div>";
}
}
Loading