Um plugin do Mapas Culturais é uma classe PHP que estende a classe abstrata MapasCulturais\Plugin e precisa implementar ao menos dois métodos: _init e register.
O método _init é onde devem ser utilizados os hooks. O método register é onde deve ser registrado os metadados, controllers, etc.
A classe Plugin deve residir dentro de uma pasta com o mesmo nome de seu namespace e, para que possa ser executado pela aplicação, deve estar na pasta protected/application/plugins.
Os plugins podem conter as pastas layouts, view, templates, pages e assets, utilizadas quando se deseja sobrescrever algum arquivo do tema ou na implementação de uma nova funcionalidade que contenha alguma visão, parte de template ou asset, etc.
Além dessas cinco pastas, o tema pode conter as pastas Cotrollers, Entities e Repositories para abrigar seus controladores, entidades e repositórios, respectivamente. Ainda, o plugin pode conter um arquivo db-updates.php onde serão escritas as migrações do banco de dados, como criação de tabelas, colunas ou visões.
Configurações de um Plugin
Os plugins podem precisar de configurações, as quais devem ser definidas no __construct da classe do plugin, como no exemplo abaixo, onde são definidas as configurações min_items e max_items com os valores padrão 3 e 10:
Como foi falado na Introdução, através dos hooks, podemos modificar o comportamento padrão da aplicação. É uma das ferramentas mais utilizadas no desenvolvimento de plugins.
Utilizando-se dos hooks, podemos manipular as permissões de um usuário sobre uma entidade, substituir um arquivo de template, criar um getter nas entidades, manipular o retorno do magic getter (em algumas entidades), criar uma rota, executar ação antes ou depois de eventos das entidades (save, insert, update e delete), e dentre muitas outras coisas.
Alguns exemplos:
classPluginextends\MapasCulturais\Plugin {function_init() { $app =App::i();// criando um getter: $agent->items $app->hook('entity(Agent).get(items)',function (&$value) { $value =is_array($value)? $value : [1,2,3,4]; });// modificando o retorno de $agent->name $app->hook('entity(Agent).get(name)',function (&$value) { $value =strtoupper($value); });// criando uma rota GET /agent/meu-plugin $app->hook('GET(agent.meu-plugin)',function () use($app) {$this->requireAuthentication();$this->json(['agent'=> $app->user->profile->simplify('id,name'),'items'=> $app->user->profile->items ]); }); $config =$this->config;// cria permissão que retorna true se o valor de $app->hook('can(Agent.addItem)',function ($user,&$can) use($config) { $can =count($this->items)< $config['max_items']; });// cria permissão que retorna true se o valor de $app->hook('can(Agent.deleteItem)',function ($user,&$can) use($config) { $can =count($this->items)> $config['min_items']; }); }
Registrando Metadados
A classe do plugin herda os seguintes métodos para auxiliar no registro de metadados e devem ser utilizados dentro do método register:
registerAgentMetadata;
registerEventMetadata;
registerOpportunityMetadata;
registerProjectMetadata;
registerRegistrationMetadata;
registerSealMetadata;
registerSpaceMetadata;
registerUserMetadata.
Exemplo de registro de metadado:
classPluginextends\MapasCulturais\Plugin {functionregister() { $max =$this->config['max_items']; $min =$this->config['min_items'];$this->registerAgentMetadata('metaDeItems', ['label'=>'meta de itens','type'=>'number','validations'=> ["v::positive()"=>"a meta de itens deve ser um número positivo" ] ]);$this->registerAgentMetadata('items', ['label'=>'items','type'=>'array',// private => true,'serialize'=>function ($value) {returnjson_encode($value); },'unserialize'=>function ($value) {returnjson_decode($value); },'validations'=> [// "required" => "items é requerido", "v::arrayVal()->length({$min}, {$max})" => "items deve ser um array com no mínimo {$min} e no máximo {$max} itens"
] ]); }
Adicionando um Campo em uma Entidade
Para adicionar o campo de um metadado registrado na página de cadastro de uma entidade, primeiro crie um template part para o campo:
// arquivo layouts/parts/meu-plugin/meta-de-items.php<label> Meta de itens: <span class="js-editable" data-edit="metaDeItems" data-type="number" data-original-title="Meta de Itens" data-emptytext="Informe a meta de itens"><?=$entity->metaDeItems?></span></label>
Em seguida, inclua via hook a parte na página da entidade:
Para criar a tabela para a entidade definida acima, entre no container na pasta /var/www/html/protected/tools e execute o comando ./doctrine orm:schema-tool:update --dump-sql | grep {table} para gerar o SQL de atualização do banco, onde {table} é o nome da tabela definida na classe:
# na pasta /var/www/html/protected/tools./doctrineorm:schema-tool:update--dump-sql|grepitemCREATESEQUENCEitem_id_seqINCREMENTBY1MINVALUE1START1;CREATETABLEitem (id INTNOTNULL,titleVARCHAR(255) NOTNULL,PRIMARYKEY(id));
Após obter o SQL, deve-se criar um arquivo db-updates.php:
// arquivo db-updates.phpusefunctionMapasCulturais\__exec;return ['create table item'=>function() {__exec("CREATESEQUENCE item_id_seq INCREMENT BY1 MINVALUE 1START1;");__exec("CREATETABLE item (id INTNOT NULL, title VARCHAR(255) NOT NULL, PRIMARY KEY(id));"); }];
Execute o script db-update.sh ou reinicie o container:
# na pasta /var/www/scripts./db-update.shApplyingdbupdate"UPDATING ENUM TYPES":--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------...Applyingdbupdate"create table item":--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Criando EntityController para a Entidade Criada
O EntityController deve ter o mesmo nome que a entidade criada, então, crie o arquivo Item.php na pasta Controllers do plugin: