Como montar um plugin no MantisBT

O intuito deste tutorial é ensinar como desenvolver um plugin para o sistema de “bug tracking” MantisBT

Definição

Por ser um sistema open-source (de código-fonte aberto), o MantisBT possibilita a integração com plugins. Os plugins são desenvolvidos de forma independente, ou seja, não é preciso alterar a estrutura principal do MantisBT, nem alterar qualquer código fonte dentro do mesmo, no entanto, é possível alterar o comportamento padrão de certos eventos, como veremos depois.

Neste tutorial iremos desenvolver um plugin nomeado Exemplo.

Para desenvolver um plugin é preciso seguir algumas restrições do MantisBT.

Estrutura

O código-fonte do plugin deve ser inserido dentro de um diretório na estrutura de diretórios do MantisBT.

O local é mantis/plugins/

Dentro desse diretório deve-se criar um diretório com o nome do seu plugin

Neste exemplo, então, seria Exemplo

  • mantis/plugins/Exemplo

Todos os códigos fontes do plugin ficarão nesse diretório. Neste turorial trabalharemos partindo dele.

Desenvolvendo a classe

Crie um arquivo PHP com o nome do seu plugin.

  • Exemplo.php

Esse arquivo será o código-fonte de uma classe.

Note que o MantisBT exige que essa classe herde a classe MantisPlugin e também que o nome do plugin seja (NomeDoPlugin)Plugin, ou seja, contenha Plugin no final. Portanto, o código fonte seria assim:

Exemplo.php
<?php
  class ExemploPlugin extends MantisPlugin{
 
  }
?>

Essa classe obrigatóriamente deve conter a função register(), responsável por armazenar as informações do plugin. As informações são:

  • name (O nome do plugin) Obrigatório;
  • description (Descrição do plugin);
  • page (A página inicial do plugin. Veremos páginas mais à frente);
  • version (Versão do plugin) Obrigatório;
  • requires (Dependências. Deve ser passado um array com a dependência e o valor)
    • Ex:
       $this->requires = array( 'MantisCore' => '1.2.0, <= 1.2.0' );); 
  • author (Autor do plugin);
  • contact (e-mail do autor(es));
  • url (Página de suporte do plugin).

No nosso exemplo

Exemplo.php
<?php
  class ExemploPlugin extends MantisPlugin{
    function register() {
      $this->name = 'Exemplo';
      $this->description = 'Apenas um plugin de exemplo';
      $this->page = 'inicio.php';
      $this->version = '1.0';
      $this->requires = '';
      $this->author = 'Seu nome';
      $this->contact = 'seuemail@email.com';
      $this->url = 'http://www.suapagina.com';
    }
  }
?>

Com isso já é possível instalar e desinstalar o nosso plugin livremente

Para testar acesse o MantisBT como Administrador,Então:

  • Gerenciar → Gerenciar Plugins

Se em algum momento for solicitada a senha novamente, então digite-a.

O plugin deve estar disponível da parte de baixo do site, em Plugins Disponíveis.

Instale o plugin para continuarmos com o tutorial.

Páginas do plugin

Para esta parte do tutorial, entende-se página como um arquivo PHP, enquanto HTML, CSS, etc. entende-se como arquivo.

As páginas do plugin devem ficar em um diretório pages partindo do diretório do plugin

  • Exemplo/pages

Dentro desse diretório então podemos criar a nossa página inicial, definida anteriormente

inicio.php
<?php
  echo "Hello world!";
?>

Acesse essa página clicando no link sobre o seu plugin instalado

Note que a URL da página ficou como

  • plugin.php?page=Exemplo/inicio.php

Ou seja

  • plugin.php?page=(NomeDoPlugin)/(PaginaDoPlugin).

O diretório pages deve ser usado apenas para páginas PHP. Se quisermos, por exemplo, adicionar um arquivo CSS, temos um outro diretório chamado files.

  • Exemplo/files

No nosso exemplo criaremos uma folha de estilo (CSS) para a nossa página inicio.php

estilo.css
p{
  color:#FF0000;
}
inicio.php
<?php
  echo "<link rel='stylesheet' type='text/css' href='" . plugin_file( 'estilo.css' ) . "'/>";
  echo "<p>Hello world!</p>";
?>

Note que a função plugin_file foi utilizada. Essa função retorna o endereço de um arquivo. No nosso exemplo acima então, retorna o endereço da folha de estilo estilo.css;

  • /mantis/plugin_file.php?file=Exemplo/estilo.css

Note que (aparentemente…) não é feita uma busca, mas sim uma formatação de texto, ou seja, se o arquivo não exisitir esse valor é retornado da mesma forma.

Do mesmo modo podemos procurar por uma página utilizando a função plugin_page dessa forma:

inicio.php
<?php
  echo "<link rel='stylesheet' type='text/css' href='" . plugin_file( 'estilo.css' ) . "'/>";
  echo "<p>Hello world!</p>";
  echo "<a href='". plugin_page('inicio.php') ."'>Eu mesmo!</a>";
?>

Igual ao plugin_file, essa função retorna o endereço, existindo a página ou não.

Até então a página do plugin deve estar apenas com uma pequena quantidade de texto. Para adicionarmos o cabeçalho e o rodapé padrão do MantisBT temos as funções html_page_top() e html_page_bottom(), que servem para adicionar o cabeçalho e o rodapé, respectivamente.

A função html_page_top() aceita uma String como parâmetro para o título da página

inicio.php
<?php
  html_page_top('Tela de teste');
  echo "<link rel='stylesheet' type='text/css' href='" . plugin_file( 'estilo.css' ) . "'/>";
  echo "<p>Hello world!</p>";
  echo "<a href='". plugin_page('inicio.php') ."'>Eu mesmo!</a>";
  html_page_bottom();
?>

Init

Assim como a função register(), a função init é executada após o carregamento do plugin. Veremos um exemplo dele na parte Eventos.

Eventos

Entenda evento como alguma ação.

Por ser uma classe, o seu plugin pode ter os seus métodos.

Esse métodos são acionados através de EVENTOS, ou seja, um evento será alguma ação que irá ativar uma função.

Podemos usar eventos declarados por nós ou então eventos do core do Mantis, que serão listados no final deste tutorial.

No nosso exemplo, utilizaremos um evento do core do Mantis para adicionar a página do nosso plugin no Menu principal, e acionaremos no método init():

Exemplo.php
<?php
  class ExemploPlugin extends MantisPlugin{
    function register() {
      $this->name = 'Exemplo';
      $this->description = 'Apenas um plugin de exemplo';
      $this->page = 'inicio.php';
      $this->version = '1.0';
      $this->requires = '';
      $this->author = 'Seu nome';
      $this->contact = 'seuemail@email.com';
      $this->url = 'http://www.suapagina.com';
    }
 
    function init(){
      plugin_event_hook( 'EVENT_MENU_MAIN', 'adicionar_menu' );
    }
 
    function adicionar_menu(){
      $array_menu[0] = "<a href='" . plugin_page('inicio') . "'>Exemplo</a>";
      return $array_menu;
    }
  }
?>

No exemplo acima ligamos a função adicionar_menu() ao evento EVENT_MENU_MAIN, que é executado ao exibir o menu principal. Lembrando que esse método é do core do MantisBT, por isso não precisamos declará-lo.

A função plugin_event_hook serve para ligar funções à eventos, ou seja, ao ocorrer aquele evento, tal função é executada.

Podemos ainda declarar os nossos próprios eventos. Para isso é necessário apenas passar como parâmetro o nome e o tipo de evento. No nosso exemplo usaremos um evento EVENT_EXEMPLO_IMPRIMIR do tipo EVENT_TYPE_OUTPUT.

Exemplo.php
<?php
  class ExemploPlugin extends MantisPlugin{
    function register() {
      $this->name = 'Exemplo';
      $this->description = 'Apenas um plugin de exemplo';
      $this->page = 'inicio.php';
      $this->version = '1.0';
      $this->requires = '';
      $this->author = 'Seu nome';
      $this->contact = 'seuemail@email.com';
      $this->url = 'http://www.suapagina.com';
    }
 
    function init(){
      plugin_event_hook( 'EVENT_MENU_MAIN', 'adicionar_menu' );
    }
 
    function events() {
      return array(
        'EVENT_EXEMPLO_IMPRIMIR' => EVENT_TYPE_OUTPUT
      );
    }
 
    function adicionar_menu(){
      $array_menu[0] = "<a href='" . plugin_page('inicio') . "'>Exemplo</a>";
      return $array_menu;
    }
  }
?>

O evento foi declarado na função events(), e retorna um array onde chave = Nome do evento e valor = tipo do evento.

Note também que o nome do evento foi EVENT_(NOME_DO_PLUGIN)_(EVENTO), não é obrigatório o uso dessa nomenclatura mas é recomendável para evitar conflitos com outros plugins.

Veremos esse evento em ação em HOOKS.

Os tipos de evento definidos pelo core são:

EVENT_TYPE_EXECUTE

São os tipos mais simples. Não recebem parâmetros e não retornam valor.

EVENT_TYPE_OUTPUT

Pra quando algo for ser exibido ao usuário

EVENT_TYPE_CHAIN

Um evento que ocorre na forma “Corrente”. Significa que vários métodos serão executados em um sequência para que o útlimo dela retorna algum valor.

Pode-se enviar um parâmetro para a primeira função para que a última retorne o valor tratado.

EVENT_TYPE_DEFAULT

O tipo mais genérico. O parâmetro passado é incluido diretamente na função que é chamada, e o resultado final é armazenado em um array. A chave desse array é o nome da função e o nome do plugin. Esse array, então, é retornado.

Hooks

São quem liga os eventos às funções. Um exemplo acima já foi exibido, onde a função adicionar_menu() é ligada ao evento EVENT_MENU_MAIN.

Aqui então criaremos um método para imprimir um valor e o ligaremos ao evento que criamos anteriormente, o evento EVENT_EXEMPLO_IMPRIMIR:

Exemplo.php
<?php
  class ExemploPlugin extends MantisPlugin{
    function register() {
      $this->name = 'Exemplo';
      $this->description = 'Apenas um plugin de exemplo';
      $this->page = 'inicio.php';
      $this->version = '1.0';
      $this->requires = '';
      $this->author = 'Seu nome';
      $this->contact = 'seuemail@email.com';
      $this->url = 'http://www.suapagina.com';
    }
 
    function init(){
      plugin_event_hook( 'EVENT_MENU_MAIN', 'adicionar_menu' );
    }
 
    function events() {
      return array(
        'EVENT_EXEMPLO_IMPRIMIR' => EVENT_TYPE_OUTPUT
      );
    }
 
    function hooks() {
      return array(
        'EVENT_EXEMPLO_IMPRIMIR' => 'imprimir'
      );
    }
 
    function adicionar_menu(){
      $array_menu[0] = "<a href='" . plugin_page('inicio') . "'>Exemplo</a>";
      return $array_menu;
    }
 
    function imprimir( $p_event ){
      echo "<p> Testando um evento </p>";
    }
  }
?>
inicio.php
<?php
  html_page_top('Tela de teste');
  echo "<link rel='stylesheet' type='text/css' href='" . plugin_file( 'estilo.css' ) . "'/>";
  echo "<p>Hello world!</p>";
  echo "<a href='". plugin_page('inicio.php') ."'>Eu mesmo!</a>";
 
  event_signal('EVENT_EXEMPLO_IMPRIMIR');
 
  html_page_bottom();
?>

Neste exemplos nós:

Ligamos o evento EVENT_EXEMPLO_IMPRIMIR à função imprimir().

Implementamos a função imprimir(), que apenas exibe um texto na tela

Chamamos o evento e, consequentemente a função, usando a função event_signal( {NOME_DA_FUNCAO} ).

Note que o método imprimir precisa aceitar um parâmetro $p_event, por restrições do core sobre as funções que são chamadas por eventos.

Configurações

Podemos criar e utilizar configurações para o nosso plugin. Veja os exemplos:

Exemplo.php
<?php
  class ExemploPlugin extends MantisPlugin{
 
    function register() {
      $this->name = 'Exemplo';
      $this->description = 'Apenas um plugin de exemplo';
      $this->page = 'inicio.php';
      $this->version = '1.0';
      $this->requires = '';
      $this->author = 'Seu nome';
      $this->contact = 'seuemail@email.com';
      $this->url = 'http://www.suapagina.com';
    }
 
    function init(){
      plugin_event_hook( 'EVENT_MENU_MAIN', 'adicionar_menu' );
    }
 
    function events() {
      return array(
        'EVENT_EXEMPLO_IMPRIMIR' => EVENT_TYPE_OUTPUT
      );
    }
 
    function hooks() {
      return array(
        'EVENT_EXEMPLO_IMPRIMIR' => 'imprimir'
      );
    }
 
    function config() {
      return array(
        'Exemplo_Num' => '1',
      );
    }
 
    function adicionar_menu(){
      $array_menu[0] = "<a href='" . plugin_page('inicio') . "'>Exemplo</a>";
      return $array_menu;
    }
 
    function imprimir( $p_event ){
      echo "<p> Testando um evento </p>";
    }
  }
?>
inicio.php
<?php
  html_page_top('Tela de teste');
  echo "<link rel='stylesheet' type='text/css' href='" . plugin_file( 'estilo.css' ) . "'/>";
  echo "<p>Hello world!</p>";
  echo "<a href='". plugin_page('inicio.php') ."'>Eu mesmo!</a>";
 
  event_signal('EVENT_EXEMPLO_IMPRIMIR');
 
  $t_exemplo_num = plugin_config_get( 'Exemplo_Num' );
  echo "<form action='" . plugin_page('alterar_conf') . "' method='post'>
    <input type='text' name='Ex_Num' value='' />
    <input type='submit' value='Alterar'>
    </form>
  ";
 
  echo "O valor = " . $t_exemplo_num;
  html_page_bottom();
?>

Um arquivo novo

alterar_conf.php
<?php
  $novo_valor = gpc_get_string( 'Ex_Num' );
  if ( $novo_valor == "" ){
    plugin_config_delete( 'Exemplo_Num' );
  }
  else{
    plugin_config_set( 'Exemplo_Num', $novo_valor );
  }
 
  print_successful_redirect( plugin_page( 'inicio.php', true ) );
?>

Neste exemplo criamos em Exemplo.php a função config(), responsável por manter todas as configurações do nosso plugin. Note que as configurações são definidas por um array, onde a chave é o nome e o valor é o valor padrão da configuração.

Em inicio.php criamos um formulário para a alteração e exibição do valor dessa configuração. Para retornar o valor usamos a função plugin_config_get, passando como parâmetro o nome da configuração.

No formulário definimos que a propriedade action direciona para a página alterar_conf do plugin.

Ainda abaixo exibimos o valor da configuração.

Criamos uma nova página, a alterar_conf.php, responsável pela alteração do valor da configuração. Primeiramente ela recebe o valor do campo Ex_Num da página anterior. Em seguida verifica se está nulo.

Se o valor estiver nulo, então retorna a configuração para o valor padrão, usando a função plugin_config_delete.

Se o valor estiver preenchido então altera o valor da configuração usando a função plugin_config_set.

Por útlimo redireciona a página para inicio.php usando a função print_successful_redirect.

Idiomas

Podemos definir diversos idiomas para os textos exibidos no nosso plugin. Para o sistema de plugin do Mantis isso é feito através de arquivos de texto. As configurações sobre idioma são diretas do core do Mantis.

O idioma padrão é Inglês, então se é passado algum idioma que não existe, o idioma Inglês é atribuido.

Os arquivos de texto ficam no diretório lang partindo da raiz do nosso plugin.

  • Exemplo/lang

Dentro desse diretório deve ser criado um arquivo de texto com o nome strings_{idioma} substituindo {idioma} pelo idioma que ele representa.

No nosso exemplo deixaremos que o nosso texto Hello World na nossa página inicio.php seja alterado de acordo com o idioma selecionado pelo usuário.

Primeiro criaremos os arquivos de texto para os idiomas Português-Brasil e Inglês

strings_english.txt
<?php
  $s_plugin_Exemplo_HelloWorld = "Hello World!";
?>
strings_portuguese_brazil.txt
<?php
  $s_plugin_Exemplo_HelloWorld = "Ola mundo!";
?>
inicio.php
<?php
  html_page_top('Tela de teste');
  echo "<link rel='stylesheet' type='text/css' href='" . plugin_file( 'estilo.css' ) . "'/>";
  echo "<p>" . plugin_lang_get('HelloWorld') . "</p>";
  echo "<a href='". plugin_page('inicio.php') ."'>Eu mesmo!</a>";
 
  event_signal('EVENT_EXEMPLO_IMPRIMIR');
 
  $t_exemplo_num = plugin_config_get( 'Exemplo_Num' );
 
  echo "<form action='" . plugin_page('alterar_conf') . "' method='post'>
    <input type='text' name='Ex_Num' value='' />
    <input type='submit' value='Alterar'>
    </form>
  ";
  echo "O valor = " . $t_exemplo_num;
 
  html_page_bottom();
?>  

Os nomes das variáveis e dos arquivos devem ser respeitados conforme nos exemplos.

Nome do arquivo

  • strings_{lingua}.txt

Variáveis

  • $s_plugin_{nome_plugin}_{nome_string} = {valor_string}

Substituindo, é claro, o que está entre chaves {} pelo seu respectivo valor.

Para então, tratar o valor que será exibido na tela usamos a função plugin_lang_get passando como parâmetro o nome da String.

Código final do tutorial

Exemplo.php
<?php
   class ExemploPlugin extends MantisPlugin{
 
     function register() {
       $this->name = 'Exemplo';
       $this->description = 'Apenas um plugin de exemplo';
       $this->page = 'inicio.php';
       $this->version = '1.0';
       $this->requires = '';
       $this->author = 'Seu nome';
       $this->contact = 'seuemail@email.com';
       $this->url = 'http://www.suapagina.com';
     }
 
     function init(){
       plugin_event_hook( 'EVENT_MENU_MAIN', 'adicionar_menu' );
     }
 
     function events() {
       return array(
         'EVENT_EXEMPLO_IMPRIMIR' => EVENT_TYPE_OUTPUT
       );
     }
 
     function hooks() {
       return array(
         'EVENT_EXEMPLO_IMPRIMIR' => 'imprimir'
       );
     }
 
     function config() {
       return array(
         'Exemplo_Num' => '1',
       );
     }
 
     function adicionar_menu(){
       $array_menu[0] = "<a href='" . plugin_page('inicio') . "'>Exemplo</a>";
       return $array_menu;
     }
 
     function imprimir( $p_event ){
       echo "<p> Testando um evento </p>";
     }
   }
?>
inicio.php
<?php
  html_page_top('Tela de teste');
  echo "<link rel='stylesheet' type='text/css' href='" . plugin_file( 'estilo.css' ) . "'/>";
  echo "<p>" . plugin_lang_get('HelloWorld') . "</p>";
  echo "<a href='". plugin_page('inicio.php') ."'>Eu mesmo!</a>";  
 
  event_signal('EVENT_EXEMPLO_IMPRIMIR');
 
  $t_exemplo_num = plugin_config_get( 'Exemplo_Num' );
  echo "<form action='" . plugin_page('alterar_conf') . "' method='post'>
    <input type='text' name='Ex_Num' value='' />
    <input type='submit' value='Alterar'>
    </form>
  ";
  echo "O valor = " . $t_exemplo_num;
 
  html_page_bottom();  
?>
alterar_conf.php
<?php
  html_page_top('Tela de teste');
  echo "<link rel='stylesheet' type='text/css' href='" . plugin_file( 'estilo.css' ) . "'/>";
  echo "<p>" . plugin_lang_get('HelloWorld') . "</p>";
  echo "<a href='". plugin_page('inicio.php') ."'>Eu mesmo!</a>";
 
  event_signal('EVENT_EXEMPLO_IMPRIMIR');
 
  $t_exemplo_num = plugin_config_get( 'Exemplo_Num' );
  echo "<form action='" . plugin_page('alterar_conf') . "' method='post'>
    <input type='text' name='Ex_Num' value='' />
    <input type='submit' value='Alterar'>
    </form>
  ";
  echo "O valor = " . $t_exemplo_num;
 
  html_page_bottom();
?>
strings_english.txt
<?php
  $s_plugin_Exemplo_HelloWorld = "Hello World!";
?>
strings_portuguese_brazil.txt
<?php
  $s_plugin_Exemplo_HelloWorld = "Ola mundo!";
?>
estilo.css
p{
  color:#FF0000;
}

Funções utilizadas neste tutorial

Esta seção irá explicar cada uma das funções utilizadas neste tutorial da forma que foram utilizadas neste tutorial.

register()

Função responsável para armazenar informações sobre o plugin. Exemplo:

function register() {
  $this->name = 'Exemplo';
  $this->description = 'Apenas um plugin de exemplo';
  $this->page = 'inicio.php';
  $this->version = '1.0';
  $this->requires = '';
  $this->author = 'Seu nome';
  $this->contact = 'seuemail@email.com';
  $this->url = 'http://www.suapagina.com';
}

init()

É uma função que é executada quando o plugin é carregado.

events()

Determina os eventos do seu plugin. Os eventos chamam funções do seu plugin e podem ser executados de qualquer local, até mesmo de outro plugins.

Exemplo:

function events() {
  return array(
    'EVENT_EXEMPLO_IMPRIMIR' => EVENT_TYPE_OUTPUT
  );
}

hooks()

Função utilizada para ligar eventos à funções.

Exemplo:

function hooks() {
  return array(
    'EVENT_EXEMPLO_IMPRIMIR' => 'imprimir'
  );
}

config()

Define as configurações do seu plugin. Esta função declara as configurações e define o seu valor padrão. Exemplo:

function config() {
  return array(
    'Exemplo_Num' => '1',
  );
}

html_page_top($titulo)

Exibe o cabeçalho do MantisBT. O parâmetro $titulo é o título da página.

html_page_bottom()

Exibe o rodapé do MantisBT.

plugin_file($file)

Retorna uma string formatada com a URL do arquivo do plugin, definido no parâmetro $file.

plugin_page($page)

Retorna uma string formatada com a URL da página do plugin, definida no parâmetro $page.

plugin_lang_get($string)

Retorna uma string do arquivo de idiomas do plugin. A string é definida no parâmetro $string.

event_signal($nome_do_evento)

Executa um evento. O parâmetro $nome_do_evento é o nome do evento que será chamado. Isso é independente de plugin, uma vez que os eventos são registrados no core do MantisBT.

plugin_config_get( $nome_configuracao)

Retorna uma configuração do plugin, definida no parâmetro $nome_configuracao.

plugin_config_set( $nome_configuracao, $valor )

Define um valor para uma configuração do plugin. A configuração é indicada em $nome_configuracao, e o valor que será definido para ela é definido em $valor.

plugin_config_delete($nome_configuracao)

Apaga qualquer valor definido na configuração determinada em $nome_configuracao e restaura o valor padrão para ela.

gpc_get_string($nome_requisicao)

Recupera uma requisição por POST ou GET.

print_successful_redirect($local)

Redireciona para o local definido em $local.

Dicas

Incluindo arquivos (include)

Não é possível incluir arquivos pela função plugin_page, pois essa função retorna uma string de uma única página. O que difere as páginas desse plugin é um parâmetro que também é retornado pela função.

Sendo assim, para incluir um arquivo em uma página do seu plugin simplesmente faça:

include_once( dirname(__FILE__) . DIRECTORY_SEPARATOR . 'seu_arquivo.php');

Sendo que 'seu_arquivo.php' é o arquivo que deseja incluir.

 
tut_plugin_mantis.txt · Última modificação: 2011/01/07 15:50 por denis.dantas
 
Exceto onde for informado ao contrário, o conteúdo neste wiki está sob a seguinte licença:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki