Kernel e Ciclo de Vida¶
O Kernel (local_middag\core\kernel\kernel) é o componente central de orquestração do plugin. Ele atua como a ponte entre o ambiente procedural do Moodle e a arquitetura orientada a objetos do MIDDAG.
Sua responsabilidade é única e crítica: Inicializar o Container de Injeção de Dependência (DI) e garantir que todos os componentes (Core e Extensões) estejam prontos para uso.
O Processo de Boot (Bootstrapping)¶
O MIDDAG utiliza um processo de inicialização "Lazy" (preguiçoso). O Kernel só é instanciado quando o primeiro recurso do plugin é solicitado.
O diagrama abaixo detalha a sequência exata de eventos quando middag::init() é chamado:
sequenceDiagram
participant Moodle as Moodle / Lib.php
participant Facade as Facade (middag)
participant Kernel as Kernel
participant Container as ContainerBuilder
participant Loaders as Loaders (Ext/Svc/Type)
Moodle->>Facade: Chama middag::init()
Facade->>Kernel: init() (Singleton Check)
alt Já inicializado
Kernel-->>Facade: Retorna instância existente
else Primeira execução
Kernel->>Container: new ContainerBuilder()
note right of Kernel: Fase 1: Descoberta
Kernel->>Loaders: Executa Loaders
Loaders-->>Container: Registra Definições (autowire)
note right of Kernel: Fase 2: Compilação
Kernel->>Container: compile() (Congela configuração)
note right of Kernel: Fase 3: Injeção Sintética
Kernel->>Container: set(serviços_vivos)
Kernel-->>Facade: Boot Concluído
end
Fases do Boot¶
- Descoberta (Discovery): O Kernel aciona os Loaders que varrem os diretórios do projeto para encontrar classes, serviços e configurações de extensões. Nenhuma classe é instanciada aqui, apenas suas definições são registradas.
- Compilação (Compilation): O
ContainerBuilderdo Symfony processa todas as definições, resolve dependências e otimiza o grafo de objetos. Após este ponto, a configuração do container torna-se imutável (frozen) para garantir performance. - Injeção Sintética (Synthetic Injection): Objetos que já existem em tempo de execução (como o próprio Kernel ou instâncias de Loaders) são injetados manualmente no container compilado.
Container de Injeção de Dependência¶
O MIDDAG utiliza o componente symfony/dependency-injection. Isso elimina a necessidade de new Class() espalhados pelo código e permite testes unitários fáceis via Mocking.
Autowiring¶
A maioria dos serviços é configurada com autowire: true. Isso significa que você não precisa configurar dependências manualmente. Basta declarar o tipo no construtor.
Exemplo:
<?php
// O Kernel lerá o tipo 'item_repository' e injetará a instância correta automaticamente.
public function __construct(private item_repository $repository) {}
Serviços Sintéticos (Synthetic Services)¶
Alguns serviços são marcados como sintéticos no Kernel. Isso significa: "Container, não tente criar isso. Eu vou te entregar a instância pronta depois de compilar". Isso é usado para evitar referências circulares durante o boot do próprio Kernel.
Loaders: O Sistema de Descoberta¶
Para evitar arquivos de configuração XML ou YAML gigantescos, o Kernel delega a descoberta de recursos para classes especializadas chamadas Loaders. Elas operam sob o princípio de Convention over Configuration (Convenção sobre Configuração).
1. Service Loader (service_loader.php)¶
Varre diretórios padrão (classes/core/service, classes/core/repository, etc.) e registra automaticamente qualquer classe encontrada como um serviço público no container.
- Cache: Em produção, o mapa de arquivos é cacheado para evitar acesso lento ao disco.
2. Extension Loader (extension_loader.php)¶
Varre a pasta classes/extensions/.
- Identifica classes que estendem
base_extension. - Lê metadados como
GROUPePRIORITY. - Executa arquivos
bootstrap.phpde cada extensão de forma isolada (try/catch), garantindo que uma extensão quebrada não derrube o sistema.
3. Type Loader (type_loader.php)¶
Responsável pelo DDD. Varre as pastas domain/entity procurando classes que definem constantes TYPE.
- Popula o
item_typesregistry. - Permite que o repositório saiba qual classe instanciar baseada em uma string (ex:
'course'->course_item::class).
HttpKernel e Roteamento¶
Embora o Kernel principal cuide dos objetos, o http_kernel cuida da Web. Ele é anexado ao Kernel principal após o boot.
Responsabilidades:¶
- Request Lifecycle: Captura a Request global do PHP/Moodle.
- Routing: Usa o
route_managerpara mapear URLs para Controllers. - Response Handling: Garante que se o Controller retornar um Array, ele seja convertido para
JsonResponseautomaticamente. - Error Handling: Intercepta exceções e as transforma em respostas JSON padronizadas (evitando a "Tela Branca da Morte" ou vazamento de HTML em chamadas AJAX).
Atributos PHP 8¶
O roteamento usa reflexão para ler atributos nativos. Não há arquivo de rotas central.
<?php
#[Route('/api/v1/courses', name: 'api.courses', methods: ['GET'])]
public function index(): Response { ... }
Como acessar o Kernel¶
Em desenvolvimento de extensões ou scripts de manutenção, você raramente acessará a classe kernel diretamente. Utilize sempre a Facade: