--- id: KB-PLUGIN-030 title: "GLPI 11 — Criação de tabelas exige classe Migration (Executing direct queries is not allowed!)" domain: plugin-dev tags: - glpi11 - plugin - install - database - ddl - migration - gotcha status: active severity: high created_at: 2026-06-02 updated_at: 2026-06-02 applies_to: - 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) ```php function plugin_meuplugin_install() { global $DB; $query = "CREATE TABLE `glpi_plugin_meuplugin_table` (...)"; $DB->queryOrDie($query, $DB->error()); } ``` ### Correto (GLPI 11) ```php 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()`.