💻
Documentação para desenvolvedores
  • Formação para desenvolvedores
    • Introdução
    • Entidades
    • Controladores
    • Backend dos Temas
    • Frontend dos Temas
    • Plugins
    • Módulo AngularJS
  • 📖Livro de receitas
    • Criação de um Tema
    • Adicionando campos adicionais ao seu tema
    • Gerando certificados personalizados para os selos
  • APIs
    • Guia de Hooks
Powered by GitBook
On this page
  • A Base do Plugin e como Habilitá-lo na Aplicação
  • Estrutura de Arquivos e Pastas
  • Configurações de um Plugin
  • Utilizando Hooks
  • Registrando Metadados
  • Adicionando um Campo em uma Entidade
  • Criando um Controlador
  • Criando uma Entidade
  • Criando uma Tabela
  • Criando EntityController para a Entidade Criada

Was this helpful?

  1. Formação para desenvolvedores

Plugins

PreviousFrontend dos TemasNextMódulo AngularJS

Last updated 3 years ago

Was this helpful?

A Base do Plugin e como Habilitá-lo na Aplicação

Um plugin do Mapas Culturais é uma classe PHP que estende a classe abstrata 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.

Abaixo, o exemplo mínimo de um plugin:

// arquivo protected/application/plugins/MeuPlugin/Plugin.php
<?php
namespace MeuPlugin;

class Plugin extends \MapasCulturais\Plugin {
   function _init () {}

   function register () {}
}

Para habilitar o plugin na aplicação é necessário colocá-lo no array de plugins habilitados na configuração da aplicação:

    'plugins' => [
        'EvaluationMethodTechnical' => ['namespace' => 'EvaluationMethodTechnical']],
        'EvaluationMethodSimple' => ['namespace' => 'EvaluationMethodSimple'],
        'EvaluationMethodDocumentary' => ['namespace' => 'EvaluationMethodDocumentary'],

        'MeuPlugin' => ['namespace' => 'MeuPlugin']
    ]

Estrutura de Arquivos e Pastas

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:

class Plugin extends \MapasCulturais\Plugin {

   function __construct($config = []) {
      $config += [
         'min_items' => 3,
         'max_items' => 10,
      ];

      parent::__construct($config);
   }

Para modificar o valor de uma configuração, deve-se informar na habilitação do plugin, da seguinte maneira:

    'plugins' => [
         .
         .
         .
         'MeuPlugin' => [
            'namespace' => 'MeuPlugin',
            'config' => ['min_items' => 1, 'max_items' => 5]
         ]
    ]

Utilizando Hooks

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:

class Plugin extends \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:

class Plugin extends \MapasCulturais\Plugin {
    function register() {
        $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) {
                return json_encode($value);
            },
            'unserialize' => function ($value) {
                return json_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:

class Plugin extends \MapasCulturais\Plugin {
    function _init() {
        $app = App::i();
        .
        .
        .
        $app->hook('template(agent.<<edit|single>>.tab-about):begin', function () {
            $entity = $this->controller->requestedEntity;
            $this->part('meu-plugin/meta-de-items.php', ['entity' => $entity]);
        });

Criando um Controlador

Para criar um controlador, primeiro crie a classe na pasta Controllers do plugin:

// arquivo Controllers/MeuPlugin.php
namespace MeuPlugin\Controllers;

class MeuPlugin extends \MapasCulturais\Controller {
   function GET_index () {
      $this->json('GET /');
   }
}

E, em seguida, registre o controlador na aplicação:

class Plugin extends \MapasCulturais\Plugin {
   function register() {
      $app = App::i();
      $app->registerController('meu-plugin', Controllers\MeuPlugin::class);
   }

Criando uma Entidade

Para criar uma entidade, deve-se criar a classe na pasta Entities do plugin, definindo todos os atributos e mapeamentos:

// arquivo Entities\Item.php
namespace MeuPlugin\Entities;

use Doctrine\ORM\Mapping as ORM;

/**
 * Item 
 * 
 * @ORM\Table(name="item")
 * @ORM\Entity
 * @ORM\entity(repositoryClass="MapasCulturais\Repository")
 */
class Item extends \MapasCulturais\Entity {
   /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="SEQUENCE")
     * @ORM\SequenceGenerator(sequenceName="item_id_seq", allocationSize=1, initialValue=1)
     */
    protected $id;

    /**
     * @var string|object
     *
     * @ORM\Column(name="title", type="string", nullable=false)
     */
    protected $title;
}

Criando uma Tabela

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
./doctrine orm:schema-tool:update --dump-sql | grep item

     CREATE SEQUENCE item_id_seq INCREMENT BY 1 MINVALUE 1 START 1;
     CREATE TABLE item (id INT NOT NULL, title VARCHAR(255) NOT NULL, PRIMARY KEY(id));

Após obter o SQL, deve-se criar um arquivo db-updates.php:

// arquivo db-updates.php
use function MapasCulturais\__exec;

return [
    'create table item' => function() {
        __exec("CREATE SEQUENCE item_id_seq INCREMENT BY 1 MINVALUE 1 START 1;");
        __exec("CREATE TABLE item (id INT NOT 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.sh

Applying db update "UPDATING ENUM TYPES":
-------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------
.
.
.

Applying db update "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:

// arquivo Controllers/Item.php
namespace MeuPlugin\Controllers;
use MapasCulturais\Traits\ControllerAPI;

class Item extends \MapasCulturais\Controllers\EntityController {
   use ControllerAPI;
}

Registre o controlador na aplicação:

class Plugin extends \MapasCulturais\Plugin {
   function register() {
      $app = App::i();
      $app->registerController('meu-plugin', Controllers\MeuPlugin::class);
      $app->registerController('item', Controllers\Item::class);
   }

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 .

Como foi falado na , através dos hooks, podemos modificar o comportamento padrão da aplicação. É uma das ferramentas mais utilizadas no desenvolvimento de plugins.

protected/application/plugins
Introdução
MapasCulturais\Plugin