How to extend security configuration from Symfony Bundle?
I have my basic config/packages/security.yaml file and another one in a bundle src/CustomBundle/Resources/config/security.yaml that adds new encoders, providers, firewalls and paths in access_control. I am trying to load it inside bundle extension class, but I get an error that security extension was not found
There is no extension able to load the configuration for "security"
class CustomExtension extends Extension
{
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container): void
{
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
$loader->load('security.yml');
}
}
Using Symfony 4.4
Related
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 have a CampusCalendarBundle extension. After I added the DependencyInjection folder to load config files. I have this error. I don't think system_configuration.yml is been loaded.
[RuntimeException]
[Symfony\Component\Config\Definition\Exception\InvalidConfigurationException]
The system configuration variable "oro_calendar.calendar_colors" is not
defined. Please make sure that it is either added to bundle
configuration settings or marked as "ui_only" in config.
<?php
namespace CampusCRM\CampusCalendarBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
class CampusCalendarExtension extends Extension
{
/**
* {#inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$container->setParameter(
'oro_calendar.enabled_system_calendar',
$config['enabled_system_calendar']
);
$container->prependExtensionConfig($this->getAlias(), array_intersect_key($config, array_flip(['settings'])));
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
$loader->load('form.yml');
}
}
Here is extension Bundle.
<?php
// src/CampusCRM/CampusCalendarBundle/CampusCalendarBundle.php
namespace CampusCRM\CampusCalendarBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class CampusCalendarBundle extends Bundle
{
public function getParent()
{
return 'OroCalendarBundle';
}
}
I have discovered a solution! I probably accidentally deleted some code in OroCalendarBundle. Everything works after I replaced OroCalendarBundle with a refresh install.
Thank you everyone for your help~
I'm trying to create a model class (which will use DBAL), and i'd like to use it like a service in my bundle.
I've tried to create a service with this configuration in my bundle :
services:
X:
class: X
arguments: [#database_connection]
But the fact is i don't want to configure this service in app/config/config.yml because it will only be used in one bundle.
Is there any way to create a specific bundle service, and giving #database_connection parameter to the class ? Or am i forced to configure it for all my app ?
My goal here is only to have distinct class for my controller and my model, without using the Doctrine ORM/Entity, just the DBAL.
Yes, every bundle has his own config files.
# src/Acme/YourBundle/Resources/config/services.yml
services:
X:
class: X
arguments: [#database_connection]
The bundle configuration is loaded trough the DIC. So this file in your bundle is important
// src/Acme/YourBundle/DependencyInjection/AcmeYourBundleExtension.php
namespace Acme\YourBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
/**
* This is the class that loads and manages your bundle configuration
*
* To learn more see {#link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class AcmeYourExtension 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');
}
}
Generally, you should configure all services in the bundle specific services.yml and not in config.yml. So you can reuse them. But the service is visible for the complete application not only for the bundle. But this should be no problem.
I've defined a service in the Resources/config/services.yml:
services:
gSm.gate.terminal:
class: Stream\TerminalBundle\StreamTerminal
arguments: [ [], [%terminal_login%, %terminal_password%] ]
And I try to access in inside my controller action:
public function displayAction() {
$terminal = $this->get('gSm.gate.terminal');
return $this->render('StreamTerminalBundle::display.html.twig');
}
Server returns following exception: 500 You have requested a non-existent service "gsm.gate.terminal". The bundle is registered in the appKernel, the bundle uses .yml config files... and I don't know what else can I look at to make this service available... thanks for any help.
EDIT:
My extension class code is:
namespace Stream\TerminalBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
/**
* This is the class that loads and manages your bundle configuration
*
* To learn more see {#link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class StreamTerminalExtension 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');
}
}
Make sure you're importing the bundle's services.yml. A simplest way is to import it from config.yml. A better and more advanced solution is to write an extension.
To see an example of an extension class, see my bundle's one. If you want to use YAML, just change services.xml to services.yml and XmlFileLoader to YamlFileLoader.
Is your services.yml file being parsed by the Extension class?
By default in a new bundle it's setup to load the xml file.
Can you paste your
Acme\Bundle\YourBundle\DependencyInjection\AcmeYourExtension
class?
I'm not sure you can use uppercase letters in you service names. The exception gives such a hint "gsm.gate.terminal" while your service is "gSm.gate.terminal".