How to access custom config value in the application? - symfony

I placed some custom configs in my config_prod.yml file like this:
store:
plugins:
installed: [abc]
Since SF2 will load and compile and cache, the config_prod.yml is actually loaded just once only. I wonder (without the need to do some custom coding to use setParameter to set my custom config values to the container, or to use my own method of caching the custom configs), how do I access these custom config values? Are they automatically cached and made available somehow?

Everything you define in the parameters section will be accessible as a parameter:
parameters:
store:
plugins:
installed: [abc]
You can access your configuration by calling getParameter() on the container:
$store = $container->getParameter('store');
If you want to have your own section in the configuration file:
store:
plugins:
installed: [abc]
you'll have to create an extension and expose a semantic configuration of your bundle.
In both cases container with all its configuration is compiled and stored in cache.
Read more:
Service Container Parameters
How to expose a Semantic Configuration for a bundle

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.

Symfony Bundle references "#Bundle" - FileLocatorFileNotFoundException

I am currently building my own Symfony bundle (I am using version 3.3). It works fine so far, but now I wanted to move the bundle-specific service definition out of my app/config/services.yml to a service definition within the bundle.
I created a src/MyBundle/Resources/config/services.yml and followed the guide How to Load Service Configuration inside a Bundle to load it. That works just fine, but I thought that the paths inside the newly created services.yml look a bit ugly:
MyBundle\:
resource: '../../*'
exclude: '../../{Tests}'
So I thought it would look a little cleaner, if I use the #Bundle-notation instead:
MyBundle\:
resource: '#MyBundle/*'
exclude: '#MyBundle/{Tests}'
However, than I was facing the error:
FileLocatorFileNotFoundException
The file "#MyBundle" does not exist (in: <...>\MyBundle\DependencyInjection/../Resources/config), where <...> corresponds to an absolute path.
I also tested whether it was a naming issue of the bundle name, but when I have a wrongly named bundle reference in the app/config/services.yml, e.g. #SomeBundleThatDoesNotExist then I get a different error:
FileLoaderLoadException
Bundle "SomeBundleThatDoesNotExist" does not exist or it is not enabled.
So my question is: Why does the #Bundle-notation work fine in the app/config/services.yml but not in the src/MyBundle/Resources/config/services.yml?
If you use the service remember make public for external use:
autowire: true
public: true
But, if your symfony dont know where is the bundle please chec this answer:
Symfony generated Bundle doesn't work

symfony: How to set configuration parameters files for different environments?

How to setup a different configuration parameters file for each environment?
At the moment parameters in parameters.yml are used in both dev and prod environment, but I need different parameters in order to deploy my app in prod.
You can put all the parameters used in your dev environment in a app\config\parameters_dev.yml file (you need to create it) and then import it in your app\config\config_dev.yml:
imports:
- { resource: config.yml }
- { resource: parameters_dev.yml }
So when you work in local any parameter used in production will be overwritten by the new file with the right parameters.
And remember to Clear the cache!

How to use a different console configuration in Symfony

I followed the guideline on how to expose a semantic configuration for a bundle and configured it in my app/config.yml (through parameters.yml).
My bundle also contains some console commands. Right now this command either uses the dev or prod configuration, which is fine.
But how can I make the console commands use an additional configuration file that sets some things different than in config.yml?
E.g.
#app/config.yml
imports:
- { resource: parameters.yml }
foo:
view_mode: %view_mode%
and
#app/parameters.yml
parameters:
view_mode: 1
How can I make it e.g. use a different parameters.yml
#app/parameters_console.yml
parameters:
view_mode: 2
when called through the console? A new environment is not what I want here.
I think you need to create a custom environement
You just have to create a config_console.yml in your app/config folder and override the configuration you need.
imports:
- { resource: config_dev.yml }
foo:
view_mode: 2
Then in your application, just run
php app/console --env=console
This will run your application with default configuration of dev and with foo.view_mode = 2
You may want to note that it will create a new cache folder named console

Symfony2 bundle configuration parameters

My team develops a very large e-commerce project. Up to now, we had something like 40 configuration parameters in that bundle and I didn't know their final relations nor had a way to structure them properly, so we ended up using the standard parameters structure in the app/config.yml file. But, somewhere along the way I decided to move the config to the semantic configuration structure - so I can validate it, have a clean structure, easily extend it by means of bundle inheritance and so on.
The problem is I can't import our bundle parameters to another bundle config, now.
Here's what I could do before:
(...)
parameters:
company.bundle.email.user: user#domain.com
company.bundle.email.pass: #MyBeAUtiFULpA55w0Rd!
(...)
swiftmailer:
(...)
username: %company.bundle.email.user%
password: %company.bundle.email.pass%
Here's what I'm trying to do now and it doesn't work at all:
(...)
company_bundle:
(...)
settings:
(...)
mailer:
(...)
user: user#domain.com
pass: #MyBeAUtiFULpA55w0Rd!
(...)
swiftmailer:
(...)
username: %company_bundle.settings.mailer.user%
password: %company_bundle.settings.mailer.pass%
(...)
Of course the company_bundle node contains the semantic configuration, processed by the DIC and defined in Company\Bundle\DependencyInjection\Configuration.php.
All I end up with for now is the following error:
[Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException]
You have requested a non-existent parameter "company_bundle.settings.mailer.user".
So the question is: how to make my bundle parameters accessible in another bundle configuration parameters (I've already taken care of including my bundle configuration always before the Swiftmailer bundle)?
NOTICE: Swiftmailer bundle configuration is shown here only for demonstration purposes, I want to be able to reuse my bundle parameters across some other bundles as well.
What's the motivation behind that?
Well I want our product to be configured by a person who doesn't know Symfony well - so she must be able to open our bundle config file and just tweak the parameters, which will then be used in some Symfony bundles we use. So I want all application configuration to be accessible in our bundle's semantic conf, since I'd want not to expose the whole configuration to that person (I've already divided everything into separate config files, one of them containing the configuration for our bundle, the rest - for all the other ones).
So, is what I'm asking even possible?
As the parameters are to be modified in each installation (they probably differ at least between development and production environments), so (as Sgoettschkes said in comment) external file is the best solution.
In Symfony2 by default place for such parameters is parameters.yml file located in app/config/ dir.
In standard installation you can find for example such entries:
parameters:
database_driver: pdo_mysql
database_host: 127.0.0.1
(...)
These params are used in config.yml this way:
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
(...)
So you can define your params (in parameters.yml):
parameters:
(...)
company_bundle_email_user: user#domain.com
company_bundle_email_pass: #MyBeAUtiFULpA55w0Rd!
and use them (in config.yml):
swiftmailer:
(...)
username: %company_bundle_email_user%
password: %company_bundle_email_pass%

Resources