At the moment we are running an online-shop for germany. Now we want also offer our products in UK with an own domain.
Depending on the domain their are several settings which should be loaded:
In a previous project we solved it by putting this settings in a domain-table in the database. But I think with the whole payment service information and key and and and.. it is not the best solution.
You can write a bundle Extension class to load your configuration depending on the host.
The bundle Extension:
// src/AcmeBundle/DependencyInjection/AcmeExtension.php
<?php
namespace AcmeBundle\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
class AcmeExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$rootdir = $container->getParameter('kernel.root_dir');
// Load the bundle's services.yml
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
// Load parameters depending on current host
$paramLoader = new Loader\YamlFileLoader($container, new FileLocator($rootdir.'/config')); // Access the root config directory
$parameters = sprintf('parameters_%s.yml', $container->getParameter('router.request_context.host'));
if (!file_exists($rootdir.'/config/'.$parameters)) {
$parameters = 'parameters.yml'; // Default
}
$paramLoader->load($parameters);
}
}
The corresponding bundle Configuration:
// src/AcmeBundle/DependencyInjection/Configuration.php
<?php
namespace AcmeBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('acme');
return $treeBuilder;
}
}
Like this, you can create a file named parameters_localhost.yml
and it will be automatically loaded.
If the file is not found, the default parameters.yml
will be used.
You can apply this logic based on every parameters you want (like _locale
used for your translations, I guess).
Hope this help.
I know that the best answer is already chosen, but I found other approach with parameters.php
:
<?php
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader;
$hostArray = explode('.', $_SERVER['HTTP_HOST']);
$hostArrayCount = count($hostArray);
$host = $hostArray[$hostArrayCount - 2] . '.' . $hostArray[$hostArrayCount - 1];
$hostDir = $container->getParameter('kernel.root_dir') . '/config/domains/';
$parameters = sprintf('%s.yml', $host);
if (file_exists($hostDir . $parameters)) {
$hostParamLoader = new Loader\YamlFileLoader($container, new FileLocator($hostDir));
$hostParamLoader->load($parameters);
}
and in config.yml
after:
imports:
- { resource: parameters.yml }
add string:
- { resource: parameters.php }
If each of your shop is a different app installation, then why not keep your config in parameters.yml
file ? You can also take a look at ParameterHandler script which will help you manage all parameters.
If you use single code base, maybe you should totally rethink your implementation, because for example, what if in the future you will need to make products from UK shop independent from products in DE shop etc. ? (there are more use cases like that)
I think that your current solution is a short term solution and if you plan to expand to different countries, you should invest some time for a long term solution. Of course it depends all from your requirements and use cases.
An option is splitting your application into channels where each channel will be a shop in UK and DE and so on..
You could then also have a different settings, products, payments, currencies per channel etc..
You could take a look at Sylius project on GitHub. They developed this nice ChannelBundle which you can see how it works.
You can use SetEnv in your (apache?) configuration for the database variables and other variables for each domain (ref)
# /etc/apache2/sites-available/one-domain.conf
<VirtualHost *:80>
ServerName onedomain.uk
DocumentRoot "/path/to/onedomain/web"
DirectoryIndex index.php index.html
SetEnv SYMFONY__GOOGLE__ANALYTICSID mygoogleanalyticsid
SetEnv SYMFONY__PAYMENT__APISECRET mysecret
# ...
<Directory "/path/to/onedomain/web">
AllowOverride All
Allow from All
</Directory>
</VirtualHost>
Then use a common parameters.yml setting the variables:
# app/config/parameters.yml
parameters:
analytics_id: "google.analyticsid"
payment_secret: "payment.apisecret"
# ...
They all have their own db settings and any variable you want to set for each.
You can also separate your cache and logs folders, by setting a variable identifying each domain (ref):
# app/AppKernel.php
public function getCacheDir()
{
if(getenv("SYMFONY__DOMAIN__NAME")){
return dirname(__DIR__).'/var/cache/'.$this->getEnvironment().'/'.getenv("SYMFONY__DOMAIN__NAME");
} else {
return dirname(__DIR__).'/var/cache/'.$this->getEnvironment();
}
}
public function getLogDir()
{
if(getenv("SYMFONY__DOMAIN__NAME")){
return dirname(__DIR__).'/var/logs/'.getenv("SYMFONY__DOMAIN__NAME");
} else {
return dirname(__DIR__).'/var/logs/';
}
}
In case you store sessions in files, you can also do this for the sessions folder:
# app/config/config.yml
framework:
# ...
session:
handler_id: session.handler.native_file
save_path: "%kernel.root_dir%/../var/sessions/%kernel.environment%/%domain.name%"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With