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 }
|