I have noticed in several bundles that some services definition files had parameters embedded in it, like in the following example:
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<!-- CUSTOMER -->
<parameter key="sonata.customer.admin.customer.class">Sonata\CustomerBundle\Admin\CustomerAdmin</parameter>
<parameter key="sonata.customer.admin.customer.controller">SonataAdminBundle:CRUD</parameter>
</parameters>
<services>
<service id="sonata.customer.admin.customer" class="%sonata.customer.admin.customer.class%">
<tag name="sonata.admin" manager_type="orm" group="sonata_ecommerce" label="B2C" label_translator_strategy="sonata.admin.label.strategy.underscore"/>
<argument />
<argument>%sonata.customer.admin.customer.entity%</argument>
<argument>%sonata.customer.admin.customer.controller%</argument>
<call method="addChild">
<argument type="service" id="sonata.customer.admin.address" />
</call>
<call method="addChild">
<argument type="service" id="sonata.order.admin.order" />
</call>
</service>
</services>
</container>
Those parameters are not exposed as bundle configuration.
I recently discovered it is possible to add a CompilerPass class to override some service definitions. Although, this looks a bit tedious to do.
Is it possible to override those <parameter> by configuration ?
In your app/config/config.yml (or whatever imported config file) add :
parameters:
parameter.name: new_value
Related
Using the CMF code as a reference I am trying to replace the default router with the chain router...not just decorate...
public function process(ContainerBuilder $container)
{
// NOT available using alias for some reason???
$definition = $container->getDefinition('MyBundle\Routing\ChainRouter');
foreach ($container->findTaggedServiceIds($this->routerTag) as $id => $attributes) {
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
$definition->addMethodCall('add', [new Reference($id), $priority]);
}
$container->setDefinition('router.default', $definition);
}
Here is the bundle services.xml
<services>
<service id="MyBundle\Routing\ChainRouter" />
<service id="cmf_routing.router" alias="MyBundle\Routing\ChainRouter" />
<!-- <service id="MyBundle\Routing\DynamicRouter">-->
<!-- <tag name="router" priority="100" />-->
<!-- </service>-->
<service id="Symfony\Bundle\FrameworkBundle\Routing\Router">
<tag name="router" priority="1" />
<tag name="monolog.logger" channel="router" />
<tag name="container.service_subscriber" id="routing.loader" />
<argument type="service" id="Psr\Container\ContainerInterface" />
<argument>%router.resource%</argument>
<argument type="collection">
<argument key="cache_dir">%kernel.cache_dir%</argument>
<argument key="debug">%kernel.debug%</argument>
<argument key="generator_class">Symfony\Component\Routing\Generator\CompiledUrlGenerator</argument>
<argument key="generator_dumper_class">Symfony\Component\Routing\Generator\Dumper\CompiledUrlGeneratorDumper</argument>
<argument key="matcher_class">Symfony\Bundle\FrameworkBundle\Routing\RedirectableCompiledUrlMatcher</argument>
<argument key="matcher_dumper_class">Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper</argument>
</argument>
<argument type="service" id="router.request_context" on-invalid="ignore" />
<argument type="service" id="parameter_bag" on-invalid="ignore" />
<argument type="service" id="logger" on-invalid="ignore" />
<argument>%kernel.default_locale%</argument>
<call method="setConfigCacheFactory">
<argument type="service" id="config_cache_factory" />
</call>
</service>
I am getting an error Cannot load resource "kernel::loadRoutes"
With the following stack trace
LoaderLoadException Symfony\Component\Config\Exception\LoaderLoadException: Cannot load resource "kernel::loadRoutes".
at vendor/symfony/config/Loader/DelegatingLoader.php:37 at Symfony\Component\Config\Loader\DelegatingLoader->load('kernel::loadRoutes', null)
(vendor/symfony/framework-bundle/Routing/DelegatingLoader.php:67) at Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader->load('kernel::loadRoutes', null)
(vendor/symfony/framework-bundle/Routing/Router.php:66) at Symfony\Bundle\FrameworkBundle\Routing\Router->getRouteCollection()
(vendor/symfony/routing/Router.php:358) at Symfony\Component\Routing\Router->getMatcherDumperInstance()
(vendor/symfony/routing/Router.php:289) at Symfony\Component\Routing\Router->Symfony\Component\Routing\{closure}(object(ResourceCheckerConfigCache))
(vendor/symfony/config/ResourceCheckerConfigCacheFactory.php:39) at Symfony\Component\Config\ResourceCheckerConfigCacheFactory->cache('/vagrant/project/var/cache/dev/url_matching_routes.php', object(Closure))
(vendor/symfony/routing/Router.php:297) at Symfony\Component\Routing\Router->getMatcher()
(vendor/symfony/routing/Router.php:251) at Symfony\Component\Routing\Router->matchRequest(object(Request))
(/vagrant/bundles/mybundle/src/Routing/ChainRouter.php:191) at MyBundle\Routing\ChainRouter->doMatch('/', object(Request))
(/vagrant/bundles/mybundle/src/Routing/ChainRouter.php:158) at MyBundle\Routing\ChainRouter->matchRequest(object(Request))
(vendor/symfony/http-kernel/EventListener/RouterListener.php:112)
truncated for brevity...
I feel this is being caused by the default router being "replaced" in the compiler pass and not properly re-initialized. Seeing as the DynamicRouter isn't even loaded the expected behavior was business as usual, not this error :)
Any thoughts, pointers, tips, suggestions?
The Bundle https://github.com/saadtazi/SaadTaziGChartBundle (version 2.0) passes "twig.form.resources" as an argument.
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="twig.extension.g_chart.class">SaadTazi\GChartBundle\Twig\GChartExtension</parameter>
<parameter key="twig.extension.visualization.template">SaadTaziGChartBundle:chart:visualizationChart.html.twig</parameter>
</parameters>
<services>
<service id="twig.extension.g_chart" class="%twig.extension.g_chart.class%">
<tag name="twig.extension" alias="g_chart" />
<argument key="twig.form.resources" type="collection">
<argument key="gChartTemplate">%twig.extension.visualization.template%</argument>
</argument>
</service>
</services>
</container>
This configuration throws an Exception in Syfony 3.3:
Invalid key "twig.form.resources" found in arguments of method "__construct()" for service "twig.extension.g_chart": only integer or $named arguments are allowed.
The constructor has a resources property:
/**
* #param array $resources a list of resources (see Resources/g_chart.xml)
*/
public function __construct(array $resources = array()) {
$this->resources = $resources;
}
I've tried fixing it by passing "twig.form_themes", which is the replacement for "twig.form.resources", but that throws an Exception too. Any thoughts appreciated, thanks!
I can define repository as a service:
<service id="books_repository" class="MyApp\BooksBundle\Repository\BooksRepository">
<factory service="doctrine.orm.default_entity_manager" method="getRepository"/>
<argument>MyApp\BooksBundle\Entity\BookEntity</argument>
</service>
and then inject:
<service id="books_service" class="MyApp\BooksBundle\Service\BooksService">
<argument type="service" id="books_repository"/>
</service>
But I can also use expression argument:
<service id="books_service" class="MyApp\BooksBundle\Service\BooksService">
<argument type="expression">service('doctrine').getManager('default').getRepository('MyApp\BooksBundle\Repository\BooksRepository')</argument>
</service>
Are there any reasons I should prefer one solution over the other one? Are they functionally equivalent?
Im trying to override EditableRolesBuilder in Security folder.
I try to make same hierarchy in
Application\Sonata\UserBundle\Security\EditableRolesBuilder which
extends the base one Sonata\UserBundle\Security\EditableRolesBuilder
from vendor but with no success.
I try to override service in
Sonata\UserBundle\Resources\config\admin.xml, to pass my custom class
but i can't find anywhere how to override whole service.This service
is without parameters but hardcoded class and i cant't pass it in
config.yml
In Sonata admin if you wish to override security roles handler you have to override 2 services
sonata.user.editable_role_builder
sonata.user.form.type.security_roles
And definitions will look like as below
<services>
<service id="sonata.user.editable_role_builder" class="Acme\DemoBundle\Security\EditableRolesBuilder">
<argument type="service" id="security.context" />
<argument type="service" id="sonata.admin.pool" />
<argument>%security.role_hierarchy.roles%</argument>
</service>
<service id="sonata.user.form.type.security_roles" class="Acme\DemoBundle\Form\Type\SecurityRolesType">
<tag name="form.type" alias="sonata_security_roles" />
<argument type="service" id="sonata.user.editable_role_builder" />
</service>
</services>
For reference see Sonata Admin Override Security Roles Handler
I need to have pagination integrated in my Backend. I am using sonataAdminBundle.
There is this Sonata\AdminBundle\Admin\Admin class which has a property called $maxPerPage = 25;
So how do i override this class so that all my other admin classes can have pagination without repeating code.
Thanks!
Use Dependency Injection. In services.xml file you can add any methods that must be called when your admin service is created.
File: ../YourAdminBundle/Resources/config/services.xml:
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<!-- You define the maxpage only once -->
<parameter key="admin_max_per_page_number">10</parameter>
</parameters>
<services>
<service id="xyz_admin" class="Abc\Bundle\YourAdminBundle\Admin\XyzAdmin">
<tag name="sonata.admin" manager_type="orm" group="xyz_group" label="Xyz"/>
<argument />
<argument>Abc\Bundle\YourAdminBundle\Entity\Xyz</argument>
<argument>SonataAdminBundle:CRUD</argument>
<call method="setMaxPerPage">
<argument>%admin_max_per_page_number%</argument>
</call>
</service>
<!-- ... another admin services... -->
</services>
</container>