vendor/ibexa/segmentation/src/lib/Event/Subscriber/TargetingBlockRenderSubscriber.php line 67

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\Segmentation\Event\Subscriber;
  8. use Ibexa\Contracts\Core\Repository\ContentService;
  9. use Ibexa\Contracts\Core\Repository\LocationService;
  10. use Ibexa\Contracts\Core\Repository\PermissionResolver;
  11. use Ibexa\Contracts\Core\Repository\UserService;
  12. use Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo;
  13. use Ibexa\Contracts\Core\Repository\Values\User\User;
  14. use Ibexa\Contracts\FieldTypePage\FieldType\LandingPage\Model\BlockValue;
  15. use Ibexa\Contracts\Segmentation\SegmentationServiceInterface;
  16. use Ibexa\FieldTypePage\FieldType\Page\Block\Renderer\BlockRenderEvents;
  17. use Ibexa\FieldTypePage\FieldType\Page\Block\Renderer\Event\PreRenderEvent;
  18. use Ibexa\HttpCache\Handler\TagHandler;
  19. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  20. final class TargetingBlockRenderSubscriber implements EventSubscriberInterface
  21. {
  22. /** @var \Ibexa\Contracts\Core\Repository\PermissionResolver */
  23. private $permissionResolver;
  24. /** @var \Ibexa\Contracts\Core\Repository\UserService */
  25. private $userService;
  26. /** @var \Ibexa\Contracts\Core\Repository\LocationService */
  27. private $locationService;
  28. /** @var \Ibexa\Contracts\Core\Repository\ContentService */
  29. private $contentService;
  30. /** @var \Ibexa\Contracts\Segmentation\SegmentationServiceInterface */
  31. private $segmentationService;
  32. /** @var \Ibexa\HttpCache\Handler\TagHandler */
  33. private $tagHandler;
  34. public function __construct(
  35. PermissionResolver $permissionResolver,
  36. UserService $userService,
  37. LocationService $locationService,
  38. ContentService $contentService,
  39. SegmentationServiceInterface $segmentationService,
  40. TagHandler $tagHandler
  41. ) {
  42. $this->permissionResolver = $permissionResolver;
  43. $this->userService = $userService;
  44. $this->locationService = $locationService;
  45. $this->contentService = $contentService;
  46. $this->segmentationService = $segmentationService;
  47. $this->tagHandler = $tagHandler;
  48. }
  49. public static function getSubscribedEvents(): array
  50. {
  51. return [
  52. BlockRenderEvents::getBlockPreRenderEventName('targeting') => 'onBlockPreRender',
  53. ];
  54. }
  55. public function onBlockPreRender(PreRenderEvent $event): void
  56. {
  57. $blockValue = $event->getBlockValue();
  58. $contentMap = $this->getContentMap($blockValue);
  59. $user = $this->getCurrentUser();
  60. $segments = $this->segmentationService->loadSegmentsAssignedToUser($user);
  61. $segmentIds = array_column($segments, 'id');
  62. $locationId = null;
  63. foreach ($contentMap as $segmentData) {
  64. if (in_array($segmentData['segmentId'], $segmentIds, true)) {
  65. $locationId = $segmentData['locationId'];
  66. break;
  67. }
  68. }
  69. if (null === $locationId) {
  70. $defaultContent = $this->getDefaultContent($blockValue);
  71. $locationId = $defaultContent->mainLocationId;
  72. }
  73. $location = $this->locationService->loadLocation($locationId);
  74. $parameters = ['location' => $location];
  75. /** @var \Ibexa\FieldTypePage\FieldType\Page\Block\Renderer\Twig\TwigRenderRequest $renderRequest */
  76. $renderRequest = $event->getRenderRequest();
  77. $renderRequest->setParameters(array_merge($renderRequest->getParameters(), $parameters));
  78. foreach ($segmentIds as $segmentId) {
  79. $this->tagHandler->addTags(['sg' . $segmentId]);
  80. }
  81. $this->tagHandler->addLocationTags([$locationId]);
  82. // @todo This is hack for problem with tags invalidation when segment is assigned/unassigned to user.
  83. $this->tagHandler->addTags(['tb']);
  84. }
  85. private function getDefaultContent(BlockValue $blockValue): ContentInfo
  86. {
  87. $defaultContentAttribute = $blockValue->getAttribute('default_content_id');
  88. $defaultContentId = (int)$defaultContentAttribute->getValue();
  89. return $this->contentService->loadContentInfo($defaultContentId);
  90. }
  91. private function getContentMap(BlockValue $blockValue): array
  92. {
  93. $contentMapAttribute = $blockValue->getAttribute('content_map');
  94. return json_decode($contentMapAttribute->getValue(), true);
  95. }
  96. private function getCurrentUser(): User
  97. {
  98. $userId = $this->permissionResolver->getCurrentUserReference()->getUserId();
  99. return $this->userService->loadUser($userId);
  100. }
  101. }
  102. class_alias(TargetingBlockRenderSubscriber::class, 'Ibexa\Platform\Segmentation\Event\Subscriber\TargetingBlockRenderSubscriber');