Issue #1978916 by likin, YesCT, disasm, ayelet_Cr, tim.plunkett, vijaycs85, Letharion: Convert locale_translate_page() to a Controller.
parent
b8d150cc89
commit
89b5fea7b4
|
@ -0,0 +1,182 @@
|
|||
<?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 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
|
|||
'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 @@ class LocaleController implements ContainerInjectionInterface {
|
|||
* 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 @@ class LocaleController implements ContainerInjectionInterface {
|
|||
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)),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\locale\Form\TranslateEditForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\locale\Form;
|
||||
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\locale\SourceString;
|
||||
|
||||
/**
|
||||
* Defines a translation edit form.
|
||||
*/
|
||||
class TranslateEditForm extends TranslateFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormID() {
|
||||
return 'locale_translate_edit_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state) {
|
||||
$filter_values = $this->translateFilterValues();
|
||||
$langcode = $filter_values['langcode'];
|
||||
|
||||
drupal_static_reset('language_list');
|
||||
$languages = language_list();
|
||||
|
||||
$langname = isset($langcode) ? $languages[$langcode]->name : "- None -";
|
||||
|
||||
$path = drupal_get_path('module', 'locale');
|
||||
$form['#attached']['css'] = array(
|
||||
$path . '/css/locale.admin.css',
|
||||
);
|
||||
$form['#attached']['library'][] = array('locale', 'drupal.locale.admin');
|
||||
|
||||
$form['langcode'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $filter_values['langcode'],
|
||||
);
|
||||
|
||||
$form['strings'] = array(
|
||||
'#type' => 'item',
|
||||
'#tree' => TRUE,
|
||||
'#language' => $langname,
|
||||
'#theme' => 'locale_translate_edit_form_strings',
|
||||
);
|
||||
|
||||
if (isset($langcode)) {
|
||||
$strings = $this->translateFilterLoadStrings();
|
||||
|
||||
$plural_formulas = $this->state->get('locale.translation.plurals') ?: array();
|
||||
|
||||
foreach ($strings as $string) {
|
||||
// Cast into source string, will do for our purposes.
|
||||
$source = new SourceString($string);
|
||||
// Split source to work with plural values.
|
||||
$source_array = $source->getPlurals();
|
||||
$translation_array = $string->getPlurals();
|
||||
if (count($source_array) == 1) {
|
||||
// Add original string value and mark as non-plural.
|
||||
$form['strings'][$string->lid]['plural'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => 0,
|
||||
);
|
||||
$form['strings'][$string->lid]['original'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => $this->t('Source string (@language)', array('@language' => $this->t('Built-in English'))),
|
||||
'#title_display' => 'invisible',
|
||||
'#markup' => '<span lang="en">' . String::checkPlain($source_array[0]) . '</span>',
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Add original string value and mark as plural.
|
||||
$form['strings'][$string->lid]['plural'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => 1,
|
||||
);
|
||||
$form['strings'][$string->lid]['original_singular'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => $this->t('Singular form'),
|
||||
'#markup' => '<span lang="en">' . String::checkPlain($source_array[0]) . '</span>',
|
||||
'#prefix' => '<span class="visually-hidden">' . $this->t('Source string (@language)', array('@language' => $this->t('Built-in English'))) . '</span>'
|
||||
);
|
||||
$form['strings'][$string->lid]['original_plural'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => $this->t('Plural form'),
|
||||
'#markup' => '<span lang="en">' . String::checkPlain($source_array[1]) . '</span>',
|
||||
);
|
||||
}
|
||||
if (!empty($string->context)) {
|
||||
$form['strings'][$string->lid]['context'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => '<span lang="en">' . String::checkPlain($string->context) . '</span>',
|
||||
);
|
||||
}
|
||||
// Approximate the number of rows to use in the default textarea.
|
||||
$rows = min(ceil(str_word_count($source_array[0]) / 12), 10);
|
||||
if (empty($form['strings'][$string->lid]['plural']['#value'])) {
|
||||
$form['strings'][$string->lid]['translations'][0] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => $this->t('Translated string (@language)', array('@language' => $langname)),
|
||||
'#title_display' => 'invisible',
|
||||
'#rows' => $rows,
|
||||
'#default_value' => $translation_array[0],
|
||||
'#attributes' => array('lang' => $langcode),
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Dealing with plural strings.
|
||||
if (isset($plural_formulas[$langcode]['plurals']) && $plural_formulas[$langcode]['plurals'] > 2) {
|
||||
// Add a textarea for each plural variant.
|
||||
for ($i = 0; $i < $plural_formulas[$langcode]['plurals']; $i++) {
|
||||
$form['strings'][$string->lid]['translations'][$i] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => ($i == 0 ? $this->t('Singular form') : format_plural($i, 'First plural form', '@count. plural form')),
|
||||
'#rows' => $rows,
|
||||
'#default_value' => isset($translation_array[$i]) ? $translation_array[$i] : '',
|
||||
'#attributes' => array('lang' => $langcode),
|
||||
'#prefix' => $i == 0 ? ('<span class="visually-hidden">' . $this->t('Translated string (@language)', array('@language' => $langname)) . '</span>') : '',
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Fallback for unknown number of plurals.
|
||||
$form['strings'][$string->lid]['translations'][0] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => $this->t('Singular form'),
|
||||
'#rows' => $rows,
|
||||
'#default_value' => $translation_array[0],
|
||||
'#attributes' => array('lang' => $langcode),
|
||||
'#prefix' => '<span class="visually-hidden">' . $this->t('Translated string (@language)', array('@language' => $langname)) . '</span>',
|
||||
);
|
||||
$form['strings'][$string->lid]['translations'][1] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => $this->t('Plural form'),
|
||||
'#rows' => $rows,
|
||||
'#default_value' => isset($translation_array[1]) ? $translation_array[1] : '',
|
||||
'#attributes' => array('lang' => $langcode),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count(element_children($form['strings']))) {
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Save translations'),
|
||||
);
|
||||
}
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, array &$form_state) {
|
||||
$langcode = $form_state['values']['langcode'];
|
||||
foreach ($form_state['values']['strings'] as $lid => $translations) {
|
||||
foreach ($translations['translations'] as $key => $value) {
|
||||
if (!locale_string_is_safe($value)) {
|
||||
form_set_error("strings][$lid][translations][$key", $this->t('The submitted string contains disallowed HTML: %string', array('%string' => $value)));
|
||||
form_set_error("translations][$langcode][$key", $this->t('The submitted string contains disallowed HTML: %string', array('%string' => $value)));
|
||||
watchdog('locale', 'Attempted submission of a translation string with disallowed HTML: %string', array('%string' => $value), WATCHDOG_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
$langcode = $form_state['values']['langcode'];
|
||||
$updated = array();
|
||||
|
||||
// Preload all translations for strings in the form.
|
||||
$lids = array_keys($form_state['values']['strings']);
|
||||
$existing_translation_objects = array();
|
||||
foreach ($this->localeStorage->getTranslations(array('lid' => $lids, 'language' => $langcode, 'translated' => TRUE)) as $existing_translation_object) {
|
||||
$existing_translation_objects[$existing_translation_object->lid] = $existing_translation_object;
|
||||
}
|
||||
|
||||
foreach ($form_state['values']['strings'] as $lid => $new_translation) {
|
||||
$existing_translation = isset($existing_translation_objects[$lid]);
|
||||
|
||||
// Plural translations are saved in a delimited string. To be able to
|
||||
// compare the new strings with the existing strings a string in the same format is created.
|
||||
$new_translation_string_delimited = implode(LOCALE_PLURAL_DELIMITER, $new_translation['translations']);
|
||||
|
||||
// Generate an imploded string without delimiter, to be able to run
|
||||
// empty() on it.
|
||||
$new_translation_string = implode('', $new_translation['translations']);
|
||||
|
||||
$is_changed = FALSE;
|
||||
|
||||
if ($existing_translation && $existing_translation_objects[$lid]->translation != $new_translation_string_delimited) {
|
||||
// If there is an existing translation in the DB and the new translation
|
||||
// is not the same as the existing one.
|
||||
$is_changed = TRUE;
|
||||
}
|
||||
elseif (!$existing_translation && !empty($new_translation_string)) {
|
||||
// Newly entered translation.
|
||||
$is_changed = TRUE;
|
||||
}
|
||||
|
||||
if ($is_changed) {
|
||||
// Only update or insert if we have a value to use.
|
||||
$target = isset($existing_translation_objects[$lid]) ? $existing_translation_objects[$lid] : $this->localeStorage->createTranslation(array('lid' => $lid, 'language' => $langcode));
|
||||
$target->setPlurals($new_translation['translations'])
|
||||
->setCustomized()
|
||||
->save();
|
||||
$updated[] = $target->getId();
|
||||
}
|
||||
if (empty($new_translation_string) && isset($existing_translation_objects[$lid])) {
|
||||
// Empty new translation entered: remove existing entry from database.
|
||||
$existing_translation_objects[$lid]->delete();
|
||||
$updated[] = $lid;
|
||||
}
|
||||
}
|
||||
|
||||
drupal_set_message($this->t('The strings have been saved.'));
|
||||
|
||||
// Keep the user on the current pager page.
|
||||
$page = $this->getRequest()->query->get('page');
|
||||
if (isset($page)) {
|
||||
$form_state['redirect'] = array('admin/config/regional/translate', array('query' => array('page' => $page)));
|
||||
}
|
||||
|
||||
if ($updated) {
|
||||
// Clear cache and force refresh of JavaScript translations.
|
||||
_locale_refresh_translations(array($langcode), $updated);
|
||||
_locale_refresh_configuration(array($langcode), $updated);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
<?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';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
<?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 @@ class LocaleConfigTranslationTest extends WebTestBase {
|
|||
'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 @@ class LocaleConfigTranslationTest extends WebTestBase {
|
|||
'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 @@ class LocaleImportFunctionalTest extends WebTestBase {
|
|||
'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 @@ class LocaleImportFunctionalTest extends WebTestBase {
|
|||
'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 @@ class LocaleImportFunctionalTest extends WebTestBase {
|
|||
'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 @@ class LocaleImportFunctionalTest extends WebTestBase {
|
|||
'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.'), 'Customized string overwritten by imported string.');
|
||||
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ class LocaleImportFunctionalTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'untranslated',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
$this->assertText($str, 'Search found the string as untranslated.');
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,7 @@ class LocaleImportFunctionalTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'all',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
$this->assertText($config_string[1], format_string('Translation of @string found.', array('@string' => $config_string[0])));
|
||||
}
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ class LocalePluralFormatTest extends WebTestBase {
|
|||
$search = array(
|
||||
'langcode' => 'fr',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
// Plural values for the langcode fr.
|
||||
$this->assertText('@count heure');
|
||||
$this->assertText('@count heures');
|
||||
|
@ -221,7 +221,7 @@ class LocalePluralFormatTest extends WebTestBase {
|
|||
'string' => '1 day',
|
||||
'langcode' => 'fr',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
|
||||
// Save complete translations for the string in langcode fr.
|
||||
$edit = array(
|
||||
|
@ -235,7 +235,7 @@ class LocalePluralFormatTest extends WebTestBase {
|
|||
'string' => '1 day',
|
||||
'langcode' => 'hr',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
|
||||
$edit = array(
|
||||
"strings[$lid][translations][0]" => '@count dan',
|
||||
|
|
|
@ -39,7 +39,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
$this->drupalLogin($admin_user);
|
||||
|
||||
$this->drupalPost('admin/config/regional/language/edit/en', array('locale_translate_english' => TRUE), t('Save language'));
|
||||
$this->assertLinkByHref('/admin/config/regional/translate/translate?langcode=en', 0, 'Enabled interface translation to English.');
|
||||
$this->assertLinkByHref('/admin/config/regional/translate?langcode=en', 0, 'Enabled interface translation to English.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,7 +87,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'untranslated',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
$this->assertText($name, 'Search found the string as untranslated.');
|
||||
|
||||
// Assume this is the only result, given the random name.
|
||||
|
@ -105,7 +105,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
$this->drupalPost('admin/config/regional/language/edit/en', array('locale_translate_english' => TRUE), t('Save language'));
|
||||
$this->drupalLogout();
|
||||
$this->drupalLogin($translate_user);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
$this->assertText($name, 'Search found the string as untranslated.');
|
||||
|
||||
// Assume this is the only result, given the random name.
|
||||
|
@ -114,15 +114,15 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
$edit = array(
|
||||
$lid => $translation,
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
|
||||
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
|
||||
$this->assertText(t('The strings have been saved.'), 'The strings have been saved.');
|
||||
$this->assertEqual($this->getUrl(), url('admin/config/regional/translate/translate', array('absolute' => TRUE)), 'Correct page redirection.');
|
||||
$this->assertEqual($this->getUrl(), url('admin/config/regional/translate', array('absolute' => TRUE)), 'Correct page redirection.');
|
||||
$search = array(
|
||||
'string' => $name,
|
||||
'langcode' => $langcode,
|
||||
'translation' => 'translated',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
$this->assertRaw($translation, 'Non-English translation properly saved.');
|
||||
|
||||
|
||||
|
@ -131,19 +131,19 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => 'en',
|
||||
'translation' => 'untranslated',
|
||||
);
|
||||
$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 => $translation_to_en,
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
|
||||
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
|
||||
$search = array(
|
||||
'string' => $name,
|
||||
'langcode' => 'en',
|
||||
'translation' => 'translated',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
$this->assertRaw($translation_to_en, 'English translation properly saved.');
|
||||
|
||||
// Reset the tag cache on the tester side in order to pick up the call to
|
||||
|
@ -164,7 +164,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => 'en',
|
||||
'translation' => 'untranslated',
|
||||
);
|
||||
$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 is translated.');
|
||||
|
||||
$this->drupalLogout();
|
||||
|
@ -190,14 +190,14 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => 'en',
|
||||
'translation' => 'translated',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
// Assume this is the only result, given the random name.
|
||||
$textarea = current($this->xpath('//textarea'));
|
||||
$lid = (string) $textarea[0]['name'];
|
||||
$edit = array(
|
||||
$lid => '',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
|
||||
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
|
||||
$this->assertRaw($name, 'The strings have been saved.');
|
||||
$this->drupalLogin($translate_user);
|
||||
$search = array(
|
||||
|
@ -205,7 +205,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => 'en',
|
||||
'translation' => 'untranslated',
|
||||
);
|
||||
$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.'), 'The translation has been removed');
|
||||
}
|
||||
|
||||
|
@ -248,14 +248,14 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'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 => $this->randomName(),
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
|
||||
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
|
||||
|
||||
// Trigger JavaScript translation parsing and building.
|
||||
_locale_rebuild_js($langcode);
|
||||
|
@ -311,7 +311,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'all',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
// Find the edit path.
|
||||
|
||||
$textarea = current($this->xpath('//textarea'));
|
||||
|
@ -320,7 +320,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
$edit = array(
|
||||
$lid => $translation,
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
|
||||
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
|
||||
// Check for a form error on the textarea.
|
||||
$form_class = $this->xpath('//form[@id="locale-translate-edit-form"]//textarea/@class');
|
||||
$this->assertNotIdentical(FALSE, strpos($form_class[0], 'error'), 'The string was rejected as unsafe.');
|
||||
|
@ -380,7 +380,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'all',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
// assertText() seems to remove the input field where $name always could be
|
||||
// found, so this is not a false assert. See how assertNoText succeeds
|
||||
// later.
|
||||
|
@ -393,7 +393,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'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.'), "Search didn't find the string.");
|
||||
|
||||
// Ensure untranslated string appears if searching on 'only untranslated
|
||||
|
@ -403,7 +403,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'untranslated',
|
||||
);
|
||||
$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.'), 'Search found the string.');
|
||||
|
||||
// Add translation.
|
||||
|
@ -414,7 +414,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
$edit = array(
|
||||
$lid => $translation,
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
|
||||
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
|
||||
|
||||
// Ensure translated string does appear if searching on 'only
|
||||
// translated strings'.
|
||||
|
@ -423,7 +423,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'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.'), 'Search found the translation.');
|
||||
|
||||
// Ensure translated source string doesn't appear if searching on 'only
|
||||
|
@ -433,7 +433,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'untranslated',
|
||||
);
|
||||
$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.'), "Search didn't find the source string.");
|
||||
|
||||
// Ensure translated string doesn't appear if searching on 'only
|
||||
|
@ -443,7 +443,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'untranslated',
|
||||
);
|
||||
$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.'), "Search didn't find the translation.");
|
||||
|
||||
// Ensure translated string does appear if searching on the custom language.
|
||||
|
@ -452,7 +452,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'all',
|
||||
);
|
||||
$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.'), 'Search found the translation.');
|
||||
|
||||
// Ensure translated string doesn't appear if searching in System (English).
|
||||
|
@ -461,7 +461,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => 'yy',
|
||||
'translation' => 'all',
|
||||
);
|
||||
$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.'), "Search didn't find the translation.");
|
||||
|
||||
// Search for a string that isn't in the system.
|
||||
|
@ -471,7 +471,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'all',
|
||||
);
|
||||
$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.'), "Search didn't find the invalid string.");
|
||||
}
|
||||
|
||||
|
@ -508,7 +508,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'translation' => 'translated',
|
||||
'customized' => '0',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
|
||||
$source = $this->assertText($translation->getString(), 'Translation is found in search result.');
|
||||
|
||||
|
@ -518,7 +518,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
$edit = array(
|
||||
$lid => $translation->getString(),
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
|
||||
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
|
||||
|
||||
// Ensure unchanged translation string does appear if searching non-customized translation.
|
||||
$search = array(
|
||||
|
@ -527,7 +527,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'translation' => 'translated',
|
||||
'customized' => '0',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
$source = $this->assertText($string->getString(), 'Translation is not marked as customized.');
|
||||
|
||||
// Submit the translations with a new translation.
|
||||
|
@ -536,7 +536,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
$edit = array(
|
||||
$lid => $this->randomName(100),
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
|
||||
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
|
||||
|
||||
// Ensure changed translation string does appear if searching customized translation.
|
||||
$search = array(
|
||||
|
@ -545,7 +545,7 @@ class LocaleTranslationUiTest extends WebTestBase {
|
|||
'translation' => 'translated',
|
||||
'customized' => '1',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
$this->assertText($string->getString(), "Translation is marked as customized.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ class LocaleUninstallTest extends WebTestBase {
|
|||
// Build the JavaScript translation file for French.
|
||||
$user = $this->drupalCreateUser(array('translate interface', 'access administration pages'));
|
||||
$this->drupalLogin($user);
|
||||
$this->drupalGet('admin/config/regional/translate/translate');
|
||||
$this->drupalGet('admin/config/regional/translate');
|
||||
// Get any of the javascript strings to translate.
|
||||
$js_strings = $this->container->get('locale.storage')->getStrings(array('type' => 'javascript'));
|
||||
$string = reset($js_strings);
|
||||
|
|
|
@ -452,7 +452,7 @@ class LocaleUpdateTest extends LocaleUpdateBase {
|
|||
'langcode' => $langcode,
|
||||
'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 successfully imported.');
|
||||
|
||||
// Ensure the multiline string was imported.
|
||||
|
@ -461,7 +461,7 @@ class LocaleUpdateTest extends LocaleUpdateBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'all',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
$this->assertText('Multiline translation string to make sure that import works with it.', 'String successfully imported.');
|
||||
|
||||
// Ensure 'Allowed HTML source string' was imported but the translation for
|
||||
|
@ -472,7 +472,7 @@ class LocaleUpdateTest extends LocaleUpdateBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'all',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
$this->assertText('Allowed HTML source string', 'String successfully imported.');
|
||||
$this->assertNoText('Another allowed HTML source string', 'String with disallowed translation not imported.');
|
||||
}
|
||||
|
|
|
@ -173,9 +173,7 @@ function locale_menu() {
|
|||
$items['admin/config/regional/translate'] = array(
|
||||
'title' => 'User interface translation',
|
||||
'description' => 'Translate the built-in user interface.',
|
||||
'page callback' => 'locale_translate_page',
|
||||
'access arguments' => array('translate interface'),
|
||||
'file' => 'locale.pages.inc',
|
||||
'route_name' => 'locale_translate_page',
|
||||
'weight' => -5,
|
||||
);
|
||||
$items['admin/config/regional/translate/translate'] = array(
|
||||
|
@ -203,7 +201,6 @@ function locale_menu() {
|
|||
$items['admin/config/regional/translate/settings'] = array(
|
||||
'title' => 'Settings',
|
||||
'route_name' => 'locale_settings',
|
||||
'access arguments' => array('translate interface'),
|
||||
'weight' => 100,
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
);
|
||||
|
@ -758,7 +755,7 @@ function locale_form_language_admin_overview_form_alter(&$form, &$form_state) {
|
|||
'@total' => $total_strings,
|
||||
'@ratio' => $stats[$langcode]['ratio'],
|
||||
)),
|
||||
'admin/config/regional/translate/translate',
|
||||
'admin/config/regional/translate',
|
||||
array('query' => array('langcode' => $langcode))
|
||||
),
|
||||
);
|
||||
|
|
|
@ -13,460 +13,27 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
|
|||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Page callback: Shows the string search screen.
|
||||
* Page callback: Checks for translation updates and displays the status.
|
||||
*
|
||||
* Manually checks the translation status without the use of cron.
|
||||
*
|
||||
* @see locale_menu()
|
||||
*/
|
||||
function locale_translate_page() {
|
||||
return array(
|
||||
'filter' => drupal_get_form('locale_translate_filter_form'),
|
||||
'form' => drupal_get_form('locale_translate_edit_form'),
|
||||
);
|
||||
}
|
||||
function locale_translation_manual_status() {
|
||||
module_load_include('compare.inc', 'locale');
|
||||
|
||||
/**
|
||||
* Builds a string search query and returns an array of string objects.
|
||||
*
|
||||
* @return array
|
||||
* Array of Drupal\locale\TranslationString objects.
|
||||
*/
|
||||
function locale_translate_filter_load_strings() {
|
||||
$filter_values = locale_translate_filter_values();
|
||||
|
||||
// Language is sanitized to be one of the possible options in
|
||||
// locale_translate_filter_values().
|
||||
$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;
|
||||
// Check the translation status of all translatable projects in all languages.
|
||||
// First we clear the cached list of projects. Although not strictly
|
||||
// necessary, this is helpful in case the project list is out of sync.
|
||||
locale_translation_flush_projects();
|
||||
locale_translation_check_projects();
|
||||
|
||||
// Execute a batch if required. A batch is only used when remote files
|
||||
// are checked.
|
||||
if (batch_get()) {
|
||||
return batch_process('admin/reports/translations');
|
||||
}
|
||||
|
||||
if (!empty($filter_values['string'])) {
|
||||
$options['filters']['source'] = $filter_values['string'];
|
||||
if ($options['translated']) {
|
||||
$options['filters']['translation'] = $filter_values['string'];
|
||||
}
|
||||
}
|
||||
|
||||
return Drupal::service('locale.storage')->getTranslations($conditions, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build array out of search criteria specified in request variables.
|
||||
*/
|
||||
function locale_translate_filter_values() {
|
||||
$filter_values = &drupal_static(__FUNCTION__);
|
||||
if (!isset($filter_values)) {
|
||||
$filter_values = array();
|
||||
$filters = locale_translate_filters();
|
||||
foreach ($filters as $key => $filter) {
|
||||
$filter_values[$key] = $filter['default'];
|
||||
// Let the filter defaults be overwritten by parameters in the URL.
|
||||
if (isset($_GET[$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'][$_GET[$key]])) {
|
||||
$filter_values[$key] = $_GET[$key];
|
||||
}
|
||||
}
|
||||
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 $filter_values;
|
||||
}
|
||||
|
||||
/**
|
||||
* List locale translation filters that can be applied.
|
||||
*/
|
||||
function locale_translate_filters() {
|
||||
$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 = language(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' => t('String contains'),
|
||||
'description' => t('Leave blank to show all strings. The search is case sensitive.'),
|
||||
'default' => '',
|
||||
);
|
||||
|
||||
$filters['langcode'] = array(
|
||||
'title' => t('Translation language'),
|
||||
'options' => $language_options,
|
||||
'default' => $default_langcode,
|
||||
);
|
||||
|
||||
$filters['translation'] = array(
|
||||
'title' => t('Search in'),
|
||||
'options' => array(
|
||||
'all' => t('Both translated and untranslated strings'),
|
||||
'translated' => t('Only translated strings'),
|
||||
'untranslated' => t('Only untranslated strings'),
|
||||
),
|
||||
'default' => 'all',
|
||||
);
|
||||
|
||||
$filters['customized'] = array(
|
||||
'title' => t('Translation type'),
|
||||
'options' => array(
|
||||
'all' => t('All'),
|
||||
LOCALE_NOT_CUSTOMIZED => t('Non-customized translation'),
|
||||
LOCALE_CUSTOMIZED => t('Customized translation'),
|
||||
),
|
||||
'states' => array(
|
||||
'visible' => array(
|
||||
':input[name=translation]' => array('value' => 'translated'),
|
||||
),
|
||||
),
|
||||
'default' => 'all',
|
||||
);
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return form for locale translation filters.
|
||||
*
|
||||
* @ingroup forms
|
||||
*/
|
||||
function locale_translate_filter_form($form, &$form_state) {
|
||||
$filters = locale_translate_filters();
|
||||
$filter_values = locale_translate_filter_values();
|
||||
|
||||
$form['#attached']['css'] = array(
|
||||
drupal_get_path('module', 'locale') . '/css/locale.admin.css',
|
||||
);
|
||||
|
||||
$form['filters'] = array(
|
||||
'#type' => 'details',
|
||||
'#title' => 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' => t('Filter'),
|
||||
);
|
||||
if (!empty($_SESSION['locale_translate_filter'])) {
|
||||
$form['filters']['actions']['reset'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Reset'),
|
||||
);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process result from locale translation filter form.
|
||||
*/
|
||||
function locale_translate_filter_form_submit($form, &$form_state) {
|
||||
$op = $form_state['values']['op'];
|
||||
$filters = locale_translate_filters();
|
||||
switch ($op) {
|
||||
case t('Filter'):
|
||||
foreach ($filters as $name => $filter) {
|
||||
if (isset($form_state['values'][$name])) {
|
||||
$_SESSION['locale_translate_filter'][$name] = $form_state['values'][$name];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case t('Reset'):
|
||||
$_SESSION['locale_translate_filter'] = array();
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
$form_state['redirect'] = 'admin/config/regional/translate/translate';
|
||||
}
|
||||
|
||||
/**
|
||||
* Form constructor for the string editing form.
|
||||
*
|
||||
* @see locale_menu()
|
||||
* @see locale_translate_edit_form_validate()
|
||||
* @see locale_translate_edit_form_submit()
|
||||
*
|
||||
* @ingroup forms
|
||||
*/
|
||||
function locale_translate_edit_form($form, &$form_state) {
|
||||
$filter_values = locale_translate_filter_values();
|
||||
$langcode = $filter_values['langcode'];
|
||||
|
||||
drupal_static_reset('language_list');
|
||||
$languages = language_list();
|
||||
|
||||
$langname = isset($langcode) ? $languages[$langcode]->name : "- None -";
|
||||
|
||||
$path = drupal_get_path('module', 'locale');
|
||||
$form['#attached']['css'] = array(
|
||||
$path . '/css/locale.admin.css',
|
||||
);
|
||||
$form['#attached']['library'][] = array('locale', 'drupal.locale.admin');
|
||||
|
||||
$form['langcode'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $filter_values['langcode'],
|
||||
);
|
||||
|
||||
$form['strings'] = array(
|
||||
'#type' => 'item',
|
||||
'#tree' => TRUE,
|
||||
'#language' => $langname,
|
||||
'#theme' => 'locale_translate_edit_form_strings',
|
||||
);
|
||||
|
||||
if (isset($langcode)) {
|
||||
$strings = locale_translate_filter_load_strings();
|
||||
|
||||
$plural_formulas = Drupal::state()->get('locale.translation.plurals') ?: array();
|
||||
|
||||
foreach ($strings as $string) {
|
||||
// Cast into source string, will do for our purposes.
|
||||
$source = new SourceString($string);
|
||||
// Split source to work with plural values.
|
||||
$source_array = $source->getPlurals();
|
||||
$translation_array = $string->getPlurals();
|
||||
if (count($source_array) == 1) {
|
||||
// Add original string value and mark as non-plural.
|
||||
$form['strings'][$string->lid]['plural'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => 0,
|
||||
);
|
||||
$form['strings'][$string->lid]['original'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Source string (@language)', array('@language' => t('Built-in English'))),
|
||||
'#title_display' => 'invisible',
|
||||
'#markup' => '<span lang="en">' . check_plain($source_array[0]) . '</span>',
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Add original string value and mark as plural.
|
||||
$form['strings'][$string->lid]['plural'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => 1,
|
||||
);
|
||||
$form['strings'][$string->lid]['original_singular'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Singular form'),
|
||||
'#markup' => '<span lang="en">' . check_plain($source_array[0]) . '</span>',
|
||||
'#prefix' => '<span class="visually-hidden">' . t('Source string (@language)', array('@language' => t('Built-in English'))) . '</span>',
|
||||
);
|
||||
$form['strings'][$string->lid]['original_plural'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Plural form'),
|
||||
'#markup' => '<span lang="en">' . check_plain($source_array[1]) . '</span>',
|
||||
);
|
||||
}
|
||||
if (!empty($string->context)) {
|
||||
$form['strings'][$string->lid]['context'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => '<span lang="en">' . check_plain($string->context) . '</span>',
|
||||
);
|
||||
}
|
||||
// Approximate the number of rows to use in the default textarea.
|
||||
$rows = min(ceil(str_word_count($source_array[0]) / 12), 10);
|
||||
if (empty($form['strings'][$string->lid]['plural']['#value'])) {
|
||||
$form['strings'][$string->lid]['translations'][0] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Translated string (@language)', array('@language' => $langname)),
|
||||
'#title_display' => 'invisible',
|
||||
'#rows' => $rows,
|
||||
'#default_value' => $translation_array[0],
|
||||
'#attributes' => array('lang' => $langcode),
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Dealing with plural strings.
|
||||
if (isset($plural_formulas[$langcode]['plurals']) && $plural_formulas[$langcode]['plurals'] > 2) {
|
||||
// Add a textarea for each plural variant.
|
||||
for ($i = 0; $i < $plural_formulas[$langcode]['plurals']; $i++) {
|
||||
$form['strings'][$string->lid]['translations'][$i] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => ($i == 0 ? t('Singular form') : format_plural($i, 'First plural form', '@count. plural form')),
|
||||
'#rows' => $rows,
|
||||
'#default_value' => isset($translation_array[$i]) ? $translation_array[$i] : '',
|
||||
'#attributes' => array('lang' => $langcode),
|
||||
'#prefix' => $i == 0 ? ('<span class="visually-hidden">' . t('Translated string (@language)', array('@language' => $langname)) . '</span>') : '',
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Fallback for unknown number of plurals.
|
||||
$form['strings'][$string->lid]['translations'][0] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Singular form'),
|
||||
'#rows' => $rows,
|
||||
'#default_value' => $translation_array[0],
|
||||
'#attributes' => array('lang' => $langcode),
|
||||
'#prefix' => '<span class="visually-hidden">' . t('Translated string (@language)', array('@language' => $langname)) . '</span>',
|
||||
);
|
||||
$form['strings'][$string->lid]['translations'][1] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Plural form'),
|
||||
'#rows' => $rows,
|
||||
'#default_value' => isset($translation_array[1]) ? $translation_array[1] : '',
|
||||
'#attributes' => array('lang' => $langcode),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count(element_children($form['strings']))) {
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save translations'));
|
||||
}
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form validation handler for locale_translate_edit_form().
|
||||
*
|
||||
* @see locale_translate_edit_form_submit()
|
||||
*/
|
||||
function locale_translate_edit_form_validate($form, &$form_state) {
|
||||
$langcode = $form_state['values']['langcode'];
|
||||
foreach ($form_state['values']['strings'] as $lid => $translations) {
|
||||
foreach ($translations['translations'] as $key => $value) {
|
||||
if (!locale_string_is_safe($value)) {
|
||||
form_set_error("strings][$lid][translations][$key", t('The submitted string contains disallowed HTML: %string', array('%string' => $value)));
|
||||
form_set_error("translations][$langcode][$key", t('The submitted string contains disallowed HTML: %string', array('%string' => $value)));
|
||||
watchdog('locale', 'Attempted submission of a translation string with disallowed HTML: %string', array('%string' => $value), WATCHDOG_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form submission handler for locale_translate_edit_form().
|
||||
*
|
||||
* @see locale_translate_edit_form_validate()
|
||||
*/
|
||||
function locale_translate_edit_form_submit($form, &$form_state) {
|
||||
$langcode = $form_state['values']['langcode'];
|
||||
$updated = array();
|
||||
|
||||
// Preload all translations for strings in the form.
|
||||
$lids = array_keys($form_state['values']['strings']);
|
||||
$existing_translation_objects = array();
|
||||
foreach (Drupal::service('locale.storage')->getTranslations(array('lid' => $lids, 'language' => $langcode, 'translated' => TRUE)) as $existing_translation_object) {
|
||||
$existing_translation_objects[$existing_translation_object->lid] = $existing_translation_object;
|
||||
}
|
||||
|
||||
foreach ($form_state['values']['strings'] as $lid => $new_translation) {
|
||||
$existing_translation = isset($existing_translation_objects[$lid]);
|
||||
|
||||
// Plural translations are saved in a delimited string. To be able to
|
||||
// compare the new strings with the existing strings a string in the same format is created.
|
||||
$new_translation_string_delimited = implode(LOCALE_PLURAL_DELIMITER, $new_translation['translations']);
|
||||
|
||||
// Generate an imploded string without delimiter, to be able to run
|
||||
// empty() on it.
|
||||
$new_translation_string = implode('', $new_translation['translations']);
|
||||
|
||||
$is_changed = FALSE;
|
||||
|
||||
if ($existing_translation && $existing_translation_objects[$lid]->translation != $new_translation_string_delimited) {
|
||||
// If there is an existing translation in the DB and the new translation
|
||||
// is not the same as the existing one.
|
||||
$is_changed = TRUE;
|
||||
}
|
||||
elseif (!$existing_translation && !empty($new_translation_string)) {
|
||||
// Newly entered translation.
|
||||
$is_changed = TRUE;
|
||||
}
|
||||
|
||||
if ($is_changed) {
|
||||
// Only update or insert if we have a value to use.
|
||||
$target = isset($existing_translation_objects[$lid]) ? $existing_translation_objects[$lid] : Drupal::service('locale.storage')->createTranslation(array('lid' => $lid, 'language' => $langcode));
|
||||
$target->setPlurals($new_translation['translations'])
|
||||
->setCustomized()
|
||||
->save();
|
||||
$updated[] = $target->getId();
|
||||
}
|
||||
if (empty($new_translation_string) && isset($existing_translation_objects[$lid])) {
|
||||
// Empty new translation entered: remove existing entry from database.
|
||||
$existing_translation_objects[$lid]->delete();
|
||||
$updated[] = $lid;
|
||||
}
|
||||
}
|
||||
|
||||
drupal_set_message(t('The strings have been saved.'));
|
||||
|
||||
// Keep the user on the current pager page.
|
||||
if (isset($_GET['page'])) {
|
||||
$form_state['redirect'] = array('admin/config/regional/translate', array('query' => array('page' => $_GET['page'])));
|
||||
}
|
||||
|
||||
if ($updated) {
|
||||
// Clear cache and refresh configuration and JavaScript translations.
|
||||
_locale_refresh_translations(array($langcode), $updated);
|
||||
_locale_refresh_configuration(array($langcode), $updated);
|
||||
}
|
||||
|
||||
return new RedirectResponse(url('admin/reports/translations', array('absolute' => TRUE)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,3 +11,10 @@ locale_check_translation:
|
|||
_controller: 'Drupal\locale\Controller\LocaleController::checkTranslation'
|
||||
requirements:
|
||||
_permission: 'translate interface'
|
||||
|
||||
locale_translate_page:
|
||||
pattern: '/admin/config/regional/translate'
|
||||
defaults:
|
||||
_content: 'Drupal\locale\Controller\LocaleController::translatePage'
|
||||
requirements:
|
||||
_permission: 'translate interface'
|
||||
|
|
|
@ -59,7 +59,7 @@ class ToolbarMenuTranslationTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'untranslated',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
// Make sure will be able to translate the menu item.
|
||||
$this->assertNoText('No strings available.', 'Search found the menu item as untranslated.');
|
||||
|
||||
|
@ -74,7 +74,7 @@ class ToolbarMenuTranslationTest extends WebTestBase {
|
|||
$edit = array(
|
||||
$lid => $menu_item_translated,
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
|
||||
$this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
|
||||
|
||||
// Search for the translated menu item.
|
||||
$search = array(
|
||||
|
@ -82,7 +82,7 @@ class ToolbarMenuTranslationTest extends WebTestBase {
|
|||
'langcode' => $langcode,
|
||||
'translation' => 'translated',
|
||||
);
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
|
||||
// Make sure the menu item string was translated.
|
||||
$this->assertText($menu_item_translated, 'Search found the menu item as translated: ' . $menu_item_translated . '.');
|
||||
|
||||
|
|
Loading…
Reference in New Issue