vendor/ibexa/personalization/src/lib/Event/Subscriber/RecommendationEventSubscriber.php line 72

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\Personalization\Event\Subscriber;
  8. use Ibexa\Contracts\Core\Repository\Values\Content\Content;
  9. use Ibexa\Core\MVC\Symfony\Locale\LocaleConverterInterface;
  10. use Ibexa\Personalization\Config\Repository\RepositoryConfigResolverInterface;
  11. use Ibexa\Personalization\Event\PersonalizationEvent;
  12. use Ibexa\Personalization\Event\RecommendationResponseEvent;
  13. use Ibexa\Personalization\OutputType\OutputTypeResolverInterface;
  14. use Ibexa\Personalization\Request\BasicRecommendationRequest as Request;
  15. use Ibexa\Personalization\Service\RecommendationServiceInterface;
  16. use Ibexa\Personalization\SPI\RecommendationRequest;
  17. use Psr\Http\Message\ResponseInterface;
  18. use Psr\Log\LoggerAwareInterface;
  19. use Psr\Log\LoggerAwareTrait;
  20. use Psr\Log\LoggerInterface;
  21. use Psr\Log\NullLogger;
  22. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  23. use Symfony\Component\HttpFoundation\ParameterBag;
  24. use Symfony\Component\HttpFoundation\Response;
  25. final class RecommendationEventSubscriber implements EventSubscriberInterfaceLoggerAwareInterface
  26. {
  27.     use LoggerAwareTrait;
  28.     private const DEFAULT_LOCALE 'eng-GB';
  29.     private const LOCALE_REQUEST_KEY '_locale';
  30.     private LocaleConverterInterface $localeConverter;
  31.     private OutputTypeResolverInterface $outputTypeResolver;
  32.     private RecommendationServiceInterface $recommendationService;
  33.     private RepositoryConfigResolverInterface $repositoryConfigResolver;
  34.     public function __construct(
  35.         LocaleConverterInterface $localeConverter,
  36.         OutputTypeResolverInterface $outputTypeResolver,
  37.         RecommendationServiceInterface $recommendationService,
  38.         RepositoryConfigResolverInterface $repositoryConfigResolver,
  39.         ?LoggerInterface $logger null
  40.     ) {
  41.         $this->localeConverter $localeConverter;
  42.         $this->outputTypeResolver $outputTypeResolver;
  43.         $this->recommendationService $recommendationService;
  44.         $this->repositoryConfigResolver $repositoryConfigResolver;
  45.         $this->logger $logger ?? new NullLogger();
  46.     }
  47.     /**
  48.      * {@inheritdoc}
  49.      */
  50.     public static function getSubscribedEvents(): array
  51.     {
  52.         return [
  53.             RecommendationResponseEvent::class => ['onRecommendationResponse'PersonalizationEvent::DEFAULT_PRIORITY],
  54.         ];
  55.     }
  56.     /**
  57.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
  58.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
  59.      */
  60.     public function onRecommendationResponse(RecommendationResponseEvent $event): void
  61.     {
  62.         $recommendationRequest $this->getRecommendationRequest($event->getParameterBag());
  63.         $response $this->recommendationService->getRecommendations($recommendationRequest);
  64.         if (!$response) {
  65.             return;
  66.         }
  67.         $event->setRecommendationItems($this->extractRecommendationItems($response));
  68.     }
  69.     /**
  70.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
  71.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
  72.      */
  73.     private function getRecommendationRequest(ParameterBag $parameterBag): Request
  74.     {
  75.         $parameters = [
  76.             RecommendationRequest::SCENARIO => $parameterBag->get(RecommendationRequest::SCENARIO''),
  77.             Request::LIMIT_KEY => (int) $parameterBag->get(Request::LIMIT_KEY3),
  78.             Request::OUTPUT_TYPE_KEY => $this->outputTypeResolver->resolveFromParameterBag($parameterBag),
  79.             Request::LANGUAGE_KEY => $this->getRequestLanguage($parameterBag->get(self::LOCALE_REQUEST_KEY)),
  80.             Request::ATTRIBUTES_KEY => $parameterBag->get(Request::ATTRIBUTES_KEY, []),
  81.             Request::FILTERS_KEY => $parameterBag->get(Request::FILTERS_KEY, []),
  82.         ];
  83.         $content $parameterBag->get(Request::CONTEXT_ITEMS_KEY);
  84.         if ($content instanceof Content) {
  85.             $parameters[Request::CONTEXT_ITEMS_KEY] = $this->repositoryConfigResolver->useRemoteId()
  86.                 ? $content->contentInfo->remoteId
  87.                 : (string) $content->id;
  88.             $parameters[Request::CONTENT_TYPE_KEY] = $content->getContentType()->id;
  89.             $parameters[Request::CATEGORY_PATH_KEY] = $this->getCategoryPath($content);
  90.         }
  91.         return new Request($parameters);
  92.     }
  93.     private function getRequestLanguage(?string $locale): string
  94.     {
  95.         return $this->localeConverter->convertToEz($locale) ?? self::DEFAULT_LOCALE;
  96.     }
  97.     private function extractRecommendationItems(ResponseInterface $response): array
  98.     {
  99.         if ($response->getStatusCode() !== Response::HTTP_OK) {
  100.             $this->logger->warning('RecommendationApi: StatusCode: ' $response->getStatusCode() . ' Message: ' $response->getReasonPhrase());
  101.         }
  102.         $recommendations $response->getBody()->getContents();
  103.         $recommendationItems json_decode($recommendationstrue512JSON_THROW_ON_ERROR);
  104.         return $this->recommendationService->getRecommendationItems($recommendationItems['recommendationItems']);
  105.     }
  106.     private function getCategoryPath(Content $content): ?string
  107.     {
  108.         $mainLocation $content->contentInfo->getMainLocation();
  109.         if (null === $mainLocation) {
  110.             return null;
  111.         }
  112.         $parentLocation $mainLocation->getParentLocation();
  113.         return null !== $parentLocation $parentLocation->pathString null;
  114.     }
  115. }
  116. class_alias(RecommendationEventSubscriber::class, 'EzSystems\EzRecommendationClient\Event\Subscriber\RecommendationEventSubscriber');