<?php
namespace App\Menu;
use App\Entity\Brand;
use App\Entity\User;
use App\Entity\UserRetailer;
use App\Repository\BrandRepository;
use App\Service\PageService;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Menu\FactoryInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface as UserInterfaceAlias;
class Builder
{
/** @var FactoryInterface */
private $factory;
/** @var AuthorizationCheckerInterface */
private $authorizationChecker;
/**
* @var Security
*/
private $security;
/**
* @var PageService
*/
private $pageService;
/**
* @var EntityManagerInterface
*/
private $entityManager;
/**
* @var BrandRepository
*/
private $brandRepository;
public function __construct(
FactoryInterface $factory,
AuthorizationCheckerInterface $authorizationChecker,
Security $security,
EntityManagerInterface $entityManager,
PageService $pageService,
BrandRepository $brandRepository,
) {
$this->factory = $factory;
$this->authorizationChecker = $authorizationChecker;
$this->security = $security;
$this->pageService = $pageService;
$this->entityManager = $entityManager;
$this->brandRepository = $brandRepository;
}
public function mainMenu(array $options)
{
$menu = $this->factory->createItem('root', [
'childrenAttributes' => [
'class' => 'navbar-nav mb-2 mb-lg-0 ',
],
],
);
$menu->addChild('Home', ['route' => 'homepage'])
->setLinkAttribute('class', 'nav-link ')
;
if (!$this->can('ROLE_USER')) {
// Check if About Us page exists and is active before adding to menu
$aboutUsPage = $this->pageService->getAboutUsPage();
if ($aboutUsPage && $aboutUsPage->getActive()) {
$menu->addChild('About Us', ['route' => 'aboutUs'])
->setLinkAttribute('class', 'nav-link ')
;
}
// Check if News & Events page exists and is active before adding to menu
$newsAndEventsPage = $this->pageService->getNewsAndEventsPage();
if ($newsAndEventsPage && $newsAndEventsPage->getActive()) {
$menu->addChild('News & Events', ['route' => 'newsAndEvents'])
->setLinkAttribute('class', 'nav-link ')
;
}
$menu->addChild('Brands', ['route' => 'brands'])
->setLinkAttribute('class', 'nav-link ')
;
$menu->addChild('Retailers', ['route' => 'retailers'])
->setLinkAttribute('class', 'nav-link ')
;
}
if ($this->can('ROLE_USER')) {
$menu->addChild('Education', ['uri' => '#'])
->setAttributes([
'class' => 'nav-item dropdown',
])
// ->setLinkAttribute('class', 'nav-link ')
->setLinkAttributes([
'class' => 'nav-link dropdown-toggle',
'data-toggle' => 'dropdown',
'role' => 'button',
'data-bs-toggle' => 'dropdown',
'href' => '#',
'aria-haspopup' => 'true',
'aria-expanded' => 'false',
])
->setChildrenAttributes([
'class' => 'dropdown-menu',
])
;
// Check if user has multiple brands
$userBrands = [];
if ($this->user() instanceof User) {
// Get user brands directly from the database
$conn = $this->entityManager->getConnection();
$sql = '
SELECT DISTINCT b.*
FROM brand b
JOIN user_retailer ur ON ur.brand_id = b.id
WHERE ur.user_id = :userId
AND ur.manage_status = :status
AND b.active = 1
';
$stmt = $conn->prepare($sql);
$result = $stmt->executeQuery([
'userId' => $this->user()->getId(),
'status' => UserRetailer::MANAGE_STATUS_APPROVED,
]);
$userBrands = $result->fetchAllAssociative();
}
if (count($userBrands) > 1) {
$menu->addChild('Offers', ['uri' => '#'])
->setAttributes([
'class' => 'nav-item dropdown',
])
// ->setLinkAttribute('class', 'nav-link ')
->setLinkAttributes([
'class' => 'nav-link dropdown-toggle',
'data-toggle' => 'dropdown',
'role' => 'button',
'data-bs-toggle' => 'dropdown',
'href' => '#',
'aria-haspopup' => 'true',
'aria-expanded' => 'false',
])
->setChildrenAttributes([
'class' => 'dropdown-menu',
])
;
foreach ($userBrands as $brandData) {
// Create a Brand object from the array data
$brandId = $brandData['id'];
$brandName = $brandData['name'];
$isActive = (bool) $brandData['active'];
if ($isActive) {
$menu['Education']->addChild($brandName, [
'route' => 'education.list',
'routeParameters' => ['brand' => $brandId],
])->setLinkAttribute('class', 'dropdown-item ');
$menu['Offers']->addChild($brandName, [
'route' => 'offers.list',
'routeParameters' => ['brand' => $brandId],
])->setLinkAttribute('class', 'dropdown-item ');
}
}
} else {
if (count($userBrands)) {
$brandData = array_values($userBrands)[0];
$brandId = $brandData['id'];
$brandName = $brandData['name'];
$menu['Education']->addChild($brandName, [
'route' => 'education.list',
'routeParameters' => ['brand' => $brandId],
])->setLinkAttribute('class', 'dropdown-item ');
$menu->addChild('Offers', [
'route' => 'offers.list',
'routeParameters' => ['brand' => $brandId],
])
->setLinkAttribute('class', 'nav-link ')
;
}
}
$menu->addChild('FAQ', ['route' => 'faq'])->setLinkAttribute('class', 'nav-link ');
$menu->addChild('My Rewards', ['uri' => '#'])
->setAttributes(['class' => 'nav-item dropdown'])
->setLinkAttributes([
'class' => 'nav-link dropdown-toggle',
'data-toggle' => 'dropdown',
'role' => 'button',
'data-bs-toggle' => 'dropdown',
'href' => '#',
'aria-haspopup' => 'true',
'aria-expanded' => 'false',
])
->setChildrenAttributes(['class' => 'dropdown-menu'])
;
$menu['My Rewards']->addChild('My Rewards', ['route' => 'submission.list'])
->setLinkAttribute('class', 'dropdown-item ')
;
// Only show Surreal Leaderboard link if user has a retailer with Surreal Diamond brand
if ($this->userHasSurrealRetailer()) {
$menu['My Rewards']->addChild('SURREAL LEADERBOARD', ['route' => 'leaderboard.index'])
->setLinkAttribute('class', 'dropdown-item ')
;
}
$menu->addChild('My Card', ['route' => 'card'])
->setLinkAttribute('class', 'nav-link ')
;
$menu->addChild('My Account', ['route' => 'profile.index'])
->setLinkAttribute('class', 'nav-link ')
;
if ($this->can('ROLE_PREVIOUS_ADMIN')) {
$menu->addChild('Exit', [
'route' => 'sonata_admin_dashboard',
'routeParameters' => ['_impersonating_user' => '_exit']])
->setLinkAttribute('class', 'nav-link ');
} else {
$menu->addChild('Signout', ['route' => 'logout'])
->setLinkAttribute('class', 'nav-link btn btn-outline-warning btn-sm mb-sm-3 mb-md-0')
;
}
} else {
$menu->addChild('Sign In', ['route' => 'login'])->setLinkAttribute('class', 'nav-link ');
$menu->addChild('Register', ['route' => 'registration'])
->setLinkAttribute('class', 'nav-link btn btn-outline-primary btn-sm mb-sm-3 mb-md-0 ')
;
}
if ($this->can('ROLE_ADMIN_PAGE')) {
$menu->addChild('Admin', ['route' => 'sonata_admin_dashboard'])
->setLinkAttribute('class', 'nav-link btn btn-danger btn-sm text-white')
;
}
return $menu;
}
/**
* laconic function alias for checking granted.
*
* @return bool
*/
protected function can($role)
{
return $this->authorizationChecker->isGranted($role);
}
protected function user(): ?UserInterfaceAlias
{
return $this->security->getUser();
}
/**
* Check if the current user has a retailer with Surreal Diamond brand.
*/
protected function userHasSurrealRetailer(): bool
{
$user = $this->security->getUser();
if (!$user instanceof User) {
return false;
}
// Get the Surreal Diamond brand
$surrealBrand = $this->brandRepository->findOneBy(['name' => 'Surreal Diamond']);
if (!$surrealBrand) {
return false;
}
$conn = $this->entityManager->getConnection();
$sql = '
SELECT COUNT(ur.id) as retailer_count
FROM user_retailer ur
JOIN retailer r ON ur.retailer_id = r.id
WHERE ur.user_id = :userId AND r.brand_id = :brandId
';
$stmt = $conn->prepare($sql);
$result = $stmt->executeQuery([
'userId' => $user->getId(),
'brandId' => $surrealBrand->getId(),
]);
$data = $result->fetchAssociative();
return (int) ($data['retailer_count'] ?? 0) > 0;
}
}