netgen / ezplatform-site-api

Netgen's Site API is site building productivity layer for eZ/Ibexa Platform
https://docs.netgen.io/projects/site-api
GNU General Public License v2.0
37 stars 8 forks source link

Enable autowired controllers #165

Closed MarioBlazek closed 4 years ago

MarioBlazek commented 4 years ago

This PR allows controllers to be autowired, which means that explicit service definition for a controller is not required anymore. By default SiteAPI controller extends the AbstractController which implements ServiceSubscriberInterface with the set of necessary services. We need to expand getSubscribedServices() method with services that are necessary for the Site API controller.

The use case we want to achieve. Custom view controller without service definition:

ng_recipe:
    template: "@ezdesign/content/full/ng_recipe.html.twig"
    controller: App\Controller\ExampleController::view
    match:
        Identifier\ContentType: ng_recipe
<?php

namespace App\Controller;

use Netgen\Bundle\EzPlatformSiteApiBundle\Controller\Controller;
use Netgen\Bundle\EzPlatformSiteApiBundle\View\ContentView;

class ExampleController extends Controller
{
    public function view(ContentView $view)
    {
        $this->getConfigResolver();
        $this->getGlobalHelper();
        $this->getQueryTypeRegistry();
        $this->getRepository();

        $this->getNamedObjectProvider();
        $this->getSite();

        return $view;
    }
}

Without this code, calling $this->getSite() would result in this error:

Service "netgen.ezplatform_site.site" not found: even though it exists in the app's container, the container inside "App\Controller\ExampleController" 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" and "twig" services. Try using dependency injection instead.
MarioBlazek commented 4 years ago

Service definitions are necessary because Symfony requires the value of array to be proper PHP type.

This won't work:

return [
    'service_id' => 'service_id',
];
emodric commented 4 years ago

Alright :+1:

emodric commented 4 years ago

Btw, don't we need an entry in NetgenEzPlatformSiteApiExtension to load autowiring.yml?

MarioBlazek commented 4 years ago

No, the main service.yml file has:

imports:
    - { resource: services/*.yml }
emodric commented 4 years ago

Ok, I'm apparently blind :D I was looking at the file and couldn't see it !

pspanja commented 4 years ago

Awesome, thanks @MarioBlazek!