diff --git a/core/modules/config_translation/config_translation.module b/core/modules/config_translation/config_translation.module index 520b108..0960018 100644 --- a/core/modules/config_translation/config_translation.module +++ b/core/modules/config_translation/config_translation.module @@ -13,12 +13,12 @@ /** * Implements hook_help(). */ -function config_translation_help($path, $arg) { +function config_translation_help($path) { switch ($path) { case 'admin/help#config_translation': $output = ''; $output .= '
' . t('The Configuration Translation module lets you translate configuration from all around your Drupal site. Views, your site name, contact module categories, vocabularies, menus, blocks, and so on are all stored with Drupal\'s unified configuration system and can be translated with this module. Content, such as nodes, taxonomy terms, custom blocks, and so on are translatable with the Content translation module in Drupal core, while the built-in user interface (such as registration forms, content submission and administration interfaces) are translated with the Interface translation module. Use these tthree modules effectively together to translate your whole site to different languages.') . '
'; + $output .= '' . t('The Configuration Translation module lets you translate configuration from all around your Drupal site. Views, your site name, contact module categories, vocabularies, menus, blocks, and so on are all stored with Drupal\'s unified configuration system and can be translated with this module. Content, such as nodes, taxonomy terms, custom blocks, and so on are translatable with the Content translation module in Drupal core, while the built-in user interface (such as registration forms, content submission and administration interfaces) are translated with the Interface translation module. Use these three modules effectively together to translate your whole site to different languages.') . '
'; return $output; } } @@ -33,12 +33,9 @@ function config_translation_menu() { $config_groups = config_translation_get_groups(); foreach ($config_groups as $group) { $path = $group->getBasePath(); - if ($group->hasEditTab()) { + if ($group->needsEditTab()) { // For pages that do not have a default tab, we need a default local task // on this level, so that the translate tab will show up. - // @todo This is not very compatible with possible other alters. Look - // into other clever ways to make this happen, - // http://drupal.org/node/2011332. $items[$path . '/edit'] = array( 'title' => 'Edit', 'type' => MENU_DEFAULT_LOCAL_TASK, @@ -48,24 +45,9 @@ function config_translation_menu() { $items[$path . '/translate'] = array( 'title' => 'Translate', 'route_name' => $group->getRouteName(), - 'type' => $group->getMenuType(), + 'type' => $group->getMenuItemType(), 'weight' => 100, ); - $items[$path . '/translate/add/%language'] = array( - 'title' => 'Translate', - 'route_name' => $group->getRouteName() . '.add', - 'type' => MENU_CALLBACK, - ); - $items[$path . '/translate/edit/%language'] = array( - 'title' => 'Translate', - 'route_name' => $group->getRouteName() . '.edit', - 'type' => MENU_CALLBACK, - ); - $items[$path . '/translate/delete/%language'] = array( - 'title' => 'Delete', - 'route_name' => $group->getRouteName() . '.delete', - 'type' => MENU_CALLBACK, - ); } return $items; @@ -166,8 +148,11 @@ function config_translation_find_translatable($schema) { if ($element instanceof Element && config_translation_find_translatable($element)) { return TRUE; } - elseif (in_array($element->getType(), array('label', 'text'))) { - return TRUE; + else{ + $definition = $element->getDefinition(); + if (isset($definition['translatable'])) { + return TRUE; + } } } return FALSE; @@ -199,7 +184,7 @@ function config_translation_original_langcode($name) { * A boolean indicating if a language has config translations. */ function config_translation_exists($name, Language $language) { - $config_translation = config('locale.config.' . $language->langcode . '.' . $name)->get(); + $config_translation = config('locale.config.' . $language->id . '.' . $name)->get(); return !empty($config_translation); } @@ -235,36 +220,53 @@ function config_translation_config_translation_group_info() { $items = array(); // Block. - $items[] = new ConfigEntityMapper('admin/structure/block/manage/{block}', 4, 'block', t('@label block'), 'block.block'); + $items[] = new ConfigEntityMapper('admin/structure/block/manage/{block}', 'block', t('@label block')); // Custom block. - $items[] = new ConfigEntityMapper('admin/structure/custom-blocks/manage/{custom_block_type}', 4, 'custom_block_type', t('@label custom block type'), 'custom_block.type'); + $items[] = new ConfigEntityMapper('admin/structure/custom-blocks/manage/{custom_block_type}', 'custom_block_type', t('@label custom block type')); // Contact. - $items[] = new ConfigEntityMapper('admin/structure/contact/manage/{contact_category}', 4, 'contact_category', t('@label contact category'), 'contact.category'); + $items[] = new ConfigEntityMapper('admin/structure/contact/manage/{contact_category}', 'contact_category', t('@label contact category')); // Filter. - $items[] = new ConfigEntityMapper('admin/config/content/formats/{filter_format}', 4, 'filter_format', t('@label text format'), 'filter.format', MENU_LOCAL_TASK, TRUE); + $items[] = new ConfigEntityMapper('admin/config/content/formats/manage/{filter_format}', 'filter_format', t('@label text format'), MENU_LOCAL_TASK, TRUE); // Menu. - $items[] = new ConfigEntityMapper('admin/structure/menu/manage/{menu}', 4, 'menu', t('@label menu'), 'menu.menu'); + $items[] = new ConfigEntityMapper('admin/structure/menu/manage/{menu}', 'menu', t('@label menu')); // Shortcut. - $items[] = new ConfigEntityMapper('admin/config/user-interface/shortcut/manage/{shortcut_set}', 5, 'shortcut', t('@label shortcut set'), 'shortcut.set'); + $items[] = new ConfigEntityMapper('admin/config/user-interface/shortcut/manage/{shortcut}', 'shortcut', t('@label shortcut set')); // System. - $items[] = new ConfigGroupMapper('admin/config/development/maintenance', t('System maintenance'), array('system.maintenance'), TRUE); + $items[] = new ConfigGroupMapper('admin/config/development/maintenance', t('System maintenance'), array('system.maintenance'), MENU_LOCAL_TASK, TRUE); $items[] = new ConfigGroupMapper('admin/config/system/site-information', t('Site information'), array('system.site'), MENU_LOCAL_TASK, TRUE); // Taxonomy. - $items[] = new ConfigEntityMapper('admin/structure/taxonomy/manage/{taxonomy_vocabulary}', 4, 'taxonomy_vocabulary', t('@label vocabulary'), 'taxonomy.vocabulary'); + $items[] = new ConfigEntityMapper('admin/structure/taxonomy/manage/{taxonomy_vocabulary}', 'taxonomy_vocabulary', t('@label vocabulary')); // User. $items[] = new ConfigGroupMapper('admin/config/people/accounts', t('Account settings'), array('user.settings', 'user.mail')); - $items[] = new ConfigEntityMapper('admin/people/roles/edit/{user_role}', 4, 'user_role', t('@label user role'), 'user.role', MENU_LOCAL_TASK, TRUE); + $items[] = new ConfigEntityMapper('admin/people/roles/manage/{user_role}', 'user_role', t('@label user role'), MENU_LOCAL_TASK, TRUE); // Views. - $items[] = new ConfigEntityMapper('admin/structure/views/view/{view}', 4, 'view', t('@label view'), 'views.view', MENU_CALLBACK); + $items[] = new ConfigEntityMapper('admin/structure/views/view/{view}', 'view', t('@label view'), MENU_CALLBACK); + + // Language. + $items[] = new ConfigEntityMapper('admin/config/regional/language/edit/{language_entity}', 'language_entity', t('@label view'), MENU_CALLBACK); + + // Fields. + $entity_manager = Drupal::entityManager(); + foreach ($entity_manager->getDefinitions() as $entity_type => $entity_info) { + // Make sure entity type is fieldable and has base path. + if ($entity_info['fieldable'] && isset($entity_info['route_base_path'])) { + // Get all available bundles available for this entity type. + foreach (entity_get_bundles($entity_type) as $bundle => $bundle_info) { + if ($path = $entity_manager->getAdminPath($entity_type, $bundle)) { + $items[] = new ConfigEntityMapper($path . '/fields/{field_instance}' , 'field_instance', t('@label field'), MENU_CALLBACK); + } + } + } + } return $items; } @@ -273,13 +275,15 @@ function config_translation_config_translation_group_info() { * Implements hook_entity_operation_alter(). */ function config_translation_entity_operation_alter(array &$operations, \Drupal\Core\Entity\EntityInterface $entity) { - $uri = $entity->uri(); - $operations['translate'] = array( - 'title' => t('Translate badabumm'), - 'href' => $uri['path'] . '/translate', - 'options' => $uri['options'], - 'weight' => 50, - ); + if (user_access('translate configuration')) { + $uri = $entity->uri(); + $operations['translate'] = array( + 'title' => t('Translate'), + 'href' => $uri['path'] . '/translate', + 'options' => $uri['options'], + 'weight' => 50, + ); + } } /** @@ -294,30 +298,6 @@ function config_translation_form_alter(&$form, &$form_state, $form_id) { return; } - // Alter the filter admin overview to add translation links. - if ($form_id == 'filter_admin_overview') { - foreach ($form['formats'] as $id => &$format) { - if (is_array($format) && isset($format['operations'])) { - $format['operations']['#links']['translate'] = array( - 'title' => t('Translate'), - 'href' => 'admin/config/content/formats/' . $id . '/translate', - ); - } - } - } - - // Alter the user roles form to add translation links. - if ($form_id == 'user_admin_roles') { - foreach ($form['roles'] as $id => &$role) { - if (is_array($role) && isset($role['operations'])) { - $role['operations']['#links']['translate'] = array( - 'title' => t('Translate'), - 'href' => 'admin/people/roles/edit/' . $id . '/translate', - ); - } - } - } - // Alter the blocks form to add translation links. if ($form_id == 'block_admin_display_form') { foreach ($form['blocks'] as $id => &$block) { @@ -330,53 +310,3 @@ function config_translation_form_alter(&$form, &$form_state, $form_id) { } } } - -/** - * Alters page operations since there is no operations API. - * - * @todo Rework this in favor of an operations API. See - * http://drupal.org/node/2004428 - */ -function config_translation_page_alter(&$page) { - if (!user_access('translate configuration')) { - // Do not alter pages with links to translations, if no access. - return; - } - - if (isset($page['content'])) { - // Grab the first content item, which is the content block hopefully. - $content_keys = array_keys($page['content']); - $content = &$page['content'][reset($content_keys)]; - - // Fingerprint the views entity list page structure. - if (isset($content['content'][0]['#attributes']['id']) && - $content['content'][0]['#attributes']['id'] == 'views-entity-list') { - $tables = &$content['content'][0]; - foreach (array('enabled', 'disabled') as $status) { - foreach ($tables[$status]['table']['#rows'] as $id => &$row) { - $row['data']['operations']['data']['#links']['translate'] = array( - 'title' => t('Translate'), - 'href' => 'admin/structure/views/view/' . $id . '/translate', - ); - } - } - } - - if (isset($content['content'][0]['#rows'])) { - $row_keys = array_keys($content['content'][0]['#rows']); - $first_key = reset($row_keys); - $rows = &$content['content'][0]['#rows']; - - // Fingerprint the menu summary table structure. - if (isset($rows[$first_key]['title']['class']) && - in_array('menu-label', $rows[$first_key]['title']['class'])) { - foreach ($rows as $id => &$row) { - $row['operations']['data']['#links']['translate'] = array( - 'title' => t('Translate'), - 'href' => 'admin/structure/menu/manage/' . $id . '/translate', - ); - } - } - } - } -} diff --git a/core/modules/config_translation/core/modules/config_translation/config_translation.admin.css b/core/modules/config_translation/core/modules/config_translation/config_translation.admin.css new file mode 100644 index 0000000..66d9ef3 --- /dev/null +++ b/core/modules/config_translation/core/modules/config_translation/config_translation.admin.css @@ -0,0 +1,38 @@ +/** + * @file + * Styles for configuration translation. + */ + +/** + * Hide the label, in an accessible way, for responsive screens which show the + * form in one column. + */ +.config-translation-form .translation-element-wrapper .translation label { + position: absolute !important; + clip: rect(1px, 1px, 1px, 1px); + overflow: hidden; + height: 1px; + width: 1px; +} + +/** + * For wider screens, show the label and display source and translation side by + * side. + */ +@media all and (min-width: 851px) { + .config-translation-form .translation-element-wrapper .source { + width: 48%; + float: left; + } + .config-translation-form .translation-element-wrapper .translation { + width: 48%; + float: right; + } + .config-translation-form .translation-element-wrapper .translation label { + position: static !important; + clip: auto; + overflow: visible; + height: auto; + width: auto; + } +} diff --git a/core/modules/config_translation/core/modules/config_translation/config_translation.api.php b/core/modules/config_translation/core/modules/config_translation/config_translation.api.php new file mode 100644 index 0000000..e6ca187 --- /dev/null +++ b/core/modules/config_translation/core/modules/config_translation/config_translation.api.php @@ -0,0 +1,66 @@ +addName('othermodule.altered_settings_key'); + } +} + +/** + * @} End of "addtogroup hooks". + */ diff --git a/core/modules/config_translation/core/modules/config_translation/config_translation.info.yml b/core/modules/config_translation/core/modules/config_translation/config_translation.info.yml new file mode 100644 index 0000000..aebc7f4 --- /dev/null +++ b/core/modules/config_translation/core/modules/config_translation/config_translation.info.yml @@ -0,0 +1,8 @@ +name: 'Configuration Translation' +type: module +description: 'Provides a translation interface for configuration.' +package: Multilingual +version: VERSION +core: 8.x +dependencies: + - locale diff --git a/core/modules/config_translation/config_translation.module b/core/modules/config_translation/core/modules/config_translation/config_translation.module similarity index 100% copy from core/modules/config_translation/config_translation.module copy to core/modules/config_translation/core/modules/config_translation/config_translation.module diff --git a/core/modules/config_translation/core/modules/config_translation/config_translation.services.yml b/core/modules/config_translation/core/modules/config_translation/config_translation.services.yml new file mode 100644 index 0000000..68fc96a --- /dev/null +++ b/core/modules/config_translation/core/modules/config_translation/config_translation.services.yml @@ -0,0 +1,9 @@ +services: + config_translation.subscriber: + class: Drupal\config_translation\Routing\RouteSubscriber + tags: + - { name: event_subscriber } + config_translation.access_check: + class: Drupal\config_translation\Access\ConfigNameCheck + tags: + - { name: access_check } diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Access/ConfigNameCheck.php b/core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/Access/ConfigNameCheck.php similarity index 100% copy from core/modules/config_translation/lib/Drupal/config_translation/Access/ConfigNameCheck.php copy to core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/Access/ConfigNameCheck.php diff --git a/core/modules/config_translation/lib/Drupal/config_translation/ConfigEntityMapper.php b/core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/ConfigEntityMapper.php similarity index 100% copy from core/modules/config_translation/lib/Drupal/config_translation/ConfigEntityMapper.php copy to core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/ConfigEntityMapper.php diff --git a/core/modules/config_translation/lib/Drupal/config_translation/ConfigGroupMapper.php b/core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/ConfigGroupMapper.php similarity index 100% copy from core/modules/config_translation/lib/Drupal/config_translation/ConfigGroupMapper.php copy to core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/ConfigGroupMapper.php diff --git a/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php b/core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php similarity index 100% copy from core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php copy to core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationController.php b/core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationController.php similarity index 100% copy from core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationController.php copy to core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationController.php diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationDeleteForm.php b/core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationDeleteForm.php similarity index 100% copy from core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationDeleteForm.php copy to core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationDeleteForm.php diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationManageForm.php b/core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationManageForm.php similarity index 100% copy from core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationManageForm.php copy to core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationManageForm.php diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php b/core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php similarity index 100% copy from core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php copy to core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUITest.php b/core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUITest.php similarity index 100% copy from core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUITest.php copy to core/modules/config_translation/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUITest.php diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Access/ConfigNameCheck.php b/core/modules/config_translation/lib/Drupal/config_translation/Access/ConfigNameCheck.php index 1af1390..5281883 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Access/ConfigNameCheck.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Access/ConfigNameCheck.php @@ -32,9 +32,12 @@ public function access(Route $route, Request $request) { // Get configuration group for this mapper. $group = $mapper->getConfigGroup($entity); $group_language = $group->getLanguageWithFallback(); + $language = NULL; + + if ($request->query->has('langcode')) { + $language = language_load($request->query->get('langcode')); + } - $langcode = $request->attributes->get('langcode'); - $language = empty($langcode) ? NULL : language_load($langcode); // Only allow access to translate configuration, if proper permissions are // granted, the configuration has translatable pieces, the source language @@ -47,7 +50,7 @@ public function access(Route $route, Request $request) { $group->hasSchema() && $group->hasTranslatable() && !$group_language->locked && - (empty($language) || (!$language->locked && $language->langcode != $group_language->langcode)) + (empty($language) || (!$language->locked && $language->id != $group_language->id)) ); } diff --git a/core/modules/config_translation/lib/Drupal/config_translation/ConfigEntityMapper.php b/core/modules/config_translation/lib/Drupal/config_translation/ConfigEntityMapper.php index f7dba2e..69bf07c 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/ConfigEntityMapper.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/ConfigEntityMapper.php @@ -20,14 +20,7 @@ class ConfigEntityMapper implements ConfigMapperInterface { * * @var string */ - private $base_path = ''; - - /** - * Index of element to retrieve entity ID from. - * - * @var int - */ - private $path_id_index = 0; + private $basePath = ''; /** * Title for translation editing screen. @@ -41,94 +34,74 @@ class ConfigEntityMapper implements ConfigMapperInterface { * * @var string */ - private $entity_type = ''; - - /** - * Configuration name prefix for the entity type. - * - * @var string - */ - private $config_prefix = ''; + private $entityType = ''; /** * Menu item type. * * @var int */ - private $menu_type = MENU_LOCAL_TASK; + private $menuItemType = MENU_LOCAL_TASK; /** * Indicator whether an edit tab should be added. * * @var bool */ - private $add_edit_tab = FALSE; + private $addEditTab = FALSE; /** * Router name for this group in the routing system. * * @var string */ - private $route_name; + private $routeName; /** * Constructor for configuration group. * * @param string $base_path * Base path to attach the group user interface to. - * @param int $path_id_index - * Index of element to retrieve entity ID from. * @param string $entity_type * Configuration entity type name. * @param string $title * Title for translation editing screen. Use @label for entity * label placement. - * @param string $config_prefix - * Configuration name prefix for the entity type. - * @param int $menu_type + * @param int $menu_item_type * (optional) Menu item type to add. * @param bool $add_edit_tab * (optional) Indicator whether an edit tab should be added. If there are * no existing tabs on the page, for the translation tab to show up, an * edit tab will need to be added. */ - function __construct($base_path, $path_id_index, $entity_type, $title, $config_prefix, $menu_type = MENU_LOCAL_TASK, $add_edit_tab = FALSE) { - $this->base_path = $base_path; - $this->path_id_index = $path_id_index; - $this->entity_type = $entity_type; + function __construct($base_path, $entity_type, $title, $menu_item_type = MENU_LOCAL_TASK, $add_edit_tab = FALSE) { + $this->basePath = $base_path; + $this->entityType = $entity_type; $this->title = $title; - $this->config_prefix = $config_prefix; - $this->menu_type = $menu_type; - $this->add_edit_tab = $add_edit_tab; + $this->menuItemType = $menu_item_type; + $this->addEditTab = $add_edit_tab; $this->setRouteName(); } /** * {@inheritdoc} */ - public function hasEditTab() { - return $this->add_edit_tab; + public function needsEditTab() { + return $this->addEditTab; } /** * {@inheritdoc} */ public function getBasePath() { - return $this->base_path; - } - - /** - * {@inheritdoc} - */ - public function getMenuType() { - return $this->menu_type; + return $this->basePath; } /** * {@inheritdoc} */ - public function getPathIdIndex() { - return $this->path_id_index; + public function getMenuItemType() { + return $this->menuItemType; } /** @@ -142,24 +115,23 @@ public function getConfigGroup($arg = NULL) { return NULL; } if (is_string($arg)) { - $entity = entity_load($this->entity_type, $arg); + $entity = entity_load($this->entityType, $arg); } else { $entity = $arg; } // Replace path segment with the ID of the entity for further processing. - $path = explode('/', $this->base_path); - $path[$this->path_id_index] = $entity->id(); - $base_path = join('/', $path); + $base_path = str_replace('{' . $this->entityType . '}', $entity->id(), $this->basePath); // Replace entity label in template title. $title = format_string($this->title, array('@label' => $entity->label())); // The list of config IDs belonging to this entity. - $names = array($this->config_prefix . '.' . $entity->id()); + $entity_type_info = entity_get_info($this->entityType); + $names = array($entity_type_info['config_prefix'] . '.' . $entity->id()); - return new ConfigGroupMapper($base_path, $title, $names, $this->menu_type, $this->add_edit_tab); + return new ConfigGroupMapper($base_path, $title, $names, $this->menuItemType, $this->addEditTab); } /** @@ -168,21 +140,21 @@ public function getConfigGroup($arg = NULL) { public function setRouteName() { $search = array('/', '-', '{', '}'); $replace = array('.', '_', '_', '_'); - $this->route_name = 'config_translation.item.' . str_replace($search, $replace, $this->base_path); + $this->routeName = 'config_translation.item.' . str_replace($search, $replace, $this->basePath); } /** * {@inheritdoc} */ public function getRouteName() { - return $this->route_name; + return $this->routeName; } /** * {@inheritdoc} */ public function getType() { - return $this->entity_type; + return $this->entityType; } } diff --git a/core/modules/config_translation/lib/Drupal/config_translation/ConfigGroupMapper.php b/core/modules/config_translation/lib/Drupal/config_translation/ConfigGroupMapper.php index 8ab5f3f..3d993c0 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/ConfigGroupMapper.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/ConfigGroupMapper.php @@ -19,7 +19,7 @@ class ConfigGroupMapper implements ConfigMapperInterface { * * @var string */ - private $base_path = ''; + private $basePath = ''; /** * Title for translation editing screen. @@ -40,21 +40,21 @@ class ConfigGroupMapper implements ConfigMapperInterface { * * @var int */ - private $menu_type = MENU_LOCAL_TASK; + private $menuItemType = MENU_LOCAL_TASK; /** * Indicator whether an edit tab should be added. * * @var bool */ - private $add_edit_tab = FALSE; + private $addEditTab = FALSE; /** * Router name for this group in the routing system. * * @var string */ - private $route_name; + private $routeName; /** * Constructor for configuration group. @@ -65,34 +65,34 @@ class ConfigGroupMapper implements ConfigMapperInterface { * Title for translation editing screen. * @param array $names * List of configuration names in group. - * @param int $menu_type + * @param int $menu_item_type * (optional) Menu item type to add. * @param bool $add_edit_tab * (optional) Indicator whether an edit tab should be added. If there are * no existing tabs on the page, for the translation tab to show up, an * edit tab will need to be added. */ - function __construct($base_path, $title, $names, $menu_type = MENU_LOCAL_TASK, $add_edit_tab = FALSE) { - $this->base_path = $base_path; + function __construct($base_path, $title, $names, $menu_item_type = MENU_LOCAL_TASK, $add_edit_tab = FALSE) { + $this->basePath = $base_path; $this->title = $title; $this->names = $names; - $this->menu_type = $menu_type; - $this->add_edit_tab = $add_edit_tab; + $this->menuItemType = $menu_item_type; + $this->addEditTab = $add_edit_tab; $this->setRouteName(); } /** * {@inheritdoc} */ - public function hasEditTab() { - return $this->add_edit_tab; + public function needsEditTab() { + return $this->addEditTab; } /** * {@inheritdoc} */ public function getBasePath() { - return $this->base_path; + return $this->basePath; } /** @@ -118,15 +118,8 @@ public function getNames() { /** * {@inheritdoc} */ - public function getMenuType() { - return $this->menu_type; - } - - /** - * {@inheritdoc} - */ - public function getPathIdIndex() { - return NULL; + public function getMenuItemType() { + return $this->menuItemType; } /** @@ -161,7 +154,7 @@ public function getLanguageWithFallback() { $langcode = $this->getLangcode(); $language = language_load($langcode); if (empty($language) && $langcode == 'en') { - $language = new Language(array('langcode' => 'en', 'name' => t('Built-in English'))); + $language = new Language(array('id' => 'en', 'name' => t('Built-in English'))); } return $language; } @@ -243,14 +236,14 @@ public function addName($name) { * {@inheritdoc} */ public function setRouteName() { - $this->route_name = 'config_translation.item.' . str_replace(array('/', '-'), array('.', '_'), $this->base_path); + $this->routeName = 'config_translation.item.' . str_replace(array('/', '-'), array('.', '_'), $this->basePath); } /** * {@inheritdoc} */ public function getRouteName() { - return $this->route_name; + return $this->routeName; } /** diff --git a/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php b/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php index 4a0c4b1..91b4da1 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php @@ -7,6 +7,9 @@ namespace Drupal\config_translation; +/** + * Defines the interface common for all configuration mappers. + */ interface ConfigMapperInterface { /** @@ -15,7 +18,7 @@ * @return bool * TRUE if this mapper needs an edit tab, FALSE otherwise. */ - public function hasEditTab(); + public function needsEditTab(); /** * Returns base path of this configuration mapper. @@ -31,21 +34,13 @@ public function getBasePath(); * @return int * The menu item type used for this mapper. */ - public function getMenuType(); - - /** - * Returns the path ID index if applicable. - * - * @return int - * The path ID index for the object ID int he path. - */ - public function getPathIdIndex(); + public function getMenuItemType(); /** * Returns the ConfigGroupMapper instance for this mapper. * * @param mixed $arg - * Menu argument if used with entity mapper. + * (optional) Menu argument if used with entity mapper. * * @return \Drupal\config_translation\ConfigGroupMapper * The ConfigGroupMapper instance for this mapper. @@ -53,23 +48,24 @@ public function getPathIdIndex(); public function getConfigGroup($arg = NULL); /** - * Returns entity type of the entity type mapper, NULL otherwise. + * Returns the entity type of the entity type mapper, NULL otherwise. * - * @return mixed + * @return string|null + * The entity type of the mapper, or NULL when it is not an entity, for + * example site information settings. */ public function getType(); /** * Creates unique route name for the group. - * - * @return mixed */ public function setRouteName(); /** - * Returns group name. + * Returns route name for the group. * - * @return mixed + * @return string + * Route name for the group. */ public function getRouteName(); diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationController.php b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationController.php index 4a6c9e0..a3f601f 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationController.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationController.php @@ -7,18 +7,18 @@ namespace Drupal\config_translation\Controller; -use Drupal\Core\Language\Language; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\HttpFoundation\Request; +use Drupal\Core\Config\Config; use Drupal\Core\Controller\ControllerInterface; +use Drupal\Core\Language\Language; use Drupal\config_translation\ConfigGroupMapper; use Drupal\config_translation\ConfigMapperInterface; -use Drupal\Core\Config\Config; -use Drupal\config_translation\Form\ConfigTranslationManageForm; use Drupal\config_translation\Form\ConfigTranslationDeleteForm; +use Drupal\config_translation\Form\ConfigTranslationManageForm; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Request; /** - * Controller providing page callbacks for the config translation interface. + * Provides page callbacks for the config translation interface. */ class ConfigTranslationController implements ControllerInterface { @@ -32,22 +32,35 @@ public static function create(ContainerInterface $container) { /** * Language translations overview page for a configuration name. * - * @param Request $request + * @param \Symfony\Component\HttpFoundation\Request $request * Page request object. - * @param ConfigMapperInterface $mapper + * @param \Drupal\config_translation\ConfigMapperInterface $mapper * Configuration mapper. * * @return array * Page render array. */ public function itemOverviewPage(Request $request, ConfigMapperInterface $mapper) { + if ($request->query->has('action') && $request->query->has('langcode') ) { + $action = $request->query->get('action'); + $langcode = $request->query->get('langcode'); + switch ($action) { + case 'add': + case 'edit': + return $this->itemTranslatePage($request, $action, $mapper); + break; + case 'delete': + return $this->itemDeletePage($request, $mapper); + break; + } + } $group = $this->getConfigGroup($request, $mapper); drupal_set_title(t('Translations for %label', array('%label' => $group->getTitle())), PASS_THROUGH); // It is possible the original language this configuration was saved with is // not on the system. For example, the configuration shipped in English but - // the site has no English configured. Represent the original language in the - // table even if it is not currently configured. + // the site has no English configured. Represent the original language in + // the table even if it is not currently configured. $languages = language_list(); $original_langcode = $group->getLangcode(); if (!isset($languages[$original_langcode])) { @@ -56,7 +69,7 @@ public function itemOverviewPage(Request $request, ConfigMapperInterface $mapper $language_name = t('Built-in English'); } // Create a dummy language object for this listing only. - $languages[$original_langcode] = new Language(array('langcode' => $original_langcode, 'name' => $language_name)); + $languages[$original_langcode] = new Language(array('id' => $original_langcode, 'name' => $language_name)); } $path = $group->getBasePath(); @@ -67,12 +80,12 @@ public function itemOverviewPage(Request $request, ConfigMapperInterface $mapper '#header' => $header, ); foreach ($languages as $language) { - if ($language->langcode == $original_langcode) { - $page['languages'][$language->langcode]['language'] = array( - '#markup' => '' . t('@language (original)', array('@language' => $language->name)) . '' + if ($language->id == $original_langcode) { + $page['languages'][$language->id]['language'] = array( + '#markup' => '' . t('@language (original)', array('@language' => $language->name)) . '', ); - // @todo: the user translating might as well not have access to + // @todo The user translating might as well not have access to // edit the original configuration. They will get a 403 for this // link when clicked. Do we know better? $operations = array(); @@ -80,35 +93,40 @@ public function itemOverviewPage(Request $request, ConfigMapperInterface $mapper 'title' => t('Edit'), 'href' => $path, ); - $page['languages'][$language->langcode]['operations'] = array( + $page['languages'][$language->id]['operations'] = array( '#type' => 'operations', '#links' => $operations, ); } else { - $page['languages'][$language->langcode]['language'] = array( + $page['languages'][$language->id]['language'] = array( '#markup' => $language->name, ); $operations = array(); - - // Check if translation exist for this language. + $path_options = array('langcode' => $language->id); + // If no translation exists for this language, link to add one. if (!$group->hasTranslation($language)) { $operations['add'] = array( 'title' => t('Add'), - 'href' => $path . '/translate/add/' . $language->langcode, + 'href' => $path . '/translate', + 'query' => array('action' => 'add') + $path_options, ); } else { + // Otherwise, link to edit the existing translation. $operations['edit'] = array( 'title' => t('Edit'), - 'href' => $path . '/translate/edit/' . $language->langcode, + 'href' => $path . '/translate', + 'query' => array('action' => 'edit') + $path_options, ); $operations['delete'] = array( 'title' => t('Delete'), - 'href' => $path . '/translate/delete/' . $language->langcode, + 'href' => $path . '/translate', + 'query' => array('action' => 'delete') + $path_options, ); } - $page['languages'][$language->langcode]['operations'] = array( + + $page['languages'][$language->id]['operations'] = array( '#type' => 'operations', '#links' => $operations, ); @@ -120,15 +138,16 @@ public function itemOverviewPage(Request $request, ConfigMapperInterface $mapper /** * Renders translation item manage form. * - * @param Request $request + * @param \Symfony\Component\HttpFoundation\Request $request * Page request object. * @param string $action * Action identifier, either 'add' or 'edit'. Used to provide proper * labeling on the screen. - * @param ConfigMapperInterface $mapper + * @param \Drupal\config_translation\ConfigMapperInterface $mapper * Configuration mapper. * * @return array + * The render array for the translation item manage form. */ public function itemTranslatePage(Request $request, $action, ConfigMapperInterface $mapper) { $group = $this->getConfigGroup($request, $mapper); @@ -168,23 +187,30 @@ public function itemTranslatePage(Request $request, $action, ConfigMapperInterfa } /** - * Item delete form. + * Renders the item delete form. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * Page request object. + * @param \Drupal\config_translation\ConfigMapperInterface $mapper + * Configuration mapper. * - * @param Request $request - * @param ConfigMapperInterface $mapper - * @return array|mixed + * @return array + * The render array for the translation item delete form. */ public function itemDeletePage(Request $request, ConfigMapperInterface $mapper) { return drupal_get_form(new ConfigTranslationDeleteForm(), $this->getConfigGroup($request, $mapper), $this->getLanguage($request, $mapper)); } /** - * Helper to get config group. + * Gets the config group. * - * @param Request $request - * @param ConfigMapperInterface $mapper + * @param \Symfony\Component\HttpFoundation\Request $request + * Page request object. + * @param \Drupal\config_translation\ConfigMapperInterface $mapper + * Configuration mapper. * - * @return ConfigGroupMapper + * @return \Drupal\config_translation\ConfigGroupMapper + * The config group. */ protected function getConfigGroup(Request $request, ConfigMapperInterface $mapper) { // Get configuration group for this mapper. @@ -193,18 +219,19 @@ protected function getConfigGroup(Request $request, ConfigMapperInterface $mappe } /** - * Helper to get language object. + * Gets the language object. * - * @param Request $request - * @param ConfigMapperInterface $mapper + * @param \Symfony\Component\HttpFoundation\Request $request + * Page request object. + * @param \Drupal\config_translation\ConfigMapperInterface $mapper + * Configuration mapper. * - * @return bool|\Drupal\core\Language\Language - * Returns Language object when langcode found in request; FALSE otherwise. + * @return false|\Drupal\core\Language\Language + * Returns Language object when langcode found in request, FALSE otherwise. */ protected function getLanguage(Request $request, ConfigMapperInterface $mapper) { - $langcode = $request->attributes->get('langcode'); - if ($langcode) { - return language_load($langcode); + if ($request->query->has('langcode')) { + return language_load($request->query->get('langcode')); } return FALSE; } diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationDeleteForm.php b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationDeleteForm.php index 29cf0f5..a4c9905 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationDeleteForm.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationDeleteForm.php @@ -8,8 +8,9 @@ namespace Drupal\config_translation\Form; use Drupal\Core\Form\ConfirmFormBase; -use Symfony\Component\HttpFoundation\Request; +use Drupal\Core\Language\Language; use Drupal\config_translation\ConfigMapperInterface; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Route; /** @@ -20,37 +21,35 @@ class ConfigTranslationDeleteForm extends ConfirmFormBase { /** * The group of config translation to be deleted. * - * @var \stdClass + * @var \Drupal\config_translation\ConfigMapperInterface */ protected $group; /** * The language of config translation. * - * @var \stdClass + * @var \Drupal\Core\Language\Language */ protected $language; /** * {@inheritdoc} */ - protected function getQuestion() { + public function getQuestion() { t('Are you sure you want to delete the @language translation of %label?', array('%label' => $this->group->getTitle(), '@language' => $this->language->name)); - } /** * {@inheritdoc} */ - protected function getConfirmText() { + public function getConfirmText() { return t('Delete'); } - /** * {@inheritdoc} */ - protected function getCancelPath() { + public function getCancelPath() { return $this->group->getBasePath() . '/translate'; } @@ -64,7 +63,7 @@ public function getFormID() { /** * {@inheritdoc} */ - public function buildForm(array $form, array &$form_state, ConfigMapperInterface $group = NULL, $language = NULL) { + public function buildForm(array $form, array &$form_state, ConfigMapperInterface $group = NULL, Language $language = NULL) { $this->group = $group; $this->language = $language; return parent::buildForm($form, $form_state); @@ -74,15 +73,12 @@ public function buildForm(array $form, array &$form_state, ConfigMapperInterface * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { - - $form_values = $form_state['values']; - $storage = drupal_container()->get('config.storage'); foreach ($this->group->getNames() as $name) { - $storage->delete('locale.config.' . $this->language->langcode . '.' . $name); + $storage->delete('locale.config.' . $this->language->id . '.' . $name); } - // @todo: do we need to flush caches? The config change may affect page display. - // drupal_flush_all_caches(); + // @todo Do we need to flush caches with drupal_flush_all_caches()? The + // config change may affect page display. drupal_set_message(t('@language translation of %label was deleted', array('%label' => $this->group->getTitle(), '@language' => $this->language->name))); $form_state['redirect'] = $this->group->getBasePath() . '/translate'; diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationManageForm.php b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationManageForm.php index e79ec9f..6c74162 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationManageForm.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationManageForm.php @@ -1,4 +1,5 @@ group = $group; $this->language = $language; - $this->source_language = $this->group->getConfigGroup()->getLanguageWithFallback(); - $this->base_config = $base_config; + $this->sourceLanguage = $this->group->getConfigGroup()->getLanguageWithFallback(); + $this->baseConfigData = $base_config_data; foreach ($this->group->getNames() as $id => $name) { $form[$id] = array( '#type' => 'container', '#tree' => TRUE, ); - $form[$id] += $this->buildConfigForm(config_typed()->get($name), config($name)->get(), $this->base_config[$name]); + $form[$id] += $this->buildConfigForm(config_typed()->get($name), config($name)->get(), $this->baseConfigData[$name]); } $form['#attached']['css'] = array(drupal_get_path('module', 'config_translation') . '/config_translation.admin.css'); @@ -93,14 +104,13 @@ public function buildForm(array $form, array &$form_state, ConfigMapperInterface } /** - * @inheritdoc + * {@inheritdoc} */ public function validateForm(array &$form, array &$form_state) { - } /** - * @inheritdoc + * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { $form_values = $form_state['values']; @@ -109,9 +119,9 @@ public function submitForm(array &$form, array &$form_state) { config_context_enter('config.context.free'); foreach ($this->group->getNames() as $id => $name) { - // Set config values based on form submission and original values. + // Set config values based on form submission and source values. $base_config = config($name); - $translation_config = config('locale.config.' . $this->language->langcode . '.' . $name); + $translation_config = config('locale.config.' . $this->language->id . '.' . $name); $locations = $this->localeStorage->getLocations(array('type' => 'configuration', 'name' => $name)); $this->setConfig($this->language, $base_config, $translation_config, $form_values[$id], !empty($locations)); @@ -135,12 +145,16 @@ public function submitForm(array &$form, array &$form_state) { /** * Formats configuration schema as a form tree. * - * @param $schema - * Schema definition of configuration. - * @param $config - * Configuration object of requested language. - * @param $base_config - * Configuration object of base language. + * @param mixed $schema + * Schema definition of configuration which is a + * \Drupal\Core\Config\Schema\Element or a + * \Drupal\Core\TypedData\TypedConfigManager. + * @param array|string $config_data + * Configuration object of requested language, a string when done traversing + * the data building each sub-structure for the form. + * @param array|string $base_config_data + * Configuration object of base language, a string when done traversing + * the data building each sub-structure for the form. * @param bool $collapsed * Flag to set collapsed state. * @param string|NULL $base_key @@ -149,19 +163,19 @@ public function submitForm(array &$form, array &$form_state) { * @return array * An associative array containing the structure of the form. * - * @todo - * Make this conditional on the translatable schema property from - * http://drupal.org/node/1905152 - currently hardcodes label and text. + * @todo Make this conditional on the translatable schema property from + * http://drupal.org/node/2035393 - currently hardcodes label and text. */ - protected function buildConfigForm($schema, $config, $base_config, $collapsed = FALSE, $base_key = '') { + protected function buildConfigForm($schema, $config_data, $base_config_data, $collapsed = FALSE, $base_key = '') { $build = array(); foreach ($schema as $key => $element) { + // Make the specific element key, "$base_key.$key". $element_key = implode('.', array_filter(array($base_key, $key))); $definition = $element->getDefinition() + array('label' => t('N/A')); if ($element instanceof Element) { // Build sub-structure and include it with a wrapper in the form // if there are any translatable elements there. - $sub_build = $this->buildConfigForm($element, $config[$key], $base_config[$key], TRUE, $element_key); + $sub_build = $this->buildConfigForm($element, $config_data[$key], $base_config_data[$key], TRUE, $element_key); if (!empty($sub_build)) { // For some configuration elements the same element structure can // repeat multiple times, (like views displays, filters, etc.). @@ -192,36 +206,34 @@ protected function buildConfigForm($schema, $config, $base_config, $collapsed = } } else { - $type = $element->getType(); - switch ($type) { - case 'label': - $type = 'textfield'; - break; - case 'text': - $type = 'textarea'; - break; - default: - continue(2); - break; + $definition = $element->getDefinition(); + + // Create form element only for translatable items. + if (!isset($definition['translatable']) || !isset($definition['type'])) { + continue; } - $value = $config[$key]; + + $value = $config_data[$key]; $build[$element_key] = array( '#theme' => 'config_translation_manage_form_element', ); $build[$element_key]['source'] = array( - '#markup' => $base_config[$key] ? ('' . nl2br($base_config[$key] . '')) : t('(Empty)'), - '#title' => t($definition['label']) . ' ('. $this->source_language->name . ')', + '#markup' => $base_config_data[$key] ? ('' . nl2br($base_config_data[$key] . '')) : t('(Empty)'), + '#title' => t($definition['label']) . ' ('. $this->sourceLanguage->name . ')', '#type' => 'item', ); + + // Estimate a comfortable size of the input textarea. $rows_words = ceil(str_word_count($value) / 5); $rows_newlines = substr_count($value, "\n" ) + 1; $rows = max($rows_words, $rows_newlines); + $build[$element_key]['translation'] = array( - '#type' => $type, + '#type' => $this->getFormElementType($definition['type']), '#default_value' => $value, '#title' => t($definition['label']) . ' (' . $this->language->name . ')', '#rows' => $rows, - '#attributes' => array('lang' => $this->language->langcode), + '#attributes' => array('lang' => $this->language->id), ); } } @@ -231,21 +243,21 @@ protected function buildConfigForm($schema, $config, $base_config, $collapsed = /** * Sets configuration based on a nested form value array. * - * @param Language $language - * Language object. + * @param \Drupal\Core\Language\Language $language + * Set the config in this language. * @param \Drupal\Core\Config\Config $base_config - * Base language configuration values instance. + * Base configuration values, in the source language. * @param \Drupal\Core\Config\Config $translation_config - * Translation configuration instance. Values from $config_values will be set - * in this instance. + * Translation configuration instance. Values from $config_values will be + * set in this instance. * @param array $config_values * A simple one dimensional or recursive array: * - simple: - * array(name => array('translation' => 'French site name')) + * array(name => array('translation' => 'French site name')); * - recursive: * cancel_confirm => array( - * cancel_confirm.subject => array('translation' => 'Subject') - * cancel_confirm.body => array('translation' => 'Body content') + * cancel_confirm.subject => array('translation' => 'Subject'), + * cancel_confirm.body => array('translation' => 'Body content'), * ); * Either format is used, the nested arrays are just containers and not * needed for saving the data. @@ -254,7 +266,6 @@ protected function buildConfigForm($schema, $config, $base_config, $collapsed = * therefore should also be stored in the locale database. */ protected function setConfig(Language $language, Config $base_config, Config $translation_config, array $config_values, $shipped_config = FALSE) { - //dpm($config_values); foreach ($config_values as $key => $value) { if (is_array($value) && !isset($value['translation'])) { // Traverse into this level in the configuration. @@ -270,7 +281,7 @@ protected function setConfig(Language $language, Config $base_config, Config $tr // Get the translation for this original source string from locale. $conditions = array( 'lid' => $source_string->lid, - 'language' => $language->langcode, + 'language' => $language->id, ); $translations = $this->localeStorage->getTranslations($conditions + array('translated' => TRUE)); // If we got a translation, take that, otherwise create a new one. @@ -285,8 +296,8 @@ protected function setConfig(Language $language, Config $base_config, Config $tr } } - // Save value, if different from original configuration. If same as - // original configuration, remove override. + // Save value, if different from the source value in the base + // configuration. If same as original configuration, remove override. if ($base_config->get($key) !== $value['translation']) { $translation_config->set($key, $value['translation']); } @@ -296,4 +307,26 @@ protected function setConfig(Language $language, Config $base_config, Config $tr } } } + + /** + * Provides a mapping of the TypedData element type to form element type. + * + * @param string $element_type + * The element type from the definition of a TypedData object. + * + * @return string + * The form element type. + */ + protected function getFormElementType($element_type) { + switch ($element_type) { + case 'text': + return 'textarea'; + break; + default: + // By default provide text field. + return 'textfield'; + break; + } + } + } diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php b/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php index 3c1a63b..ad11867 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php @@ -52,31 +52,6 @@ public function routes(RouteBuildEvent $event) { )); $collection->add($group->getRouteName(), $route); - $route = new Route($path . '/translate/add/{langcode}', array( - '_controller' => '\Drupal\config_translation\Controller\ConfigTranslationController::itemTranslatePage', - 'action' => 'add', - 'mapper' => $group, - ),array( - '_config_translation_config_name_access' => 'TRUE', - )); - $collection->add($group->getRouteName() . '.add', $route); - - $route = new Route($path . '/translate/edit/{langcode}', array( - '_controller' => '\Drupal\config_translation\Controller\ConfigTranslationController::itemTranslatePage', - 'action' => 'edit', - 'mapper' => $group, - ),array( - '_config_translation_config_name_access' => 'TRUE', - )); - $collection->add($group->getRouteName() . '.edit', $route); - - $route = new Route($path . '/translate/delete/{langcode}', array( - '_controller' => '\Drupal\config_translation\Controller\ConfigTranslationController::itemDeletePage', - 'mapper' => $group, - ),array( - '_config_translation_config_name_access' => 'TRUE', - )); - $collection->add($group->getRouteName() . '.delete', $route); } } diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationListUITest.php b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationListUITest.php new file mode 100644 index 0000000..75f958b --- /dev/null +++ b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationListUITest.php @@ -0,0 +1,360 @@ + 'Configuration Translation lists', + 'description' => 'Visit all lists.', + 'group' => 'Configuration Translation', + ); + } + + /** + * Admin user with all needed permissions. + * + * @var \Drupal\user\Plugin\Core\Entity\User + */ + protected $adminUser; + + public function setUp() { + parent::setUp(); + + $permissions = array( + 'access site-wide contact form', + 'administer blocks', + 'administer contact forms', + 'administer filters', + 'administer menu', + 'administer permissions', + 'administer shortcuts', + 'administer site configuration', + 'administer taxonomy', + 'administer users', + 'administer languages', + 'translate configuration', + ); + + // Create and log in user. + $this->adminUser = $this->drupalCreateUser($permissions); + $this->drupalLogin($this->adminUser); + } + + /** + * Tests the block listing for the translate operation. + * + * There are no blocks placed in the testing profile. Add one, then check + * for Translate operation. + */ + protected function doBlockListTest() { + // Add a test block, any block will do. + // Set the machine name so the translate link can be built later. + $block_machine_name = Unicode::strtolower($this->randomName(16)); + $this->drupalPlaceBlock('system_powered_by_block', array('machine_name' => $block_machine_name)); + + // Get the Block listing. + $this->drupalGet('admin/structure/block'); + + $translate_link = 'admin/structure/block/manage/stark.' . $block_machine_name . '/translate'; + // Test if the link to translate the block is on the page. + $this->assertLinkByHref($translate_link); + + // Test if the link to translate actually goes to the translate page. + // @todo does not work yet, see https://drupal.org/node/2027857 When it is + // fixed, uncomment the tests below. + //$this->drupalGet($translate_link); + //$this->assertRaw('