Aprendizados validados no desenvolvimento do plugin sync: - KB-PLUGIN-032: subclasse DBmysql read-only para banco externo (gotchas de senha rawurldecode, query() guard, flag connected). - KB-PLUGIN-033: comandos de console de plugin exigem src/ + namespace de nome plugins:<key>:. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2.9 KiB
| id | title | domain | tags | status | severity | created_at | updated_at | applies_to | related_records | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| KB-PLUGIN-033 | GLPI 11 — Comandos de console de plugin exigem src/ e namespace de nome plugins:<key>: | plugin-dev |
|
active | high | 2026-06-16 | 2026-06-16 |
|
|
GLPI 11 — Comandos de console de plugin
Como o core descobre os comandos
Glpi\Console\CommandLoader::findPluginCommands() varre, para cada plugin
ativo, os diretórios inc/ e src/, instanciando classes que sejam
Symfony\Component\Console\Command\Command. Os prefixos de classe tentados são:
GlpiPlugin\<Ucfirst(key)>\(namespaced — recomendado), ouPlugin<Ucfirst(key)>(legado não-namespaced), ou- vazio (PSR-4 sem namespace).
O src/ do plugin é registrado como PSR-4 GlpiPlugin\<Ucfirst(key)>\ → src/
(Plugin.php, ~linha 406). Então src/Console/FooCommand.php deve declarar
namespace GlpiPlugin\<Ucfirst(key)>\Console;.
Regra rígida do nome (a armadilha)
O nome do comando DEVE casar com o padrão plugins:<key>:<algo> (regex no
core: ^plugins:<key>(:[^:]+)+$). Se não casar, o core emite
E_USER_WARNING ("must be moved in the plugins:<key> namespace") e não
registra o comando — ele simplesmente não aparece em bin/console.
namespace GlpiPlugin\Sync\Console;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class TestConnectionCommand extends Command
{
protected function configure(): void
{
$this->setName('plugins:sync:test-connection'); // <- obrigatório
$this->setDescription('...');
$this->addOption('host', null, InputOption::VALUE_REQUIRED, '...');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
// ... lógica ...
return Command::SUCCESS; // SUCCESS / FAILURE / INVALID
}
}
Notas
- Estender o
Commanddo Symfony direto é suficiente (não exigeGlpi\Console\AbstractCommand). O Kernel já está bootado quando o comando roda, então classes do core e dos plugins ativos estão disponíveis. - O plugin precisa estar ativado para os comandos aparecerem.
- Arquivos de teste sob
src//inc/que casem o padrão também são varridos — manter scripts de teste fora desses dirs (ver.gitignoredo plugin).
Validação
Comprovado no plugin sync (2026-06-16): plugins:sync:test-connection
registrou e executou; ver [KB-PLUGIN-032] para o conteúdo do comando (segunda
conexão DBmysql).
Classificação
- Tipo: gotcha + padrão de implementação.
- Reutilização: qualquer plugin com comando de CLI.