knowledge-base/records/plugin-dev/KB-PLUGIN-009-transformconditionvalue-empty-array.md

2.4 KiB

id title domain tags status severity created_at updated_at applies_to
KB-PLUGIN-009 Validacao mandatory ignora respostas que sao arrays nao-vazios com chaves em branco plugin-dev
glpi
glpi11
form-builder
validation
answers-handler
active high 2026-05-02 2026-05-02
GLPI 11.0.x

Validacao mandatory ignora respostas que sao arrays nao-vazios com chaves em branco

Sintoma

Um campo obrigatório (mandatory) de um novo QuestionType não dispara nenhum erro de validação se o usuário o enviar vazio. Em vez disso, a página tenta enviar e falha, devolvendo um erro genérico do sistema (geralmente gerado na hora de gravar os destinos).

Causa

O mecanismo do AnswersHandler do GLPI verifica campos vazios da seguinte forma:

if ($answer === null || (is_string($answer) && strip_tags($answer) === '') || (is_array($answer) && count($answer) === 0))

Em widgets complexos que retornam uma estrutura via vários inputs (como [items_id] e [itemtype]), se o usuário não selecionar nada, a resposta "crua" (raw) pode chegar no backend como um array:

$answer = [
    'itemtype' => 'ITILCategory',
    'items_id' => ''
];

Este array possui 2 chaves, logo count($answer) === 0 é false. O GLPI entende que a pergunta "foi respondida" e pula a checagem de obrigatoriedade.

Solucao

A classe QuestionType deve implementar (ou sobrescrever) o método transformConditionValueForComparisons originado da ConditionValueTransformerInterface.

O objetivo é examinar a resposta raw precocemente e convertê-la ativamente em uma string vazia '' caso os dados essenciais estejam ausentes.

use Override;

#[Override]
public function transformConditionValueForComparisons(mixed $value, ?\Glpi\DBAL\JsonFieldInterface $question_config): string 
{
    if (is_array($value)) {
        $items_id = $value['items_id'] ?? '';
        
        // Trata chaves em branco ou nulas como resposta vazia global
        if ($items_id === '' || $items_id === null || (int)$items_id <= 0) {
            return ''; // string vazia dispara o check nativo do AnswersHandler!
        }
    }

    // Passa adiante se tudo estiver ok
    return parent::transformConditionValueForComparisons($value, $question_config);
}

Ao retornar '', o AnswersHandler passará a reconhecer que o usuário pulou o campo, ativando corretamente a mensagem de erro (ou a sua CustomMandatoryMessageInterface caso definida).