Skip to content

Form Helpdesk: custom field value overwritten by stale $value from previous QuestionTypeItemDropdown answer #1201

@DaviidMM

Description

@DaviidMM

GLPI Version

11.0.7

Plugin version

1.24.0

Bug description

When a ticket is created from a Helpdesk form (GLPI 11 forms), the value of a PluginFieldsQuestionType answer linked to a simple field (number, text, textarea, richtext, url, date, datetime) can be silently overwritten by the items_id of a previously processed QuestionTypeItemDropdown answer.

Examples observed in production on a custom number field "contact phone":

User typed Stored value Cause
3800 18 An earlier item-dropdown answer in the form had items_id = 18
3632 1 An earlier item-dropdown answer in the form had items_id = 1

Relevant log output

No PHP error / log output. The value is silently corrupted on save.

Page URL

No response

Steps To reproduce

  1. Create a Helpdesk form whose destination is Ticket.
  2. Add at least one question of type GLPI item (rendered as QuestionTypeItemDropdown, e.g. Location, Category…).
  3. Add a "Field" question (PluginFieldsQuestionType) linked to a custom field of type number (or any non-dropdown, non-glpi_item type).
  4. As an end user, submit the form: pick any item in the GLPI item question, and type any value (e.g. 3800) in the number field.
  5. Open the resulting ticket and look at the stored value of the custom field.

Expected: the field stores 3800 (the value typed by the user).
Actual: the field stores the items_id of the item selected in the GLPI item question.

Your GLPI setup information

No response

Anything else?

Root cause

In inc/destinationfield.class.php, PluginFieldsDestinationField::applyConfiguratedValueToInputUsingAnswers() iterates over the form answers. Inside the loop, $value is assigned only in the QuestionTypeItemDropdown branch:

foreach ($answers as $answer) {
    ...
    if ($question->getQuestionType() instanceof QuestionTypeItemDropdown) {
        ...
        $value = $answer->getRawAnswer()['items_id']; // set here
    } else {
        $field_id = (new PluginFieldsQuestionType())->getDefaultValueFieldId($question);
        $field = PluginFieldsField::getById($field_id);
        // $value is NOT reset
    }
    ...
    } else {
        $input[$field_name] = $value ?? $answer->getRawAnswer(); // leaks across iterations
    }
}

$value is never reset between iterations, so on a later PluginFieldsQuestionType iteration whose target field type falls into the final else branch (number, text, textarea, richtext, url, date, datetime), the expression $value ?? $answer->getRawAnswer() returns the stale $value from the previous iteration instead of the user's actual answer.

Suggested fix (and applied to my local version)

$value only has meaning in the QuestionTypeItemDropdown branch, and even there it is not consumed by the glpi_item / dropdown branches (which use $answer->getRawAnswer()['items_id'] directly). For the fall-through else, the value should always come from the current answer:

- $input[$field_name] = $value ?? $answer->getRawAnswer();
+ $input[$field_name] = $answer->getRawAnswer();

Alternatively, reset $value = null; at the top of the foreach. Either patch removes the cross-iteration leak.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions