Você está na página 1de 12

Programando componentes para Joomla!

(parte 1)
Seg, 05 de Setembro de 2005 10:17 Matheus Mendes

Continuando a série de tutoriais que começaram com o Mambo 4.5.2 e agora continuarão para as versões do
Joomla! aqui está a primeira parte (de 3) explicando como fazer um componente para o recém-nascido CMS.

{mosauthorinfo} Este tutorial foi divido em 3 partes e pretende abordar os conceitos básicos da construção de um
simples (porém útil) componente para joomla. O exemplo utilizado será um componente de catálogo aonde o
administrador poderá enviar imagens através de um formulário e depois poderá cadastrar produtos e vincular um
produto a uma imagem (ou vários produtos a uma imagem). Esses produtos serão listados e haverá a
possibilidade do visitante selecionar quais ele tem interesse e depois envie um e-mail ao proprietário do site.
- Primeiro iremos abordar os aspectos básicos: o arquivo de instalação, as classes de banco de dados, arquivos
de controle, menus e design.
- Na segunda parte, iremos avançar um pouquinho e adicionaremos o recurso de envio de imagem e atribuição de
uma imagem a um produto.
- Na terceira e última parte, adicionaremos o recurso de ordenação e faremos um front-end para o nosso
componente.

É evidente que mesmo um tutorial longo como esse, não aborda todos os recursos que podem ser empregados em
um componente, mas a idéia é que se tenha um ponto de partida. Como em todos os outros tutoriais, a idéia não é
ensinar ninguém a programar em PHP pois há muito material na internet com esse propósito. O tutorial foi escrito
partindo do princípio de que o leitor está habituado com a programação PHP e quer começar a programar
componentes para joomla. (uma leitura prévia dos tutoriais anteriores é recomendável porém não é obrigatória).

Como a idéia é que ao final de cada parte você tenha um componente pronto para rodar para que você possa ver
o seu progresso, eu criei três componentes (um para cada etapa) e os aspectos já explicados não serão
abordados novamente.

Certo, vamos começar.

Este nosso primeiro componente conterá apenas arquivos básicos. O 'mínimo' necessário para se fazer um
componente descente para joomla (a idéia é fazer um componente que seja compatível com os padrões adotados
pela equipe de desenvolvedores e que seja fácil de manter)

Esta primeira parte conterá os seguintes arquivos:

- admin.pedidos.php - Arquivo que será chamado quando nosso componente for acessado na parte administrativa
do site. Este arquivo deverá controlar todas as ações do componente.
- admin.pedidos.html.php - Arquivo que conterá as telas do componente. O modo encontrado de separar o código
do design (as últimas versões do joomla já permitem que seja utilizado o patTemplate).
- pedidos.class.php - Este arquivo conterá as classes abstratas que ligarão o nosso componente ao banco de
dados.
- toolbar.pedidos.php - Assim como o admin.pedidos.php controla os eventos do componente. Este arquivo
controla os menus.
- toolbar.pedidos.html.php - Este arquivo conterá as chamadas dos menus para cada parte do menu e será
chamado pelo toolbar.pedidos.php.
- pedidos.xml - O arquivo responsável pela instalação, nele serão armazenadas todas as informações (arquivos,
imagens, sql, menus,...) que possibilitarão que o componente seja instalado.
- install.pedidos.php - Arquivo que será chamado ao final da instalação do componente.
- uninstall.pedidos.php - Arquivo que será chamado quando o componente for removido.

Não se preocupe em copiar e colar os códigos pois uma versão .zip do componente estará disponível para
download no final deste tutorial.

admin.pedidos.php

Este arquivo será o cérebro do nosso componente. Todas as ações que forem executadas na parte administrativa
referentes ao nosso componente, o joomla irá passar para este arquivo. Perceba que todas as ações são
direcionadas para este arquivo, ou seja, as variáveis serão utilizadas em diversas funções e as vezes com
propósitos diferentes (explico isso no decorrer do tutorial).

defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );


Se você já leu os outros tutoriais, você já sabe que esta linha garante que este arquivo não será acessado
diretamente. (esta constante é definida no index.php)

if (!($acl->acl_check( 'administration', 'edit', 'users', $my->usertype, 'components', 'all' )


| $acl->acl_check( 'administration', 'edit', 'users', $my->usertype, 'components', 'com_pedidos' ))) {
mosRedirect( 'index2.php', _NOT_AUTH );
}
O método acl_check do objeto $acl verifica se este usuário tem permissões para acessar este componente.

require_once( $mainframe->getPath( 'class' ) );


require_once( $mainframe->getPath( 'admin_html' ) );
Hora de incluír os arquivos pedidos.class.php e admin.pedidos.html.php pois eles serão utilizados no decorrer do
código. Esses métodos padronizam a inclusão dos arquivos porém nada proíbe que esta inclusão seja feita da
maneira manual ( require_once( $mosConfig_absolute_path . "/administrator/".....).

$task = mosGetParam( $_REQUEST, 'task', '' );


A variável task irá conter a ação que foi passada para o componente. É esta variável que dirá o que o componente
deve fazer.

$cid = mosGetParam( $_REQUEST, 'cid', array(0) );


A variável cid será um vetor com eventuais id's que serão passados. Ela é utilizada principalmente quando o
usuário quiser apagar mais de um ítem em uma lista.

$id = $cid[0] ? $cid[0] : mosGetParam($_REQUEST, 'id', 0);


A variável normalmente será a primeira posição do $cid ou pode ser passada diretamente com o nome de id. Eu
prefiro separar (para facilitar a programção) o que vai ser vetor e o que vai ser variável com apenas uma posição.

O bloco a seguir determina quais as ações o nosso componente terá. (nas próximas partes você verá que este
bloco será incrementado conforme o nosso componente possuir mais funcionalidades (dã!). Por enquanto só
temos a parte do produto. Então vamos lá (como o bloco está bem comentado, não irei me ater a comentar linha-a-
linha pois a única coisa que ele faz é chamar as funções que terão responsabilidade sobre as ações):

switch ( $task ) {
/* - - - P R O D U T O S - - - */
/* listar produtos */
case 'list_produtos':
list_produtos( $option );
/* para o list só preciso passar o nome do meu componente. */
break;
/* inserir produto */
case 'new_produtos':
mnt_produtos( 0, $option );
/* um novo produto, nada mais é do que a edição de um produto com o id zero. Ou seja,
se eu passar um id que não existe, o joomla irá criá-lo. */
break;
/* manutenção de produtos (alterar) */
case 'mnt_produtos':
mnt_produtos( $id, $option );
/* estou passando o valor $id (veja que este valor foi resgatado no início do código) */
break;
/* armazenar no banco, os dados de um produto. */
case 'save_produtos':
save_produtos( $option );
/* por que não estou passando o id que eu quero salvar?! :D depois eu te conto. */
break;
/* apagar um ou mais produtos */
case 'rm_produtos':
rm_produtos( $cid, $option );
/* veja que estou usando $cid pois poderá ser mais de um id ;P */
break;
}
Agora que já sei o que eu devo fazer... vamos ver COMO fazer. A primeira situação de acordo com o nosso switch é
listar os produtos já cadastrados. (é interessante manter a mesma ordem das funções para facilitar a manutenção)

function list_produtos( $option ) {


global $database, $mainframe;

O objeto $database contém as informações referentes ao banco de dados. e do objeto $mainframe nós iremos
utilizar os métodos para construir a nossa paginação (esta classe possui diversos métodos úteis para a
programação
de componentes)

// Bloco de paginação e navegação.


$limit = $mainframe->getUserStateFromRequest( "viewlistlimit", 'limit', 10 );
$limitstart = $mainframe->getUserStateFromRequest( "view{$option}limitstart", 'limitstart', 0 );
$database->setQuery( "SELECT COUNT(*) FROM #__joomla_produtos" ); // nos outros tutoriais você entendeu o
que faz esta função
$total = $database->loadResult(); // este método joga o resultado (será apenas um campo na tabela) para dentro
da variável.
require_once( "includes/pageNavigation.php" );
$pageNav = new mosPageNav( $total, $limitstart, $limit );
// fim_paginação

Para construir a paginação da minha lista eu preciso fazer basicamente 4 coisas:


- Saber até qual registro eu tenho que ir a partir de onde eu estou. (último desta página)
- Saber aonde eu estou (em qual página)
- Saber quantos ítens eu tenho na minha lista.
- Criar um objeto da classe mosPageNav() e jogar o total, o último desta página e a posicao aonde eu estou
para ela. O joomla se encarrega do resto para que eu utilize na minha classe de design a na minha consulta
principal (logo a seguir)

$database->setQuery("SELECT * FROM #__joomla_produtos LIMIT $pageNav->limitstart,$pageNav->limit");


Vou selecionar só os dados que serão mostrados.

$arrProdutos = $database->loadObjectList();
Agora eu pego o resultado e jogo tudo pra dentro de um vetor que irá conter os dados dos produtos. (por
padrão, os elemtnso do vetor são tratados como objetos.

HTML_pedidos::html_list_produtos($arrProdutos, $option, $pageNav);


Agora que já tenho todos dados de que preciso para montar a minha tela, eu chamo o método da classe que
será responsável por montar esta tela (passando os dados que eu acabei de lavantar, é óbvio).
}

A segunda função fará a manutenção de produtos (por manutenção entenda inserção e edição). Ele vai trazer do
banco
os dados referente ao id que for passado para ela.
function mnt_produtos( $id=0, $option ) {
global $database; // novamente nosso objeto com as informações do banco.

$objProduto = new mosProdutos($database);


$objProduto->load($id);
Agora nós utilizamos uma das minhas classes favoritas. Uma classe (mosProdutos) que irá extender a
mosDBTable. A classe mosProdutos é extremamente simples pois ela só contém a estrutura da nossa tabela no
banco de dados. Quando eu disparo o método load(int $id); eu vou preencher os campos (atributos) desse meu
novo objeto com as informações referentes áquele id que foi passado. É como se eu executasse um select * from
TABELA e fizesse um laço para atribuir cada valor à sua respectiva variável. A diferença é que o joomla faz isso
para mim (e não para por aí, como você verá mais adiante)

$lista = array(); // bom, eu esqueci de tirar a parte das imagens daqui. Isso será visto no segundo tutorial.

HTML_pedidos::html_mnt_produtos( $objProduto, $option, $lista );


Agora que já levantei todos os dados que eu preciso para *montar* a tela de manutenção (no nosso caso foi
só o $objProduto, eu posso jogar tudo para a nossa tela de design (que está no arquivo admin.pedidos.html.php e
será explicada mais tarde)
}

Pronto, agora que já montei as telas que listam os ítens já inscritos, e a tela de manutenção, está faltando a função
que irá salvar os dados que foram digitados na tela de manutenção montada acima. E esta função é extremamente
fácil de ser implementada:

function save_produtos( $option ) {


global $database; // nem preciso mais explicar esse objeto né?

$obj = new mosProdutos( $database );


Vou montar mais um objeto com a mesma estrutura da minha tabela no banco de dados para apresentar mais
umas funções muito legais da classe mosDBTable (você verá mais tarde que a classe mosProdutos extende a
mosDBTable)

if (!$obj->bind( $_POST )) {
echo "<script> alert('".$obj->getError()."'); window.history.go(-1); </script>n";
exit();
}
Bom, o método bind(array) vai 'ligar' cada atributo do objeto ao valor da chave de um array (associativo),
exemplo, o $obj->id valerá $_POST['id']. (note que ligar não quer dizer que esta informação já foi armazenada no
banco)

if (!$obj->check()) {
echo "<script> alert('".$obj->getError()."'); window.history.go(-1); </script>n";
exit();
}
O método check é chamado após o bind() para verificar se deu tudo certo na hora de ligar o objeto ao vetor.
Na verdade este método existe para ser sobreescrito pelas classes que herdem a mosDBTable para verificar a
consistência do objeto aonde as informações foram carregadas.

if (!$obj->store()) {
echo "<script> alert('".$obj->getError()."'); window.history.go(-1); </script>n";
exit();
}
Agora sim, pego o objeto ($obj) e armazeno este objeto no meu banco de dados. (insert? update? nããoo..
deixa o joomla cuidar disso!) Lembre-se que ele sabe a qual tabela inserir pois estamos usando o objeto da classe
mosProdutos e como você verá mais adiante, esta classe já contém essas informações.

mosRedirect("index2.php?option=$option&task=list_produtos" );
Pronto! Agora eu redireciono o usuário para uma página qualquer. Normalmente é a página do LIST pois a
função save é sempre chamada pela manutenção (veja a explicação dos menus mais tarde) e o usuário vai querer
ver o novo ítem que foi inserido!

Certo. Recapitulando: Já listamos, modificamos, inserimos e atualizamos os ítens. O que está faltando? Apagar :P
Então vamos à nossa função que irá apagar um *vetor* de ítens (como faremos um checkbox ao lado do list, o
número de ítens a serem apagados poerá ser mais de um).

function rm_produtos ( $cid, $option ) {


global $database;

if (!is_array( $cid ) || count( $cid ) < 1) {


echo "<script> alert('Selecione um ítem para apagar'); window.history.go(-1);</script>n";
exit;
}

if (count( $cid )) {
$cids = implode( ',', $cid );
Utilizo a função 'implode' pois preciso transformar meu vetor em uma string separada por vírgulas para
poder fazer toda a exclusão em um sql apenas.
$query = "DELETE FROM #__joomla_produtos"
. "n WHERE id IN ($cids)" ;
essa será minha sql.
$database->setQuery( $query );
ainda não executei! Apenas passei a minha string que será a sql, para o objeto do banco de dados.
if (!$database->query()) {
echo "<script> alert('".$database->getErrorMsg()."'); window.history.go(-1); </script>n";
}
agora sim. Acabou-se o que era doce. Os ítens foram excluídos.
}

mosRedirect("index2.php?option=$option&task=list_produtos" );
Agora redirecionamos o nosso usuário para uma tela amigável (de preferência aonde ele possa ver o efeito de
sua última ação)
}

Pronto! O Cérebro de nosso componente está feito. Vamos nos preocupar um pouco com as telas agora

Você deve ter notado que por diversas vezes nós chamamos uma classe abstrata HTML_pedidos e você
provavelmente ficou se perguntando o que ela faz não é? Pois bem, ela será a responsável por receber os dados e
desenhar as telas da parte administrativa do nosso componente. Sim, só isso. Ela existe para deixar mais fácil (ou
menos difícil) a vida dos designers.

Uma observação é que hoje em dia já é possível utilizar patTemplates para separar completamente o layout dos
códigos.

Vamos criar, então, o nosso segundo arquivo: admin.pedidos.html.php

class HTML_pedidos {
essa é a classe que conterá as telas. As funções são bastante simples e não contém nada que um programador
acostumado com php não entenda. Vou dar atenção apenas as partes importantes.
function html_list_produtos( $rows, $option, $pageNav ) {
Esta função é responsável pela tela de lista de produtos. Ela está recebendo três variáveis:
$rows : um vetor de objetos que contem as informações que serão mostradas.
$option : o nome do nosso componente. Será utilizada para fazer os links e as páginas do redirecionamento
$pageNav : um objeto que ficará responsável por construir a paginação de resultados (deixe o joomla cuidar
disso)

<form method="post" action="" name="adminForm">


<input type="hidden" name="option" value="<?php echo $option;?>" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="boxchecked" value="0" />
<input type="hidden" name="hidemainmenu" value="0">

<table width="100%" border="0" class="adminheading">


<tr>
<th>Produtos</th>
</tr>
</table>
<br>
<table width="100%" border="0" class="adminlist">
<tr>
<th>#</th>
<th width="20"> <input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count( $rows ); ?
>);" />
</th>
<th class="title">Nome</th>
<th><div align="center">Ativo:</div></th>
<th><div align="center">Vendido:</div></th>
</tr>

A única coisa a se prestar atenção neste trecho é o nome do formulário: 'adminForm' que é obrigatório. '<th>'
foram utilizados pois eles contém os estilos para deixar o componente no padrão do joomla. Agora veremos o laço
principal:
$k = 0;
for ($i=0, $n=count( $rows ); $i < $n; $i++) {
$row = &$rows[$i];
$link = 'index2.php?option='.$option.'&task=mnt_produtos&hidemainmenu=1&id='. $row->id;

o $link diz respeito à ação que será executada quando a palavra for clicada. Veja que no nesse caso
a $task irá valer 'mnt_produtos'. hidemainmenu=1 significa que o menu principal deverá ser escondido quando a
ação for executada, em funções de manutenção você esconde o menu (na nova versão ele será apenas
desabilitado).

$checked = mosCommonHTML::CheckedOutProcessing( $row, $i );

Vamos utilizar esse metodozinho da API do joomla que verifica se o ítem está ou não sendo editado
por outro usuário. Na verdade este ítem não é utilizado nesta primeira parte do componente pois ainda não
implementamos o recurso de 'bloquear' um ítem para outros usuários.

?>
<tr class="<?php echo "row$k"; ?>">
<td align="center">
<?php echo $pageNav->rowNumber( $i ); ?>
</td>
<td align="center">
<?php echo $checked; ?>
</td>
<td>
<a href="<?php echo $link; ?>" title="Editar produto">
<?php echo $row->titulo; ?>
</a>
</td>
<td align="center">
<div align="center"><a href="javascript: void(0);" onclick="return listItemTask('cb<?php echo $i;?>','<?php echo
$task;?>')">
<img src="images/<?php echo $img;?>" width="12" height="12" border="0" alt="<?php echo $alt; ?>" />
</a>
</div></td>

<td width="65" align="center">


<div align="center"><a href="#<?=$taske;?>" onclick="return listItemTask('cb<?php echo $i;?>','<?php echo
$taske;?>')">
<img src="images/<?php echo $imge;?>" width="12" height="12" border="0" alt="" /></a></div>
</td>
</tr>
<?
$k = 1 - $k;
} ?>
</table>
<?php echo $pageNav->getListFooter(); ?>
Por fim, construímos a navegação.
</form>

Agora vamos cuidar da tela de manutenção. Esta tela será um formulário normal, a única diferença são alguns
campos hidden e modo com que o editor WYSIWYG será chamado.

function html_mnt_produtos (&$linha , $option, $imagens) {


?>
a nossa função recebe três parâmetros:
$linha - as informações do produto (lembre que manutenção não é apenas inserção...
$option - o nome do nosso componente
$imagens - O combobox com a lista das imagens (será utilizado na segunda parte desse tutorial)

<script language="javascript" type="text/javascript">


function submitbutton(pressbutton) {
var form = document.adminForm;
if (pressbutton == "cancel") {
submitform( pressbutton );
return;
}
<? getEditorContents('desc','descricao'); ?>
submitform( pressbutton );
}
</script>
<form action="index2.php" method="post" name="adminForm" id="adminForm" class="adminForm">
<input type="hidden" name="option" value="<?php echo $option;?>" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="hidemainmenu" value="0">
<input type="hidden" name="id" value="<?php echo $linha->id; ?>" />

Aqui estão os nossos campos hidden que servirão de controle para o joomla. O campo 'option' irá armazenar o
nome do nosso componente (foi passado para a função), precisamos de um campo 'task' que será manipulado
pelo menu (veremos isso depois), o campo hidemainmenu fará o controle do menu, hidemainmenu 0, quer dizer
que na próxima tela, o menu principal será mostrado. Finalmente, o campo ID contém o id do ítem que está sendo
editado. Quando estivermos inserindo um novo ítem, este campo será nulo. O restante é um formulário normal....

<table width="90%" class="adminheading">


<tr>
<td width="21%" rowspan="2" valign="bottom"><div align="right">T&iacute;tulo/nome:
</div></td>
<td width="53%" rowspan="2" valign="bottom"><input name="titulo" type="text" id="titulo" value="<?php echo
$linha->titulo; ?>" size="50" maxsize="100" /></td>
<td width="26%" valign="bottom">&nbsp;</td>
</tr>
<tr>
<td valign="bottom">&nbsp;</td>
</tr>
<tr>
<td><div align="right">Pre&ccedil;o:</div></td>
<td colspan="2">R$
<input name="preco" value="<?php echo $linha->preco; ?>" type="text" id="preco" size="20" maxlength="20">
</td>
</tr>
<tr>
<td><div align="right">Imagem:</div></td>
<td colspan="2"><?php echo $imagens; ?></td>
</tr>
<tr>
<td><div align="right">Descri&ccedil;&atilde;o:</div></td>
<td colspan="2">
<?php
// parametros : areaname, content, hidden field, width, height, rows, cols
editorArea( 'desc',$linha->descricao, 'descricao', '500', '200', '70', '10' ) ;

Aqui mais uma diferença, estamos chamando o editor para dar mais possibilidades de formatação de
texto para o nosso usuário. note que o segundo parâmetro é o conteúdo que estará no editor.

?>
</td>
</tr>
</table>
</form>

<?
}

Pronto. Aí está a 'cara' do nosso componente. O próximo passo é fazer a classe que fará a interface com o banco
de dados.
A classe que irá manipular a maior parte dos nossos dados é bastante simples, ela apenas irá extender a classe
mosDBTable do joomla que contém os métodos importantes. Vamos lá.

arquivo pedidos.class.php

class mosProdutos extends mosDBTable {


var $id = null;
var $titulo = null;
var $preco = null;
var $descricao = null;
var $checked_out = null;
var $checked_out_time = null;

cada campo da minha tabela foi transformado em uma variável. Isso é muito importante para o bom funcionamento
do seu
componente.

function mosProdutos( &$db ) {


$this->mosDBTable( 'jos_joomla_produtos', 'id', $db );
}

no construtor, eu chamo o método principal da mosDBTable passando para ela o nome da tabela, qual é a
chave primária e passo o objeto que contém a conexão com o banco de dados (normalmente é o objeto
$database)

Simples não? Agora vamos brincar um pouco com os menus.

O funcionamento dos menus no joomla é bastante simples pois a api já está toda pronta e você só precisa informar
os parâmetros. Bom, como já foi dito, para manipular os menus vamos precisar de dois arquivos (na verdade não
são obrigatórios os dois arquivos, mas como estamos fazendo um componente dentro do padrão do joomla, iremos
utilizar os mesmos procedimentos que os membros do core utilizam).

arquivo toolbar.pedidos.php

Este arquivo será chamado automaticamente junto com a parte administrativa do nosso componente. Ele também
receberá o conteúdo da variável $task (na verdade ele receberá o conteúdo de todas as variáveis que forem
passadas ao componente... mas utilizaremos apenas a $task) e irá disparar os métodos da classe abstrata
menuPEDIDOS. Esta classe conterá os botões propriamente ditos.

switch($task) {
/* produtos */
case 'list_produtos':
menuPEDIDOS::LIST_PRODUTOS();
break;
case 'new_produtos':
case 'mnt_produtos':
menuPEDIDOS::MNT_PRODUTOS();
break;
}

Como você pode perceber, para menus nós temos apenas duas opções que são as duas telas... Um dos menus irá
mostrar os botões quando estamos mostrando a lista de produtos e outro irá mostrar os botões para quando
estivermos editando ou criando um novo ítem. Bastante simples né? Ok, última parte da criação de menus! here we
goOoOOo!

Lembra que nós fizemos um arquivo separado para as 'telas' dos formulários? Este aqui, são as 'telas' dos menus.
Mas não vamos precisar inserir nada de código HTML nele pois já está tudo na API, só vamos usar. Nesta primeira
etapa, vamos criar menus simples.
arquivo: toolbar.pedidos.html.php

class menuPEDIDOS {
function LIST_PRODUTOS() {
mosMenuBar::startTable();

o método startTable() inicia a tabela que irá conter os menus. Como você pode ver, há também um
método chamado endTable() e acho que você já entendeu o que ele fará xD

mosMenuBar::addNewX('new_produtos');

O método addNew desenha o botão padrão do joomla para ítens novos. e estou passando um parâmetro
chamado 'new_produtos'. Este parâmetros será o valor da $task (lembre-se: tudo aponta para o index.php e é
controlado pela $task, ou seja, a ação que o componente executará quando este botão for clicado, será definida
dentro dos parênteses).

mosMenuBar::spacer();

este método desenha uma pequena coluna na vertical para separar os botões... perfumaria ;)

mosMenuBar::editListX('mnt_produtos');

O método editList é semelhante ao addNew, a diferença é o ícone que será utilizado.

mosMenuBar::spacer();
mosMenuBar::deleteList('','rm_produtos');

Veja que no metodo deleteList há um novo parâmetro, ele é opcional, eu coloquei aqui só para você
saber que existe. Ele é uma mensagem que poderá ser mostrada ao usuário. E o segundo parâmetro é a task.

mosMenuBar::spacer();
mosMenuBar::endTable();

Você notou que o método addNew e editList estão escritos com um X no final não é? Bom, isso foi
adicionado no mambo 4.5.2 e serve para alterar o estatus do hidemenu, um parâmetro que está escondido nos
formulários. É um controle para evitar que o usuário feche a janela sem salvar ou cancelar (causando aquele
inconveniente de você ter de ir lá e dar um global checkin - desbloqueio global, em português)
Você pode usar tanto com o 'X' como sem o X a única diferença é esse parâmetro que ele tenta trocar nos
formulários.
}

function MNT_PRODUTOS() {
mosMenuBar::startTable();
mosMenuBar::save('save_produtos');
mosMenuBar::spacer();
mosMenuBar::back();
mosMenuBar::spacer();
mosMenuBar::endTable();

ok.. nada novo aqui.


}

Finalmente, vamos criar dois arquivos extramente simples que serão chamados um na instalação e outro na
desinstalação. Estes arquivos são chamados após o componente ser instalado/desintalado. Normalmente só
contém uma mensagem explicativa (alguns componentes botam as SQL de criação de banco nesses arquivos. eu
prefiro usar a api do joomla para isso).

arquivo install.pedidos.php

function com_install() {
echo "Parte 1 - Componente Exemplo - by Matheus Teixeira Mendes - bigodines - http://www.joomla.com.br";
}

Sim.. é só isso! e o uninstall também não é muito diferente:

arquivo uninstall.pedidos.php

function com_uninstall() {
echo "Parte 1 - Componente Exemplo - by Matheus Teixeira Mendes - bigodines - http://www.joomla.com.br";
}

na verdade a única coisa que trocou foi o nome da função (e do arquivo, óbvio).

Bom, agora nosso componente está quase pronto. Só falta fazer o arquivo de instalação para que o joomla saiba o
que criar, aonde e quais os bancos serão necessários. Talvez um dos recursos mais impressinoantes do joomla
seja a facilidade de instalar novos componentes. Como você já leu os outros tutorias (o de criação de módulos e
de mambots) você já está familiarizado com muitas das informações deste arquivo. Vou me ater apenas às
novidades. Por favor, quem ainda não leu os outros tutoriais, as explicações sobre o que faz cada parte do xml
podem ser encontradas lá.

<?xml version="1.0" encoding="ISO-8859-1"?>


<mosinstall type="component">
Primeira mudança: temos de dizer ao joomla que estamos instlando um 'component'

<name>Pedidos</name>
<creationDate>May, 2005</creationDate>
<author>Matheus Mendes (bigodines)</author>
<copyright>This software was released under comercial license.</copyright>
<authorEmail> matheus@metasig.com.br</authorEmail>
<authorUrl>http://www.joomla.com.br</authorUrl>
<version>Tutorial</version>
as informações gerais.. como sempre aqui o nome, o autor, site, versão.. e-mail e essa coisa toda.

<files>
<filename>pedidos.class.php</filename>
</files>

aqui vai uma lista dos arquivos que deverão ser copiados para dentro do servidor. Aqui ficam os arquivos que
irão para a pasta /componentes/com_seu_componente/*. Os que vão para a parte administrativa, vão mais abaixo.

A seguir, começa o bloco de instalação. Aqui, listamos os comandos sql que farão a criação das novas
tabelas. Devemos separar cada comando dentro de uma <query> O número de queries é ilimitado.
<install>
<queries>
<query>
DROP TABLE IF EXISTS `#__joomla_produtos`;
</query>
<query>
CREATE TABLE `jos_joomla_produtos` (
`id` int(11) NOT NULL auto_increment,
`titulo` varchar(100) default NULL,
`preco` varchar(30) default '00,00',
`descricao` text NOT NULL,
`checked_out` int(11) default '0',
`checked_out_time` datetime default '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
);
</query>
</queries>
</install>

E quando formos desintalar este componente, devemos dizer ao joomla quais comandos devem ser
executados (temos que eliminar as tabelas que criamos)
<uninstall>
<queries>
<query>
DROP TABLE IF EXISTS `#__joomla_produtos`;
</query>
</queries>
</uninstall>

Depois nós temos de avisar ao joomla qual será o arquivo que irá coordenar a instalação e qual deverá ser
chamado para desinstalar. Esses arquivos são bem simples... o joomla cuida de tudo para nós.
<installfile>
<filename>install.pedidos.php</filename>
</installfile>
<uninstallfile>
<filename>uninstall.pedidos.php</filename>
</uninstallfile>

Agora sim, vamos cuidar da parte administrativa. O primeiro passo é dizer qual o menu será criado e quais os
submenus ele conterá
<administration>
<menu>Pedidos de orçamento - Parte 1</menu>
<submenu>
<menu task="list_produtos">Produtos</menu>
o parametro 'task' quer dizer que quando este submenu for clicado, a variável $task deverá receber
'list_produtos'. Posso ter vários menus dentro do submenu. Nunca tentei com mais de dois níveis, não creio que
seja possível.
</submenu>

Agora eu digo quais os arquivos deverão ser copiados para dentro do


administrator/components/com_seu_compoente/* preciso listar TODOS os arquivos que deverão ser copiados e
não apenas os .php (no nosso caso, só temos php :D )
<files>
<filename>admin.pedidos.php</filename>
<filename>admin.pedidos.html.php</filename>
<filename>toolbar.pedidos.php</filename>
<filename>toolbar.pedidos.html.php</filename>
</files>
</administration>
</mosinstall>

pronto... rápido e indolor. Espero que todo mundo tenha entendido a idéia.

Para ver como o componente ficou, faça o download do zip na próxima página. Não esqueça de ler as
considerações finais;

Bom amigos, com esta série de tutoriais iremos cobrir a parte mais importante do desenvolvimento para joomla!
gostaria de receber o retorno de vocês que leram até aqui para que possa melhorar ou continuar o trabalho para
os próximos tutoriais. Estou direto no http://forum.opensourcematters.org (provavelmente já deve haver uma thread
falando sobre esse tutorial lá) e a sua opinião é importante.

Este tutorial está sendo lançado num momento de turbulência (troca do nome, novo logo, slogan, domínio e tudo
mais), como eu comecei a escrever quando o Joomla! ainda era Mambo, os fontes do .zip estão todos
referenciando ao nome antigo. Peço desculpas por isso.

Gostaria de agradecer ao Ronildo que mantém o joomla.com.br atualizado, à equipe de tradução (especialmente
ao Fabio, Marcelo e Fabrício) que estão sempre dando idéias e colaborando com a nossa comunidade (a equipe
de tradução tem mais gente, mas os 'macacos-velhos' merecem um agradecimento especial. Outro agradecimento
para todo o pessoal que participa do http://forum.opensourcematters.org (em especial àqueles que não fazem só
perguntas e que tentam dar a sua contribuição para a comunidade).

Finalmente algumas explicações: Esse texto foi feito ao longe de 15-20 dias. Usando alguns minutos do tempo
livre que eu tinha por dia. Portanto, muitas partes podem estar redundantes. Perdoe-me por isso. Aproveita que
está perdoando e perdoe-me pelos erros de português (eu faço computação, não faço letras!).
Bom, faça o download dessa nossa primeira parte do nosso componente. Vejo você na segunda parte. Não
esqueça de avaliar este texto! CLIQUE AQUI

Até lá pessoal.

Para de usar, comece a participar!!

Você também pode gostar