Question

Looking at the code of the Sylius Bundle for Symfony I noticed the Resource Bundle has an interesting way of defining resource controllers as services. Here is the cart item controller service configuration in XML

<service id="sylius.controller.cart_item" class="%sylius.controller.cart_item.class%">
        <argument type="service">
            <service factory-service="sylius.controller.configuration_factory" factory-method="createConfiguration" class="Sylius\Bundle\ResourceBundle\Controller\Configuration">
                <argument>sylius</argument>
                <argument>cart_item</argument>
                <argument>SyliusCartBundle:CartItem</argument>
            </service>
        </argument>
        <call method="setContainer">
            <argument type="service" id="service_container" />
        </call>
    </service>

If I understand it correctly this code instantiates the controller class and passes as the constructor argument the result of a call to the factory-method "createConfiguration" in the factory-service class. Arguments are specified, so everything is fine.

My question is twofold: 1) Where is this documented? I could not find one example of this kind of arguments-as-a factory-callable in the docs. 2) What would be the YAML version of this?

Thanks...

Was it helpful?

Solution

Here is the way:

<service id="sylius.controller.cart_item" class="%sylius.controller.cart_item.class%">
    <argument type="service">
        <service factory-service="sylius.controller.configuration_factory" factory-method="createConfiguration" class="Sylius\Bundle\ResourceBundle\Controller\Configuration">
            <argument>sylius</argument>
            <argument>cart_item</argument>
            <argument>SyliusCartBundle:CartItem</argument>
        </service>
    </argument>
    <call method="setContainer">
        <argument type="service" id="service_container" />
    </call>
</service>

Can be written as the following in yml

sylius.controller.cart_item:
    class: %sylius.controller.cart_item.class%
    arguments:
        - "@=service('sylius.controller.configuration_factory').createConfiguration('sylius', 'cart_item', 'SyliusCartBundle:CartItem')"
    calls:
        - [setContainer, ["@service_container"]]

OTHER TIPS

You can find the answer to both of your questions in the dependency injection docs.

As far as defining a service nested under another service in YAML, it doesn't seem the parser that ships with Symfony can handle that, but I did find someone's pet project that seems to aim for this functionality: https://gist.github.com/Mikulas/8004470

I was trying to override the CartItemController and came across this, because I thought i needed to do it this way. But it's not the way to go. Anyways, to answer your question. Here is how the xml transforms into yaml

(because the solution suggested by Alexei Tenitski didn't work for me, I did it like so)

sylius.controller.cart_item:
    class:    Sylius\Bundle\ResourceBundle\Controller\ResourceController
    arguments:   ["@sylius.cart_item.config_factory"]
    calls:
       - [setContainer, ["@service_container"]]

sylius.cart_item.config_factory:
    class:  Sylius\Bundle\ResourceBundle\Controller\Configuration
    factory_class: Sylius\Bundle\ResourceBundle\Controller\ConfigurationFactory
    factory_method: createConfiguration
    arguments: ["sylius", "cart_item", "SyliusCartBundle:CartItem"]

But I'm guessing you were trying to override the CartItem controller, right? :) that's what I was trying to do anyways.

In the Sylius Docs is explained how you would go about doing that. Like this :

location : yourbundle/resources/config/config.yml

sylius_cart:
    classes:
        item:
            controller: YourBundle\Controller\CartItemController

Also, make sure that if you configure the route to your new controller action, you use the controller service instead of the normal approach.

location : yourbundle/resources/config/routing.yml

mybundle_ajaxcart_add:
    path:     /ajax/cart/add
    defaults: { _controller: sylius.controller.cart_item:addAjaxAction }

I wanted to post it here, because I was looking for this for about half a day and probably someone is going to be looking for the same solution. And I like to save that person the headache ;)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top