M

Manual Rede das Artes

Desenvolvimento

Módulos

Estenda o Mapas Culturais com módulos: estrutura, registro, configuração, ciclo de vida e lista dos módulos já incluídos.

Um módulo é um pacote autocontido de funcionalidade que se acopla ao núcleo do Mapas Culturais. Cada módulo é uma classe PHP que estende MapasCulturais\Module. Os módulos registram seu comportamento, como hooks, controllers, entidades e tipos de job, dentro do método _init(), chamado automaticamente pelo framework durante o boot da aplicação.

Estrutura de um módulo

src/modules/MyModule/
  Module.php       → Classe principal do módulo (deve estender `MapasCulturais\Module`)
  Entities/        → Entidades Doctrine adicionadas pelo módulo (opcional)
  Controllers/     → Controllers adicionados pelo módulo (opcional)
  Jobs/            → Tipos de job em background (opcional)
  views/           → Overrides ou novas views (opcional)

Escrevendo um módulo

<?php
namespace MapasCulturais\Modules\MyModule;

use MapasCulturais\App;

class Module extends \MapasCulturais\Module
{
    function _init(): void
    {
        $app = App::i();

        // Access module configuration
        $setting = $this->_config['my_setting'] ?? 'default';

        // Register a hook
        $app->hook('entity(Agent).save:after', function() use ($app, $setting) {
            // $this is the Agent entity that was just saved
            $app->log->info("Agent saved: {$this->name}");
        });

        // Register a controller
        $app->registerController('my-module', Controllers\MyController::class);

        // Register a background job type
        $app->registerJobType(new Jobs\MyJob(Jobs\MyJob::SLUG));
    }

    function register(): void
    {
        // Called before _init(). Use to register definitions,
        // evaluation methods, or other early-boot items.
    }
}

Entidades de módulo colocadas em Entities/ são descobertas automaticamente pelo Doctrine. Nenhuma configuração extra de ORM é necessária.

Registrando um módulo

Adicione o módulo à chave plugins do seu arquivo de configuração:

// config/config.php or dev/config.d/0.main.php
return [
    'plugins' => [
        'MyModule' => [
            'namespace' => 'MapasCulturais\Modules\MyModule',
            'my_setting' => 'custom_value',
        ],
    ],
];

A chave ('MyModule') é um identificador arbitrário. O valor de namespace deve bater com o namespace PHP do módulo. Quaisquer chaves adicionais do array são passadas como $config e ficam disponíveis dentro do módulo em $this->_config.

Ciclo de vida do módulo

Module::__construct() roda quando o módulo é instanciado. Ele dispara module({ClassName}).init:before, chama _init() e depois dispara module({ClassName}).init:after.

O módulo registra seus hooks, controllers e serviços. É aqui que toda a lógica do módulo é conectada.

Chamado antes no boot para itens que precisam ser registrados antes de _init() rodar em todos os módulos.

Quando todos os módulos terminaram de inicializar, a aplicação dispara mapasculturais.init. Use esse hook para código que depende de todos os módulos já estarem prontos.

Acessando a configuração do módulo

Dentro do módulo, valores de configuração ficam disponíveis via $this->_config:

function _init(): void
{
    $maxItems = $this->_config['max_items'] ?? 100;
    $apiKey   = $this->_config['api_key']   ?? null;
}

Módulos incluídos

Ecosystem plugins

Beyond the bundled modules, older installations often referenced external plugins maintained per project, edital, or deployment. They are not part of the core distribution, but these names still help when reading old configs and forks:

CategoryHistorical examples
Opportunity workflowsplugin-RegistrationPayments, plugin-AldirBlanc, plugin-AldirBlancDataprev, plugin-AldirBlancValidador, plugin-AldirBlancValidadorFinanceiro, plugin-AldirBlancValidadorRecurso, plugin-AppealValidator, plugin-GenericValidator, Plugin-FinancialValidador, plugin-GenericPaymentExport, plugin-ClaimForm
Integrations and supportplugin-Metabase, plugin-Analytics, plugin-Zammad, plugin-Integrator, plugin-MailImage
Data and admin toolingplugin-DataAnonymization, plugin-MapasBlame, plugin-AccountConsolidator, plugin-DisableModules, plugin-UndeletableEntities, plugin-MetadataKeyword
UX and installation behaviorplugin-Accessibility, plugin-SpamDetector, plugin-MapasOportunidade, plugin-MapasOportunidadeFrontend, plugin-EmbedTools, plugin-HomeContent, plugin-SubsiteFilter, plugin-SubsiteImport
Geography and localizationplugin-LocationPatch, plugin-GeodivisionsBR, plugin-CreateGeoDivisions

Use this list only as an orientation aid for technical archaeology. For current behavior, verify whether the capability is implemented as a bundled module, project-specific plugin, or theme customization in the repository you are maintaining.

Real-world example: Opportunities module

The following excerpt from src/modules/Opportunities/Module.php shows the _init() pattern in practice — registering job types, hooks that run after entity operations, and hooks that intercept API parameters:

function _init(): void
{
    $app = App::i();

    // Register background job types
    $app->registerJobType(new Jobs\StartEvaluationPhase(Jobs\StartEvaluationPhase::SLUG));
    $app->registerJobType(new Jobs\PublishResult(Jobs\PublishResult::SLUG));

    // Create a default registration step when a new opportunity is inserted
    $app->hook('entity(Opportunity).insert:after', function() {
        if ($this->registrationSteps && count($this->registrationSteps) > 0) {
            return;
        }
        $step = new RegistrationStep();
        $step->opportunity = $this;
        $step->save(true);
    });

    // Propagate owner changes to all subsequent phases
    $app->hook('entity(Opportunity).saveOwnerAgent', function() {
        if (!$this->isNew()) {
            foreach ($this->allPhases as $phase) {
                $phase->owner = $this->owner;
                $phase->save(true);
            }
        }
    });
}

Esse material é fruto do Programa de Difusão Nacional - Funarte Redes das Artes, realizado pelo Laboratório do Futuro (entidade vinculada à Universidade Federal do Ceará) no ano de 2025.

Felicilab
Mutirão
Lab do Futuro UFC
UFC
Rede das Artes Funarte
Funarte
MinC Governo Federal

On this page