FriendsOfSymfony / FOSCommentBundle

Threaded comments for Symfony
http://friendsofsymfony.github.com/
MIT License
462 stars 230 forks source link

Cannot use form factory when extending controller #684

Open Martin1982 opened 5 years ago

Martin1982 commented 5 years ago

When extending the FOS\CommentBundle\Controller\ThreadController class and overriding the newThreadCommentsAction I'm not able to use the $this->container->get('fos_comment.form_factory.comment') like it is called in the parent method.

The error returned is; Service "fos_comment.form_factory.comment" not found: even though it exists in the app's container, the container inside "App\Controller\ThreadController" is a smaller service locator that only knows about the "doctrine", "form.factory", "http_kernel", "parameter_bag", "request_stack", "router", "security.authorization_checker", "security.csrf.token_manager", "security.token_storage", "serializer", "session", "templating" and "twig" services. Try using dependency injection instead.

I'm using Symfony 4.2 with FOSCommentBundle 2.3. Up till FOSCommentBundle 2.2 this did work. Therefor it seems like it might be a BC-break.

rakini-yassine commented 5 years ago

i have the same issue ? did u found the solution

onEXHovia commented 5 years ago

Its related https://github.com/FriendsOfSymfony/FOSCommentBundle/pull/681

@jyyyy temporary solution:

use FOS\CommentBundle\Controller\ThreadController as BaseThreadController;
use Symfony\Component\DependencyInjection\ContainerInterface;

class ThreadController extends BaseThreadController
{
    protected $container;

    public function __construct(ContainerInterface $container)
    {
        // Override container
        $this->container = $container;
    }

    public function setContainer(\Psr\Container\ContainerInterface $container)
    {
    }
}
XWB commented 5 years ago

You will have to inject the fos_comment.form_factory.comment service into your controller class. If autowire is enabled, you should be able to do something like this:


use FOS\CommentBundle\Controller\ThreadController;
use FOS\CommentBundle\FormFactory\CommentFormFactory;

class CustomThreadController extends BaseThreadController
{
    private $formFactory;

    public function __construct(CommentFormFactory $formFactory)
    {
        $this->formFactory = $formFactory;
    }
}
XWB commented 5 years ago

Another solution that might work is adding a getSubscribedServices method to your controller class.


use FOS\CommentBundle\Controller\ThreadController;
use FOS\CommentBundle\FormFactory\CommentFormFactory;

class CustomThreadController extends BaseThreadController
{
    public static function getSubscribedServices(): array
    {
        $services = parent::getSubscribedServices();
        $services['fos_comment.form_factory.comment'] = CommentFormFactory::class;

        return $services;
    }
}

Note: this probably won't work if you use a custom comment form factory.

onEXHovia commented 5 years ago

@XWB, should then method getSubscribedServices added by default with required dependencies in AbstractController https://github.com/FriendsOfSymfony/FOSCommentBundle/blob/master/Controller/AbstractController.php#L15 such as fos_comment.manager.thread fos_comment.manager.comment and other? Оtherwise I do not understand how it defines these default dependencies. After the update, i received exceptions:

An exception has been thrown during the rendering of a template ("Service "fos_comment.manager.thread" not found: even though it exists in the app's container, the container inside "App\Controller\ThreadController" is a smaller service locator that only knows about the "doctrine", "form.factory", "http_kernel", "parameter_bag", "request_stack", "router", "security.authorization_checker", "security.csrf.token_manager", "security.token_storage", "serializer", "session", "templating" and "twig" services. Try using dependency injection instead.").

XWB commented 5 years ago

The getSubscribedServices is not recommended however, Symfony advises that the app container should remain small. The best solution is to inject the required services via dependency injection as provided in my first example.

Martin1982 commented 5 years ago

The getSubscribedServices is not recommended however, Symfony advises that the app container should remain small. The best solution is to inject the required services via dependency injection as provided in my first example.

@XWB Even though I understand that dependency injection is the correct way to solve this. Your solution still gives me an error message;

Cannot autowire service "App\Controller\ThreadController": argument "$formFactory" of method "__construct()" references class "FOS\CommentBundle\FormFactory\CommentFormFactory" but no such service exists. You should maybe alias this class to the existing "fos_comment.form_factory.comment.default" service.

The reason I posted it here instead of StackOverflow is because this error only occurred after updating from 2.2.x to 2.3.x

Even though a workaround would help me personally, I think this might be a bug since the upgrade is not backwards compatible in this particular situation.

Loving this bundle though, and thanks for taking the time to respond so quickly! I really appreciate it.

PouleR commented 4 years ago

Is there maybe any update regarding this issue?

alekseyTr commented 3 years ago

any update???