Symfony 5 Как сгенерировать URL с помощью slug? - PullRequest
0 голосов
/ 14 января 2020

У меня есть приложение со слагом. Все маршруты будут начинаться с одного и того же URL. URL выглядит как myapp.com/company_slug/locale/.....

После того, как я отправил форму входа, у меня в GuardAuthenticator есть ошибка getLoginUrl (). Отсутствуют некоторые обязательные параметры ("company_slug") для создания URL-адреса для маршрута "app_login".

Как я могу использовать company_slug на всех маршрутах моего приложения и как исправить эту ошибку ?

<?php

namespace App\Security;

[.....]

/**
 * Class LoginFormAuthenticator
 */
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
    use TargetPathTrait;

    private $entityManager;
    private $urlGenerator;
    private $csrfTokenManager;
    private $passwordEncoder;

    public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
    {
        $this->entityManager = $entityManager;
        $this->urlGenerator = $urlGenerator;
        $this->csrfTokenManager = $csrfTokenManager;
        $this->passwordEncoder = $passwordEncoder;
    }

    [....]

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }

        $url = $this->urlGenerator->generate('index');

        return new RedirectResponse($url);
    }

    protected function getLoginUrl()
    {
        return $this->urlGenerator->generate('app_login');
    }
}

Контроллер, куда я хотел бы перенаправить на маршрут "index" (/ {company_slug} / {_ locale} / index).

<?php

namespace App\Controller;

use App\Entity\Candidate;
use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\User\UserInterface;

/**
 * Class DefaultController.
 *
 * @Route("/{company_slug}/{_locale}")
 */
class DefaultController extends AbstractController
{
    /**
     * @Route("/", name="index")
     */
    public function index()
    {
        if ($this->getUser() instanceof User) {
            return $this->redirectToRoute('admin_index');
        } elseif ($this->getUser() instanceof Candidate) {
            return $this->redirectToRoute('candidate_index');
        } else {
            return $this->redirectToRoute('app_login');
        }
    }
}

На всякий случай я установил атрибут компании в событии ядра.

<?php

namespace App\EventSubscriber;

use App\ContextStorage;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;

/**
 * Class AgencyContextSubscriber.
 */
class CompanyContextSubscriber implements EventSubscriberInterface
{
    /**
     * @var ContextStorage
     */
    private $contextStorage;

    public function __construct(ContextStorage $contextStorage)
    {
        $this->contextStorage = $contextStorage;
    }

    public function onKernelRequest(RequestEvent $event)
    {
        if (!$event->isMasterRequest()) {
            return;
        }

        $companySlug = $event->getRequest()->get('company_slug');

        if (!$companySlug) {
            return;
        }

        $company = $this->contextStorage->activateContextBySlug($companySlug);

        $event->getRequest()->attributes->set('company', $company);
    }

    public static function getSubscribedEvents()
    {
        return [
            'kernel.request' => 'onKernelRequest',
        ];
    }
}

1 Ответ

1 голос
/ 14 января 2020

Вам нужно передать массив параметров в $this->urlGenerator->generate('index');, он просто пытается сгенерировать ваш маршрут, но видит, что company_slug отсутствует, поэтому он не может сгенерировать URL для вас, в вашем CompanyContextSubscriber вы устанавливаете атрибут по запросу try чтобы получить его в onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey), попробуйте следующее:

$this->urlGenerator->generate('index', ['company_slug' => $request->attributes->get('company')]);

Я полагаю, вам нужно будет передать параметр _locale в массив выше

...