Menu em ExtJS com Permissões usando PHP e Mysql
Uma das coisas que mais me deu dor de cabeça quando comecei a trabalhar com ExtJS foi montar uma estrutura de Menu Dinâmico de acordo com as permissões do usuário logado. Por isso vou compartilhar minha solução:
Primeiro de tudo vamos criar o nosso banco de dados. Vamos precisar de duas tabelas: uma para o nosso menu e outra com as permissões de cada usuário.
A tabela do Menu terá os campos de id (o id do objeto no Extjs para facilitar manipulação posterior), o nome, o ícone, a pai (caso exista), a ordem e é claro a função que será chamada na ação do clique. Na segunda tabela vamos ter apenas duas chave, o id do usuário e o id do menu. Segue abaixo de exemplo a que eu utilizei:
MySQL
# # Estrutura da Tabela Menu # CREATE TABLE /*!32312 IF NOT EXISTS*/ `menu` ( `id_menu` int(3) NOT NULL AUTO_INCREMENT, `id` varchar(20) DEFAULT NULL, `menu` varchar(70) DEFAULT NULL, `ordem` int(3) DEFAULT NULL, `pai` int(3) DEFAULT NULL, `ico` varchar(50) DEFAULT NULL, `funcao` varchar(80) DEFAULT NULL, PRIMARY KEY (`id_menu`) ) TYPE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; # # Estrutura da Tabela de Permissões # CREATE TABLE /*!32312 IF NOT EXISTS*/ `permissoes` ( `id_usuario` int(3) NOT NULL DEFAULT '0', `id_menu` int(3) NOT NULL DEFAULT '0', PRIMARY KEY (`id_menu`,`id_usuario`) ) TYPE=MyISAM DEFAULT CHARSET=latin1;
Dica: Vale lembrar que o ícone dos pais são definidos pelo nome da classe CSS e os filhos devemos especificar o caminho físico da imagem. Não sei por que, mas sub-menus não possuem o atributo “iconCls”. No PHP já vamos levar isso em conta.
A outra parte do nosso Menu é a montagem do Json que irá ser lido no ExtJS. Este método foi testado apenas com 1 sub-nível de menu, mas é fácil de modificar para funcionar com mais. Se alguém fizer, comente a experiência. O método é bem simples de entender. Basicamente buscamos os ítens do Menu principal e percorremos ele em busca de sub-menus alocando tudo em um array associativo.
PHP
private function trataObjJson($strJson,$arrObjs)
{
foreach($arrObjs AS $obj)
$strJson = str_replace("\"" . $obj . "\"",$obj,$strJson);
return $strJson;
}
public function getMenu()
{
if($this->Search("SELECT id_usuario FROM usuarios WHERE id_usuario=" . $_SESSION['id_usuario']))
{
$menu = "";
$tmpMenuPai = $this->Search("SELECT A.id_menu,id,menu,ordem,pai,ico,funcao FROM menu A JOIN permissoes B ON A.id_menu=B.id_menu WHERE A.pai=0 AND B.id_usuario=" . $_SESSION['id_usuario'] . " ORDER By A.ordem");
$i=0;
$funcoes = array();
foreach($tmpMenuPai AS $item)
{
$menu[$i]['text'] = $item['menu'];
$menu[$i]['iconCls'] = $item['ico'];
$menu[$i]['tabIndex'] = $i;
if($item['funcao']) {
$menu[$i]['id'] = $item['id'];
$menu[$i]['handler'] = $item['funcao'];
$funcoes[] = $item['funcao'];
}
$tmpMenuFilho = $this->Search("SELECT A.id_menu,menu,id,ordem,ico,funcao FROM menu A JOIN permissoes B ON A.id_menu=B.id_menu WHERE A.pai=" . $item['id_menu'] . " AND B.id_usuario=" . $this->_id . " ORDER By A.ordem");
$arrFilho = Array();
$j=0;
foreach($tmpMenuFilho AS $filho)
{
$arrFilho[$j]['text'] = $filho['menu'];
$arrFilho[$j]['icon'] = $filho['ico'];
if($filho['funcao']) {
$arrFilho[$j]['id'] = $filho['id'];
$arrFilho[$j]['handler'] = $filho['funcao'];
$funcoes[] = $filho['funcao'];
}
$j++;
}
if($arrFilho)
$menu[$i]['menu'] = $arrFilho;
$i++;
}
header("Content-Type: application/json");
echo $this->trataObjJson(json_encode($menu),$funcoes);
}
}
Observe que precisamos de um método auxiliar para tratar as funções. Isso se deve pelo fato da função json_encode do PHP colocar áspas em tudo, então para o ExtJS não interpretar nossa função como uma string e gerar um erro, utilizamos uma função para retira-las.
Agora que já temos a nossa estrutura de menu em Json, bastam poucas linhas em ExtJS para finalizar:
ExtJS
Ext.onReady(function(){
var conn = new Ext.data.Connection();
conn.request({
url: 'inc/php/menu.class.php',
success: function(a){Ext.getCmp('menuPrincipal').bottomToolbar.add(Ext.util.JSON.decode(a.responseText));},
failure: function(){Ext.MessageBox.alert('Erro', 'Erro ao carregar menu. Atualize a página.');}
});
});
Espero ter ajudado.
Hi Buddy,
Do you have any online demo about this article? It seems to be interesting but I’d like to see it in real action.
Thanks,
Kob
Along with online demo, I would also like to see the json string that gets generated. The php above seems to have lot of html entities and is difficult to really read
Muito bacana Marcos! Gostei dos posts sobre Ext. Quando quiser podemos trocar figurinhas (: abs!
Marcos muito legal. Eu tentei usar, mas tive dificuldades por conta das “aspas”. Você poderia disponibilizar para download?
Muito bom o tutorial… so que estou tendo problema com o seu codigo PHP… será que voce poderia disponiblizar o fonte pra gente… vlw!!!