<?php
/**
* Created by simpson <simpsonwork@gmail.com>
* Date: 2019-07-19
* Time: 13:32
*/
namespace App\Service;
use App\Controller\ProfileListController;
use App\Entity\Location\City;
use App\Routing\DynamicRouter;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class CanonicalUrlGenerator
{
private string $defaultCity;
public function __construct(
protected UrlGeneratorInterface $urlGenerator,
protected RequestStack $requestStack,
private Features $features,
ParameterBagInterface $parameterBag
)
{
$this->defaultCity = $parameterBag->get('default_city');
}
public function generate(?string $host = null): string
{
$request = $this->requestStack->getMasterRequest();
if (!$request) {
return '';
}
$routeName = $request->attributes->get('_route', '');
$parameters = $request->attributes->get('_route_params', []);
if (!$routeName) {
return '';
}
if (ProfileListController::class.'::listByCity' === $request->attributes->get('_controller') && !$this->features->homepage_as_city_list()) {
$currentPage = $this->features->canonical_url_with_pagination()
? (int)$request->get('page')
: 1; // При выключенной пагинации для каноникалов генерим урл для первой страницы
$currentCity = $parameters['city'] ?? '';
if ($this->defaultCity === $currentCity && $currentPage < 2) {
$routeName = 'homepage';
}
}
// Если открыта страница переопределенного роута, выдаем в canonical новый адрес
if ($request->attributes->has(DynamicRouter::OVERRIDDEN_ROUTE_PARAMETER)) {
$routeName = $request->attributes->get(DynamicRouter::OVERRIDDEN_ROUTE_PARAMETER);
}
// Удаляем параметры, начинающиеся с "_", чтобы они не попали в query string
$parameters = array_filter($parameters, function ($paramName): bool {
return '_' !== substr($paramName, 0, 1);
}, ARRAY_FILTER_USE_KEY);
if (!$this->features->canonical_url_with_pagination()) {
// На страницах пагинации для canonical выдаем адрес первой страницы
$parameters['page'] = 1;
if (false !== strpos($routeName, DynamicRouter::PAGINATION_ROUTE_POSTFIX)) {
$routeName = str_replace(DynamicRouter::PAGINATION_ROUTE_POSTFIX, '', $routeName);
}
}
$url = $this->generateUrl(
$routeName,
$parameters,
null !== $host ? UrlGeneratorInterface::ABSOLUTE_URL : UrlGeneratorInterface::ABSOLUTE_PATH,
$host
);
return strtolower($url);
}
public function generateCityProfiles(City $city, ?string $host = null): string
{
$routeName = $this->defaultCity === $city->getUriIdentity()
? 'homepage'
: 'profile_list.list_by_city';
$parameters = 'homepage' === $routeName
? []
: ['city' => $city->getUriIdentity()];
$url = $this->generateUrl($routeName, $parameters, UrlGeneratorInterface::ABSOLUTE_URL, $host);
return 'homepage' === $routeName ? rtrim(strtolower($url), '/') : strtolower($url);
}
private function generateUrl(string $routeName, array $parameters, int $referenceType, ?string $host = null): string
{
if (null === $host) {
return $this->urlGenerator->generate($routeName, $parameters, $referenceType);
}
$context = $this->urlGenerator->getContext();
$prevHost = $context->getHost();
$context->setHost($host);
$url = $this->urlGenerator->generate($routeName, $parameters, $referenceType);
$context->setHost($prevHost);
return $url;
}
}