【问题标题】:InvalidConfigurationException with custom bundle in Symfony6.2Symfony6.2 中带有自定义包的 InvalidConfigurationException
【发布时间】:2022-12-07 03:52:06
【问题描述】:

我正在尝试将我的自定义包从 symfony 3 迁移到 symfony 6.2 支持,但被 InvalidConfigurationException 卡住了。

我一直在关注thisthis 文档,但我似乎遗漏了一个重要部分。

src/SchoenefHtmlToPdfBundle.php:

<?php

namespace Schoenef\HtmlToPdfBundle;

use Symfony\Component\HttpKernel\Bundle\AbstractBundle;

class SchoenefHtmlToPdfBundle extends AbstractBundle
{

}

src/DependencyInjection/SchoenefHtmlToPdfExtension.php:

namespace Schoenef\HtmlToPdfBundle\DependencyInjection;

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

class SchoenefHtmlToPdfExtension extends Extension
{

    /**
     * {@inheritdoc}
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../../config'));
        $loader->load('services.yml');
    }

}

源代码/DependencyInjection/Configuration.php

<?php
namespace Schoenef\HtmlToPdfBundle\DependencyInjection;

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

/**
 * This is the class that validates and merges configuration from your app/config files
 * this is testing the configuration in the following manner:
 * html2pdf:
 *   provider: defualt pdfrocket
 *   timeout: default 20
 *   apikey: required
 *
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
 */
class Configuration implements ConfigurationInterface
{

    const pageSizes = ['A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'B0', 'B1', 'B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B9', 'C5E', 'Comm10E', 'DLE', 'Executive', 'Folio', 'Ledger', 'Legal', 'Letter', 'Tabloid'];
    const PROVIDER_PDF_ROCKET = 'pdfrocket';

    const KEY_PROVIDER = 'provider';
    const KEY_TIMEOUT = 'timeout';
    const KEY_APIKEY = 'apikey';
    const KEY_DEFAULT_OPTIONS = 'default_options';

    const OPTION_DPI = 'dpi';
    const OPTION_SHRINKING = 'shrinking';
    const OPTION_IMAGE_QUALITY = 'image_quality';
    const OPTION_PAGE_SIZE = 'page_size';
    const OPTION_ZOOM = 'zoom';
    const OPTION_JS_DELAY = 'js_delay';

    /**
     * {@inheritdoc}
     */
    public function getConfigTreeBuilder(): TreeBuilder
    {
        $treeBuilder = new TreeBuilder('schoenef_html_to_pdf');

        $treeBuilder->getRootNode()
            ->children()
                ->enumNode(self::KEY_PROVIDER)->values([self::PROVIDER_PDF_ROCKET])->defaultValue(self::PROVIDER_PDF_ROCKET)->end()
                ->integerNode(self::KEY_TIMEOUT)->defaultValue(20)->end()
                ->scalarNode(self::KEY_APIKEY)->isRequired()->end()
                ->arrayNode(self::KEY_DEFAULT_OPTIONS)
                    ->children()
                        ->integerNode(self::OPTION_DPI)->end()
                        ->floatNode(self::OPTION_ZOOM)->end()
                        ->integerNode(self::OPTION_JS_DELAY)->end()
                        ->booleanNode(self::OPTION_SHRINKING)->defaultTrue()->end()
                        ->integerNode(self::OPTION_IMAGE_QUALITY)->end()
                        ->enumNode(self::OPTION_PAGE_SIZE)->values(self::pageSizes)->end()
                    ->end()
                ->end()
            ->end();
        return $treeBuilder;
    }
}

任何人都可以看到可能非常明显的错误吗?我只得到:

Unrecognized options "provider, timeout, apikey, default_options" under "schoenef_html_to_pdf". Available options are "".

多谢!

【问题讨论】:

  • 我将您的配置类复制到一个新的 6.2 应用程序中,一切似乎都按预期工作。尝试在 Extension::load 中添加一个 dd() 以确保它被调用。如果不是,你可能会得到一个不同的错误,但这就是我能想到的。除非您可能正在编辑错误的项目目录。
  • 哈。我刚刚注意到您扩展了 AbstractBundle 而不是 Bundle。我更改了测试用例并遇到了与您相同的问题。不确定这是否是预期的行为。所以回到扩展 Bundle 或用 AbstractBundle 的 loadExtension 和 configure 方法替换你的扩展和配置类。

标签: php symfony bundle symfony6


【解决方案1】:

Symfony 6.1 引入了一个新的AbstractBundle 类。使用 AbstractBundle,您不再需要单独的扩展和配置类。直到看到这个问题我才意识到 AbstractBundle 与旧的 Bundle 类不兼容。

所以这个问题的简短答案是扩展原来的 Bundle 类,一切都应该像以前一样工作。 Bundle 类本身不会去任何地方。

use SymfonyComponentHttpKernelBundleBundle;

class SchoenefHtmlToPdfBundle extends Bundle

一个更长的答案是继续并利用 AbstractBundle 的功能。就像是:

class CeradMyBundle extends AbstractBundle
{
  const pageSizes = ['A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'B0', 'B1', 'B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B9', 'C5E', 'Comm10E', 'DLE', 'Executive', 'Folio', 'Ledger', 'Legal', 'Letter', 'Tabloid'];
  const PROVIDER_PDF_ROCKET = 'pdfrocket';

  const KEY_PROVIDER = 'provider';
  const KEY_TIMEOUT = 'timeout';
  const KEY_APIKEY = 'apikey';
  const KEY_DEFAULT_OPTIONS = 'default_options';

  const OPTION_DPI = 'dpi';
  const OPTION_SHRINKING = 'shrinking';
  const OPTION_IMAGE_QUALITY = 'image_quality';
  const OPTION_PAGE_SIZE = 'page_size';
  const OPTION_ZOOM = 'zoom';
  const OPTION_JS_DELAY = 'js_delay';

  public function configure(DefinitionConfigurator $definition): void
  {
    $definition->rootNode()
      ->children()
        ->enumNode(self::KEY_PROVIDER)->values([self::PROVIDER_PDF_ROCKET])->defaultValue(self::PROVIDER_PDF_ROCKET)->end()
        ->integerNode(self::KEY_TIMEOUT)->defaultValue(20)->end()
        ->scalarNode(self::KEY_APIKEY)->isRequired()->end()
        ->arrayNode(self::KEY_DEFAULT_OPTIONS)
            ->children()
                ->integerNode(self::OPTION_DPI)->end()
                ->floatNode(self::OPTION_ZOOM)->end()
                ->integerNode(self::OPTION_JS_DELAY)->end()
                ->booleanNode(self::OPTION_SHRINKING)->defaultTrue()->end()
                ->integerNode(self::OPTION_IMAGE_QUALITY)->end()
                ->enumNode(self::OPTION_PAGE_SIZE)->values(self::pageSizes)->end()
            ->end()
        ->end()
    ->end();
  }
  public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
  {
    $container->import('../config/services.yaml');
  }
}

您也可以考虑将配置内容移动到它自己的 config/definition.php 文件中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多