可选和动态服务参数

时间:2017-05-18 14:22:57

标签: php symfony

我使用的软件(商店)使用了一些Symfony组件,因此我认为这个问题主要与Symfony相关。

当我在services.xml中创建一个服务时,我遇到了一个问题(或不确定性),该服务具有service.xml中不可用的可选参数或动态参数。

两个例子

  1. 创建自己的monolog实例
  2. 除了系统默认的monolog实例,我想为我的插件提供一个自己的monolog实例,其中包含不同的处理程序和配置。

    在我的services.xml中我有这样的东西:

    <service id="my_plugin.monolog.handler.rotating_file_debug" class="Monolog\Handler\RotatingFileHandler" public="false">
       <argument>%kernel.logs_dir%/myplugin_debug.log</argument>
       <argument>14</argument>
    </service>
    
    <service id="my_plugin.monolog.handler.rotating_file_error" class="Monolog\Handler\RotatingFileHandler" public="false">
       <argument>%kernel.logs_dir%/myplugin_error.log</argument>
       <argument>14</argument>
       <argument>%monolog.logger.constant.error%</argument>
       <argument>false</argument>
    </service>
    
    <service id="my_plugin.logger" class="Monolog\Logger">
       <argument>myplugin.logger</argument>
       <argument type="collection">
          <argument type="service" id="my_plugin.monolog.handler.rotating_file_error" />
          <argument type="service" id="my_plugin.monolog.handler.rotating_file_debug" />
       </argument>
    </service>
    

    这很好但现在我想添加一个额外的邮件处理程序如果错误的电子邮件地址可用(后端插件配置)。

    问题是我不知道如何在services.xml中检查这个。

    我的解决方案是工厂级,所以我修改了services.xml,如下所示:

    <service id="my_plugin.logger" class="Monolog\Logger">
       <factory class="MyPlugin\Components\Factory" method="createLogger" />
       <argument>myplugin.logger</argument>
       <argument type="collection">
          <argument type="service" id="my_plugin.monolog.handler.rotating_file_error" />
          <argument type="service" id="my_plugin.monolog.handler.rotating_file_debug" />
       </argument>
    </service>
    

    这有效但感觉不对,好像我在这里有一个逻辑问题。

    1. API-客户端
    2. Api-Client需要apiUser,apiKey和apiUrl作为构造函数参数。 service.xml中没有这些值可用。我还创建了一个工厂方法。

      所以我的问题是什么是&#34;最佳实践&#34;解决方案 可选或动态参数?

      我是否存在逻辑问题或工厂是否是一个好的解决方案? 有关编译器传递的内容是否适用于这种情况?

      更新19.05

      我创建了一个CompilerPass,但是在流程方法中我无法访问DI-Container,因此我无法通过该服务访问数据库。

      这是一个限制还是我错过了什么?

      更新19.05#2

      似乎它不打算在CompilerPass中访问DIC,因此我无法访问所需的后端配置值。

      我现在尝试了不同的东西:

      // services.xml

      <service id="my_plugin.logger" class="MyPlugin\Components\Logger">
         <argument>myplugin.logger</argument>
         <argument type="collection">
            <argument type="service" id="my_plugin.monolog.handler.rotating_file_critical" />
            <argument type="service" id="my_plugin.monolog.handler.rotating_file_error" />
            <argument type="service" id="my_plugin.monolog.handler.rotating_file_debug" />
         </argument>
         <argument type="collection"></argument>
         <argument type="service" id="shopware.plugin.config_reader" />
         <argument type="service" id="Config" />
      </service>
      

      // MyPlugin \ Components \ Logger

      <?php
      namespace MyPlugin\Components;
      
      use Monolog\Formatter\HtmlFormatter;
      use Monolog\Handler\NativeMailerHandler;
      use Shopware\Components\Plugin\DBALConfigReader;
      
      class Logger
          extends \Monolog\Logger
      {
          /** @var DBALConfigReader */
          private $pluginConfigReader;
      
          /** @var \Shopware_Components_Config */
          private $config;
      
          public function __construct($name, array $handlers = array(), array $processors = array(), DBALConfigReader $pluginConfigReader, \Shopware_Components_Config $config)
          {
              $this->pluginConfigReader = $pluginConfigReader;
              $this->config = $config;
      
              parent::__construct($name, $handlers, $processors);
      
              $pluginConfig = $this->pluginConfigReader->getByPluginName('MyPlugin');
              $errorEmail = $pluginConfig['critical_error_email'];
      
              if($errorEmail != "")
              {
                  $this->addMailHandler($errorEmail);
              }
          }
      
          private function addMailHandler($recipient)
          {
              $mailHandler = new NativeMailerHandler(
                  $recipient,
                  $this->config->get('shopName').' - Critial Issue',
                  $this->config->get('mail'),
                  Logger::CRITICAL
              );
      
              $mailHandler->setFormatter(new HtmlFormatter());
      
              $this->pushHandler($mailHandler);
          }
      }
      

      不确定这个解决方案是否比工厂更好但是有效。 如果有人有更好的解决方案,我仍然会反馈意见。

0 个答案:

没有答案