Symfony 4 Custom yaml файл конфигурации для Bundle

Я пытаюсь преобразовать пакет в Symfony 4 и мне нужно обновить мои древние параметры.yml до современного образа жизни Symfony 4. По сути, сам пакет, совместно используемый несколькими приложениями, должен иметь настраиваемый файл в /config/packages/.

Однако я получаю эту ошибку:

(1/1) InvalidArgumentException

There is no extension able to load the configuration for "ptmr" (in /var/www/html/ptmr/pws_ptmrio_dev/PtmrBundle/DependencyInjection/../../config/packages/ptmr.yaml). Looked for namespace "ptmr", found none

/ PtmrBundle / DependencyInjection /PtmrExtension.php

<?php
namespace PtmrBundle\DependencyInjection;

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

class PtmrExtension extends Extension
{

    public function load(array $configs, ContainerBuilder $container)
    {

        $configuration = new Configuration(true);
        $config = $this->processConfiguration($configuration, $configs);

        $loader = new YamlFileLoader(
            $container,
            new FileLocator(__DIR__ . '/../../config/packages')
        );

        $loader->load('ptmr.yaml');

    }


}

/ PtmrBundle / DependencyInjection /Configuration.php

<?php
namespace PtmrBundle\DependencyInjection;

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

class Configuration implements ConfigurationInterface
{

    private $debug;

    public function  __construct($debug = true)
    {
        $this->debug = (bool) $debug;
    }

    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder('ptmr');

        $treeBuilder->getRootNode()
            ->children()
            ->arrayNode('twitter')
            ->children()
            ->integerNode('client_id')->end()
            ->scalarNode('client_secret')->end()
            ->end()
            ->end() // twitter
            ->end()
        ;

        return $treeBuilder;
    }
}

/ config / packages /ptmr.yaml

ptmr:
  twitter:
    client_id: 123
    client_secret: your_secret

- Примечание: сам Bundle работает.

Я добавил эту строку в psr-4 в composer.json:

    "PtmrBundle\\": "PtmrBundle/"

Это строки для config / маршруты /annotations.yml

ptmr_bundle:
    resource: ../PtmrBundle/Controller/
    type: annotation

Эти строки в config /services.yaml

services:
    ...

    PtmrBundle\:
        resource: '../PtmrBundle/*'
        exclude: '../PtmrBundle/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

    ...

    PtmrBundle\Controller\:
        resource: '../PtmrBundle/Controller'
        tags: ['controller.service_arguments']

И, конечно же, PtmrBundle/PtmrBundle.php

<?php

namespace PtmrBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class PtmrBundle extends Bundle
{

}

Я следую этим инструкциям и не вижу никаких ошибок. Что мне не хватает? Symfony 4.2.

1 ответ

Я все-таки нашел ответ. Сделать свой собственныйconfig/bundle.yaml файл параметров, просто выполните:

Шаг 1. Создайте файл в своем пакетеDependencyInjection/{BundleNameWithoutBundle}Extension.php, например, для MyBundle > MyExtension.php

<?php
namespace MyBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;

class MyExtension extends \Symfony\Component\DependencyInjection\Extension\Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        $container->setParameter('my', $config);
    }
}

Также см. Как загрузить конфигурацию службы внутри пакета

Шаг 2. Создайте файл конфигурации, который предоставляет схему для вашего файла.yaml.DependencyInjection/Configuration.php

<?php

namespace MyBundle\DependencyInjection;

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

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder('my');

        $treeBuilder->getRootNode()
            ->children()
                ->variableNode('project_name')->end()
            ->end()
        ;

        return $treeBuilder;
    }
}

Также см. Как создать удобную конфигурацию для пакета

Шаг 3: ОтразитеConfiguration.php в твоем config/my.yaml

my:
  project_name: "My Name"

Теперь параметр myдоступен (установлен в MyExtension Class). Просто загрузите его в свой контроллер, например:

class IndexController extends AbstractController
{
    public function indexAction(ParameterBagInterface $parameterBag)
    {
        ...
        dump($parameterBag->get('ptmr'));
        return $this->render('index.html.twig');
    }

}

Примечание. Большинство пакетов идут дальше и манипулируют XML-файлами конфигурации пакетов, что выходит за рамки простого вопроса, подобного этому. Простым примером того, как это сделать, является KnpPaginatorBundle, который не слишком сложен для понимания параметров настроек.

Личное примечание: мне кажется, что документы Symfony слишком сложны и должны содержать простой пример. Вы должны знать много номенклатуры, и ее трудно выучить, особенно по сравнению с другими хорошо документированными разделами Symfony.

Вы пытаетесь загрузить конфигурацию для своего пакета до того, как Symfony узнает о вашем пакете. Ваш класс комплекта должен быть загружен и настроен, прежде чем вы сможете проанализировать конфигурацию в ptmr имущество.

Как правило, ваш пакет будет загружен __DIR__.'/../Resources/config/services.yaml который содержит service а также parameters определения. Вне вашего пакета, в вашем приложении config/ DIR, вы бы тогда загрузить конфигурацию под ptmr имущество.

Другие вопросы по тегам