Update to Drupal 8.1.8. For more information, see https://www.drupal.org/project/drupal/releases/8.1.8
This commit is contained in:
parent
e9f047ccf8
commit
f9f23cdf38
312 changed files with 6751 additions and 1546 deletions
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Drupal\config_translation\Access;
|
||||
|
||||
use Drupal\config_translation\ConfigMapperInterface;
|
||||
use Drupal\config_translation\Exception\ConfigMapperLanguageException;
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
@ -12,27 +14,68 @@ use Drupal\Core\Session\AccountInterface;
|
|||
class ConfigTranslationFormAccess extends ConfigTranslationOverviewAccess {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Checks access to the overview based on permissions and translatability.
|
||||
*
|
||||
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
||||
* The route_match to check against.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The account to check access for.
|
||||
* @param string $langcode
|
||||
* The language code of the target language.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The access result.
|
||||
*/
|
||||
public function access(RouteMatchInterface $route_match, AccountInterface $account, $langcode = NULL) {
|
||||
// For the translation forms we have a target language, so we need some
|
||||
// checks in addition to the checks performed for the translation overview.
|
||||
$base_access = parent::access($route_match, $account);
|
||||
if ($base_access->isAllowed()) {
|
||||
$mapper = $this->getMapperFromRouteMatch($route_match);
|
||||
|
||||
try {
|
||||
$source_langcode = $mapper->getLangcode();
|
||||
$source_language = $this->languageManager->getLanguage($source_langcode);
|
||||
|
||||
$target_language = $this->languageManager->getLanguage($langcode);
|
||||
|
||||
// Make sure that the target language is not locked, and that the target
|
||||
// language is not the original submission language. Although technically
|
||||
// configuration can be overlaid with translations in the same language,
|
||||
// that is logically not a good idea.
|
||||
$access =
|
||||
!empty($target_language) &&
|
||||
!$target_language->isLocked() &&
|
||||
(empty($this->sourceLanguage) || ($target_language->getId() != $this->sourceLanguage->getId()));
|
||||
|
||||
return $base_access->andIf(AccessResult::allowedIf($access));
|
||||
return $this->doCheckAccess($account, $mapper, $source_language, $target_language);
|
||||
}
|
||||
return $base_access;
|
||||
catch (ConfigMapperLanguageException $exception) {
|
||||
return AccessResult::forbidden();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks access given an account, configuration mapper, and source language.
|
||||
*
|
||||
* In addition to the checks performed by
|
||||
* ConfigTranslationOverviewAccess::doCheckAccess() this makes sure the target
|
||||
* language is not locked and the target language is not the source language.
|
||||
*
|
||||
* Although technically configuration can be overlaid with translations in the
|
||||
* same language, that is logically not a good idea.
|
||||
*
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The account to check access for.
|
||||
* @param \Drupal\config_translation\ConfigMapperInterface $mapper
|
||||
* The configuration mapper to check access for.
|
||||
* @param \Drupal\Core\Language\LanguageInterface|null $source_language
|
||||
* The source language to check for, if any.
|
||||
* @param \Drupal\Core\Language\LanguageInterface|null $target_language
|
||||
* The target language to check for, if any.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The result of the access check.
|
||||
*
|
||||
* @see \Drupal\config_translation\Access\ConfigTranslationOverviewAccess::doCheckAccess()
|
||||
*/
|
||||
protected function doCheckAccess(AccountInterface $account, ConfigMapperInterface $mapper, $source_language = NULL, $target_language = NULL) {
|
||||
$base_access_result = parent::doCheckAccess($account, $mapper, $source_language);
|
||||
|
||||
$access =
|
||||
$target_language &&
|
||||
!$target_language->isLocked() &&
|
||||
(!$source_language || ($target_language->getId() !== $source_language->getId()));
|
||||
|
||||
return $base_access_result->andIf(AccessResult::allowedIf($access));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Drupal\config_translation\Access;
|
||||
|
||||
use Drupal\config_translation\ConfigMapperInterface;
|
||||
use Drupal\config_translation\Exception\ConfigMapperLanguageException;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\config_translation\ConfigMapperManagerInterface;
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
|
@ -28,13 +30,6 @@ class ConfigTranslationOverviewAccess implements AccessInterface {
|
|||
*/
|
||||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* The source language.
|
||||
*
|
||||
* @var \Drupal\Core\Language\LanguageInterface
|
||||
*/
|
||||
protected $sourceLanguage;
|
||||
|
||||
/**
|
||||
* Constructs a ConfigTranslationOverviewAccess object.
|
||||
*
|
||||
|
@ -54,28 +49,66 @@ class ConfigTranslationOverviewAccess implements AccessInterface {
|
|||
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
||||
* The route_match to check against.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The currently logged in account.
|
||||
* The account to check access for.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The access result.
|
||||
*/
|
||||
public function access(RouteMatchInterface $route_match, AccountInterface $account) {
|
||||
$route = $route_match->getRouteObject();
|
||||
$mapper = $this->getMapperFromRouteMatch($route_match);
|
||||
|
||||
/** @var \Drupal\config_translation\ConfigMapperInterface $mapper */
|
||||
$mapper = $this->configMapperManager->createInstance($route->getDefault('plugin_id'));
|
||||
try {
|
||||
$langcode = $mapper->getLangcode();
|
||||
}
|
||||
catch (ConfigMapperLanguageException $exception) {
|
||||
// ConfigTranslationController shows a helpful message if the language
|
||||
// codes do not match, so do not let that prevent granting access.
|
||||
$langcode = 'en';
|
||||
}
|
||||
$source_language = $this->languageManager->getLanguage($langcode);
|
||||
|
||||
return $this->doCheckAccess($account, $mapper, $source_language);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a configuration mapper using a route match.
|
||||
*
|
||||
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
||||
* The route match to populate the mapper with.
|
||||
*
|
||||
* @return \Drupal\config_translation\ConfigMapperInterface
|
||||
* The configuration mapper.
|
||||
*/
|
||||
protected function getMapperFromRouteMatch(RouteMatchInterface $route_match) {
|
||||
$mapper = $this->configMapperManager->createInstance($route_match->getRouteObject()
|
||||
->getDefault('plugin_id'));
|
||||
$mapper->populateFromRouteMatch($route_match);
|
||||
$this->sourceLanguage = $this->languageManager->getLanguage($mapper->getLangcode());
|
||||
return $mapper;
|
||||
}
|
||||
|
||||
// Allow access to the translation overview if the proper permission is
|
||||
// granted, the configuration has translatable pieces, and the source
|
||||
// language is not locked if it is present.
|
||||
$source_language_access = is_null($this->sourceLanguage) || !$this->sourceLanguage->isLocked();
|
||||
/**
|
||||
* Checks access given an account, configuration mapper, and source language.
|
||||
*
|
||||
* Grants access if the proper permission is granted to the account, the
|
||||
* configuration has translatable pieces, and the source language is not
|
||||
* locked given it is present.
|
||||
*
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The account to check access for.
|
||||
* @param \Drupal\config_translation\ConfigMapperInterface $mapper
|
||||
* The configuration mapper to check access for.
|
||||
* @param \Drupal\Core\Language\LanguageInterface|null $source_language
|
||||
* The source language to check for, if any.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The result of the access check.
|
||||
*/
|
||||
protected function doCheckAccess(AccountInterface $account, ConfigMapperInterface $mapper, $source_language = NULL) {
|
||||
$access =
|
||||
$account->hasPermission('translate configuration') &&
|
||||
$mapper->hasSchema() &&
|
||||
$mapper->hasTranslatable() &&
|
||||
$source_language_access;
|
||||
(!$source_language || !$source_language->isLocked());
|
||||
|
||||
return AccessResult::allowedIf($access)->cachePerPermissions();
|
||||
}
|
||||
|
|
|
@ -202,6 +202,17 @@ interface ConfigMapperInterface {
|
|||
*/
|
||||
public function getLangcode();
|
||||
|
||||
/**
|
||||
* Returns the language code of a configuration object given its name.
|
||||
*
|
||||
* @param string $config_name
|
||||
* The name of the configuration object.
|
||||
*
|
||||
* @return string
|
||||
* The language code of the configuration object.
|
||||
*/
|
||||
public function getLangcodeFromConfig($config_name);
|
||||
|
||||
/**
|
||||
* Sets the original language code.
|
||||
*
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\config_translation;
|
||||
|
||||
use Drupal\config_translation\Exception\ConfigMapperLanguageException;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Config\TypedConfigManagerInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
|
@ -380,22 +381,26 @@ class ConfigNamesMapper extends PluginBase implements ConfigMapperInterface, Con
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLangcode() {
|
||||
$config_factory = $this->configFactory;
|
||||
$langcodes = array_map(function($name) use ($config_factory) {
|
||||
// Default to English if no language code was provided in the file.
|
||||
// Although it is a best practice to include a language code, if the
|
||||
// developer did not think about a multilingual use-case, we fall back
|
||||
// on assuming the file is English.
|
||||
return $config_factory->get($name)->get('langcode') ?: 'en';
|
||||
}, $this->getConfigNames());
|
||||
$langcodes = array_map([$this, 'getLangcodeFromConfig'], $this->getConfigNames());
|
||||
|
||||
if (count(array_unique($langcodes)) > 1) {
|
||||
throw new \RuntimeException('A config mapper can only contain configuration for a single language.');
|
||||
throw new ConfigMapperLanguageException('A config mapper can only contain configuration for a single language.');
|
||||
}
|
||||
|
||||
return reset($langcodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLangcodeFromConfig($config_name) {
|
||||
// Default to English if no language code was provided in the file.
|
||||
// Although it is a best practice to include a language code, if the
|
||||
// developer did not think about a multilingual use case, we fall back
|
||||
// on assuming the file is English.
|
||||
return $this->configFactory->get($config_name)->get('langcode') ?: 'en';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
namespace Drupal\config_translation\Controller;
|
||||
|
||||
use Drupal\config_translation\ConfigMapperManagerInterface;
|
||||
use Drupal\config_translation\Exception\ConfigMapperLanguageException;
|
||||
use Drupal\Core\Access\AccessManagerInterface;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\Routing\RouteMatch;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
@ -63,6 +66,13 @@ class ConfigTranslationController extends ControllerBase {
|
|||
*/
|
||||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* The renderer.
|
||||
*
|
||||
* @var \Drupal\Core\Render\RendererInterface
|
||||
*/
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* Constructs a ConfigTranslationController.
|
||||
*
|
||||
|
@ -78,14 +88,17 @@ class ConfigTranslationController extends ControllerBase {
|
|||
* The current user.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
* @param \Drupal\Core\Render\RendererInterface $renderer
|
||||
* The renderer.
|
||||
*/
|
||||
public function __construct(ConfigMapperManagerInterface $config_mapper_manager, AccessManagerInterface $access_manager, RequestMatcherInterface $router, InboundPathProcessorInterface $path_processor, AccountInterface $account, LanguageManagerInterface $language_manager) {
|
||||
public function __construct(ConfigMapperManagerInterface $config_mapper_manager, AccessManagerInterface $access_manager, RequestMatcherInterface $router, InboundPathProcessorInterface $path_processor, AccountInterface $account, LanguageManagerInterface $language_manager, RendererInterface $renderer) {
|
||||
$this->configMapperManager = $config_mapper_manager;
|
||||
$this->accessManager = $access_manager;
|
||||
$this->router = $router;
|
||||
$this->pathProcessor = $path_processor;
|
||||
$this->account = $account;
|
||||
$this->languageManager = $language_manager;
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,7 +111,8 @@ class ConfigTranslationController extends ControllerBase {
|
|||
$container->get('router'),
|
||||
$container->get('path_processor_manager'),
|
||||
$container->get('current_user'),
|
||||
$container->get('language_manager')
|
||||
$container->get('language_manager'),
|
||||
$container->get('renderer')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -127,7 +141,33 @@ class ConfigTranslationController extends ControllerBase {
|
|||
if (count($languages) == 1) {
|
||||
drupal_set_message($this->t('In order to translate configuration, the website must have at least two <a href=":url">languages</a>.', array(':url' => $this->url('entity.configurable_language.collection'))), 'warning');
|
||||
}
|
||||
$original_langcode = $mapper->getLangcode();
|
||||
|
||||
try {
|
||||
$original_langcode = $mapper->getLangcode();
|
||||
$operations_access = TRUE;
|
||||
}
|
||||
catch (ConfigMapperLanguageException $exception) {
|
||||
$items = [];
|
||||
foreach ($mapper->getConfigNames() as $config_name) {
|
||||
$langcode = $mapper->getLangcodeFromConfig($config_name);
|
||||
$items[] = $this->t('@name: @langcode', [
|
||||
'@name' => $config_name,
|
||||
'@langcode' => $langcode,
|
||||
]);
|
||||
}
|
||||
$message = [
|
||||
'message' => ['#markup' => $this->t('The configuration objects have different language codes so they cannot be translated:')],
|
||||
'items' => [
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $items,
|
||||
],
|
||||
];
|
||||
drupal_set_message($this->renderer->renderPlain($message), 'warning');
|
||||
|
||||
$original_langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
|
||||
$operations_access = FALSE;
|
||||
}
|
||||
|
||||
if (!isset($languages[$original_langcode])) {
|
||||
// If the language is not configured on the site, create a dummy language
|
||||
// object for this listing only to ensure the user gets useful info.
|
||||
|
@ -205,6 +245,9 @@ class ConfigTranslationController extends ControllerBase {
|
|||
$page['languages'][$langcode]['operations'] = array(
|
||||
'#type' => 'operations',
|
||||
'#links' => $operations,
|
||||
// Even if the mapper contains multiple language codes, the source
|
||||
// configuration can still be edited.
|
||||
'#access' => ($langcode == $original_langcode) || $operations_access,
|
||||
);
|
||||
}
|
||||
return $page;
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\config_translation\Exception;
|
||||
|
||||
/**
|
||||
* Provides an exception for configuration mappers with multiple languages.
|
||||
*/
|
||||
class ConfigMapperLanguageException extends \RuntimeException {
|
||||
}
|
|
@ -138,7 +138,12 @@ abstract class ConfigTranslationFormBase extends FormBase implements BaseFormIdI
|
|||
|
||||
$this->mapper = $mapper;
|
||||
$this->language = $language;
|
||||
$this->sourceLanguage = $this->languageManager->getLanguage($this->mapper->getLangcode());
|
||||
|
||||
// ConfigTranslationFormAccess will not grant access if this raises an
|
||||
// exception, so we can call this without a try-catch block here.
|
||||
$langcode = $this->mapper->getLangcode();
|
||||
|
||||
$this->sourceLanguage = $this->languageManager->getLanguage($langcode);
|
||||
|
||||
// Get base language configuration to display in the form before setting the
|
||||
// language to use for the form. This avoids repetitively settings and
|
||||
|
|
Reference in a new issue