Commit d471d097 authored by bojanz's avatar bojanz

Implement the country and locale resolvers.

parent 783d0bc8
services:
commerce.country_context:
class: Drupal\commerce\CountryContext
arguments: ['@request_stack', '@commerce.chain_country_resolver']
commerce.chain_country_resolver:
class: Drupal\commerce\Resolver\ChainCountryResolver
tags:
- { name: service_collector, call: addResolver, tag: commerce.country_resolver }
commerce.default_country_resolver:
class: Drupal\commerce\Resolver\DefaultCountryResolver
arguments: ['@config.factory']
tags:
- { name: commerce.country_resolver, priority: -100 }
commerce.locale_context:
class: Drupal\commerce\LocaleContext
arguments: ['@request_stack', '@commerce.chain_locale_resolver']
commerce.chain_locale_resolver:
class: Drupal\commerce\Resolver\ChainLocaleResolver
tags:
- { name: service_collector, call: addResolver, tag: commerce.locale_resolver }
commerce.default_locale_resolver:
class: Drupal\commerce\Resolver\DefaultLocaleResolver
arguments: ['@language_manager', '@commerce.country_context']
tags:
- { name: commerce.locale_resolver, priority: -100 }
<?php
/**
* @file
* Contains \Drupal\commerce\CountryContext.
*/
namespace Drupal\commerce;
use Drupal\commerce\Resolver\ChainCountryResolverInterface;
/**
* Country context.
*
* Holds a reference to the current country, resolved on demand.
*
* The ChainCountryResolver runs the registered country resolvers one by one
* until one of them returns the country.
* The DefaultCountryResolver runs last, and will select the site's default
* country. Custom resolvers can choose based on the user profile, GeoIP, etc.
*
* @see \Drupal\commerce\Resolver\ChainCountryResolver
* @see \Drupal\commerce\Resolver\DefaultCountryResolver
*/
class CountryContext implements CountryContextInterface {
/**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* The chain resolver.
*
* @var \Drupal\commerce\Resolver\ChainCountryResolverInterface
*/
protected $chainResolver;
/**
* Static cache of resolved countries. One per request.
*
* @var \SplObjectStorage
*/
protected $countries;
/**
* Constructs a new CountryContext object.
*
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
* The request stack.
* @param\Drupal\commerce\Resolver\ChainCountryResolverInterface $chainResolver
* The chain resolver.
*/
public function __construct(RequestStack $requestStack, ChainCountryResolverInterface $chainResolver) {
$this->requestStack = $requestStack;
$this->chainResolver = $chainResolver;
$this->countries = new \SplObjectStorage();
}
/**
* {@inheritdoc}
*/
public function getCountry() {
$request = $this->requestStack->getCurrentRequest();
if (!$this->countries->contains($request)) {
$this->countries[$request] = $this->chainResolver->resolve();
}
return $this->countries[$request];
}
}
<?php
/**
* @file
* Contains \Drupal\commerce\CountryContextInterface.
*/
namespace Drupal\commerce;
/**
* Country context interface
*
* Holds a reference to the current country, resolved on demand.
*
* @see \Drupal\commerce\CountryContext
*/
interface CountryContextInterface {
/**
* Gets the country for the current request.
*
* @return \Drupal\commerce\CountryInterface
*/
public function getCountry();
}
<?php
/**
* @file
* Contains \Drupal\commerce\LocaleContext.
*/
namespace Drupal\commerce;
use Drupal\commerce\Resolver\ChainLocaleResolverInterface;
/**
* Locale context.
*
* Holds a reference to the current locale, resolved on demand.
*
* The ChainLocaleResolver runs the registered locale resolvers one by one until
* one of them returns the locale.
* The DefaultLocaleResolver runs last, and contains the default logic
* which assembles the locale based on the current language and country.
*
* @see \Drupal\commerce\Resolver\ChainLocaleResolver
* @see \Drupal\commerce\Resolver\DefaultLocaleResolver
*/
class LocaleContext implements LocaleContextInterface {
/**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* The chain resolver.
*
* @var \Drupal\commerce\Resolver\ChainLocaleResolverInterface
*/
protected $chainResolver;
/**
* Static cache of resolved locales. One per request.
*
* @var \SplObjectStorage
*/
protected $locales;
/**
* Constructs a new LocaleContext object.
*
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
* The request stack.
* @param\Drupal\commerce\Resolver\ChainLocaleResolverInterface $chainResolver
* The chain resolver.
*/
public function __construct(RequestStack $requestStack, ChainLocaleResolverInterface $chainResolver) {
$this->requestStack = $requestStack;
$this->chainResolver = $chainResolver;
$this->locales = new \SplObjectStorage();
}
/**
* {@inheritdoc}
*/
public function getLocale() {
$request = $this->requestStack->getCurrentRequest();
if (!$this->locales->contains($request)) {
$this->locales[$request] = $this->chainResolver->resolve();
}
return $this->locales[$request];
}
}
<?php
/**
* @file
* Contains \Drupal\commerce\LocaleContextInterface.
*/
namespace Drupal\commerce;
/**
* Locale context interface
*
* Holds a reference to the current locale, resolved on demand.
*
* @see \Drupal\commerce\LocaleContext
*/
interface LocaleContextInterface {
/**
* Gets the locale for the current request.
*
* @return \Drupal\commerce\LocaleInterface
*/
public function getLocale();
}
<?php
/**
* @file
* Contains \Drupal\commerce\Resolver\ChainCountryResolver.
*/
namespace Drupal\commerce\Resolver;
/**
* Default implementation of the chain country resolver.
*/
class ChainCountryResolver implements ChainCountryResolverInterface {
/**
* The resolvers.
*
* @var \Drupal\commerce\Resolver\CountryResolverInterface[]
*/
protected $resolvers = [];
/**
* Constructs a new ChainCountryResolver object.
*
* @param \Drupal\commerce\Resolver\CountryResolverInterface[] $resolvers
* The resolvers.
*/
public function __construct(array $resolvers = []) {
$this->resolvers = $resolvers;
}
/**
* {@inheritdoc}
*/
public function addResolver(CountryResolverInterface $resolver) {
$this->resolvers[] = $resolver;
}
/**
* {@inheritdoc}
*/
public function resolve() {
foreach ($this->resolvers as $resolver) {
$result = $resolver->resolve();
if ($result) {
return $result;
}
}
}
}
<?php
/**
* @file
* Contains \Drupal\commerce\Resolver\ChainCountryResolverInterface.
*/
namespace Drupal\commerce\Resolver;
/**
* Chain country resolver interface.
*
* Runs the added resolvers one by one until one of them returns the country.
* Each resolver in the chain can be another chain, which is why this interface
* extends the country resolver one.
*/
interface ChainCountryResolverInterface extends CountryResolverInterface {
/**
* Adds a resolver.
*
* @param \Drupal\commerce\Resolver\CountryResolverInterface $resolver
* The resolver.
*/
public function addResolver(CountryResolverInterface $resolver);
}
<?php
/**
* @file
* Contains \Drupal\commerce\Resolver\ChainLocaleResolver.
*/
namespace Drupal\commerce\Resolver;
/**
* Default implementation of the chain locale resolver.
*/
class ChainLocaleResolver implements ChainLocaleResolverInterface {
/**
* The resolvers.
*
* @var \Drupal\commerce\Resolver\LocaleResolverInterface[]
*/
protected $resolvers = [];
/**
* Constructs a new ChainLocaleResolver object.
*
* @param \Drupal\commerce\Resolver\LocaleResolverInterface[] $resolvers
* The resolvers.
*/
public function __construct(array $resolvers = []) {
$this->resolvers = $resolvers;
}
/**
* {@inheritdoc}
*/
public function addResolver(LocaleResolverInterface $resolver) {
$this->resolvers[] = $resolver;
}
/**
* {@inheritdoc}
*/
public function resolve() {
foreach ($this->resolvers as $resolver) {
$result = $resolver->resolve();
if ($result) {
return $result;
}
}
}
}
<?php
/**
* @file
* Contains \Drupal\commerce\Resolver\ChainLocaleResolverInterface.
*/
namespace Drupal\commerce\Resolver;
/**
* Chain locale resolver interface.
*
* Runs the added resolvers one by one until one of them returns the locale.
* Each resolver in the chain can be another chain, which is why this interface
* extends the locale resolver one.
*/
interface ChainLocaleResolverInterface extends LocaleResolverInterface {
/**
* Adds a resolver.
*
* @param \Drupal\commerce\Resolver\LocaleResolverInterface $resolver
* The resolver.
*/
public function addResolver(LocaleResolverInterface $resolver);
}
<?php
/**
* @file
* Contains \Drupal\commerce\Resolver\CountryResolverInterface.
*/
namespace Drupal\commerce\Resolver;
/**
* Country resolver interface
*
* Each resolver tries to determine the current country based on its own logic,
* and returns it if successful. Otherwise, it returns NULL to indicate that
* the next resolver in the chain should be called.
*/
interface CountryResolverInterface {
/**
* Resolves the country.
*
* @return string|null
*/
public function resolve();
}
<?php
/**
* @file
* Contains \Drupal\commerce\Resolver\DefaultCountryResolver.
*/
namespace Drupal\commerce\Resolver;
use Drupal\Core\Config\ConfigFactoryInterface;
/**
* Returns the site's default country.
*/
class DefaultCountryResolver implements CountryResolverInterface {
/**
* The configuration factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* Constructs a new DefaultCountryResolver object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory.
*/
public function __construct(ConfigFactoryInterface $configFactory) {
$this->configFactory = $configFactory;
}
/**
* {@inheritdoc}
*/
public function resolve() {
return $this->configFactory->get('system.date')->get('country.default');
}
}
<?php
/**
* @file
* Contains \Drupal\commerce\Resolver\DefaultLocaleResolver.
*/
namespace Drupal\commerce\Resolver;
use Drupal\commerce\CountryContextInterface;
use Drupal\Core\Language\LanguageManagerInterfacee;
/**
* Returns the locale based on the current language and country.
*/
class DefaultLocaleResolver implements LocaleResolverInterface {
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* The country context.
*
* @var \Drupal\commerce\CountryContextInterface
*/
protected $countryContext;
/**
* Constructs a new DefaultLocaleResolver object.
*
* @param \Drupal\Core\Language\LanguageManagerInterface $languageManager
* The language manager.
* @param \Drupal\commerce\CountryContextInterface $countryContext
* The country context.
*/
public function __construct(LanguageManagerInterface $languageManager, CountryContextInterface $countryContext) {
$this->languageManager = $languageManager;
$this->countryContext = $countryContext;
}
/**
* {@inheritdoc}
*/
public function resolve() {
$language = $this->languageManager->getConfigOverrideLanguage()->getId();
$languageParts = explode('-', $language);
if (count($languageParts) > 1 && strlen(end($languageParts)) == 2) {
// The current language already has a country component (e.g. 'pt-br'),
// it qualifies as a full locale.
$locale = $language;
}
elseif ($country = $this->countryContext->getCountry()) {
// Assemble the locale using the resolved country. This can result
// in non-existent combinations such as 'en-RS', it's up to the locale
// consumers (e.g. the number format repository) to perform fallback.
$locale = $language . '-' . $country;
}
else {
// Worst case scenario, the country is unknown.
$locale = $language;
}
return $locale;
}
}
<?php
/**
* @file
* Contains \Drupal\commerce\Resolver\LocaleResolverInterface.
*/
namespace Drupal\commerce\Resolver;
/**
* Locale resolver interface
*
* Each resolver tries to determine the current locale based on its own logic,
* and returns it if successful. Otherwise, it returns NULL to indicate that
* the next resolver in the chain should be called.
*/
interface LocaleResolverInterface {
/**
* Resolves the locale.
*
* @return string|null
*/
public function resolve();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment