5
votes

I'm on symfony 2.7 and need to override Symfony\Component\Asset\UrlPackage

I've looked at http://symfony.com/doc/current/cookbook/bundles/override.html and http://symfony.com/doc/current/cookbook/service_container/compiler_passes.html but can't get it working.

I have made a file in my bundle MyApp\CoreBundle\Overrides\UrlPackage; I registered UrlPackage as a service and added a function:

public function process(ContainerBuilder $container)
{
    $definition = $container->getDefinition('assets.url_package');
    $definition->setClass('MyApp\CoreBundle\Overrides\UrlPackage');
}

The weird thing is, if I call $this->has('assets.url_package') in any controller, it returns false. I did grab it from the services file under Symfony:

<service id="assets.url_package" class="Symfony\Component\Asset\UrlPackage" abstract="true">
        <argument /> <!-- base URLs -->
        <argument type="service" /> <!-- version strategy -->
        <argument type="service" id="assets.context" />
    </service>

If I run php app/console debug:container, the UrlPackage from symfony isn't in there, but, if I change something inside the vendor/*/UrlPackge file, it does work

Can someone point me in the right direction?

2
It shouldn't be necessary to use complier passes to override an existing service - the service definition should be enough. Are you sure you're using the right service id? I'm using 2.6 and in this version it's templating.asset.url_package.mickadoo
Yep they changed that, all the templating.assets settings are also deprecated, assets is now something on it's own, also, urlpackage was a parameter which could be overwritten, now it isn't :( - symfony.com/blog/new-in-symfony-2-7-the-new-asset-componentMazzy

2 Answers

5
votes

Decorating the service is the thing you're looking for:

bar:
    public: false
    class: stdClass
    decorates: foo
    arguments: ["@bar.inner"]

You can inject the original service in your own service, and implement the original interface to make them compatible.

http://symfony.com/doc/2.7/service_container/service_decoration.html

0
votes

Symfony 5.1+

Symfony 5.1+ provide a simpler service decoration:

In previous Symfony versions you needed to use the syntax decorating service ID + .inner to refer to that service. This quickly becomes cumbersome in YAML/XML when using PHP classes as service IDs. That's why in Symfony 5.1 we've simplified this feature to always use .inner to refer to the original service.

@source: https://symfony.com/blog/new-in-symfony-5-1-simpler-service-decoration

# config/services.yaml

services:
    App\MyService: ~

    # Before
    App\SpecialMyService:
        decorates: App\MyService
        arguments: ['@App\SpecialMyService.inner']

    # After
    App\SpecialMyService:
        decorates: App\MyService
        arguments: ['@.inner'] # <--- the service ID is no longer needed