Skip to content

Commit 333636d

Browse files
authored
feat(questiontype): add condition handlers and support for dropdown field type in forms (#1174)
1 parent 62116eb commit 333636d

File tree

6 files changed

+300
-7
lines changed

6 files changed

+300
-7
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Support for new value operators for “Field” question type linked to a field that is a dropdown in forms
13+
1014
### Fixed
1115

1216
- Fix error when submitting a form with an hidden question of type `Field`

inc/destinationfield.class.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ public function applyConfiguratedValueToInputUsingAnswers(
134134
if ($field->fields['type'] == 'glpi_item') {
135135
$input[sprintf('itemtype_%s', $field_name)] = $answer->getRawAnswer()['itemtype'];
136136
$input[sprintf('items_id_%s', $field_name)] = $answer->getRawAnswer()['items_id'];
137+
} elseif ($field->fields['type'] == 'dropdown') {
138+
$input[$field_name] = $answer->getRawAnswer()['items_id'];
137139
} else {
138140
$input[$field_name] = $value ?? $answer->getRawAnswer();
139141
}

inc/questiontype.class.php

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
*/
3030

3131
use Glpi\Application\View\TemplateRenderer;
32+
use Glpi\DBAL\JsonFieldInterface;
33+
use Glpi\Form\Condition\ConditionHandler\ItemAsTextConditionHandler;
34+
use Glpi\Form\Condition\ConditionHandler\ItemConditionHandler;
3235
use Glpi\Form\Form;
3336
use Glpi\Form\Migration\FormQuestionDataConverterInterface;
3437
use Glpi\Form\Question;
@@ -167,12 +170,24 @@ public function renderEndUserTemplate(Question $question): string
167170
$default_value = json_decode($question->fields['default_value'], true);
168171
}
169172

173+
$itemtype = null;
174+
if (str_starts_with((string) $current_field->fields['type'], 'dropdown')) {
175+
if ($current_field->fields['type'] == 'dropdown') {
176+
$itemtype = PluginFieldsDropdown::getClassname($current_field->fields['name']);
177+
} else {
178+
$dropdown_matches = [];
179+
preg_match('/^dropdown-(?<class>.+)$/', (string) $current_field->fields['type'], $dropdown_matches);
180+
$itemtype = $dropdown_matches['class'];
181+
}
182+
}
183+
170184
$twig = TemplateRenderer::getInstance();
171185
return $twig->render('@fields/question_type_end_user.html.twig', [
172186
'question' => $question,
173187
'field' => $current_field->fields,
174188
'default_value' => $default_value,
175189
'item' => new Form(),
190+
'itemtype' => $itemtype,
176191
]);
177192
}
178193

@@ -196,7 +211,8 @@ public function formatRawAnswer(mixed $answer, Question $question): string
196211
case 'date':
197212
return (string) $answer;
198213
case 'dropdown':
199-
if (is_string($answer)) {
214+
$answer = $answer['items_id'];
215+
if (is_string($answer) || is_numeric($answer)) {
200216
$answer = [$answer];
201217
}
202218

@@ -283,6 +299,42 @@ public function getTargetQuestionType(array $rawData): string
283299
return self::class;
284300
}
285301

302+
#[Override]
303+
public function getConditionHandlers(
304+
?JsonFieldInterface $question_config,
305+
): array {
306+
$condition_handlers = parent::getConditionHandlers($question_config);
307+
if (!$question_config instanceof PluginFieldsQuestionTypeExtraDataConfig) {
308+
throw new InvalidArgumentException();
309+
}
310+
311+
if (!$question_config->getFieldId()) {
312+
return parent::getConditionHandlers($question_config);
313+
}
314+
315+
// If the question is configured with a dropdown field, we add condition handlers to handle item and item as text conditions on the dropdown options
316+
$field = PluginFieldsField::getById($question_config->getFieldId());
317+
if ($field && str_starts_with((string) $field->fields['type'], 'dropdown')) {
318+
if ($field->fields['type'] == 'dropdown') {
319+
$itemtype = PluginFieldsDropdown::getClassname($field->fields['name']);
320+
} else {
321+
$dropdown_matches = [];
322+
preg_match('/^dropdown-(?<class>.+)$/', (string) $field->fields['type'], $dropdown_matches);
323+
$itemtype = $dropdown_matches['class'];
324+
}
325+
326+
$condition_handlers = array_merge(
327+
$condition_handlers,
328+
[
329+
new ItemConditionHandler($itemtype),
330+
new ItemAsTextConditionHandler($itemtype),
331+
],
332+
);
333+
}
334+
335+
return $condition_handlers;
336+
}
337+
286338
/**
287339
* Retrieve the default value block from the question's extra data
288340
*

templates/question_type_administration.html.twig

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@
3232

3333
{% set is_ajax_reload = is_ajax_reload|default(false) %}
3434

35+
{% set is_dropdown = field.type starts with 'dropdown' %}
36+
{% set name_suffix = is_dropdown ? '[items_id]' : '' %}
37+
3538
{% set field_for_html = field|merge({
36-
'default_value': default_value ?? field.default_value,
39+
'default_value': default_value.items_id ?? default_value ?? field.default_value,
3740
'mandatory': false
3841
}) %}
3942

@@ -44,8 +47,8 @@
4447
true,
4548
false,
4649
{
47-
'input_name' : 'default_value',
48-
'full_width' : not (field.type starts with 'dropdown' or field.type == 'glpi_item'),
50+
'input_name' : 'default_value' ~ name_suffix,
51+
'full_width' : not (is_dropdown or field.type == 'glpi_item'),
4952
'no_label' : true,
5053
'mb' : '',
5154
'init' : is_ajax_reload or (question is not null),

templates/question_type_end_user.html.twig

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,20 @@
2626
# -------------------------------------------------------------------------
2727
#}
2828

29+
{% import 'components/form/fields_macros.html.twig' as fields %}
30+
2931
{% set field = field|merge({
30-
'default_value': default_value ?? field.default_value
32+
'default_value': default_value.items_id ?? default_value ?? field.default_value
3133
}) %}
3234

35+
{% set is_dropdown = field.type starts with 'dropdown' %}
36+
{% set name_suffix = is_dropdown ? '[items_id]' : '' %}
37+
38+
{{ fields.hiddenField(
39+
question.getEndUserInputName() ~ '[itemtype]',
40+
itemtype
41+
) }}
42+
3343
<div data-glpi-form-renderer-fields-question-type-specific-container>
3444
{{ call('PluginFieldsField::prepareHtmlFields', [
3545
[field],
@@ -38,7 +48,7 @@
3848
true,
3949
false,
4050
{
41-
'input_name' : question.getEndUserInputName(),
51+
'input_name' : question.getEndUserInputName() ~ name_suffix,
4252
'full_width' : not (field.type starts with 'dropdown' or field.type == 'glpi_item'),
4353
'no_label' : true,
4454
'mb' : '',

0 commit comments

Comments
 (0)