在 symfony 4.3 中覆盖 FOS 控制器时无法解析参数 $token

Could not resolve argument $token on override FOS Controller in symfony 4.3

首先,我尝试了与该主题相关的所有问题和答案。此外,我尝试了相关问题并尝试解决但没有成功。所以请仔细阅读我的问题。

我想覆盖 FOS 控制器。我成功重定向但没有得到完美的 /register/confirm/{token} 工作。 我收到令牌错误。

获取错误: 无法解析 "App\Controller\RegistrationController::confirmaction()" 的参数 $token,也许您忘记将控制器注册为服务或错过了用 "controller.service_arguments"?

标记它

我的代码

RegistrationController.php

<?php

/*
 * This file is part of the FOSUserBundle package.
 *
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace App\Controller;

use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;


class RegistrationController extends \FOS\UserBundle\Controller\RegistrationController
{
    private $eventDispatcher;
    private $formFactory;
    private $userManager;
    private $tokenStorage;

    public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, UserManagerInterface $userManager, TokenStorageInterface $tokenStorage)
    {
        $this->eventDispatcher = $eventDispatcher;
        $this->formFactory     = $formFactory;
        $this->userManager     = $userManager;
        $this->tokenStorage    = $tokenStorage;
    }

    public function registerAction(Request $request)
    {
        dump('d1');
        $user = $this->userManager->createUser();
        $user->setEnabled(true);

        $event = new GetResponseUserEvent($user, $request);
        $this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);

        if (null !== $event->getResponse()) {
            return $event->getResponse();
        }

        $form = $this->formFactory->createForm();
        $form->setData($user);

        $form->handleRequest($request);

        if ($form->isSubmitted()) {
            if ($form->isValid()) {
                $event = new FormEvent($form, $request);
                $this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);

                $this->userManager->updateUser($user);

                if (null === $response = $event->getResponse()) {
                    $url = $this->generateUrl('fos_user_registration_confirmed');
                    $response = new RedirectResponse($url);
                }

                $this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));

                return $response;
            }

            $event = new FormEvent($form, $request);
            $this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_FAILURE, $event);

            if (null !== $response = $event->getResponse()) {
                return $response;
            }
        }

        return $this->render('@FOSUser/Registration/register.html.twig', array(
            'form' => $form->createView(),
        ));
    }


    public function confirmAction(Request $request, $token)
    {
        dump('d');
        $userManager = $this->userManager;

        $user = $userManager->findUserByConfirmationToken($token);

        if (null === $user) {
            throw new NotFoundHttpException(sprintf('The user with confirmation token "%s" does not exist', $token));
        }

        $user->setConfirmationToken(null);
        $user->setEnabled(true);

        $event = new GetResponseUserEvent($user, $request);
        $this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_CONFIRM, $event);

        $userManager->updateUser($user);

        if (null === $response = $event->getResponse()) {
            $url = $this->generateUrl('fos_user_registration_confirmed');
            $response = new RedirectResponse($url);
        }

        $this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_CONFIRMED, new FilterUserResponseEvent($user, $request, $response));

        return $response;
    }

    public function confirmedAction(Request $request)
    {
        $user = $this->getUser();
        if (!is_object($user) || !$user instanceof UserInterface) {
            throw new AccessDeniedException('This user does not have access to this section.');
        }

        return $this->render('@FOSUser/Registration/confirmed.html.twig', array(
            'user' => $user,
            'targetUrl' => $this->getTargetUrlFromSession($request->getSession()),
        ));
    }
    /**
     * @return string|null
     */
    private function getTargetUrlFromSession(SessionInterface $session)
    {
        $key = sprintf('_security.%s.target_path', $this->tokenStorage->getToken()->getProviderKey());

        if ($session->has($key)) {
            return $session->get($key);
        }

        return null;
    }


}

Service.yml

# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
    locale: 'en'


services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']

    # add more service definitions when explicit configuration is needed
    # please note that last definitions always *replace* previous ones

    app.fos_overriding_routes:
        class: App\EventListener\FosOverridingRoutes
        arguments: ['@router']
        tags:
            - { name: kernel.event_subscriber }

    App\Controller\RegistrationController:
        tags: ['controller.service_arguments']
        autowire: true
        arguments:
            $eventDispatcher: '@event_dispatcher'
            $formFactory: '@fos_user.registration.form.factory'
            $userManager: '@fos_user.user_manager'
            $tokenStorage: '@security.token_storage'

routes.yaml

fos_user:
    resource: "@FOSUserBundle/Resources/config/routing/all.xml"
#    prefix: setting

fos_user_registration_register:
    resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
    defaults: { _controller: App\Controller\RegistrationController::registerAction}
    #prefix: /register/

#
fos_user_registration_confirm:
    resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
    defaults: { _controller: App\Controller\RegistrationController::confirmAction }
    #path: /register/
    #prefix: /confirm/{token}
    prefix: /register/

尝试覆盖控制器操作时不要将资源条目与您自己的控制器条目组合

将路由更改为:

fos_user_registration_register:  
    controller: App\Controller\RegistrationController::registerAction
    path: /register


fos_user_registration_confirm:
    controller:App\Controller\RegistrationController::confirmAction
    path: /register/confirm/{token} 

你也可以将路由放在你的控制器中并带有注释: https://symfony.com/doc/4.1/routing.html