vendor/ibexa/site-context/src/bundle/EventSubscriber/LocationFilterSubscriber.php line 47

Open in your IDE?
  1. <?php
  2. /**
  3. * @copyright Copyright (C) Ibexa AS. All rights reserved.
  4. * @license For full copyright and license information view LICENSE file distributed with this source code.
  5. */
  6. declare(strict_types=1);
  7. namespace Ibexa\Bundle\SiteContext\EventSubscriber;
  8. use Ibexa\Bundle\SiteContext\Specification\IsAdmin;
  9. use Ibexa\Contracts\Core\Repository\Values\Content\Location;
  10. use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
  11. use Ibexa\Contracts\SiteContext\SiteContextServiceInterface;
  12. use Ibexa\Core\MVC\Symfony\Event\PreContentViewEvent;
  13. use Ibexa\Core\MVC\Symfony\MVCEvents;
  14. use Ibexa\Core\MVC\Symfony\SiteAccess\SiteAccessServiceInterface;
  15. use Ibexa\Core\MVC\Symfony\View\ContentView;
  16. use Ibexa\SiteContext\Specification\IsContextAware;
  17. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  18. final class LocationFilterSubscriber implements EventSubscriberInterface
  19. {
  20. private SiteAccessServiceInterface $siteAccessService;
  21. private SiteContextServiceInterface $siteContextService;
  22. private ConfigResolverInterface $configResolver;
  23. public function __construct(
  24. SiteAccessServiceInterface $siteDefinitionAccessService,
  25. SiteContextServiceInterface $siteContextService,
  26. ConfigResolverInterface $configResolver
  27. ) {
  28. $this->siteAccessService = $siteDefinitionAccessService;
  29. $this->siteContextService = $siteContextService;
  30. $this->configResolver = $configResolver;
  31. }
  32. public static function getSubscribedEvents(): array
  33. {
  34. return [
  35. MVCEvents::PRE_CONTENT_VIEW => 'onPreContentView',
  36. ];
  37. }
  38. public function onPreContentView(PreContentViewEvent $event): void
  39. {
  40. $view = $event->getContentView();
  41. if ($view instanceof ContentView && $this->isAdminSiteAccess()) {
  42. $location = $view->getLocation();
  43. if ($location instanceof Location && $this->isContextAware($location)) {
  44. $rootLocationId = $this->getTreeRootLocationId();
  45. if ($rootLocationId !== null) {
  46. $this->applyContentTreeFilter($view, $rootLocationId);
  47. $this->applyBreadcrumbsFilter($view, $rootLocationId);
  48. }
  49. }
  50. }
  51. }
  52. private function applyBreadcrumbsFilter(ContentView $view, int $rootLocationId): void
  53. {
  54. if ($view->hasParameter('path_locations')) {
  55. /** @var \Ibexa\Contracts\Core\Repository\Values\Content\Location[] $segments */
  56. $segments = $view->getParameter('path_locations');
  57. foreach ($segments as $segment) {
  58. if ($segment->id === $rootLocationId) {
  59. break;
  60. }
  61. array_shift($segments);
  62. }
  63. $view->addParameters([
  64. 'path_locations' => $segments,
  65. ]);
  66. }
  67. }
  68. private function applyContentTreeFilter(ContentView $view, int $rootLocationId): void
  69. {
  70. $view->addParameters([
  71. 'content_tree_module_root' => $rootLocationId,
  72. ]);
  73. }
  74. /**
  75. * Returns true if current siteaccess is administrative.
  76. */
  77. private function isAdminSiteAccess(): bool
  78. {
  79. $siteAccess = $this->siteAccessService->getCurrent();
  80. if ($siteAccess === null) {
  81. return false;
  82. }
  83. return (new IsAdmin())->isSatisfiedBy($siteAccess);
  84. }
  85. private function getTreeRootLocationId(): ?int
  86. {
  87. $siteaccess = $this->siteContextService->getCurrentContext();
  88. if ($siteaccess !== null) {
  89. return $this->configResolver->getParameter(
  90. 'content.tree_root.location_id',
  91. null,
  92. $siteaccess->name
  93. );
  94. }
  95. return null;
  96. }
  97. private function isContextAware(Location $location): bool
  98. {
  99. return IsContextAware::fromConfiguration($this->configResolver)->isSatisfiedBy($location);
  100. }
  101. }