View source
<?php
namespace Drupal\language\Plugin\LanguageNegotiation;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Url;
use Drupal\language\LanguageNegotiationMethodBase;
use Drupal\language\LanguageSwitcherInterface;
use Symfony\Component\HttpFoundation\Request;
class LanguageNegotiationUrl extends LanguageNegotiationMethodBase implements InboundPathProcessorInterface, OutboundPathProcessorInterface, LanguageSwitcherInterface {
const METHOD_ID = 'language-url';
const CONFIG_PATH_PREFIX = 'path_prefix';
const CONFIG_DOMAIN = 'domain';
public function getLangcode(Request $request = NULL) {
$langcode = NULL;
if ($request && $this->languageManager) {
$languages = $this->languageManager
->getLanguages();
$config = $this->config
->get('language.negotiation')
->get('url');
switch ($config['source']) {
case LanguageNegotiationUrl::CONFIG_PATH_PREFIX:
$request_path = urldecode(trim($request
->getPathInfo(), '/'));
$path_args = explode('/', $request_path);
$prefix = array_shift($path_args);
$negotiated_language = FALSE;
foreach ($languages as $language) {
if (isset($config['prefixes'][$language
->getId()]) && $config['prefixes'][$language
->getId()] == $prefix) {
$negotiated_language = $language;
break;
}
}
if ($negotiated_language) {
$langcode = $negotiated_language
->getId();
}
break;
case LanguageNegotiationUrl::CONFIG_DOMAIN:
$http_host = $request
->getHost();
foreach ($languages as $language) {
if (!empty($config['domains'][$language
->getId()])) {
$host = 'http://' . str_replace(array(
'http://',
'https://',
), '', $config['domains'][$language
->getId()]);
$host = parse_url($host, PHP_URL_HOST);
if ($http_host == $host) {
$langcode = $language
->getId();
break;
}
}
}
break;
}
}
return $langcode;
}
public function processInbound($path, Request $request) {
$config = $this->config
->get('language.negotiation')
->get('url');
$parts = explode('/', trim($path, '/'));
$prefix = array_shift($parts);
foreach ($this->languageManager
->getLanguages() as $language) {
if (isset($config['prefixes'][$language
->getId()]) && $config['prefixes'][$language
->getId()] == $prefix) {
$path = '/' . implode('/', $parts);
break;
}
}
return $path;
}
public function processOutbound($path, &$options = array(), Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
$url_scheme = 'http';
$port = 80;
if ($request) {
$url_scheme = $request
->getScheme();
$port = $request
->getPort();
}
$languages = array_flip(array_keys($this->languageManager
->getLanguages()));
if (!isset($options['language'])) {
$language_url = $this->languageManager
->getCurrentLanguage(LanguageInterface::TYPE_URL);
$options['language'] = $language_url;
}
elseif (!is_object($options['language']) || !isset($languages[$options['language']
->getId()])) {
return $path;
}
$config = $this->config
->get('language.negotiation')
->get('url');
if ($config['source'] == LanguageNegotiationUrl::CONFIG_PATH_PREFIX) {
if (is_object($options['language']) && !empty($config['prefixes'][$options['language']
->getId()])) {
$options['prefix'] = $config['prefixes'][$options['language']
->getId()] . '/';
if ($bubbleable_metadata) {
$bubbleable_metadata
->addCacheContexts([
'languages:' . LanguageInterface::TYPE_URL,
]);
}
}
}
elseif ($config['source'] == LanguageNegotiationUrl::CONFIG_DOMAIN) {
if (is_object($options['language']) && !empty($config['domains'][$options['language']
->getId()])) {
if (!empty($options['base_url'])) {
$normalized_base_url = str_replace(array(
'https://',
'http://',
), '', $options['base_url']);
}
$options['absolute'] = TRUE;
$options['base_url'] = $url_scheme . '://' . $config['domains'][$options['language']
->getId()];
if (isset($normalized_base_url) && strpos($normalized_base_url, ':') !== FALSE) {
list(, $port) = explode(':', $normalized_base_url);
$options['base_url'] .= ':' . $port;
}
elseif ($url_scheme == 'http' && $port != 80 || $url_scheme == 'https' && $port != 443) {
$options['base_url'] .= ':' . $port;
}
if (isset($options['https'])) {
if ($options['https'] === TRUE) {
$options['base_url'] = str_replace('http://', 'https://', $options['base_url']);
}
elseif ($options['https'] === FALSE) {
$options['base_url'] = str_replace('https://', 'http://', $options['base_url']);
}
}
$options['base_url'] .= rtrim(base_path(), '/');
if ($bubbleable_metadata) {
$bubbleable_metadata
->addCacheContexts([
'languages:' . LanguageInterface::TYPE_URL,
'url.site',
]);
}
}
}
return $path;
}
public function getLanguageSwitchLinks(Request $request, $type, Url $url) {
$links = array();
foreach ($this->languageManager
->getNativeLanguages() as $language) {
$links[$language
->getId()] = array(
'url' => clone $url,
'title' => $language
->getName(),
'language' => $language,
'attributes' => array(
'class' => array(
'language-link',
),
),
);
}
return $links;
}
}