Download the PHP package gsebastiao/laravel-menu without Composer

On this page you can find all versions of the php package gsebastiao/laravel-menu. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-menu

Laravel Menu

Latest Version Testes

Menus para Laravel guardados na base de dados, com os níveis que precisares (menu › submenu › sub-submenu…), que mostram a cada utilizador só o que ele pode ver.


Índice

  1. Requisitos
  2. Começar em 5 minutos
  3. Criar itens de menu
  4. Mostrar o menu
  5. Permissões
  6. Proteger rotas (middleware)
  7. Cache
  8. Auditoria (opcional)
  9. Configuração
  10. Referência rápida
  11. Resolução de problemas
  12. Atualizar de uma versão anterior
  13. Testes

Requisitos

Laravel PHP
11.x e 12.x 8.2 ou mais recente
13.x 8.3 ou mais recente

Começar em 5 minutos

1. Instala o pacote

2. Cria a tabela menu_items

3. Cria alguns itens. Para experimentar, usa o menu de exemplo que vem com o pacote:

O primeiro comando copia o exemplo para database/seeders/MenuItemsSeeder.php, onde o podes editar. Podes correr o seeder as vezes que quiseres: os itens são atualizados, não duplicados.

4. Mostra o menu. No teu layout (ex.: resources/views/layouts/app.blade.php):

Pronto: tens um menu a funcionar. Os itens do exemplo que apontam para rotas que ainda não existem no teu projeto aparecem sem link, sem erros.

Queres mudar alguma opção (permissões, cache, nome da tabela...)? Não precisas de publicar o config: basta acrescentar variáveis MENU_* ao teu .env. A lista completa, com o padrão de cada uma, está em Configuração. Se fores mudar o nome da tabela (MENU_TABLE), faz isso antes do migrate.

5. (Opcional) Dá-lhe um estilo simples:


Criar itens de menu

Cada item é uma linha da tabela menu_items. Crias, editas e apagas itens como qualquer model do Laravel:

Podes pôr este código num seeder (como o de exemplo) ou experimentá-lo no php artisan tinker. A cache do menu é limpa automaticamente sempre que crias, editas, apagas ou restauras um item assim.

Os campos de um item

Campo Obrigatório Para que serve Exemplo
name sim Identificador interno do item. Usa um nome diferente para cada item. 'admin.users'
label sim O texto que aparece no menu. 'Utilizadores'
parent_id não O id do item pai. Vazio = item de topo. $admin->id
route não Para onde o item leva (ver tabela abaixo). Vazio = item sem link (ex.: um grupo). 'users.index'
params não Parâmetros da rota. ['user' => 5]
order não (0) Posição entre os irmãos: os números menores aparecem primeiro. 1
icon não Classes CSS do ícone (do pacote de ícones que usas). 'bi bi-people'
badge não Texto pequeno ao lado do nome. 'novo'
description não Texto de ajuda (aparece ao passar o rato). 'Gerir contas'
target não '_blank' abre o link num novo separador. '_blank'
permission não Permissão necessária para ver o item (ver Permissões). 'users.view'
is_active não (true) false esconde o item e todos os filhos dele. false
is_separator não (false) Mostra uma linha divisória em vez de um link. true

O que pode ir no campo route

Escreves O item leva a…
'users.index' a rota com esse nome (route('users.index', $params))
'/sobre' um caminho da tua aplicação (começa por /)
'https://exemplo.com' um endereço externo (também mailto: e tel:)
'#contactos' uma âncora na página

Se o nome de rota não existir (ou faltar um parâmetro obrigatório), o item aparece sem link em vez de dar erro na página. Por segurança, endereços javascript: e data: nunca viram link.

Dica: num painel de administração, gere os itens com um CRUD normal (controller + formulário) sobre o model MenuItem.


Mostrar o menu

Com o componente pronto

Mostra o menu do utilizador autenticado, já filtrado pelas permissões, com os submenus aninhados. Também aceita outros itens e atributos para a <ul> principal:

O HTML gerado usa estas classes, para poderes dar-lhe o estilo que quiseres:

Classe Onde aparece
menu cada <ul> do menu
menu-submenu cada <ul> de um submenu
menu-item cada <li> com um item
is-active o <li> da página atual e dos seus pais (para abrires o submenu certo)
has-children o <li> de um item com submenu
menu-link o <a> de cada item (sem href quando o item não tem link)
menu-icon, menu-label, menu-badge o ícone, o texto e o badge
menu-separator o <li> de um separador

Além das classes, o <a> da página atual leva aria-current="page", para que um leitor de ecrã a anuncie. Só esse: os itens-pai ficam apenas com a classe is-active.

Mudar o HTML do componente

Publica a view e edita a cópia (ex.: para usares as classes do Bootstrap ou do Tailwind):

A cópia fica em resources/views/vendor/laravel-menu/components/menu.blade.php e passa a ser usada no lugar da original.

Montar o teu próprio HTML

Se preferires escrever tudo à mão, estas são as peças que o componente usa:


Permissões

Por omissão não há permissões: todos os itens aparecem a toda a gente. Para esconder itens, são dois passos.

Passo 1: escolhe o modo

No .env:

Modo O que guardas no campo permission de cada item
none Nada — as permissões são ignoradas (é o padrão).
string O nome da permissão, ex.: users.view.
id O id da permissão numa tabela tua, ex.: 42 (ver Modo id).

Passo 2: diz ao pacote quais são as permissões do utilizador

Usas o gsebastiao/laravel-authz? Não precisas de fazer nada: salta para Com o gsebastiao/laravel-authz.

Usas o spatie/laravel-permission? Também não: o pacote usa $user->getAllPermissions() automaticamente.

Tens outra lógica? Define-a no boot() do app/Providers/AppServiceProvider.php:

O $user é o utilizador autenticado (ou null para visitantes). Podes devolver um array ou uma Collection de textos, models, arrays ou enums (de um model ou array é lida a coluna name; no modo id, a coluna id).

Alternativa: indicar uma classe no config/menu.php **Não escrevas uma função (closure) diretamente no ficheiro de config:** funciona, mas o `php artisan config:cache` deixa de funcionar.

Com o gsebastiao/laravel-authz

O gsebastiao/laravel-authz traz grupos e permissões (RBAC) ao teu projeto. Com ele instalado, o menu descobre-o sozinho — não escreves resolver nenhum.

1. Instala e prepara o pacote (se ainda não o fizeste):

2. Põe o trait no teu model User:

3. Escolhe o modo string e guarda o nome da permissão em cada item:

É tudo. A partir daqui cada pessoa só vê o que pode, com a cascata do laravel-authz respeitada: negações individuais, regras dos grupos, validade por datas e o tenant atual. A cache do menu guarda a árvore, não as permissões de cada pessoa — quem perde uma permissão deixa de ver o item logo no pedido seguinte.

O middleware faz a mesma leitura, por isso a rota fica protegida com a mesma permissão que esconde o item:

Guardar o id da permissão em vez do nome Se preferires que o campo `permission` guarde o id da permissão (sobrevive a uma mudança de nome), usa o modo `id`: `$item->resolvedPermissionLabel()` passa a devolver o nome da permissão, lido da tabela `auth_permissions`. Com `MENU_RESOLVER_COLUMN=label` recebes antes o nome amigável (ex.: «Ver utilizadores»), que costuma ser o que queres mostrar num painel de administração.
Escolher a fonte das permissões em vez de a deixar ser descoberta Sem configuração, o pacote procura por esta ordem: laravel-authz, depois `$user->getAllPermissions()` (Spatie). Para não deixar nada ao acaso, diz qual é no `.env`: Os valores aceites são `auto` (o padrão), `authz` e `spatie`. Se escolheres `authz` sem o pacote instalado, a aplicação pára no arranque com uma mensagem a explicar o que falta — em vez de esconder o menu todo em silêncio. Duas notas: se o teu model `User` não tiver o trait `HasAuthz`, o menu lê as permissões à mesma, pelo id do utilizador; e um `Menu::resolvePermissionsUsing(...)` que tenhas escrito continua a ter a última palavra sobre tudo isto.

Quem vê o quê

Situação Resultado
Item sem permission Aparece a todos.
Item com permission Aparece só a quem tiver essa permissão.
Item com is_active = false Não aparece a ninguém, nem os filhos.
Item cujo pai o utilizador não pode ver Aparece na mesma, e o pai também (para não ficar um "buraco" na navegação).
Grupo sem link cujos filhos ficaram todos escondidos Desaparece (não fica um grupo vazio).
Separador Não conta como filho visível; separadores soltos (no início, no fim ou repetidos) são removidos.

Verificar permissões no teu código

No modo none, hasPermission() devolve sempre true.

Modo id

Usa este modo se o campo permission guardar ids de uma tabela tua. Indica a tabela no .env:


Proteger rotas (middleware)

O pacote regista o middleware menu.permission:


Cache

A árvore do menu é guardada em cache e limpa-se sozinha quando um item é criado, editado, apagado ou restaurado através do model (create(), update(), save(), delete(), restore()).

A cache não é limpa sozinha quando alteras os itens por outras vias:

Nesses casos, limpa-a à mão:

As opções da cache ficam no .env (ver a tabela em Configuração):


Auditoria (opcional)

Com o pacote gsebastiao/laravel-auditable, fica registado quem criou, editou, apagou ou restaurou cada item de menu, quando e o que mudou. O laravel-menu não depende desse pacote: só o instalas se quiseres.

1. Instala o pacote de auditoria:

O pacote de auditoria traz a própria migration e o migrate a executa: não precisas de publicar nada. (Só publica o config ou a migration se os quiseres editar — vê o README do laravel-auditable.)

2. Liga a auditoria no .env:

Não tens de mudar mais nada: MenuItem::create(), $item->update(), $item->delete() e $item->restore() passam a ficar registados. Em vez do parent_id, a auditoria guarda o nome do item pai.

Se ligares a auditoria sem o pacote instalado, a aplicação pára no arranque com uma mensagem a explicar como instalá-lo. Assim nunca ficas a pensar que a auditoria está a gravar quando não está.

Mudar o que é gravado Cria um model teu que estenda o `MenuItem` e sobrescreve `getAuditOptions()`: Indica-o no `config/menu.php` (`'model' => \App\Models\MenuItem::class`) e usa-o no teu código. Se quiseres os métodos extra do laravel-auditable (`auditAction()`, `operations()`…), acrescenta `use \Gsebastiao\Auditable\Concerns\Auditable;` a essa classe — o laravel-menu deteta-o e não grava nada em duplicado.

Configuração

Tudo funciona sem configurar nada, e não precisas de publicar o ficheiro de configuração. Para mudar alguma coisa, usa o .env:

Variável Padrão Para que serve
MENU_TABLE menu_items Nome da tabela (muda antes do migrate)
MENU_MODEL Gsebastiao\LaravelMenu\Models\MenuItem Model dos itens (uma classe tua que estenda o do pacote)
MENU_PERMISSION_MODE none none, string ou id (Permissões)
MENU_RESOLVER_TABLE auth_permissions Tabela de permissões (só no modo id)
MENU_RESOLVER_KEY id Coluna comparada com o campo permission (só no modo id)
MENU_RESOLVER_COLUMN name Coluna com o nome legível da permissão (com o laravel-authz: permission ou label)
MENU_USER_PERMISSION (não definir) Fonte das permissões do utilizador: auto (o padrão), authz, spatie, ou uma classe com __invoke($user)
MENU_CACHE_ENABLED true Liga/desliga a cache
MENU_CACHE_STORE (não definir) Cache a usar (sem valor = a padrão da aplicação)
MENU_CACHE_TTL (não definir) Validade da cache em segundos (sem valor ou 0 = sem prazo)
MENU_CACHE_KEY laravel_menu Prefixo da chave na cache
MENU_AUDITING_ENABLED false Liga a auditoria

Não deixes uma variável em branco (MENU_CACHE_STORE=): o Laravel lê isso como texto vazio. Para voltar ao padrão, apaga a linha. Com php artisan config:cache, corre-o de novo depois de mudar o .env.

Se preferires editar o ficheiro, publica a configuração:

Tudo o que podes publicar:

Comando Cria
php artisan vendor:publish --tag=laravel-menu-config config/menu.php
php artisan vendor:publish --tag=laravel-menu-views resources/views/vendor/laravel-menu/components/menu.blade.php
php artisan vendor:publish --tag=laravel-menu-seeders database/seeders/MenuItemsSeeder.php
php artisan vendor:publish --tag=laravel-menu-migrations a migration, em database/migrations/ (só se a quiseres alterar)

Referência rápida

Facade Menu (use Gsebastiao\LaravelMenu\Facades\Menu; — nas views Blade já está disponível):

Método O que faz
Menu::forUser($user = null) Itens que o utilizador pode ver, prontos a mostrar. Sem argumentos usa o utilizador autenticado.
Menu::forUser(null, ['a', 'b']) O mesmo, para uma lista de permissões que indicas.
Menu::tree() Todos os itens ativos, sem filtrar permissões.
Menu::url($item) Link do item, ou null.
Menu::isActive($item) true se o item ou um dos filhos é a página atual.
Menu::hasPermission('a') true se o utilizador tiver a permissão (ou uma de várias).
Menu::resolvePermissionsUsing(fn ($user) => ...) Define como obter as permissões do utilizador.
Menu::resolveUserPermissions($user = null) As permissões do utilizador, tal como o pacote as vê (útil para depurar).
Menu::rebuildCache() / Menu::flushCache() Reconstrói / limpa a cache.
Menu::cacheEnabled() A cache está ligada? (o mesmo que config('menu.cache.enabled'), com o padrão aplicado).

Model MenuItem:

Uso O que faz
$item->parent, $item->children Pai e filhos diretos (pela ordem do menu).
$item->childrenRecursive Todos os descendentes, carregados de uma vez.
MenuItem::active(), ::roots(), ::ordered() Só ativos / só de topo / pela ordem do menu.
$item->isVisibleTo($permissoes) O item é visível com estas permissões?
$item->resolvedPermissionLabel() Nome legível da permissão (no modo id, lido da tua tabela).
$item->audits Histórico de auditoria (requer o laravel-auditable).

Comando: php artisan laravel-menu:cache (com --flush só limpa).


Resolução de problemas

O menu aparece vazio. Confirma que há itens com is_active = true. Se usas permissões, vê o que o pacote recebe com dd(Menu::resolveUserPermissions()) — se vier vazio, revê o passo 2 das permissões.

Instalei o gsebastiao/laravel-authz e o menu continua vazio. Confirma três coisas: o MENU_PERMISSION_MODE está em string (ou em id, se guardares ids); o campo permission de cada item é exatamente igual ao nome da permissão no auth_permissions (a comparação distingue maiúsculas de minúsculas); e a permissão chega mesmo ao utilizador — dd(Menu::resolveUserPermissions()) mostra o que o pacote está a ver.

Alterei itens e o menu não mudou. Provavelmente alteraste-os sem passar pelos eventos do model (update em massa, SQL direto…). Corre php artisan laravel-menu:cache. Ver Cache.

Um item aparece sem link. O nome de rota no campo route não existe (confirma com php artisan route:list), falta um parâmetro obrigatório em params, ou é um caminho sem / no início (usa /sobre, não sobre).

O super-administrador não vê todos os itens. O pacote compara listas de permissões e não passa pelo Gate. Faz o resolver devolver todas as permissões nesse caso:

php artisan config:cache falha com "Your configuration files are not serializable". Tens uma closure no config/menu.php (normalmente em user_permissions). Troca-a por Menu::resolvePermissionsUsing() ou por uma classe — ver Permissões.

Target class [Database\Seeders\MenuItemsSeeder] does not exist. O seeder foi publicado por uma versão anterior a 2.1, que o copiava com o namespace errado. Publica-o de novo: php artisan vendor:publish --tag=laravel-menu-seeders --force.

Erro no arranque: "A auditoria do laravel-menu está ativada … mas o pacote … não está instalado". Instala o pacote de auditoria (ver Auditoria) ou define MENU_AUDITING_ENABLED=false.

Erro: "Valor inválido em config('menu.permission_mode')". O MENU_PERMISSION_MODE tem um valor desconhecido (ex.: strings). Usa none, string ou id.


Atualizar de uma versão anterior

De 2.1 para 2.2

Não há passos obrigatórios. Uma única coisa a rever: se já tens o gsebastiao/laravel-authz instalado e não configuraste nenhum resolver de permissões, o menu deixa de esconder todos os itens com permission e passa a mostrar os que cada pessoa pode ver — ver Com o gsebastiao/laravel-authz. Se tens um Menu::resolvePermissionsUsing(...) ou uma classe em config('menu.user_permissions'), nada muda.

De 2.0 para 2.1

Não há passos obrigatórios. Revê apenas:

O CHANGELOG tem a lista completa.

De 1.x (gsebastiao/laravel-dynamic-menu) para 2.x

Na 2.0 o pacote mudou de nome. A tabela e os dados não mudam, e a migration não volta a correr.

  1. Troca o pacote:

  2. No teu código, substitui Gsebastiao\DynamicMenu\ por Gsebastiao\LaravelMenu\.
  3. Se publicaste a config, renomeia config/dynamic-menu.php para config/menu.php e troca config('dynamic-menu.…') por config('menu.…').
  4. No .env, troca o prefixo DYNAMIC_MENU_ por MENU_ (ex.: DYNAMIC_MENU_PERMISSION_MODE → MENU_PERMISSION_MODE).
  5. Modo id sem config publicada: a tabela padrão passou de permissions para auth_permissions. Se usas permissions, define MENU_RESOLVER_TABLE=permissions.
  6. Nos scripts de deploy, troca php artisan dynamic-menu:cache por php artisan laravel-menu:cache, e as tags dynamic-menu-* do vendor:publish por laravel-menu-*.
  7. Corre php artisan laravel-menu:cache (a chave da cache mudou de dynamic_menu para laravel_menu).

Testes

A suíte usa Pest com Orchestra Testbench e corre no CI com Laravel 11, 12 e 13, em PHP 8.2 a 8.4, com e sem o pacote de auditoria.


Licença

MIT. Ver LICENSE.


All versions of laravel-menu with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
illuminate/cache Version ^11.0|^12.0|^13.0
illuminate/console Version ^11.0|^12.0|^13.0
illuminate/contracts Version ^11.0|^12.0|^13.0
illuminate/database Version ^11.0|^12.0|^13.0
illuminate/http Version ^11.0|^12.0|^13.0
illuminate/routing Version ^11.0|^12.0|^13.0
illuminate/support Version ^11.0|^12.0|^13.0
illuminate/view Version ^11.0|^12.0|^13.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package gsebastiao/laravel-menu contains the following files

Loading the files please wait ...