Symfony2: overriding Sensio FrameworkExtraBundle template guesser - symfony

I am trying to override the standard template guesser ( located in Sensio\Bundle\FrameworkExtraBundle\Templating; ) becouse I want to use annotations to set the view but need to change the logic of how the actual view file is chosen.
I have seen this: https://github.com/elnur/ElnurTemplateGuesserBundle
but I was wondering if there is a way to just override the service in configuration.
I tried setting:
services:
sensio_framework_extra.view.guesser:
class: myCompany\myBundle\Templating\TemplateGuesser
but I get:
ContextErrorException: Catchable Fatal Error:
Argument 1 passed to Sensio\Bundle\FrameworkExtraBundle\Templating\TemplateGuesser::__construct()
must implement interface Symfony\Component\HttpKernel\KernelInterface, none given
Am I supposed to set an argument in the service config setting? But how do I reference the HttpKernel?
Or am I missing something?
TIA.

You can inject the kernel the same way the as the original TemplateGuesser. The name of the Kernel service is just simply kernel.
services:
sensio_framework_extra.view.guesser:
class: myCompany\myBundle\Templating\TemplateGuesser
arguments: [ "#kernel" ]
To see a full list of services in the container, run
$ php app/console container:debug
Of which you'll see the kernel listed as one of them.

Related

bundle's service (autowire) not available in controller's method

I'd like to use https://github.com/tedious/TedivmStashBundle bundle in my symfony 4 project. Added by composer, configured in /config/stash.yaml file and according to the profiler bar, it's working basically.
Now, I want to use to caching values in my controller. I've try to add the service stash by its name to the method's parameter, using the same name as the example says:
$pool = $this->container->get('stash');
but the framework did not find the service. It can't be added like the example explained neither.
How can I use this bundle as a service (autowired) in my symfony 4 app?
UPDATE
services.yaml:
stash.default_cache:
class: Tedivm\StashBundle\Service\CacheService
public: true
arguments:
$name: 'stash'
Tedivm\StashBundle\Service\CacheService: '#stash.default_cache'
Controller:
public function something(Request $request, CacheService $service, ...
It's looks like working now :)
Thanx for the suggestion (and the correct solution later) to #Cerad
Here is an example of how to approach this sort of problem when dealing with bundles that are not quite ready for autowire.
Start by installing a test project:
symfony new --full stash --version=lts
composer require tedivm/stash-bundle
Note that the bundle does not directly support Symfony 5 hence the lts. Note also that the bundles does not support Flex so you have to add your own config/packages/stash.yaml file per the bundle's readme file.
# config/packages/stash.yaml
stash:
drivers: [ FileSystem ]
FileSystem: ~
At this point we can determine which service we need to inject:
bin/console debug:container stash
Information for Service "stash.default_cache"
=============================================
Class CacheService
---------------- -----------------------------------------
Option Value
---------------- -----------------------------------------
Service ID stash.default_cache
Class Tedivm\StashBundle\Service\CacheService
Most of the time you would like to use an interface for injection but a peek at the source code reveals that the bundle does not use interfaces. As a side note, calling a third party service 'stash' is not a good idea. It really should have been 'tedivm.stash' but I digress.
We can now create an alias and then typehint against it:
# config/services.yaml
Tedivm\StashBundle\Service\CacheService : '#stash' # alias for typehinting
# Controller class
public function index(CacheService $cacheService)
{
return new Response('Cache ' . get_class($cacheService));
}
And that should do it.

Generate admin Sonata with command line in Symfony 4

I'm starting to use Sonata with Symfony 4.
I try to generate an admin with the command line "make:sonata:admin" and i've an error at the end of the process like this:
2018-10-11T15:55:23+00:00 [error] Error thrown while running command "make:sonata:admin". Message: "There are no model managers registered."
In AdminMaker.php line 286:
There are no model managers registered.
So I try wit hthe other command line "sonata:admin:generate" and I have an other error like this :
Welcome to the AdminBundle object ACL generator
This command helps you to generate ACL entities for the objects handled by the AdminBundle.
If the step option is used, you will be asked if you want to generate the object ACL entities for each Admin.
You must use the shortcut notation like AcmeDemoBundle:User if you want to set an object owner.
Admin class is using a manager type that has no manipulator implemented : ignoring
Admin class is using a manager type that has no manipulator implemented : ignoring
Admin class is using a manager type that has no manipulator implemented : ignoring
My implementation code is like this :
src
Entity
Clients
Vehicules
Can you help me please ?
Thanks a lot for your answer
Try to config the service, so you can give the model manager that you use.
services:
sonata.admin.maker:
class: Sonata\AdminBundle\Maker\AdminMaker
arguments: ['%kernel.project_dir%', ['#sonata.admin.manager.orm']]
tags:
- { name: maker.command }
You need to install Doctrine ORM Admin Bundle first
composer require sonata-project/doctrine-orm-admin-bundle

symfony4 migrate autowire to true - get error message

I am migrating from symofony 2.7 to symfony 4.0. With success I migrated one bundle. Now I am migrating the second bundle and the error message is coming up. I don't get at all what symfony 4.0 wants from me.
If I turn on autowire: true this error message is coming up.
Cannot autowire service "App\Kernel": argument "$environment" of method "Symfony\Component\HttpKernel\Kernel::__construct()" must have a type-hint or be given a value explicitly.
Can somebody help me?
If I turn it off, no message is coming up.
Update
I registered my bundle only in bundles.php
App\Backend\AccountBundle\BackendAccountBundle::class => ['all' => true],
Usually the Kernel is added to the Service Container as a so called synthetic service, meaning it's not generated by the DI-container from configuration. Rather the id is set and then the previously configured service is just added to the container. It seems rather odd that your bundle's container wants to create a new kernel here. So I would check where and how you want to access the kernel in any of the bundle's services and whether you actually want to pass in the kernel and not something else. If you do you might want to check the Service Container-documentation on synthetic services.
As to the error itself. Symfony's autowiring often falls flat when you have services that require parameters like with the Kernel:
public function __construct(string $environment, bool $debug) {...}
In these cases you have to either have a parameter defined in your services.yaml that matches the name of the parameter:
# config/services.yaml
parameters:
environment: prod
debug: false
or you have to tell the configuration which parameters you want to have in those places.
App\Kernel:
$environment: prod
$debug: false
This will tell the autowiring that only the 2 arguments named environment and debug should be overwritten with the values you provide, but the rest is done via autowiring. This way you can skip the arguments: part of the definition and you can also skip all arguments you know are correctly set via autowiring.
For example if you have a service like this:
class MyService {
public function __construct(OtherServce $service, string $someParameter) {}
}
# config/services.yaml
services:
_defaults:
autowiring: true
MyService:
$someParameter: 'someValue'
This is the same as explicitly writing:
services:
MyService:
class: MyService
arguments:
- '#OtherServce'
- 'someValue'

GetConfig() in Symfony2

I looked after this, but I didn't found something useful.
Is there a method like Symfony1.4 getConfig() in Symfony2.7 to get a config value from a Yaml file? Thanks in advance.
Instead of define hard-coded configuration values, create a parameter :
# app/config/parameters.yml or app/config/config.yml
parameters:
your_param: value # Define the parameter
Use it in your configuration :
# app/config/config.yml
my_package:
my_parameter: "%your_param%"
Retrieve it from your controller or another context which can access the service container :
$this->container->getParameter('yourparam');
See DI and parameters and How do I read configuration settings from Symfony2 config.yml?

After tagging a service in services.yml symfony starts throwing ReflectionException

I have the following configuration in my SF2 Bundle
parameters:
catalogue.title.class: My\SomeBundle\Services\TitleService
services:
catalogue.title:
class: %catalogue.title.class%
Which works like a charm.
Now I want to enhance the configured service and tag it so it gets the knp_paginator injected (I've also tried with other tags). My config becomes:
parameters:
catalogue.title.class: My\SomeBundle\Services\TitleService
services:
catalogue.title:
class: %catalogue.title.class%
tags:
- { name: knp_paginator.injectable, paginator: knp_paginator }
For the mentioned tag to work the service implements the Knp\Bundle\PaginatorBundle\Definition\PaginatorAware. As mentioned on the KnpPaginatorBundle docs.
Running my app will show the following:
ReflectionException: Class %catalogue.title.class% does not exist.
Since it works without adding the tags part, I know the class does exist.
Replacing %catalogue.title.class% with the value of the parameter (the fully qualified class name) solves the issue, but we are using this way of configuring our service classes in all our projects and really don't want to deviate from that just to resolve this issue.
[EDIT] Using a different parameter like catalogue_title_class or my_abc has the same result.
I'm running Symfony version 2.3.5.
What am I doing wrong?
Probably this exceptions throws because of same names of class of parameter and provided service name.
Try to rename
parameters:
catalogue.title.class: My\SomeBundle\Services\TitleService
to some other name
parameters:
catalogue_title.class: My\SomeBundle\Services\TitleService
and use this
services:
catalogue.title:
class: %catalogue_title.class%
tags:
- { name: knp_paginator.injectable, paginator: knp_paginator }

Resources