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; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('plugin.manager.config_translation.mapper'), $container->get('access_manager'), $container->get('router'), $container->get('path_processor_manager'), $container->get('current_user'), $container->get('language_manager'), $container->get('renderer') ); } /** * Language translations overview page for a configuration name. * * @param \Symfony\Component\HttpFoundation\Request $request * Page request object. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The route match. * @param string $plugin_id * The plugin ID of the mapper. * * @return array * Page render array. */ public function itemPage(Request $request, RouteMatchInterface $route_match, $plugin_id) { /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */ $mapper = $this->configMapperManager->createInstance($plugin_id); $mapper->populateFromRouteMatch($route_match); $page = []; $page['#title'] = $this->t('Translations for %label', ['%label' => $mapper->getTitle()]); $languages = $this->languageManager->getLanguages(); if (count($languages) == 1) { $this->messenger()->addWarning($this->t('In order to translate configuration, the website must have at least two languages.', [':url' => $this->url('entity.configurable_language.collection')])); } 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, ], ]; $this->messenger()->addWarning($this->renderer->renderPlain($message)); $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. $language_name = $this->languageManager->getLanguageName($original_langcode); $languages[$original_langcode] = new Language(['id' => $original_langcode, 'name' => $language_name]); } // We create a fake request object to pass into // ConfigMapperInterface::populateFromRouteMatch() for the different languages. // Creating a separate request for each language and route is neither easily // possible nor performant. $fake_request = $request->duplicate(); $page['languages'] = [ '#type' => 'table', '#header' => [$this->t('Language'), $this->t('Operations')], ]; foreach ($languages as $language) { $langcode = $language->getId(); // This is needed because // ConfigMapperInterface::getAddRouteParameters(), for example, // needs to return the correct language code for each table row. $fake_route_match = RouteMatch::createFromRequest($fake_request); $mapper->populateFromRouteMatch($fake_route_match); $mapper->setLangcode($langcode); // Prepare the language name and the operations depending on whether this // is the original language or not. if ($langcode == $original_langcode) { $language_name = '' . $this->t('@language (original)', ['@language' => $language->getName()]) . ''; // Check access for the path/route for editing, so we can decide to // include a link to edit or not. $edit_access = $this->accessManager->checkNamedRoute($mapper->getBaseRouteName(), $route_match->getRawParameters()->all(), $this->account); // Build list of operations. $operations = []; if ($edit_access) { $operations['edit'] = [ 'title' => $this->t('Edit'), 'url' => Url::fromRoute($mapper->getBaseRouteName(), $mapper->getBaseRouteParameters(), ['query' => ['destination' => $mapper->getOverviewPath()]]), ]; } } else { $language_name = $language->getName(); $operations = []; // If no translation exists for this language, link to add one. if (!$mapper->hasTranslation($language)) { $operations['add'] = [ 'title' => $this->t('Add'), 'url' => Url::fromRoute($mapper->getAddRouteName(), $mapper->getAddRouteParameters()), ]; } else { // Otherwise, link to edit the existing translation. $operations['edit'] = [ 'title' => $this->t('Edit'), 'url' => Url::fromRoute($mapper->getEditRouteName(), $mapper->getEditRouteParameters()), ]; $operations['delete'] = [ 'title' => $this->t('Delete'), 'url' => Url::fromRoute($mapper->getDeleteRouteName(), $mapper->getDeleteRouteParameters()), ]; } } $page['languages'][$langcode]['language'] = [ '#markup' => $language_name, ]; $page['languages'][$langcode]['operations'] = [ '#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; } }