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?
Related
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?
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
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 have a FosUserBundle service I need to convert to yml format. How can I do this is there a dumper convertor or anything?
How this would look in yml?
<service id="fos_user.mailer.twig_swift" class="FOS\UserBundle\Mailer\TwigSwiftMailer" public="false">
<argument type="service" id="mailer" />
<argument type="service" id="router" />
<argument type="service" id="twig" />
<argument type="collection">
<argument key="template" type="collection">
<argument key="confirmation">%fos_user.registration.confirmation.template%</argument>
<argument key="resetting">%fos_user.resetting.email.template%</argument>
</argument>
<argument key="from_email" type="collection">
<argument key="confirmation">%fos_user.registration.confirmation.from_email%</argument>
<argument key="resetting">%fos_user.resetting.email.from_email%</argument>
</argument>
</argument>
</service>
I was trying to use Yml dumper but this is just giving me serialised object:
$cs = new ContainerBuilder();
$loader1 = new Loader\XmlFileLoader($cs, new FileLocator(__DIR__ . '/../../../../vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Resources/config'));
$loader1->load('mailer.xml');
$dumper = new \Symfony\Component\Yaml\Dumper();
file_put_contents(__DIR__ . '/test2.yml', $dumper->dump($cs));
Any tips would be much appreciated. Thanks in advance.
You can try do it in such way:
services:
fos_user.mailer.twig_swift:
class: FOS\UserBundle\Mailer\TwigSwiftMailer
arguments:
- #mailer
- #router
- #templating
- { template: { confirmation: %fos_user.registration.confirmation.template%, resetting: %fos_user.resetting.email.template% }, from_email: { confirmation: %fos_user.registration.confirmation.from_email%, resetting: %fos_user.resetting.email.from_email% } }
You use wrong dumper as well you should use Symfony\Component\DependencyInjection\Dumper\YamlDumper