-1

Recently I am upgrading the system to Symfony 4.2, in one of my page, I encountered the error saying

Call to protected method Symfony\Bundle\FrameworkBundle\Controller\Controller::generateUrl() from context 'Acme\Bundle\Security\Listener\SecurityListener'

The line at which the error is showing:

$this_url = $controller[0]->generateUrl($event->getRequest()->get('_route'), $event->getRequest()->get('_route_params'));

Please let me know, is there anything that I have left.

Captain Planet
  • 408
  • 3
  • 19
  • Protected methods are only visible within the class instance, which means you cannot use them from outside the class. It is possible to use them with Reflection, but its not advisable. – ArtisticPhoenix Feb 19 '19 at 09:12
  • What is the content of `$controller`? – D4V1D Feb 19 '19 at 09:12
  • If you extend the class you can use it, but should it extend the class with the method. – ArtisticPhoenix Feb 19 '19 at 09:14
  • SecurityListener.php on line 45: array:2 [▼ 0 => AcmeController {#583 ▼ -country_name: array:249 [▶] +email_sender: array:1 [▶] #container: appAppKernelDevDebugContainer {#460 …20} } 1 => "acmeAction" ] This is the content of the Controller @D4V1D – Captain Planet Feb 19 '19 at 09:17
  • @ArtisticPhoenix I did found the url https://api.symfony.com/master/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.html#method_generateUrl but trait cannot be extended. Please check. – Captain Planet Feb 19 '19 at 09:21
  • I didn't realize it's a trait, Im not a symfony user, you can rename the trait's method. then write your own with the original name, and reference the renamed trait method from witin your (public) method. – ArtisticPhoenix Feb 19 '19 at 09:24

2 Answers2

2

You are trying to call the controller helper method from a listener. As @ArtisticPhoenix has said in the comments, this is not allowed. What you could do here is instead rewrite your listener to use not the controller's method (which is just intended to be a helper for your actions), but the actual router method that generates the URL. Take a look at the Controller (or ControllerTrait depending on your Symfony version). The generateUrl() method makes a call on the @router service:

/**
 * Generates a URL from the given parameters.
 *
 * @see UrlGeneratorInterface
 *
 * @final
 */
protected function generateUrl(string $route, array $parameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): string
{
    return $this->container->get('router')->generate($route, $parameters, $referenceType);
}

That's what you actually have to use instead of calling the controller's method. You could try something like this:

$this_url = $this->container->get('router')->generate($event->getRequest()->get('_route'), $event->getRequest()->get('_route_params'));

Although, you'd have to make sure you either have the container available (which in general is not a good pattern), or you pass the Router into your service as a dependency. This way, you'd change $this->container->get('router') to the prop you're injecting the router into.

kix
  • 3,290
  • 27
  • 39
0

If you just want to generate an url in your Listener, you can simply inject the router component to you class :

private $router;

public function __construct(UrlGeneratorInterface $router)
{
    $this->router = $router;
}

...

// Use it like this

$url = $this->router->generate(
    $event->getRequest()->get('_route'),
    $event->getRequest()->get('_route_params')
);
Zak
  • 1,005
  • 10
  • 22