segunda-feira, 1 de setembro de 2014

Exibindo menu de acordo com o perfil

Olá galera,

Após receber inúmeras solicitações, vou mostrar como exibir somente itens do menu que o usuário tem permissão.

Recomendo que você dê uma olhada nos comentários do post Autenticação e ACL com Laravel 4.1 - Final para saber do que estamos falando.

Tomando como base os códigos da série Autenticação e ACL com Laravel 4.1, abra o arquivo app/macros.php e adicione a macro abaixo.

    HTML::macro('mountMenu', function() {
      $menu = null;
      $cache = Cache::get('actions' . Auth::user()->id);
      $index = preg_grep('/index|\*/', $cache);

      $links = array(
        'veiculo' => 'Veículos',
        'usuario' => 'Usuários',
        'perfil' => 'Perfis',
      );

      foreach($links as $key => $value) {
        foreach($index as $i) {
          if($key == current(explode('.', $i)) || $i == '*')
            $menu .= '
  • ' . link_to($key, $value) . '
  • '; } } return $menu; });

    Já no arquivo app/views/partials/_navigation.blade.php, remova as tags 'li' que contém os links do menu e adicione {{ HTML::mountMenu() }}

    Explicando a macro que gera o menu.

    Linha 3: Recuperando as permissões do usuário logado

    Linha 4: Retorno as entradas do array de acordo com o padrão que pode ser o 'index' ou '*'

    Linhas 6 a 10: Array de itens do menu com chave e valor, sendo que a chave é minha rota e o valor é o label a ser exibido.

    Linhas 12 a 14: Percorro os dois arrays comparando se as chaves são iguais

    Linha 15: Concateno os itens de menu que atendem a minha condição

    Bastante simples não é verdade? Fica aí a dica.

    Um grande abraço e até a próxima.

    12 comentários:

    1. Cara, estou acompanhando sua serie de laravel 4.1.. É sensacional, os videos de Autenticação e ACL são muito top. Fiquei impressionado. Parabéns. Por favor não pare com os videos e as dicas, são muito boas.

      ResponderExcluir
      Respostas
      1. Olá Romário,

        Valeu por acompanhar o blog. Pode deixar que sempre que possível vou estar postando novidades e dicas.

        Grande abraço

        Excluir
    2. Olá Benicio, estava trabalhando no meu projeto quando me deparei com o seguinte problema:

      preg_grep() expects parameter 2 to be array, null given (View: C:\xampp\htdocs\laravel\app\views\partials\_navigation.blade.php)

      Na linha 4 do macro mountMenu:
      $index = preg_grep('/index|\*/', $cache);

      Isso ocorreu depois de eu ter logado, ficado um tempão sem mexer na página e apertar F5, parece que ele não encontrou o cache..

      Tive que voltar para página de login e autenticar novamente...

      Acredito que se isso ocorrer ele deve ser redirecionado para página de login, sem estourar o erro..

      Se o erro for esse mesmo, como podemos fazer esse redirecionamento?

      Abraço amigo.


      ResponderExcluir
      Respostas
      1. Olá Romário,

        O erro é exatamente por conta da sessão ter expirado. O ideal é fazer a checagem do cache com um if e depois dar um redirect para a tela de login.

        Abraço

        Excluir
    3. Aproveitando, todas vez que tentamos acessar uma página que não temos permissão de acesso, ele da um erro : Cannot redirect to an empty URL

      Sabe o que pode ser isso?

      ResponderExcluir
      Respostas
      1. Olá Romário,

        Você conseguiu debugar no filter ACL? Está dando algum erro lá?

        Abraço

        Excluir
      2. Debuguei agora, ele entra na Exception nessa linha:
        return Redirect::back()

        Excluir
      3. Realmente é muito estranho. A lógica é que você estar na "página A" (você tem permissão), aí quando você tenta ir para a "página B" (você não tem permissão), o sistema dá um redirect::back mandando você para a "página A".

        Excluir
      4. Isso, ele não está encontrando a página anterior, por isso acontece isso. Estou tentando uma outra de forma saber qual a página anterior . Ainda sem sucesso.

        Excluir
    4. penso que falta um } antes do ); final

      ResponderExcluir
    5. enganei-me é antes do return menu(); que precisa de }.
      Abraço.
      Pode editar se quiser o post..

      ResponderExcluir
      Respostas
      1. Olá amigo,

        Na linha 20 tem exatamente um } que está fechando a function.

        Abraço

        Excluir