Skip to content

__construct() must implement interface Symfony\Component\EventDispatcher\EventDispatcherInterface, none given #2744

Closed
@LailaMai

Description

@LailaMai

Hello,
My project was working just fine till I made composer update and I get this error:

Catchable Fatal Error: Argument 1 passed to FOS\UserBundle\Controller\ProfileController::__construct() must implement interface Symfony\Component\EventDispatcher\EventDispatcherInterface, none given, called in C:\wamp\www\themecheck.org\var\cache\dev\jms_diextra\controller_injectors\UserBundleControllerAccountController.php on line 13 and defined

My composer infos:

"require": {
"php": ">=5.5.9",
"symfony/symfony": "3.1.*",
"doctrine/orm": "^2.5",
"doctrine/doctrine-bundle": "^1.6",
"doctrine/doctrine-cache-bundle": "^1.2",
"symfony/swiftmailer-bundle": "^2.3.10",
"symfony/monolog-bundle": "^3.0.2",
"symfony/polyfill-apcu": "^1.0",
"sensio/distribution-bundle": "^5.0",
"sensio/framework-extra-bundle": "^3.0.2",
"incenteev/composer-parameter-handler": "^2.0",
"friendsofsymfony/user-bundle": "~2.0",
"jms/i18n-routing-bundle": "^2.0",
"jms/translation-bundle": "^1.3",
"jms/di-extra-bundle": "^1.8",
"guzzlehttp/guzzle": "^6.2",
"stof/doctrine-extensions-bundle": "^1.2"
},

Stack Trace

in vendor\friendsofsymfony\user-bundle\Controller\ProfileController.php at line 39 -

36: private $formFactory;
37: private $userManager;
38:
39: public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, UserManagerInterface $userManager)
40: {
41: $this->eventDispatcher = $eventDispatcher;
42: $this->formFactory = $formFactory;

**highlight the 39 line in log

I have tried many solutions like overriding the parent constructor or adding public function __construct(){parent::__construct();} in the override controller but nothing seems to work.

Is there something changed in the FosUserBundle that create this bug? how can I fix it ?

Activity

LailaMai

LailaMai commented on Feb 27, 2018

@LailaMai
Author

Actually I set in composer the version like that:
"friendsofsymfony/user-bundle": "=2.0.1", (run composer update of course) and now things work again, I see that the recent changes made in FosUserBundle cause code breakage which normally shouldn't.

phpeek

phpeek commented on Feb 27, 2018

@phpeek

@LailaMai This is probably due to the fact that Your AccountController extends ProfileController and overrides its original actions. This is correct and works in Symfony 2 / 3(though deprecated) but will no longer work in Symfony 4 since bundle inheritance is no longer supported - https://symfony.com/doc/current/bundles/inheritance.html

Since FOSUserBundle version 2.1 supports Symfony 4, all controllers are registered as services - e.g.
https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/config/profile.xml#L21. Your controller's class will never be injected with those services - hence an error You're seeing.

I've reached out to @stof via Twitter on how to handle this and used his advice by overriding via routing - https://twitter.com/Stof70/status/968478748906541057, however this will not work, since controller still won't be injected with services.

What I would suggest for now is creating compiler pass and overriding fos_user.profile.controller service's class as described here - https://symfony.com/doc/current/bundles/override.html#services-configuration

This proves to be working for me.

P.S. Not sure if that's a game changer, but I'm on Symfony 2.8. 😢

LailaMai

LailaMai commented on Feb 28, 2018

@LailaMai
Author

OK I'll try this solution and see what will happen, Thanks @phpeek 👍

XWB

XWB commented on Mar 2, 2018

@XWB
Member

Thanks @phpeek

stof

stof commented on Mar 2, 2018

@stof
Member

@phpeek overriding via routing still allows you to use DI for yoru own class. And when creating your own controller replacing some action, you should probably not even make it extend the FOSUserbundle class (which does not provide inheritance-based extension point anyway)

slince

slince commented on Mar 5, 2018

@slince

@phpeek @XWB

I have created a controller ChangePasswordController extends FOS\UserBundle\Controller\ChangePasswordController

However how i get service from container? $this->container is invalid in the constructor.

class ChangePasswordController extends FOSChangePasswordController
{
    public function __construct() {
        $eventDispatcher = $this->get('event_dispatcher');
        $formFactory = $this->get('fos_user.change_password.form.factory');
        $userManager = $this->get('fos_user.user_manager');
        parent::__construct($eventDispatcher, $formFactory, $userManager);
    }
}
phpeek

phpeek commented on Mar 5, 2018

@phpeek

@stof Granted, this is probably not the best way on extending FOSUserBundle controllers. However, I see issues related to this problem being submitted, so looks like people took this bad approach. Do You think this should be treated as BC break and bump in major version ?

@slince If you've created a compiler pass for Your ChangePasswordController, those services will be injected into its constructor. If You're not doing anything custom in Your controller's constructor, You don't have to override parent's constructor.

blackarcanis

blackarcanis commented on Mar 21, 2018

@blackarcanis

@phpeek So to be sure, "good way" to do is to create a compiler pass, right ?

LailaMai

LailaMai commented on Mar 21, 2018

@LailaMai
Author

Finally in my case, I had at first time, "AccountController extends FOS\UserBundle\Controller\ProfileController" , with overriding the editAction and I had also "RegistrationController extends FOS\UserBundle\Controller\RegistrationController" with overriding confirmAction and confirmedAction, I updated my composer as following:
"require": {
"symfony/symfony": "3.4.*",
"friendsofsymfony/user-bundle": "~2.0",
.....
},
I don't really know how to work with compiler pass in my case, so in order to fix the bundle inheritance deprecation ,I just removed this line from UserBundle:
public function getParent() { return 'FOSUserBundle'; }
And changed "class AccountController extends Controller" and "class RegistrationController extends Controller" and everything works fine as normal, the deprecation messages also disappeared.

phpeek

phpeek commented on Mar 28, 2018

@phpeek

@blackarcanis No :) Consider it a "hacky" way.

As @stof mentioned here extending any of the FOSUserBundle's controllers is not a a valid extension point. You should rather create Your own controller instead.

The problem here is that properties of base controller classes are marked as private, not protected - e.g ProfileController

It means You won't be able to access them in Your controller when extending base controller unless You redefine them in Your controller, override __constructor and create compiler pass. With all that said, it should be more clear why this is a "hacky" way of solving this issue. 😢

marcel-burkhard

marcel-burkhard commented on Apr 9, 2018

@marcel-burkhard

I didn't override the Controller but used another (nasty) shortcut in an application where the user can request to reset his password in another application (not symfony) and that request is sent to the symfony application through a json api:

$response = $this->forward('FOS\UserBundle\Controller\ResettingController::sendEmailAction', [
    'request' => $request
]);

$expectedRedirectUrl = $this->generateUrl('fos_user_resetting_check_email', ['username' => $username]);

if (!$response instanceof RedirectResponse) {
	return new JsonResponse([
		'error' => 'Something went wrong.'
	], 500);
}

if ($response->getTargetUrl() != $expectedRedirectUrl) {
	return new JsonResponse([
		'error' => 'Something went wrong.'
	], 500);
}

return new JsonResponse([
	'success' => true
], 200);

this doesn't work with "friendsofsymfony/user-bundle": "~2.1" so I downgraded to ~2.0
error (shortened) was:

[3] request.CRITICAL: Uncaught PHP Exception Type error: Too few arguments to function FOS\UserBundle\Controller\ResettingController::__construct(), 0 passed in ...\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Controller\ControllerResolver.php on line 195 and exactly 6 expected" "} []`

I'm actually surprised that $this->forward() doesn't know how to create a ResettingController.
Silly question: Is there a configuration workaround so I can keep my code and version 2.1?

DH-INT

DH-INT commented on Apr 14, 2018

@DH-INT

@LailaMai it's work fine for me after downgrading fosuserbundle with ~2.0.1

LailaMai

LailaMai commented on Apr 16, 2018

@LailaMai
Author

@DH-INT I know , I mentioned that on my second comment, but if you need to upgrade the bundle in future you need to make some modifications to make it work fine again.

devozanges

devozanges commented on Jun 4, 2018

@devozanges

the version 2.0.2 fix the same problem for me.
thx

HeahDude

HeahDude commented on Jun 7, 2018

@HeahDude

I had the same issue, see #2807.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @stof@XWB@phpeek@slince@marcel-burkhard

      Issue actions

        __construct() must implement interface Symfony\Component\EventDispatcher\EventDispatcherInterface, none given · Issue #2744 · FriendsOfSymfony/FOSUserBundle