在 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
首先,我尝试了与该主题相关的所有问题和答案。此外,我尝试了相关问题并尝试解决但没有成功。所以请仔细阅读我的问题。
我想覆盖 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