src/Aqarmap/Bundle/ListingBundle/EventListener/ConfigureMenuEventSubscriber.php line 132

  1. <?php
  2. namespace Aqarmap\Bundle\ListingBundle\EventListener;
  3. use Aqarmap\Bundle\FeatureToggleBundle\Service\FeatureToggleManager;
  4. use Aqarmap\Bundle\ListingBundle\Constant\LocationLevels;
  5. use Aqarmap\Bundle\ListingBundle\Entity\Listing;
  6. use Aqarmap\Bundle\ListingBundle\EventListener\MenuBuilder\RenderSideBar;
  7. use Aqarmap\Bundle\ListingBundle\Twig\ListingExtension;
  8. use Aqarmap\Bundle\MainBundle\Event\ConfigureMenuEvent;
  9. use Aqarmap\Bundle\MainBundle\Service\Setting;
  10. use Doctrine\ORM\EntityManagerInterface;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. use Symfony\Component\HttpFoundation\RequestStack;
  13. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  14. use Symfony\Contracts\Translation\TranslatorInterface;
  15. class ConfigureMenuEventSubscriber implements EventSubscriberInterface
  16. {
  17. /**
  18. * List of roles.
  19. *
  20. * @var array
  21. */
  22. protected $roles = [
  23. 'ROLE_FREE_LISTING',
  24. 'ROLE_PROJECTS',
  25. 'ROLE_INCREASING_LISTINGS',
  26. 'ROLE_PAID_LISTING',
  27. 'ROLE_ADMIN_ACTIVITIES',
  28. 'ROLE_WEBMASTER',
  29. 'ROLE_ACCESS_TO_ADMIN_LEADS',
  30. 'ROLE_MARKETING',
  31. 'ROLE_CRM',
  32. 'ROLE_CUSTOMER_PROFILING',
  33. 'ROLE_SUPER_ADMIN',
  34. 'ROLE_LEADS_STATISTICS',
  35. 'ROLE_PENDING_FEATURING_LISTING',
  36. 'ROLE_LOCATIONS',
  37. 'ROLE_PUBLISHED_LISTINGS_COUNT',
  38. 'ROLE_RELIST_LISTING',
  39. 'ROLE_SCRAPPED_LISTING',
  40. 'ROLE_ACTIVE_CUSTOMER',
  41. ];
  42. /**
  43. * Translator instance.
  44. */
  45. protected $translator;
  46. public function __construct(
  47. TranslatorInterface $translator,
  48. private readonly FeatureToggleManager $featureToggleManager,
  49. private readonly Setting $setting,
  50. private readonly AuthorizationCheckerInterface $authorizationChecker,
  51. private readonly EntityManagerInterface $entityManager,
  52. private readonly ListingExtension $listingExtension,
  53. private readonly RequestStack $requestStack,
  54. ) {
  55. $this->translator = $translator;
  56. }
  57. public function onAdminSidebarMenuConfigure(ConfigureMenuEvent $event): void
  58. {
  59. $userRole = $this->authorizationChecker;
  60. $renderSideBar = (new RenderSideBar($this->featureToggleManager, $this->authorizationChecker))
  61. ->setMenu($event->getMenu())
  62. ->setTranslator($this->translator);
  63. foreach ($this->roles as $role) {
  64. if ($userRole->isGranted($role)) {
  65. $fn = 'has'.$this->snakeToCamel($role);
  66. $renderSideBar->$fn();
  67. }
  68. }
  69. }
  70. public function onMainNavbarMenuConfigure(ConfigureMenuEvent $event): void
  71. {
  72. $menu = $event->getMenu();
  73. if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  74. // My Listings
  75. $menu
  76. ->addChild('my_listings', ['route' => 'aqarmap_listing_default_mylistings'])
  77. ->setLabel($this->translator->trans('layout.my_listings.title'))
  78. ->setExtra('position', 50);
  79. // List your property
  80. $menu
  81. ->addChild('add_listing', ['route' => 'listing_initialize'])
  82. ->setLabel($this->translator->trans('layout.add_listing'))
  83. ->setExtra('position', 40);
  84. }
  85. }
  86. public function onBreadcrumbConfigure(ConfigureMenuEvent $event): void
  87. {
  88. $menu = $event->getMenu();
  89. $listing = $this->getRequest()->attributes->get('listing');
  90. if ($listing instanceof Listing) {
  91. $this->getRequest()->attributes->set('section', $listing->getSection());
  92. $this->getRequest()->attributes->set('propertyType', $listing->getPropertyType());
  93. $this->getRequest()->attributes->set('location', $listing->getLocation());
  94. }
  95. if ($section = $this->getRequest()->attributes->get('section')) {
  96. // If not searchable section, than it's premium section (Projects)
  97. $premium_section = !$section->getSearchable() || ($listing instanceof Listing && $listing->getParent() instanceof Listing);
  98. // Search links
  99. if (($propertyType = $this->getRequest()->attributes->get('propertyType')) && !$premium_section) {
  100. $menu
  101. ->addChild($section->getSlug(), [
  102. 'route' => 'property_type_search',
  103. 'routeParameters' => [
  104. 'section_slug' => $section->getSlug(),
  105. 'property_type_slug' => 'property-type',
  106. ],
  107. ])
  108. ->setAttribute('title', $this->translator
  109. ->trans('listing.quickLinks_title_section', [
  110. '%section%' => $section->getTitle(),
  111. ]))
  112. ->setLabel($this->translator
  113. ->trans('listing.quickLinks_title_section', [
  114. '%section%' => $section->getTitle(),
  115. ]));
  116. $menu
  117. ->addChild($propertyType->getSlug(), [
  118. 'route' => 'property_type_search',
  119. 'routeParameters' => [
  120. 'section_slug' => $section->getSlug(),
  121. 'property_type_slug' => $propertyType->getSlug(),
  122. ],
  123. ])
  124. ->setAttribute('title', $this->translator
  125. ->trans('listing.quickLinks_title_wo_location', [
  126. '%property_type%' => $propertyType->getTitle(),
  127. '%section%' => $section->getTitle(),
  128. ]))
  129. ->setLabel($propertyType->getTitle());
  130. // Locations
  131. if ($location = $this->getRequest()->attributes->get('location')) {
  132. /** @var $locationRepo \Aqarmap\Bundle\ListingBundle\Entity\LocationRepository */
  133. $locationRepo = $this->entityManager->getRepository(\Aqarmap\Bundle\ListingBundle\Entity\Location::class);
  134. foreach ($locationRepo->getPath($location) as $treeLocation) {
  135. // Skip non-searchable locations
  136. if ($treeLocation->getLevel() > LocationLevels::MAX_LEVEL) {
  137. continue;
  138. }
  139. $menu
  140. ->addChild($treeLocation->getSlug(), [
  141. 'route' => 'search',
  142. 'routeParameters' => [
  143. 'section_slug' => $section->getSlug(),
  144. 'property_type_slug' => $propertyType->getSlug(),
  145. 'location_slug' => $treeLocation->getSlug(),
  146. ],
  147. ])
  148. ->setAttribute('title', $this->translator
  149. ->trans('listing.quickLinks_title', [
  150. '%property_type%' => $propertyType->getTitle(),
  151. '%section%' => $section->getTitle(),
  152. '%location%' => $treeLocation->getTitle(),
  153. ]))
  154. ->setLabel($treeLocation->getTitle());
  155. }
  156. }
  157. } elseif ($listing = $this->getRequest()->attributes->get('listing')) {
  158. $menu
  159. ->addChild('section', ['route' => 'compound_search'])
  160. ->setAttribute('title', $this->translator
  161. ->trans('listing.quickLinks_title_section', [
  162. '%section%' => $section->getTitle(),
  163. ]))
  164. ->setLabel($section->getTitle());
  165. /** @var $compoundLocation \Aqarmap\Bundle\ListingBundle\Entity\CompoundLocation */
  166. if ($compoundLocation = $listing->getCompoundLocation()) {
  167. $compoundsLabel = $this->translator
  168. ->trans(
  169. 'layout.location_compound',
  170. ['%location%' => $compoundLocation]
  171. );
  172. if ('SA' == $this->setting->getSetting('general', 'country')) {
  173. $compoundsLabel = $this->translator
  174. ->trans(
  175. 'layout.location_project',
  176. ['%location%' => $compoundLocation]
  177. );
  178. }
  179. $menu
  180. ->addChild('section_location', [
  181. 'route' => 'compound_search_with_location',
  182. 'routeParameters' => [
  183. 'location' => $compoundLocation->getSlug(),
  184. ],
  185. ])
  186. ->setLabel($compoundsLabel);
  187. }
  188. }
  189. }
  190. $listingExtension = $this->listingExtension;
  191. if ($listing && $listing->getParent()) {
  192. // With Slug
  193. if ($listing->getParent()->getSlug()) {
  194. $parentRoute = [
  195. 'route' => 'listing_slug',
  196. 'routeParameters' => [
  197. 'id' => $listing->getParent()->getId(),
  198. 'slug' => $listing->getParent()->getSlug(),
  199. ],
  200. 'extras' => [
  201. 'safe_label' => true,
  202. ],
  203. ];
  204. } // Without Slug
  205. else {
  206. $parentRoute = ['route' => 'listing_view', 'routeParameters' => [
  207. 'id' => $listing->getParent()->getId(),
  208. ]];
  209. }
  210. $menu
  211. ->addChild($listing->getParent()->getId(), $parentRoute)
  212. ->setLabel($listingExtension->fixArabicNumbers($listing->getParent()->getTitle()));
  213. }
  214. if ($listing) {
  215. // With Slug
  216. if ($listing->getSlug()) {
  217. $listingRoute = [
  218. 'route' => 'listing_slug',
  219. 'routeParameters' => [
  220. 'id' => $listing->getId(),
  221. 'slug' => $listing->getSlug(),
  222. ],
  223. 'extras' => [
  224. 'safe_label' => true,
  225. ],
  226. ];
  227. } // Without Slug
  228. else {
  229. $listingRoute = ['route' => 'listing_view', 'routeParameters' => [
  230. 'id' => $listing->getId(),
  231. ]];
  232. }
  233. $menu
  234. ->addChild($listing->getId(), $listingRoute)
  235. ->setLabel($listingExtension->fixArabicNumbers($listing->getTitle()));
  236. } elseif ($section = $this->getRequest()->attributes->get('section')) {
  237. $translatedTitle = $this->translator
  238. ->trans('listing.quickLinks_title_section', [
  239. '%section%' => $section->getTitle(),
  240. ]);
  241. $menu
  242. ->addChild($section->getSlug(), [
  243. 'route' => 'property_type_search',
  244. 'routeParameters' => [
  245. 'section_slug' => $section->getSlug(),
  246. 'property_type_slug' => 'property-type',
  247. ],
  248. ])
  249. ->setAttribute('title', $translatedTitle)
  250. ->setLabel($translatedTitle);
  251. }
  252. }
  253. public function getRequest()
  254. {
  255. return $this->requestStack->getCurrentRequest();
  256. }
  257. /**
  258. * Convert underscore_strings to camelCase.
  259. *
  260. * @param string $str
  261. *
  262. * @return string
  263. */
  264. private function snakeToCamel($str)
  265. {
  266. return str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($str))));
  267. }
  268. /**
  269. * @return array<string, mixed>
  270. */
  271. public static function getSubscribedEvents(): array
  272. {
  273. return [
  274. 'aqarmap.main.admin_sidebar_menu_configure' => 'onAdminSidebarMenuConfigure',
  275. 'aqarmap.main.breadcrumb_configure' => 'onBreadcrumbConfigure',
  276. ];
  277. }
  278. }