diff --git a/core/modules/config_translation/src/Access/ConfigTranslationFormAccess.php b/core/modules/config_translation/src/Access/ConfigTranslationFormAccess.php index af584de..e3877e9 100644 --- a/core/modules/config_translation/src/Access/ConfigTranslationFormAccess.php +++ b/core/modules/config_translation/src/Access/ConfigTranslationFormAccess.php @@ -7,6 +7,7 @@ namespace Drupal\config_translation\Access; +use Drupal\config_translation\Exception\ConfigMapperLanguageException; use Drupal\Core\Access\AccessResult; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Session\AccountInterface; @@ -24,6 +25,11 @@ public function access(RouteMatchInterface $route_match, AccountInterface $accou // checks in addition to the checks performed for the translation overview. $base_access = parent::access($route_match, $account); if ($base_access->isAllowed()) { + try { + // We do not use the result value, but we need to check that the mapper + // only has a single language code. + $this->mapper->getLangcode(); + $target_language = $this->languageManager->getLanguage($langcode); // Make sure that the target language is not locked, and that the target @@ -37,6 +43,12 @@ public function access(RouteMatchInterface $route_match, AccountInterface $accou return $base_access->andIf(AccessResult::allowedIf($access)); } + catch (ConfigMapperLanguageException $exception) { + // In contrast to ConfigTranslationOverviewAccess this does not grant + // access to a mapper if the languages do not match. + return $base_access->andIf(AccessResult::forbidden()); + } + } return $base_access; } diff --git a/core/modules/config_translation/src/Access/ConfigTranslationOverviewAccess.php b/core/modules/config_translation/src/Access/ConfigTranslationOverviewAccess.php index 8504ea9..8162d4b 100644 --- a/core/modules/config_translation/src/Access/ConfigTranslationOverviewAccess.php +++ b/core/modules/config_translation/src/Access/ConfigTranslationOverviewAccess.php @@ -35,6 +35,13 @@ class ConfigTranslationOverviewAccess implements AccessInterface { protected $languageManager; /** + * The configuration mapper to check access for. + * + * @var \Drupal\config_translation\ConfigMapperInterface + */ + protected $mapper; + + /** * The source language. * * @var \Drupal\Core\Language\LanguageInterface @@ -68,17 +75,15 @@ public function __construct(ConfigMapperManagerInterface $config_mapper_manager, public function access(RouteMatchInterface $route_match, AccountInterface $account) { $route = $route_match->getRouteObject(); - /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */ - $mapper = $this->configMapperManager->createInstance($route->getDefault('plugin_id')); - $mapper->populateFromRouteMatch($route_match); + $this->mapper = $this->configMapperManager->createInstance($route->getDefault('plugin_id')); + $this->mapper->populateFromRouteMatch($route_match); try { - $langcode = $mapper->getLangcode(); + $langcode = $this->mapper->getLangcode(); } catch (ConfigMapperLanguageException $exception) { - // ConfigTranslationController and ConfigTranslationFormBase show a - // helpful message if the language codes do not match, so do not let that - // prevent granting access. + // ConfigTranslationController shows a helpful message if the language + // codes do not match, so do not let that prevent granting access. $langcode = 'en'; } @@ -90,8 +95,8 @@ public function access(RouteMatchInterface $route_match, AccountInterface $accou $source_language_access = is_null($this->sourceLanguage) || !$this->sourceLanguage->isLocked(); $access = $account->hasPermission('translate configuration') && - $mapper->hasSchema() && - $mapper->hasTranslatable() && + $this->mapper->hasSchema() && + $this->mapper->hasTranslatable() && $source_language_access; return AccessResult::allowedIf($access)->cachePerPermissions(); diff --git a/core/modules/config_translation/src/ConfigMapperInterface.php b/core/modules/config_translation/src/ConfigMapperInterface.php index 507b191..e8b1717 100644 --- a/core/modules/config_translation/src/ConfigMapperInterface.php +++ b/core/modules/config_translation/src/ConfigMapperInterface.php @@ -208,6 +208,17 @@ public function getConfigData(); 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. * * @param string $langcode diff --git a/core/modules/config_translation/src/ConfigNamesMapper.php b/core/modules/config_translation/src/ConfigNamesMapper.php index 83c1d21..f8f7ae0 100644 --- a/core/modules/config_translation/src/ConfigNamesMapper.php +++ b/core/modules/config_translation/src/ConfigNamesMapper.php @@ -396,13 +396,7 @@ 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. + * {@inheritdoc} */ public function getLangcodeFromConfig($config_name) { // Default to English if no language code was provided in the file. diff --git a/core/modules/config_translation/src/Controller/ConfigTranslationController.php b/core/modules/config_translation/src/Controller/ConfigTranslationController.php index 6f277b1..6e33354 100644 --- a/core/modules/config_translation/src/Controller/ConfigTranslationController.php +++ b/core/modules/config_translation/src/Controller/ConfigTranslationController.php @@ -15,6 +15,7 @@ use Drupal\Core\Language\Language; 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; @@ -71,6 +72,13 @@ class ConfigTranslationController extends ControllerBase { protected $languageManager; /** + * The renderer. + * + * @var \Drupal\Core\Render\RendererInterface + */ + protected $renderer; + + /** * Constructs a ConfigTranslationController. * * @param \Drupal\config_translation\ConfigMapperManagerInterface $config_mapper_manager @@ -85,14 +93,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; } /** @@ -105,7 +116,8 @@ public static function create(ContainerInterface $container) { $container->get('router'), $container->get('path_processor_manager'), $container->get('current_user'), - $container->get('language_manager') + $container->get('language_manager'), + $container->get('renderer') ); } @@ -137,10 +149,23 @@ public function itemPage(Request $request, RouteMatchInterface $route_match, $pl try { $original_langcode = $mapper->getLangcode(); + $operations_access = TRUE; } catch (ConfigMapperLanguageException $exception) { - $page['message'] = $exception->getMessageFromMapper($mapper); - return $page; + $items = []; + foreach ($mapper->getconfigNames() as $config_name) { + $langcode = $mapper->getLangcodeFromConfig($config_name); + $items[] = $config_name . ': ' . $langcode; + } + $message = [ + 'message' => ['#markup' => 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'); + $operations_access = FALSE; } @@ -221,6 +246,9 @@ public function itemPage(Request $request, RouteMatchInterface $route_match, $pl $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; diff --git a/core/modules/config_translation/src/Exception/ConfigMapperLanguageException.php b/core/modules/config_translation/src/Exception/ConfigMapperLanguageException.php index 5ead590..c66848a 100644 --- a/core/modules/config_translation/src/Exception/ConfigMapperLanguageException.php +++ b/core/modules/config_translation/src/Exception/ConfigMapperLanguageException.php @@ -5,34 +5,9 @@ */ namespace Drupal\config_translation\Exception; -use Drupal\config_translation\ConfigNamesMapper; /** * Class ConfigMapperLanguageException */ class ConfigMapperLanguageException extends \RuntimeException { - - /** - * @param $mapper - * - * @return array - */ - public function getMessageFromMapper($mapper) { - $message = ''; - if ($mapper instanceof ConfigNamesMapper) { - $items = []; - foreach ($mapper->getconfigNames() as $config_name) { - $langcode = $mapper->getLangcodeFromConfig($config_name); - $items[] = $config_name .': ' . $langcode; - } - $message = [ - 'message' => ['#markup' => t('Configuration objects have different language codes:')], - 'items' => [ - '#theme' => 'item_list', - '#items' => $items, - ] - ]; - } - return $message; - } } diff --git a/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php b/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php index e4fe134..14720aa 100644 --- a/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php +++ b/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php @@ -157,13 +157,9 @@ public function buildForm(array $form, FormStateInterface $form_state, RouteMatc $this->mapper = $mapper; $this->language = $language; - try { + // 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(); - } - catch (ConfigMapperLanguageException $exception) { - $message = $exception->getMessageFromMapper($mapper); - drupal_set_message($this->renderer->renderRoot($message), 'warning'); - } $this->sourceLanguage = $this->languageManager->getLanguage($langcode);