I have successfully installed the sncRedisBundle and used the predis element of it within a controller, using:
$this->container->get('snc_redis.default');
I want to do the same within an extension:
class MyExtension extends Extension
{
/**
* {#inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$redis = $container->get('snc_redis.default');
}
}
But I get:
The service definition "snc_redis.default" does not exist.
Is this a scoping issue? How do I access redis from within an Extension?
Thanks!
services:
site:
class: Emlaktown\AppBundle\Site\Site
arguments: [%api_url%, "#request_stack", "#service_container"]
....
use Symfony\Component\DependencyInjection\Container;
....
public function __construct($apiUrl, RequestStack $requestStack, Container $container)
{
$this->client = new Client($apiUrl);
$this->redis = $container->get('snc_redis.cache');
$request = $requestStack->getCurrentRequest();
$this->client->setDefaultOption('Accept-Language', $request->getLocale());
}
Related
I'm writing a Symfony bundle and I need to setup a service definition in my Extension class depending on the value of a configuration parameter.
An it works fine, as long as you don't try to use any expressions in the parameter value.
My extension class looks like this:
class MyBundleExtension extends Extension
{
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);
dd($config['custom_param']);
}
...
}
In my application, I set the parameter like this:
.env.local:
MY_BUNDLE_CUSTOM_PARAM=blah
config.yaml:
parameters:
my_bundle_custom_param: '%env(MY_BUNDLE_CUSTOM_PARAM)%'
my_bundle:
custom_param: '%my_bundle_custom_param%'
The problem is, that in the Extension class, this parameter is not yet resolved, so dd() shows this:
"env_de85db6c4d65707d_MY_BUNDLE_CUSTOM_PARAM_71f5c271abfed252c958c82c1e3fb8dc"
instead of the expected blah.
Is there any way to get the resolved value of the parameter in the Extension class?
You gave the correct answer in your comment:
/**
* #throws \Exception
*/
public function load(array $configs, ContainerBuilder $container): void
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$resolve = $container->resolveEnvPlaceholders($config, true);
$config['upload_path'] = \str_replace($_SERVER['DOCUMENT_ROOT'], '', $resolve['upload_directory']);
$container->setParameter("mybundle", $config);
I just created a symfony DI extension , where I'm trying to append some form theme configuration to my app/config.yml.
1) My Extension class:
class ELFinderFieldTypeExtension extends Extension implements PrependExtensionInterface
{
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('form_themes.yml');
}
...
2) My form_themes.yml
twig:
form_themes:
- 'ELFinderFieldTypeBundle:elfinder:elfinder_widget.html.twig'
Unfortunately, It's not the right way to load a twig config, that's way I'm getting kind of:
There is no extension able to load the configuration for "twig" (in
/var/www/html/..../DependencyInjection/../Resources/config/form_themes.yml).
Looked for namespace "twig", found none
Anyone have any idea would be voted and appreciated.
I found an easy solution, ally I need is to append my config after implementing PrependExtensionInterface Interface:
public function prepend(ContainerBuilder $container)
{
$configFile = \sprintf('%s%s', __DIR__, '/../Resources/config/form_themes.yml');
$this->prependYamlConfigFile($container, 'twig', $configFile);
}
I'm creating a bundle that uses Workflow component.
I've created a Workflow in the file Resources/config/workflows.yml.
Then I've tried to load this file automatically from the AcmeAwesomeBundleExtension class:
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
// This loads the Workflows
$loader->load('workflows.yml');
$loader->load('services.yml');
...
}
}
This is the content of the workflows.yml file:
framework:
workflows:
the_name:
type: workflow
supports:
- My\Bundle\Namespace\Entity\MyEntity
places:
- wait_config
- configured
transitions:
give_config:
from: wait_config
to: configured
Nothing so complex for the moment.
But this returns me this error:
An error occurred when executing the "'cache:clear --no-warmup'"
command:
[Symfony\Component\DependencyInjection\Exception\InvalidArgumentException]
There is no extension able to load the configuration for "framework" (in /U
sers/Aerendir/Documents/JooServer/_Projects/Coommercio/Apps/app-coommercio-
www/vendor/myvendor/myawesomebundle/src/DependencyInjection/../Resources/config/workflows.yml). Looked for namespace "framework", found none
Obviously all is loaded well if I manually import the file directly in my config.yml file, the one of my app:
imports:
- { resource: '#MyAwesomeBundle/Resources/config/workflows.yml' }
So, how can I load automatically the workflows from my third-party bundle?
The solution is really simple.
Instead of loading the configuration in the MyAwesomeExtension::load() method, the workflow has to be loaded in the method MyAwesomeExtension::prepend():
class MyAwesomExtension extends Extension implements PrependExtensionInterface
{
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.yml');
...
}
/**
* ! ! ! LOAD THE WORKFLOW HERE ! ! !
*
* #param ContainerBuilder $container
*/
public function prepend(ContainerBuilder $container)
{
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('workflows.yml');
}
This way my third-party bundle can load the configuration required to create the workflow.
More information can be found on the Symfony's documentation about the ConfigComponent: How to simplify configuration of multiple bundles.
I try to prepend a config array to a different bundle using the prependExtensionConfig from my bundle. All works fine until $config is hardcoded.
My goal is to load the $config values using a service (from the db for example) and than prepend it to the other bundle.
The problem is that the services are not loaded at that moment.
I guess this is a limitation is symfony2.
Any ideas? thx
class MyExtension extends Extension implements PrependExtensionInterface
{
/**
* {#inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.yml');
}
public function prepend(ContainerBuilder $container)
{
$config = // load config from a service ...
$container->prependExtensionConfig('other_bundle', $config);
}
}
First of all you need to set up your config to take values from parameters section of Service container:
Setup config.yml:
# app/config/config.yml
namespace:
subnamespace:
param1: %param1%
param2: %param2%
Then you need to fill %param1% and %param2% parameters in container with values from database. To do that you need to declare your CompilerPass and add it to the container. After whole container will be loaded (in the compile time) you will have access to all services in it.
Just get the entity manager service and query for needed parameters and register them in container.
Define Compiler pass:
# src/Acme/YourBundle/DependencyInjection/Compiler/ParametersCompilerPass.php
class ParametersCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$em = $container->get('doctrine.orm.default_entity_manager');
$param1 = $em->getRepository('Acme:Params')->find(1);
$param2 = $em->getRepository('Acme:Params')->find(2);
$container->setParameter('param1', $param1);
$container->setParameter('param2', $param2);
}
}
In the bundle definition class you need to add compiler pass to your container
# src/Acme/YourBundle/AcmeYourBundle.php
class AcmeYourBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new ParametersCompilerPass(), PassConfig::TYPE_AFTER_REMOVING);
}
}
PassConfig::TYPE_AFTER_REMOVING means that this CompilerPass will be processed almost after all other compiler passes and in this moment you will already have every service injected.
I need to get some data in my db and the current user, so I use the entity manager and security.context in my service
I have this error :
Fatal error: Call to a member function getRepository() on a non-object
in path/to/file on line 84
service.yml :
services:
ns_messagerie.letterboxcore:
class: ns\MessagerieBundle\LetterBoxCore\LetterBoxCore
arguments: [#security.context, #doctrine.orm.entity_manager]
Dependency injection :
class nsMessagerieExtension extends Extension
{
/**
* {#inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
And my service :
class LetterBoxCore {
protected $securityContext;
protected $em;
public function __construct( $securityContext, $entityManager) {
$this->securityContext = $securityContext;
$this->em = $entityManager;
}
public function countNbNotRead(Utilisateur $user = null, Discussion $discussions) {
//...
}
public function getAllDiscussion(Utilisateur $user = null, $all = null) {
// line 84:
$list = $em->getRepository('nsMessagerieBundle:ParticipantMessagerie')
->findBy(array('participant' => $user,
'supprimer' => $all
)
);
}
public function getBAL(Utilisateur $user = null) {
// Call the method countNbNotRead and GetAllDiscussion
}