PHP code example of chamber-orchestra / menu-bundle

1. Go to this page and download the library: Download chamber-orchestra/menu-bundle library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

chamber-orchestra / menu-bundle example snippets


// config/bundles.php
return [
    // ...
    ChamberOrchestra\MenuBundle\ChamberOrchestraMenuBundle::class => ['all' => true],
];



namespace App\Navigation;

use ChamberOrchestra\MenuBundle\Menu\MenuBuilder;
use ChamberOrchestra\MenuBundle\Navigation\AbstractCachedNavigation;

final class SidebarNavigation extends AbstractCachedNavigation
{
    public function build(MenuBuilder $builder, array $options = []): void
    {
        $builder
            ->add('dashboard', ['label' => 'Dashboard', 'route' => 'app_dashboard', 'icon' => 'fa-home'])
            ->add('blog', ['label' => 'Blog'])
            ->children()
                ->add('posts', ['label' => 'Posts', 'route' => 'app_blog_post_index'])
                ->add('tags',  ['label' => 'Tags',  'route' => 'app_blog_tag_index'])
            ->end()
            ->add('settings', ['label' => 'Settings', 'route' => 'app_settings',
                               'roles' => ['ROLE_ADMIN']]);
    }
}

$builder
    ->add('main', ['label' => 'Main Section'], section: true)
    ->children()
        ->add('dashboard', ['label' => 'Dashboard', 'route' => 'app_dashboard'])
    ->end();



namespace App\Navigation;

use ChamberOrchestra\MenuBundle\Menu\MenuBuilder;
use ChamberOrchestra\MenuBundle\Navigation\AbstractCachedNavigation;
use Symfony\Contracts\Cache\ItemInterface;

final class MainNavigation extends AbstractCachedNavigation
{
    public function __construct(private readonly string $locale)
    {
        parent::__construct();
    }

    // Override the cache key if you need per-locale or per-user trees
    public function getCacheKey(): string
    {
        return 'main_nav_'.$this->locale;
    }

    // Fine-tune TTL and tags
    public function configureCacheItem(ItemInterface $item): void
    {
        $item->expiresAfter(3600);
        $item->tag(['navigation', 'main_nav']);
    }

    public function build(MenuBuilder $builder, array $options = []): void
    {
        $builder->add('home', ['label' => 'Home', 'route' => 'app_home']);
    }
}

use ChamberOrchestra\MenuBundle\Navigation\ClosureNavigation;

// Uncached (default)
$nav = new ClosureNavigation(function (MenuBuilder $builder): void {
    $builder->add('home', ['label' => 'Home', 'route' => 'app_home']);
});

// Cached for 1 hour
$nav = new ClosureNavigation(
    callback: function (MenuBuilder $builder): void {
        $builder->add('home', ['label' => 'Home', 'route' => 'app_home']);
    },
    cacheKey: 'sidebar_nav',
    ttl: 3600,
);

$builder->add('blog', [
    'label'  => 'Blog',
    'route'  => 'app_blog_post_index',
    'routes' => [
        ['route' => 'app_blog_.*'], // all blog_* routes keep the item active
    ],
]);



namespace App\Navigation\Voter;

use ChamberOrchestra\MenuBundle\Matcher\Voter\VoterInterface;
use ChamberOrchestra\MenuBundle\Menu\Item;

final class QueryParamVoter implements VoterInterface
{
    public function __construct(private readonly RequestStack $requestStack)
    {
    }

    public function matchItem(Item $item): ?bool
    {
        // Return true to mark current, false to reject, null to abstain
        $request = $this->requestStack->getCurrentRequest();
        if (null === $request) {
            return null;
        }

        $expectedTab = $item->getOption('tab');
        if (null === $expectedTab) {
            return null;
        }

        return $request->query->get('tab') === $expectedTab ? true : null;
    }
}

$builder->add('dashboard', ['label' => 'Dashboard', 'icon' => 'fa-home']);

$builder->add('separator', ['divider' => true]);

$builder
    ->add('beta_feature', ['label' => 'Beta', 'visible' => false])
    ->add('promo', ['label' => 'Promo', 'visible' => fn (): bool => $this->featureFlags->isEnabled('promo')]);

$builder
    ->add('news', ['label' => 'News', 'badge' => 3])
    ->add('inbox', ['label' => 'Inbox', 'badge' => fn (): int => $this->messages->countUnread()]);



namespace App\Navigation\Extension;

use App\Repository\MessageRepository;
use ChamberOrchestra\MenuBundle\Factory\Extension\RuntimeExtensionInterface;
use ChamberOrchestra\MenuBundle\Menu\Item;

final class InboxBadgeExtension implements RuntimeExtensionInterface
{
    public function __construct(private readonly MessageRepository $messages)
    {
    }

    public function processItem(Item $item): void
    {
        if ('inbox' === $item->getName()) {
            $item->setExtra('badge', $this->messages->countUnread());
        }
    }
}

$builder->add('orders', [
    'label' => 'Orders',
    'counters' => [
        'pending' => fn (): int => $this->orders->countPending(),
        'shipped' => fn (): int => $this->orders->countShipped(),
    ],
]);

$builder
    ->add('scores', ['label' => 'nav.scores'])
    ->add('rehearsals', ['label' => 'nav.rehearsals', 'translation_domain' => 'navigation']);

use ChamberOrchestra\MenuBundle\Factory\Extension\ExtensionInterface;

final class TooltipExtension implements ExtensionInterface
{
    public function buildOptions(array $options): array
    {
        if (isset($options['tooltip'])) {
            $extras = $options['extras'] ?? [];
            $extras['tooltip'] = $options['tooltip'];
            $options['extras'] = $extras;
            unset($options['tooltip']);
        }

        return $options;
    }
}

use ChamberOrchestra\MenuBundle\Factory\Extension\RuntimeExtensionInterface;
use ChamberOrchestra\MenuBundle\Menu\Item;

final class NotificationBadgeExtension implements RuntimeExtensionInterface
{
    public function __construct(private readonly NotificationRepository $notifications) {}

    public function processItem(Item $item): void
    {
        if ('alerts' === $item->getName()) {
            $item->setExtra('badge', $this->notifications->countUnread());
        }
    }
}