Symfony: get() - how exactly does this work? - php

I have a line in a sample Symfony app that reads:
$seo = $this->get('sonata.seo.page');
However the config.yml file reads:
sonata_seo:
page:
metas:
property: ... etc ...
I've read http://symfony.com/doc/current/service_container.html but I'm not clear how exactly the get('sonata.seo.page') works. Does it somehow equate to the key / values in the config file? i.e. does the underscore in sonata_seo get magically changed to a period?

You cannot access values in config.yml direcly, like values in parameters.yml.
That file can store configuration values for bundles thought.
Read more here

What it is 'getting' in this instance, usually within a controller action, is a Symfony Service.
In this instance, sonata.seo.page is a reference to a service, setup in the sonata-project/seo-bundle, which returns an instance of the SeoPage class. Normally, this information is set within your local configuration file (config.yml, or a file that it includes), but the service returns the class that allows you to change the values at runtime.

No service are (directly) defined inside config.yml. It's the bundle that define the service. With $this->get('sonata.seo.page'); you get those.
The config.yml file it's just used to customize the bundles.

The SeoBundle defines the semantic configuration section sonata_seo from config.yml and registers the own Extension of DI container.
Extension implements the load() method. Configuration values from sonata_seo are passed as its first argument.
Method loads various resources including service definition from Resources/config/service.xml:
<parameter key="sonata.seo.page.default.class">Sonata\SeoBundle\Seo\SeoPage</parameter>
...
<service id="sonata.seo.page.default" class="%sonata.seo.page.default.class%"/>
Next, extension set up sonata.seo.page definition with given configuration parameters.
This process will be invoked during the container compilation, when the service definition and its settings will be embedded in the container. Result of this process you can find in the dumped container in the cache directory.
This is a typical scheme of work for the Symfony bundles: define the configuration structure, make an extension, set up the services.

Related

Custom configuration file for Symfony project

My goal is to add to a new Symfony 4.4 project an extra config file to define some behavior of the system. It could be anything, like, pancakes.yaml:
pancakes:
enablePancakes: false
I wish to know how can I load that config file. find a way to read its parameters and values to change some custom behavior the system might have but honestly I think I'm not smart enough to understand what the documentation says.
For now it could be anything, like printing the configuration file values, for now I only need to know how to load it.
you can update the following file :
# config/service.yaml
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
parameters:
locale: 'en'
chat_update_interval: 10000
and use service decoration in your new application to override your parameters.

How to set logger output path to directory which is provided by a service?

I have a symfony 3.2 project and want to log to a configurable directory. This directory is configured as a registry key in the Windows Registry (I cannot change that).
So I have built a service that reads the log path from the registry key, and now want to log to that path. This service does not need a logger, of course :-)
How can I do that?
It actually depends on how and what you want to log.
Generally speaking, if you want to define another path for the logging of your application, your best bet is to do in the AppKernel.php
Nothing prevent you to override this method in your own AppKernel and use PHP code to fetch the path in the Windows Registry, no need for a Symfony service.
You should call your service function with the expression language:
# app/config/config.yml
services:
log_writer:
class: AppBundle\Log\LogWriter
arguments: ["#=service('log_reader').getLogDirectory()"]
Check out the documentation.

Symfony - get parameters.yml with front Controller

I have a legacy application.
I must get some parameters from parameters.yml in FrontController (app.php or app_dev.php) before system initialize Symfony Security Firewall. This parameter is path to config file ( this config is outside my project - config is required for connect to "library" with my model).
Model is outside my project.
I must include this library by "include" function, composer drops.
In my system I have securityController, and userProvider which connect to database by "library".
So I don't know how can I get parameter with paramters.yml
in FrontController.
I'm afraid you couldn't, Symfony Firewall is always be run before the request hit to controller.
So in your scenario, I think you should go to your security event listener (not sure what is the type of firewall you are using, x509, simple token...), so you can get parameter normally by $container->getParameter() and store it in somewhere, then controller can read it

Access to the base_path of a particular Asset directory from a controller

I want to access the base_path (base_url registered) of a specific Asset component directory from a controller in order to store my reports to a specific path preconfigured in config.yml.
I started changing my configuration, after upgrading to Symfony 2.7, like the following:
app/config/config.yml
framework:
assets:
version: 'v5'
version_format: '%%s?version=%%s'
base_path: ~
base_urls: ['http://cdn.example.com', 'https://secure.example.com']
packages:
reports:
base_path: bundles/mybundle
So, when I request a specific route, with the correct request parameters my controller generate the HTML from a particular Twig template and, at the end, it will be converted to PDF using KnpSnappyBundle.
At last, my purpose is to build a list of generated PDF reports accessible from a public assets directory.
$kernel->locateResource()
However, I can access the complete path using a workaround like the following:
$this->container->get('kernel')->locateResource('#MyBundle/Resources/public/reports')
Using parameters.yml
I have also asked for some hints and it seems legit to use the parameters.yml in order to manage the Asset component configuration. So, from the controller, they would be accessed using $this->getParameter() and, at the same time, as a configuration value for Asset.
The simplest way to deal with that is to define it as a parameter in parameters.yml, as you suggested yourself.
It's really easy to get it and it totally makes sense.
Update
I wanted to provide a bit more reasoning for my answer, so I will cite http://symfony.com/doc/current/best_practices/configuration.html as a reference.
Reading there, it seems that you should put into "parameters.yml" all infrastructure parameters which do not really change your application behaviours. I think this applies to your case as well: your application does not change its behaviour according to assets paths, it only needs to know where they are.
So, again, I'd say that putting them in parameters.yml not only provides you an easy solution but also it's a "good practice".

Symfony custom config cascade

In Symfony 1.4, is it possible for one to define a custom config file (e.g. my_config.yml) that allows cascading; for instance, having a global custom config file and a module level analogue?
Yes.
Define a config handler in config_handlers.yml. It'll probably look like:
config/my_config.yml:
class: myConfigHandler
Write your config handler. You can look at many of the other config handlers in lib/config for examples. You'll likely want to extend sfYamlConfigHandler.
To access your config values:
sfContext::getInstance()->getConfigCache()->checkConfig('/config/my_config.yml');

Categories