Commit 89b5fea7 authored by webchick's avatar webchick

Issue #1978916 by likin, YesCT, disasm, ayelet_Cr, tim.plunkett, vijaycs85,...

Issue #1978916 by likin, YesCT, disasm, ayelet_Cr, tim.plunkett, vijaycs85, Letharion: Convert locale_translate_page() to a Controller.
parent b8d150cc
<?php
/**
* @file
* Contains \Drupal\language\Form\ContentLanguageSettingsForm.
*/
namespace Drupal\language\Form;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Config\Context\ContextInterface;
use Drupal\Core\Entity\EntityManager;
use Drupal\system\SystemConfigFormBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Configure the content language settings for this site.
*/
class ContentLanguageSettingsForm extends SystemConfigFormBase {
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityManager
*/
protected $entityManager;
/**
* Constructs a ContentLanguageSettingsForm object.
*
* @param \Drupal\Core\Config\ConfigFactory $config_factory
* The config factory.
* @param \Drupal\Core\Config\Context\ContextInterface $context
* The configuration context to use.
* @param \Drupal\Core\Entity\EntityManager $entity_manager
* The entity manager.
*/
public function __construct(ConfigFactory $config_factory, ContextInterface $context, EntityManager $entity_manager) {
parent::__construct($config_factory, $context);
$this->entityManager = $entity_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory'),
$container->get('config.context.free'),
$container->get('plugin.manager.entity')
);
}
/**
* Return a list of entity types for which language settings are supported.
*
* @return array
* A list of entity types which are translatable.
*/
protected function entitySupported() {
$supported = array();
foreach ($this->entityManager->getDefinitions() as $entity_type => $info) {
if (!empty($info['translatable'])) {
$supported[$entity_type] = $entity_type;
}
}
return $supported;
}
/**
* {@inheritdoc}
*/
public function getFormID() {
return 'language_content_settings_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, array &$form_state) {
$entity_info = $this->entityManager->getDefinitions();
$labels = array();
$default = array();
$bundles = entity_get_bundles();
$language_configuration = array();
foreach ($this->entitySupported() as $entity_type) {
$labels[$entity_type] = isset($entity_info[$entity_type]['label']) ? $entity_info[$entity_type]['label'] : $entity_type;
$default[$entity_type] = FALSE;
// Check whether we have any custom setting.
foreach ($bundles as $bundle => $bundle_info) {
$conf = language_get_default_configuration($entity_type, $bundle);
if (!empty($conf['language_show']) || $conf['langcode'] != 'site_default') {
$default[$entity_type] = $entity_type;
}
$language_configuration[$entity_type][$bundle] = $conf;
}
}
asort($labels);
$form = array(
'#labels' => $labels,
'#attached' => array(
'library' => array(
array('language', 'drupal.language.admin'),
),
),
);
$form['entity_types'] = array(
'#title' => $this->t('Custom language settings'),
'#type' => 'checkboxes',
'#options' => $labels,
'#default_value' => $default,
);
$form['settings'] = array('#tree' => TRUE);
foreach ($labels as $entity_type => $label) {
$info = $entity_info[$entity_type];
$form['settings'][$entity_type] = array(
'#title' => $label,
'#type' => 'container',
'#entity_type' => $entity_type,
'#theme' => 'language_content_settings_table',
'#bundle_label' => isset($info['bundle_label']) ? $info['bundle_label'] : $label,
'#states' => array(
'visible' => array(
':input[name="entity_types[' . $entity_type . ']"]' => array('checked' => TRUE),
),
),
);
foreach ($bundles as $bundle => $bundle_info) {
$form['settings'][$entity_type][$bundle]['settings'] = array(
'#type' => 'item',
'#label' => $bundle_info['label'],
'language' => array(
'#type' => 'language_configuration',
'#entity_information' => array(
'entity_type' => $entity_type,
'bundle' => $bundle,
),
'#default_value' => $language_configuration[$entity_type][$bundle],
),
);
}
}
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => $this->t('Save'),
);
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, array &$form_state) {
$config = $this->configFactory->get('language.settings');
foreach ($form_state['values']['settings'] as $entity_type => $entity_settings) {
foreach ($entity_settings as $bundle => $bundle_settings) {
$config->set(language_get_default_configuration_settings_key($entity_type, $bundle),
array(
'langcode' => $bundle_settings['settings']['language']['langcode'],
'language_show' => $bundle_settings['settings']['langcode']['language_show'],
)
);
}
}
$config->save();
parent::submitForm($form, $form_state);
}
}
......@@ -122,25 +122,25 @@ function testUILanguageNegotiation() {
'string' => $default_string,
'langcode' => $langcode_browser_fallback,
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $language_browser_fallback_string,
);
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
$search = array(
'string' => $default_string,
'langcode' => $langcode,
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $language_string,
);
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
// Configure URL language rewrite.
variable_set('language_negotiation_url_type', Language::TYPE_INTERFACE);
......
......@@ -6,43 +6,15 @@
namespace Drupal\locale\Controller;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\locale\Form\TranslateEditForm;
use Drupal\locale\Form\TranslateFilterForm;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Return response for manual check translations.
*/
class LocaleController implements ContainerInjectionInterface {
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* Constructs a \Drupal\locale\Controller\LocaleController object.
*
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct(ModuleHandlerInterface $module_handler, UrlGeneratorInterface $url_generator) {
$this->moduleHandler = $module_handler;
$this->urlGenerator = $url_generator;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('module_handler'),
$container->get('url_generator')
);
}
class LocaleController extends ControllerBase {
/**
* Checks for translation updates and displays the translations status.
......@@ -53,11 +25,11 @@ public static function create(ContainerInterface $container) {
* A redirection to translations reports page.
*/
public function checkTranslation() {
$this->moduleHandler->loadInclude('locale', 'inc', 'locale.compare');
$this->moduleHandler()->loadInclude('locale', 'inc', 'locale.compare');
// Check translation status of all translatable project in all languages.
// First we clear the cached list of projects. Although not strictly
// nescessary, this is helpfull in case the project list is out of sync.
// necessary, this is helpful in case the project list is out of sync.
locale_translation_flush_projects();
locale_translation_check_projects();
......@@ -67,6 +39,21 @@ public function checkTranslation() {
return batch_process('admin/reports/translations');
}
return new RedirectResponse($this->urlGenerator->generateFromPath('admin/reports/translations', array('absolute' => TRUE)));
// @todo Use $this->redirect() after https://drupal.org/node/1978926.
return new RedirectResponse($this->urlGenerator()->generateFromPath('admin/reports/translations', array('absolute' => TRUE)));
}
/**
* Shows the string search screen.
*
* @return array
* The render array for the string search screen.
*/
public function translatePage() {
return array(
'filter' => drupal_get_form(TranslateFilterForm::create($this->container)),
'form' => drupal_get_form(TranslateEditForm::create($this->container)),
);
}
}
<?php
/**
* @file
* Contains \Drupal\locale\Form\TranslateFilterForm.
*/
namespace Drupal\locale\Form;
/**
* Provides a filtered translation edit form.
*/
class TranslateFilterForm extends TranslateFormBase {
/**
* {@inheritdoc}
*/
public function getFormID() {
return 'locale_translate_filter_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, array &$form_state) {
$filters = $this->translateFilters();
$filter_values = $this->translateFilterValues();
$form['#attached']['css'] = array(
drupal_get_path('module', 'locale') . '/css/locale.admin.css',
);
$form['filters'] = array(
'#type' => 'details',
'#title' => $this->t('Filter translatable strings'),
'#collapsed' => FALSE,
);
foreach ($filters as $key => $filter) {
// Special case for 'string' filter.
if ($key == 'string') {
$form['filters']['status']['string'] = array(
'#type' => 'search',
'#title' => $filter['title'],
'#description' => $filter['description'],
'#default_value' => $filter_values[$key],
);
}
else {
$empty_option = isset($filter['options'][$filter['default']]) ? $filter['options'][$filter['default']] : '- None -';
$form['filters']['status'][$key] = array(
'#title' => $filter['title'],
'#type' => 'select',
'#empty_value' => $filter['default'],
'#empty_option' => $empty_option,
'#size' => 0,
'#options' => $filter['options'],
'#default_value' => $filter_values[$key],
);
if (isset($filter['states'])) {
$form['filters']['status'][$key]['#states'] = $filter['states'];
}
}
}
$form['filters']['actions'] = array(
'#type' => 'actions',
'#attributes' => array('class' => array('container-inline')),
);
$form['filters']['actions']['submit'] = array(
'#type' => 'submit',
'#value' => $this->t('Filter'),
);
if (!empty($_SESSION['locale_translate_filter'])) {
$form['filters']['actions']['reset'] = array(
'#type' => 'submit',
'#value' => $this->t('Reset'),
'#submit' => array(array($this, 'resetForm')),
);
}
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, array &$form_state) {
$filters = $this->translateFilters();
foreach ($filters as $name => $filter) {
if (isset($form_state['values'][$name])) {
$_SESSION['locale_translate_filter'][$name] = $form_state['values'][$name];
}
}
$form_state['redirect'] = 'admin/config/regional/translate';
}
/**
* Provides a submit handler for the reset button.
*/
public function resetForm(array &$form, array &$form_state) {
$_SESSION['locale_translate_filter'] = array();
$form_state['redirect'] = 'admin/config/regional/translate';
}
}
<?php
/**
* @file
* Contains \Drupal\locale\Form\TranslateFormBase.
*/
namespace Drupal\locale\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Language\Language;
use Drupal\Core\Language\LanguageManager;
use Drupal\locale\StringStorageInterface;
use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines the locale user interface translation form base.
*
* Provides methods for searching and filtering strings.
*/
abstract class TranslateFormBase extends FormBase {
/**
* The locale storage.
*
* @var \Drupal\locale\StringStorageInterface
*/
protected $localeStorage;
/**
* The state store.
*
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface
*/
protected $state;
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManager
*/
protected $languageManager;
/*
* Filter values. Shared between objects that inherit this class.
*
* @var array|null
*/
protected static $filterValues;
/**
* Constructs a new TranslationFormBase object.
*
* @param \Drupal\locale\StringStorageInterface $locale_storage
* The locale storage.
* @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface $state
* The state service.
* @param \Drupal\Core\Language\LanguageManager $language_manager
* The language manager.
*/
public function __construct(StringStorageInterface $locale_storage, KeyValueStoreInterface $state, LanguageManager $language_manager) {
$this->localeStorage = $locale_storage;
$this->state = $state;
$this->languageManager = $language_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('locale.storage'),
$container->get('state'),
$container->get('language_manager')
);
}
/**
* Builds a string search query and returns an array of string objects.
*
* @return \Drupal\locale\TranslationString[]
* Array of \Drupal\locale\TranslationString objects.
*/
protected function translateFilterLoadStrings() {
$filter_values = $this->translateFilterValues();
// Language is sanitized to be one of the possible options in
// translateFilterValues().
$conditions = array('language' => $filter_values['langcode']);
$options = array('pager limit' => 30, 'translated' => TRUE, 'untranslated' => TRUE);
// Add translation status conditions and options.
switch ($filter_values['translation']) {
case 'translated':
$conditions['translated'] = TRUE;
if ($filter_values['customized'] != 'all') {
$conditions['customized'] = $filter_values['customized'];
}
break;
case 'untranslated':
$conditions['translated'] = FALSE;
break;
}
if (!empty($filter_values['string'])) {
$options['filters']['source'] = $filter_values['string'];
if ($options['translated']) {
$options['filters']['translation'] = $filter_values['string'];
}
}
return $this->localeStorage->getTranslations($conditions, $options);
}
/**
* Builds an array out of search criteria specified in request variables.
*
* @param bool $reset
* If the list of values should be reset.
*
* @return array $filter_values
* The filter values.
*/
protected function translateFilterValues($reset = FALSE) {
if (!$reset && static::$filterValues) {
return static::$filterValues;
}
$filter_values = array();
$filters = $this->translateFilters();
foreach ($filters as $key => $filter) {
$filter_values[$key] = $filter['default'];
// Let the filter defaults be overwritten by parameters in the URL.
if ($this->getRequest()->query->has($key)) {
// Only allow this value if it was among the options, or
// if there were no fixed options to filter for.
$value = $this->getRequest()->query->get($key);
if (!isset($filter['options']) || isset($filter['options'][$value])) {
$filter_values[$key] = $value;
}
}
elseif (isset($_SESSION['locale_translate_filter'][$key])) {
// Only allow this value if it was among the options, or
// if there were no fixed options to filter for.
if (!isset($filter['options']) || isset($filter['options'][$_SESSION['locale_translate_filter'][$key]])) {
$filter_values[$key] = $_SESSION['locale_translate_filter'][$key];
}
}
}
return static::$filterValues = $filter_values;
}
/**
* Lists locale translation filters that can be applied.
*/
protected function translateFilters() {
$filters = array();
// Get all languages, except English.
drupal_static_reset('language_list');
$languages = language_list();
$language_options = array();
foreach ($languages as $langcode => $language) {
if ($langcode != 'en' || locale_translate_english()) {
$language_options[$langcode] = $language->name;
}
}
// Pick the current interface language code for the filter.
$default_langcode = $this->languageManager->getLanguage(Language::TYPE_INTERFACE)->id;
if (!isset($language_options[$default_langcode])) {
$available_langcodes = array_keys($language_options);
$default_langcode = array_shift($available_langcodes);
}
$filters['string'] = array(
'title' => $this->t('String contains'),
'description' => $this->t('Leave blank to show all strings. The search is case sensitive.'),
'default' => '',
);
$filters['langcode'] = array(
'title' => $this->t('Translation language'),
'options' => $language_options,
'default' => $default_langcode,
);
$filters['translation'] = array(
'title' => $this->t('Search in'),
'options' => array(
'all' => $this->t('Both translated and untranslated strings'),
'translated' => $this->t('Only translated strings'),
'untranslated' => $this->t('Only untranslated strings'),
),
'default' => 'all',
);
$filters['customized'] = array(
'title' => $this->t('Translation type'),
'options' => array(
'all' => $this->t('All'),
LOCALE_NOT_CUSTOMIZED => $this->t('Non-customized translation'),
LOCALE_CUSTOMIZED => $this->t('Customized translation'),
),
'states' => array(
'visible' => array(
':input[name=translation]' => array('value' => 'translated'),
),
),
'default' => 'all',
);
return $filters;
}
}
......@@ -69,14 +69,14 @@ function testConfigTranslation() {
'langcode' => $langcode,
'translation' => 'all',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$textareas = $this->xpath('//textarea');
$textarea = current($textareas);
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $site_name,
);
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
$wrapper = $this->container->get('locale.config.typed')->get('system.site');
......@@ -115,13 +115,13 @@ function testConfigTranslation() {
'langcode' => $langcode,
'translation' => 'all',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $image_style_label,
);
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
// Check the right single translation has been created.
$translations = $this->storage->getTranslations(array('language' => $langcode, 'type' => 'configuration', 'name' => 'image.style.medium'));
......
......@@ -111,7 +111,7 @@ function testStandalonePoFile() {
'langcode' => 'fr',
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText(t('No strings available.'), 'String not overwritten by imported string.');
// This import should not have changed number of plural forms.
......@@ -133,7 +133,7 @@ function testStandalonePoFile() {
'langcode' => 'fr',
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertNoText(t('No strings available.'), 'String overwritten by imported string.');
// This import should have changed number of plural forms.
$locale_plurals = \Drupal::state()->get('locale.translation.plurals') ?: array();
......@@ -169,7 +169,7 @@ function testStandalonePoFile() {
'langcode' => 'fr',
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText(t('No strings available.'), 'Customized string not overwritten by imported string.');
// Try importing a .po file with overriding strings, and ensure existing
......@@ -188,7 +188,7 @@ function testStandalonePoFile() {
'langcode' => 'fr',