knowledge-base/records/plugin-dev/KB-PLUGIN-030-glpi11-migration-class-required-for-ddl.md
Rodolpho Lopes 200cd6c2ce kb: KB-PLUGIN-031 runbook de workflow dev/deploy de plugins + commit dos registros 021-030 pendentes
- Novo runbook KB-PLUGIN-031: nascimento do plugin ate validacao E2E no
  GLPI dev (scaffold, Forgejo local, deploy CT100, console, bootstrap
  Kernel para testes CLI). Validado de ponta a ponta com o assetinherit.
- Registros KB-PLUGIN-021..030 existiam apenas no disco (drift) e foram
  incluidos no versionamento; index.json sincronizado via kb-fix.
- Ignora lixo AppleDouble/.DS_Store do macOS.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 17:59:47 +00:00

2.2 KiB
Executable file

id title domain tags status severity created_at updated_at applies_to
KB-PLUGIN-030 GLPI 11 — Criação de tabelas exige classe Migration (Executing direct queries is not allowed!) plugin-dev
glpi11
plugin
install
database
ddl
migration
gotcha
active high 2026-06-02 2026-06-02
plugins locais GLPI 11.x
hook.php

GLPI 11 — Criação de tabelas exige classe Migration

Sintoma

Ao tentar instalar um plugin via interface web do GLPI (ou CLI), o processo entra em loop (loading infinito na UI) ou falha silenciosamente. Nos logs (files/_log/php-errors.log), o seguinte Fatal Error (Uncaught Exception) aparece:

glpi.CRITICAL: *** Uncaught PHP Exception Exception: "Executing direct queries is not allowed!" at DBmysql.php

Causa raiz

No GLPI 11, o método $DB->query() (e os seus derivados como queryOrDie()) bloqueia ativamente a execução direta de comandos DDL (Data Definition Language) como CREATE TABLE, ALTER TABLE ou DROP TABLE. Essa é uma medida de segurança e padronização.

Qualquer plugin que tente criar suas tabelas usando $DB->queryOrDie("CREATE TABLE ...") dentro de hook.php sofrerá quebra imediata na instalação.

Solução padrão GLPI 11

A criação ou alteração de estrutura de banco de dados deve ser envelopada dentro da classe nativa \Migration.

Errado (Legacy - GLPI 9.x/10.x)

function plugin_meuplugin_install() {
    global $DB;
    $query = "CREATE TABLE `glpi_plugin_meuplugin_table` (...)";
    $DB->queryOrDie($query, $DB->error());
}

Correto (GLPI 11)

function plugin_meuplugin_install() {
    global $DB;
    $migration = new \Migration(MEUPLUGIN_VERSION);

    if (!$DB->tableExists('glpi_plugin_meuplugin_table')) {
        $query = "CREATE TABLE `glpi_plugin_meuplugin_table` (...)";
        $migration->addPostQuery($query);
    }
    
    // Essencial: executa a fila de queries da migration
    $migration->executeMigration();
    
    return true;
}

Checklist de validação

Sempre procure nos arquivos de instalação (hook.php ou setup.php) se o plugin chama diretamente $DB->query para criar tabelas. Se encontrar, reescreva para usar $migration->addPostQuery().