popov130 popov130 - 1 month ago 21
PHP Question

Symfony 3.1 - create global parameter for AppBundle

I'm trying to define some parameters inside the AppBundle without success. It's one of my first test on this framework so there may be obvious concept that I misunderstood.

The first problem is the field bundle_version which is not read inside the YAML file. The error returned is the following :

[Symfony\Component\Config\Definition\Exception\InvalidConfigurationException]
The child node "bundle_version" at path "costs" must be configured.


When i comment this line, i get another error :

[Symfony\Component\DependencyInjection\Exception\InvalidArgumentException]
There is no extension able to load the configuration for "costs" (in W:\wamp64\www\test\src\AppBundle\DependencyInjecti
on/../Resources/config\costs.yml). Looked for namespace "costs", found none


src/AppBundle/DependencyInjection/Configuration.php

namespace AppBundle\DependencyInjection;

use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;

class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('costs');

$rootNode->children()
// THIS LINE DON'T WORK AND CAUSE THE 1st PROBLEM
->floatNode('bundle_version')->isRequired()->end()
->arrayNode('shipping')
->children()
->floatNode('es')->isRequired()->end()
->floatNode('it')->isRequired()->end()
->floatNode('uk')->isRequired()->end()
->end()
->end()

->arrayNode('services')
->children()
->floatNode('serviceA')->isRequired()->end()
->floatNode('serviceB')->isRequired()->end()
->end()
->end()
->end();

return $treeBuilder;
}
}


/src/AppBundle/Resources/config.costs.yml

costs:
bundle_version: 1.0 # THIS FIELD IS NOT RECOGNIZED
shipping:
es: 18.00
it: 19.00
uk: 20.00
services:
serviceA: 15.00
serviceB: 20.00


/src/AppBundle/DependencyInjection/AppExtension.php

namespace AppBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\Config\FileLocator;

class AppExtension extends Extension
{

public function load(array $config, ContainerBuilder $container)
{
$loader = new YamlFileLoader(
$container,
new FileLocator(__DIR__.'/../Resources/config')
);
$loader->load('costs.yml');
}
}

Answer

The solution is quite simple as i expected ... In /app/config/config.yml there's a predefined "parameters" key and we're supposed to putt our params here if they're not Bundle specific.

So it's just something like :

# /app/config/config.yml
imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: services.yml }

# Put parameters here that don't need to change on each machine where the app is deployed
 # http://symfony.com/doc/current/best_practices/configuration.html#application-    related-configuration
parameters:
      locale: fr
my_param: my_value

Then in your controller :

//   /src/AppBundle/Controller/DefaultController.php

    class DefaultController extends Controller
    {
        /**
         * @Route("/", name="homepage")
         */
        public function indexAction(Request $request)
        {
            $this->getParameter('my_param'); // or $this->getContainer()->getParameter('my_param');

            // replace this example code with whatever you need
            return $this->render('default/index.html.twig', [
                'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
            ]);
        }
    }

Hope it helps