Pular para conteúdo

Classes-Base

Classes-base residem em classes/base/. São a fronteira de heranca estavel entre o framework interno e as extensions. Classificadas como Grupo B (extensão controlada).


Padrao de uso

use local_middag\base\entity;

class my_entity extends entity
{
    // ...
}

Base — Raiz (classes/base/)

Classe O que fornece Quando usar
extension Lifecycle hooks (register(), boot()), registro no kernel, acesso ao container Toda extension do framework
licensed_extension Tudo de extension + verificação de licenca, grace period, feature gating Extensions com licenciamento
controller Integração com routing, $PAGE setup, template rendering, Inertia support Controllers de página Moodle ou Inertia SPA
api_controller Envelope de resposta padrão ({success, data, message}), dual auth (wstoken + session) Controllers de API JSON
form_request Regras de validação declarativas, auto-validação pelo resolver chain, acesso a dados validados Validação de input
service Acesso ao container, integração com transaction manager, dispatcher Services de dominio
repository CRUD base, integração com db_support, query builder, páginação Repositorios de persistência
entity Identidade, hydration, tipagem de propriedades Entities de dominio
dto Imutabilidade, factory method from(), serialização DTOs entre camadas
mapper Contrato de mapeamento bidirecional Mapeamento entity/DTO
command Contrato de command, serialização, dispatching via bus Commands para o command bus
command_handler Contrato de handler, integração com container para DI Handlers de commands
facade Proxy estatico para services, resolução via container Facades de extension (geradas via CLI)
block Lifecycle de bloco, rendering, configuração Blocos do framework
dashboard_widget Rendering, configuração, permissoes Widgets de dashboard
widget Contrato de widget, integração com Mustache templates Componentes server-side reutilizaveis
activity_feed_renderer Contrato de rendering, acesso ao contexto do feed Rendering customizado de activity feed
global_scope Contrato de scope, registro no kernel Escopos globais em queries

Base — Domain (classes/base/domain/)

Classes-base para aggregates do framework. Usadas quando a extension trabalha com items, auditoria ou jobs.

Classe Aggregate O que fornece Quando usar
item item Persistencia EAV, type registration, validação de schema Criar novos tipos de item
item_dto item DTO tipado com factory method DTOs de item customizados
item_revision item_revision Versionamento de dados Revisoes de item
item_repository item CRUD de items + busca por type, query engine integration Repositorios de item
item_revision_repository item_revision CRUD de revisoes Repositorios de revisão
item_service item CRUD com validação, signals, auditoria automatica Services de item
audit_log audit Logs de auditoria customizados Audit logs customizados
job job Serialização, retries, attempts tracking Jobs assincronos

Exemplos

Extension

class ecommerce extends \local_middag\base\extension
{
    public function register(): void
    {
        $this->container->bind(site_service_interface::class, site_service::class);
    }

    public function boot(): void
    {
        $this->register_controllers();
    }
}

Controller

class site_controller extends \local_middag\base\controller
{
    use interacts_with_auth;
    use interacts_with_page;

    #[Route('/ecommerce/sites', methods: ['GET'])]
    public function index(): string
    {
        $this->require_login();
        return $this->render('local_middag/ecommerce/sites', ['sites' => $sites]);
    }
}

API Controller

class site_api_controller extends \local_middag\base\api_controller
{
    #[Route('/api/v1/sites', methods: ['GET'])]
    public function list(): JsonResponse
    {
        return $this->json_success($this->site_service->list());
    }
}

Item type

class product extends \local_middag\base\domain\item
{
    protected string $type = 'product';

    protected function schema(): array
    {
        return [
            'price'  => ['type' => 'float', 'required' => true],
            'sku'    => ['type' => 'string', 'required' => true],
            'active' => ['type' => 'bool', 'default' => true],
        ];
    }
}

Job

class sync_products_job extends \local_middag\base\domain\job
{
    public function __construct(
        private int $site_id,
    ) {}

    public function handle(site_service $service): void
    {
        $service->sync_products($this->site_id);
    }
}

Form request

class site_store_request extends \local_middag\base\form_request
{
    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            'url'  => ['required', 'url'],
        ];
    }
}

O que NÃO sobrescrever

  • Métodos final nas classes-base
  • Contracts internos (@internal) do framework
  • Métodos de lifecycle do kernel (register() e boot() devem chamar parent::)

O que NÃO fazer em extensions via base/

  • Acesso direto a $DB, $CFG, $PAGE (usar boundary Moodle via facades)
  • Heranca de classes internas do framework/ (usar apenas base/)
  • Implementação de interfaces @internal