src/Service/CanonicalUrlGenerator.php line 33

Open in your IDE?
  1. <?php
  2. /**
  3.  * Created by simpson <simpsonwork@gmail.com>
  4.  * Date: 2019-07-19
  5.  * Time: 13:32
  6.  */
  7. namespace App\Service;
  8. use App\Controller\ProfileListController;
  9. use App\Entity\Location\City;
  10. use App\Routing\DynamicRouter;
  11. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  12. use Symfony\Component\HttpFoundation\RequestStack;
  13. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  14. class CanonicalUrlGenerator
  15. {
  16.     private string $defaultCity;
  17.     public function __construct(
  18.         protected UrlGeneratorInterface $urlGenerator,
  19.         protected RequestStack $requestStack,
  20.         private Features $features,
  21.         ParameterBagInterface $parameterBag
  22.     )
  23.     {
  24.         $this->defaultCity = $parameterBag->get('default_city');
  25.     }
  26.     public function generate(?string $host = null): string
  27.     {
  28.         $request = $this->requestStack->getMasterRequest();
  29.         if (!$request) {
  30.             return '';
  31.         }
  32.         $routeName = $request->attributes->get('_route', '');
  33.         $parameters = $request->attributes->get('_route_params', []);
  34.         if (!$routeName) {
  35.             return '';
  36.         }
  37.         if (ProfileListController::class.'::listByCity' === $request->attributes->get('_controller') && !$this->features->homepage_as_city_list()) {
  38.             $currentPage = $this->features->canonical_url_with_pagination()
  39.                 ? (int)$request->get('page')
  40.                 : 1; // При выключенной пагинации для каноникалов генерим урл для первой страницы
  41.             $currentCity = $parameters['city'] ?? '';
  42.             if ($this->defaultCity === $currentCity && $currentPage < 2) {
  43.                 $routeName = 'homepage';
  44.             }
  45.         }
  46.         // Если открыта страница переопределенного роута, выдаем в canonical новый адрес
  47.         if ($request->attributes->has(DynamicRouter::OVERRIDDEN_ROUTE_PARAMETER)) {
  48.             $routeName = $request->attributes->get(DynamicRouter::OVERRIDDEN_ROUTE_PARAMETER);
  49.         }
  50.         // Удаляем параметры, начинающиеся с "_", чтобы они не попали в query string
  51.         $parameters = array_filter($parameters, function ($paramName): bool {
  52.             return '_' !== substr($paramName, 0, 1);
  53.         }, ARRAY_FILTER_USE_KEY);
  54.         if (!$this->features->canonical_url_with_pagination()) {
  55.             // На страницах пагинации для canonical выдаем адрес первой страницы
  56.             $parameters['page'] = 1;
  57.             if (false !== strpos($routeName, DynamicRouter::PAGINATION_ROUTE_POSTFIX)) {
  58.                 $routeName = str_replace(DynamicRouter::PAGINATION_ROUTE_POSTFIX, '', $routeName);
  59.             }
  60.         }
  61.         $url = $this->generateUrl(
  62.             $routeName,
  63.             $parameters,
  64.             null !== $host ? UrlGeneratorInterface::ABSOLUTE_URL : UrlGeneratorInterface::ABSOLUTE_PATH,
  65.             $host
  66.         );
  67.         return strtolower($url);
  68.     }
  69.     public function generateCityProfiles(City $city, ?string $host = null): string
  70.     {
  71.         $routeName = $this->defaultCity === $city->getUriIdentity()
  72.             ? 'homepage'
  73.             : 'profile_list.list_by_city';
  74.         $parameters = 'homepage' === $routeName
  75.             ? []
  76.             : ['city' => $city->getUriIdentity()];
  77.         $url = $this->generateUrl($routeName, $parameters, UrlGeneratorInterface::ABSOLUTE_URL, $host);
  78.         return 'homepage' === $routeName ? rtrim(strtolower($url), '/') : strtolower($url);
  79.     }
  80.     private function generateUrl(string $routeName, array $parameters, int $referenceType, ?string $host = null): string
  81.     {
  82.         if (null === $host) {
  83.             return $this->urlGenerator->generate($routeName, $parameters, $referenceType);
  84.         }
  85.         $context = $this->urlGenerator->getContext();
  86.         $prevHost = $context->getHost();
  87.         $context->setHost($host);
  88.         $url = $this->urlGenerator->generate($routeName, $parameters, $referenceType);
  89.         $context->setHost($prevHost);
  90.         return $url;
  91.     }
  92. }