Symfony2中基于区域设置的参数值

时间:2015-08-08 10:50:28

标签: php facebook symfony

我有一个Symfony2应用程序,具有多个区域设置,并且每个域都有自己的域名(意味着区域设置没有前缀或在域后添加),如“shoes.com”和“schue.de”。

要执行此操作,我正在使用jms_i18n_routing捆绑包,它负责设置正确的区域设置。

当我想要整合Facebook时,我的问题就出现了hwi_ouath bundle,,我必须在我的config.yml中设置“app id”和“app secret”,但这些应用也是特定于语言环境的(从现在开始在Facebook上你只能创建一个重定向URL)所以我应该在某处更改参数值,但在容器编译时,我无权访问Request对象,检查语言环境以后我可以不要更改参数值。

知道如何解决这个问题吗?

3 个答案:

答案 0 :(得分:0)

你可以通过工厂服务来做到这一点。

<service id="facebook.factory" class="Acme\Facebook\Factory">
    <argument type="service" id="request_stack"/>
    <argument>%facebook_credentials%</argument>
</service>
<service id="facebook" class="Facebook"
         factory-service="facebook.factory" factory-method="create"/>

<!-- use "facebook" where you need it -->

创建工厂,就像这样:

namespace Acme\Facebook;

class Factory
{
    //...

    public function __construct($requestStack, $credentials)
    {
        $this->requestStack = $requestStack;
        $this->credentials = $credentials;
    }

    public function create()
    {
        $r = $requestStack->getCurrentRequest();
        // throw if $r is null
        $c = $this->credentials[$r->getHost()];
        return new Facebook($c);
    }
}

请记住,facebook服务只会创建一次。假设主机名/语言环境在单个请求中没有变化,这应该没问题。如果它可以更改,请注入工厂本身并在需要时调用create。当然,在这种情况下,您可以为每个语言环境保存已创建的Facebook对象并重复使用它们。

不幸的是,您将不得不重新定义服务,因为捆绑包使用一组参数配置服务,这在您的情况下是不可接受的。因此,捆绑集成可能不会开箱即用,但您仍然可以使用它提供的所有类。

答案 1 :(得分:0)

最后我使用了这个解决方案,也许有人需要这样的东西:

在AppKernel中,我使用当前的http host:

创建了一个服务器变量
class AppKernel extends Kernel
{
   /**
    * @inheritdoc
    */
   public function __construct($environment, $debug)
   {
       parent::__construct($environment, $debug);
       if ($hostEnv = $this->getHostEnv()) {
           $_SERVER['SYMFONY__HOST'] = $hostEnv;
       }
   }
  ...
   private function getHostEnv()
   {
       if (!empty($_SERVER['HTTP_HOST'])) {
           return $_SERVER['HTTP_HOST'];
       }

       return null;
   }
   public function registerContainerConfiguration(LoaderInterface $loader)
   {
       $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
       $loader->load(__DIR__.'/config/parameters.php');
   }
}

使用SYMFONY__%服务器变量,您可以自动创建参数。

然后parameter.php

<?php

require_once('PlasticConfig.php');

if (!empty($container)) {
    $plasticConfig = new PlasticConfig($container);
    $container = $plasticConfig->load();
}

然后PlasticConfig.php

<?php

use \Symfony\Component\DependencyInjection\ContainerInterface;

class PlasticConfig {

    /**
     * @var Symfony\Component\DependencyInjection\ContainerInterface
     */
    protected $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    public function load()
    {
        /** 
         * this was defined in the constructor of AppKernel 
         * at console command there is no HTTP_HOST variable
         */
        if (!$this->container->hasParameter('host')) {
            return $this->container;
        }

        $host = $this->container->getParameter('host');
        //Magic can be done here, important is, that you return your container instance here

        return $this->container;
    }
} 

在我的parameters.yml中我有一些参数,名称为host_de,host_en ...我将遍历所有参数,如果我找到与当前主机的匹配,那么我有参数名称的区域设置。之后我只需要从parameters.yml设置facebook参数,其中我有facebook.de.app_id: XYfacebook.en.app_id: ZS等参数。

答案 2 :(得分:0)

<强> config.yml

imports:
    - { resource: parameters.php } #add this import

hwi_ouath bundle:
    # put this in the right place
    app_id: %facebook.app_id%
    app_secret: %facebook.secret%

<强> parameters.php

<?php

$lang = 'en';

if ('schue.de' === $_SERVER['HTTP_HOST']) {
    $lang = 'de';
} // elseif (...

$container->setParameter('facebook.app_id', $container->getParameter('facebook.'.$lang.'.app_id'));
$container->setParameter('facebook.secret', $container->getParameter('facebook.'.$lang.'.secret'));