annotate core/modules/config_translation/src/Controller/ConfigTranslationController.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\config_translation\Controller;
Chris@0 4
Chris@0 5 use Drupal\config_translation\ConfigMapperManagerInterface;
Chris@0 6 use Drupal\config_translation\Exception\ConfigMapperLanguageException;
Chris@0 7 use Drupal\Core\Access\AccessManagerInterface;
Chris@0 8 use Drupal\Core\Controller\ControllerBase;
Chris@0 9 use Drupal\Core\Language\Language;
Chris@0 10 use Drupal\Core\Language\LanguageInterface;
Chris@0 11 use Drupal\Core\Language\LanguageManagerInterface;
Chris@0 12 use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
Chris@0 13 use Drupal\Core\Render\RendererInterface;
Chris@0 14 use Drupal\Core\Routing\RouteMatch;
Chris@0 15 use Drupal\Core\Routing\RouteMatchInterface;
Chris@0 16 use Drupal\Core\Session\AccountInterface;
Chris@0 17 use Drupal\Core\Url;
Chris@0 18 use Symfony\Component\DependencyInjection\ContainerInterface;
Chris@0 19 use Symfony\Component\HttpFoundation\Request;
Chris@0 20 use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
Chris@0 21
Chris@0 22 /**
Chris@0 23 * Provides page callbacks for the configuration translation interface.
Chris@0 24 */
Chris@0 25 class ConfigTranslationController extends ControllerBase {
Chris@0 26
Chris@0 27 /**
Chris@0 28 * The configuration mapper manager.
Chris@0 29 *
Chris@0 30 * @var \Drupal\config_translation\ConfigMapperManagerInterface
Chris@0 31 */
Chris@0 32 protected $configMapperManager;
Chris@0 33
Chris@0 34 /**
Chris@0 35 * The menu link access service.
Chris@0 36 *
Chris@0 37 * @var \Drupal\Core\Access\AccessManagerInterface
Chris@0 38 */
Chris@0 39 protected $accessManager;
Chris@0 40
Chris@0 41 /**
Chris@0 42 * The dynamic router service.
Chris@0 43 *
Chris@0 44 * @var \Symfony\Component\Routing\Matcher\RequestMatcherInterface
Chris@0 45 */
Chris@0 46 protected $router;
Chris@0 47
Chris@0 48 /**
Chris@0 49 * The path processor service.
Chris@0 50 *
Chris@0 51 * @var \Drupal\Core\PathProcessor\InboundPathProcessorInterface
Chris@0 52 */
Chris@0 53 protected $pathProcessor;
Chris@0 54
Chris@0 55 /**
Chris@0 56 * The current user.
Chris@0 57 *
Chris@0 58 * @var \Drupal\Core\Session\AccountInterface
Chris@0 59 */
Chris@0 60 protected $account;
Chris@0 61
Chris@0 62 /**
Chris@0 63 * The language manager.
Chris@0 64 *
Chris@12 65 * @var \Drupal\Core\Language\LanguageManagerInterface
Chris@0 66 */
Chris@0 67 protected $languageManager;
Chris@0 68
Chris@0 69 /**
Chris@0 70 * The renderer.
Chris@0 71 *
Chris@0 72 * @var \Drupal\Core\Render\RendererInterface
Chris@0 73 */
Chris@0 74 protected $renderer;
Chris@0 75
Chris@0 76 /**
Chris@0 77 * Constructs a ConfigTranslationController.
Chris@0 78 *
Chris@0 79 * @param \Drupal\config_translation\ConfigMapperManagerInterface $config_mapper_manager
Chris@0 80 * The configuration mapper manager.
Chris@0 81 * @param \Drupal\Core\Access\AccessManagerInterface $access_manager
Chris@0 82 * The menu link access service.
Chris@0 83 * @param \Symfony\Component\Routing\Matcher\RequestMatcherInterface $router
Chris@0 84 * The dynamic router service.
Chris@0 85 * @param \Drupal\Core\PathProcessor\InboundPathProcessorInterface $path_processor
Chris@0 86 * The inbound path processor.
Chris@0 87 * @param \Drupal\Core\Session\AccountInterface $account
Chris@0 88 * The current user.
Chris@0 89 * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
Chris@0 90 * The language manager.
Chris@0 91 * @param \Drupal\Core\Render\RendererInterface $renderer
Chris@0 92 * The renderer.
Chris@0 93 */
Chris@0 94 public function __construct(ConfigMapperManagerInterface $config_mapper_manager, AccessManagerInterface $access_manager, RequestMatcherInterface $router, InboundPathProcessorInterface $path_processor, AccountInterface $account, LanguageManagerInterface $language_manager, RendererInterface $renderer) {
Chris@0 95 $this->configMapperManager = $config_mapper_manager;
Chris@0 96 $this->accessManager = $access_manager;
Chris@0 97 $this->router = $router;
Chris@0 98 $this->pathProcessor = $path_processor;
Chris@0 99 $this->account = $account;
Chris@0 100 $this->languageManager = $language_manager;
Chris@0 101 $this->renderer = $renderer;
Chris@0 102 }
Chris@0 103
Chris@0 104 /**
Chris@0 105 * {@inheritdoc}
Chris@0 106 */
Chris@0 107 public static function create(ContainerInterface $container) {
Chris@0 108 return new static(
Chris@0 109 $container->get('plugin.manager.config_translation.mapper'),
Chris@0 110 $container->get('access_manager'),
Chris@0 111 $container->get('router'),
Chris@0 112 $container->get('path_processor_manager'),
Chris@0 113 $container->get('current_user'),
Chris@0 114 $container->get('language_manager'),
Chris@0 115 $container->get('renderer')
Chris@0 116 );
Chris@0 117 }
Chris@0 118
Chris@0 119 /**
Chris@0 120 * Language translations overview page for a configuration name.
Chris@0 121 *
Chris@0 122 * @param \Symfony\Component\HttpFoundation\Request $request
Chris@0 123 * Page request object.
Chris@0 124 * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
Chris@0 125 * The route match.
Chris@0 126 * @param string $plugin_id
Chris@0 127 * The plugin ID of the mapper.
Chris@0 128 *
Chris@0 129 * @return array
Chris@0 130 * Page render array.
Chris@0 131 */
Chris@0 132 public function itemPage(Request $request, RouteMatchInterface $route_match, $plugin_id) {
Chris@0 133 /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */
Chris@0 134 $mapper = $this->configMapperManager->createInstance($plugin_id);
Chris@0 135 $mapper->populateFromRouteMatch($route_match);
Chris@0 136
Chris@0 137 $page = [];
Chris@0 138 $page['#title'] = $this->t('Translations for %label', ['%label' => $mapper->getTitle()]);
Chris@0 139
Chris@0 140 $languages = $this->languageManager->getLanguages();
Chris@0 141 if (count($languages) == 1) {
Chris@17 142 $this->messenger()->addWarning($this->t('In order to translate configuration, the website must have at least two <a href=":url">languages</a>.', [':url' => $this->url('entity.configurable_language.collection')]));
Chris@0 143 }
Chris@0 144
Chris@0 145 try {
Chris@0 146 $original_langcode = $mapper->getLangcode();
Chris@0 147 $operations_access = TRUE;
Chris@0 148 }
Chris@0 149 catch (ConfigMapperLanguageException $exception) {
Chris@0 150 $items = [];
Chris@0 151 foreach ($mapper->getConfigNames() as $config_name) {
Chris@0 152 $langcode = $mapper->getLangcodeFromConfig($config_name);
Chris@0 153 $items[] = $this->t('@name: @langcode', [
Chris@0 154 '@name' => $config_name,
Chris@0 155 '@langcode' => $langcode,
Chris@0 156 ]);
Chris@0 157 }
Chris@0 158 $message = [
Chris@0 159 'message' => ['#markup' => $this->t('The configuration objects have different language codes so they cannot be translated:')],
Chris@0 160 'items' => [
Chris@0 161 '#theme' => 'item_list',
Chris@0 162 '#items' => $items,
Chris@0 163 ],
Chris@0 164 ];
Chris@17 165 $this->messenger()->addWarning($this->renderer->renderPlain($message));
Chris@0 166
Chris@0 167 $original_langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
Chris@0 168 $operations_access = FALSE;
Chris@0 169 }
Chris@0 170
Chris@0 171 if (!isset($languages[$original_langcode])) {
Chris@0 172 // If the language is not configured on the site, create a dummy language
Chris@0 173 // object for this listing only to ensure the user gets useful info.
Chris@0 174 $language_name = $this->languageManager->getLanguageName($original_langcode);
Chris@0 175 $languages[$original_langcode] = new Language(['id' => $original_langcode, 'name' => $language_name]);
Chris@0 176 }
Chris@0 177
Chris@0 178 // We create a fake request object to pass into
Chris@0 179 // ConfigMapperInterface::populateFromRouteMatch() for the different languages.
Chris@0 180 // Creating a separate request for each language and route is neither easily
Chris@0 181 // possible nor performant.
Chris@0 182 $fake_request = $request->duplicate();
Chris@0 183
Chris@0 184 $page['languages'] = [
Chris@0 185 '#type' => 'table',
Chris@0 186 '#header' => [$this->t('Language'), $this->t('Operations')],
Chris@0 187 ];
Chris@0 188 foreach ($languages as $language) {
Chris@0 189 $langcode = $language->getId();
Chris@0 190
Chris@0 191 // This is needed because
Chris@0 192 // ConfigMapperInterface::getAddRouteParameters(), for example,
Chris@0 193 // needs to return the correct language code for each table row.
Chris@0 194 $fake_route_match = RouteMatch::createFromRequest($fake_request);
Chris@0 195 $mapper->populateFromRouteMatch($fake_route_match);
Chris@0 196 $mapper->setLangcode($langcode);
Chris@0 197
Chris@0 198 // Prepare the language name and the operations depending on whether this
Chris@0 199 // is the original language or not.
Chris@0 200 if ($langcode == $original_langcode) {
Chris@0 201 $language_name = '<strong>' . $this->t('@language (original)', ['@language' => $language->getName()]) . '</strong>';
Chris@0 202
Chris@0 203 // Check access for the path/route for editing, so we can decide to
Chris@0 204 // include a link to edit or not.
Chris@0 205 $edit_access = $this->accessManager->checkNamedRoute($mapper->getBaseRouteName(), $route_match->getRawParameters()->all(), $this->account);
Chris@0 206
Chris@0 207 // Build list of operations.
Chris@0 208 $operations = [];
Chris@0 209 if ($edit_access) {
Chris@0 210 $operations['edit'] = [
Chris@0 211 'title' => $this->t('Edit'),
Chris@0 212 'url' => Url::fromRoute($mapper->getBaseRouteName(), $mapper->getBaseRouteParameters(), ['query' => ['destination' => $mapper->getOverviewPath()]]),
Chris@0 213 ];
Chris@0 214 }
Chris@0 215 }
Chris@0 216 else {
Chris@0 217 $language_name = $language->getName();
Chris@0 218
Chris@0 219 $operations = [];
Chris@0 220 // If no translation exists for this language, link to add one.
Chris@0 221 if (!$mapper->hasTranslation($language)) {
Chris@0 222 $operations['add'] = [
Chris@0 223 'title' => $this->t('Add'),
Chris@0 224 'url' => Url::fromRoute($mapper->getAddRouteName(), $mapper->getAddRouteParameters()),
Chris@0 225 ];
Chris@0 226 }
Chris@0 227 else {
Chris@0 228 // Otherwise, link to edit the existing translation.
Chris@0 229 $operations['edit'] = [
Chris@0 230 'title' => $this->t('Edit'),
Chris@0 231 'url' => Url::fromRoute($mapper->getEditRouteName(), $mapper->getEditRouteParameters()),
Chris@0 232 ];
Chris@0 233
Chris@0 234 $operations['delete'] = [
Chris@0 235 'title' => $this->t('Delete'),
Chris@0 236 'url' => Url::fromRoute($mapper->getDeleteRouteName(), $mapper->getDeleteRouteParameters()),
Chris@0 237 ];
Chris@0 238 }
Chris@0 239 }
Chris@0 240
Chris@0 241 $page['languages'][$langcode]['language'] = [
Chris@0 242 '#markup' => $language_name,
Chris@0 243 ];
Chris@0 244
Chris@0 245 $page['languages'][$langcode]['operations'] = [
Chris@0 246 '#type' => 'operations',
Chris@0 247 '#links' => $operations,
Chris@0 248 // Even if the mapper contains multiple language codes, the source
Chris@0 249 // configuration can still be edited.
Chris@0 250 '#access' => ($langcode == $original_langcode) || $operations_access,
Chris@0 251 ];
Chris@0 252 }
Chris@0 253 return $page;
Chris@0 254 }
Chris@0 255
Chris@0 256 }