Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 166 |
TranslateEditForm | |
0.00% |
0 / 1 |
|
0.00% |
0 / 4 |
992 | |
0.00% |
0 / 166 |
getFormId | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
buildForm | |
0.00% |
0 / 1 |
182 | |
0.00% |
0 / 109 |
|||
validateForm | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 11 |
|||
submitForm | |
0.00% |
0 / 1 |
182 | |
0.00% |
0 / 44 |
<?php | |
/** | |
* @file | |
* Contains \Drupal\locale\Form\TranslateEditForm. | |
*/ | |
namespace Drupal\locale\Form; | |
use Drupal\Core\Form\FormStateInterface; | |
use Drupal\Core\Render\Element; | |
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, FormStateInterface $form_state) { | |
$filter_values = $this->translateFilterValues(); | |
$langcode = $filter_values['langcode']; | |
$this->languageManager->reset(); | |
$languages = $this->languageManager->getLanguages(); | |
$langname = isset($langcode) ? $languages[$langcode]->getName() : "- None -"; | |
$form['#attached']['library'][] = 'locale/drupal.locale.admin'; | |
$form['langcode'] = array( | |
'#type' => 'value', | |
'#value' => $filter_values['langcode'], | |
); | |
$form['strings'] = array( | |
'#type' => 'table', | |
'#tree' => TRUE, | |
'#language' => $langname, | |
'#header' => [ | |
$this->t('Source string'), | |
$this->t('Translation for @language', ['@language' => $langname]), | |
], | |
'#empty' => $this->t('No strings available.'), | |
'#attributes' => ['class' => ['locale-translate-edit-table']], | |
); | |
if (isset($langcode)) { | |
$strings = $this->translateFilterLoadStrings(); | |
$plurals = $this->getNumberOfPlurals($langcode); | |
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. | |
$plural = FALSE; | |
$form['strings'][$string->lid]['original'] = array( | |
'#type' => 'item', | |
'#title' => $this->t('Source string (@language)', array('@language' => $this->t('Built-in English'))), | |
'#title_display' => 'invisible', | |
'#plain_text' => $source_array[0], | |
'#preffix' => '<span lang="en">', | |
'#suffix' => '</span>', | |
); | |
} | |
else { | |
// Add original string value and mark as plural. | |
$plural = TRUE; | |
$original_singular = [ | |
'#type' => 'item', | |
'#title' => $this->t('Singular form'), | |
'#plain_text' => $source_array[0], | |
'#prefix' => '<span class="visually-hidden">' . $this->t('Source string (@language)', array('@language' => $this->t('Built-in English'))) . '</span><span lang="en">', | |
'#suffix' => '</span>', | |
]; | |
$original_plural = [ | |
'#type' => 'item', | |
'#title' => $this->t('Plural form'), | |
'#plain_text' => $source_array[1], | |
'#preffix' => '<span lang="en">', | |
'#suffix' => '</span>', | |
]; | |
$form['strings'][$string->lid]['original'] = [ | |
$original_singular, | |
['#markup' => '<br>'], | |
$original_plural, | |
]; | |
} | |
if (!empty($string->context)) { | |
$form['strings'][$string->lid]['original'][] = [ | |
'#type' => 'inline_template', | |
'#template' => '<br><small>{{ context_title }}: <span lang="en">{{ context }}</span></small>', | |
'#context' => [ | |
'context_title' => $this->t('In Context'), | |
'context' => $string->context, | |
], | |
]; | |
} | |
// Approximate the number of rows to use in the default textarea. | |
$rows = min(ceil(str_word_count($source_array[0]) / 12), 10); | |
if (!$plural) { | |
$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 { | |
// Add a textarea for each plural variant. | |
for ($i = 0; $i < $plurals; $i++) { | |
$form['strings'][$string->lid]['translations'][$i] = array( | |
'#type' => 'textarea', | |
// @todo Should use better labels https://www.drupal.org/node/2499639 | |
'#title' => ($i == 0 ? $this->t('Singular form') : $this->formatPlural($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>') : '', | |
); | |
} | |
if ($plurals == 2) { | |
// Simplify interface text for the most common case. | |
$form['strings'][$string->lid]['translations'][1]['#title'] = $this->t('Plural form'); | |
} | |
} | |
} | |
if (count(Element::children($form['strings']))) { | |
$form['actions'] = array('#type' => 'actions'); | |
$form['actions']['submit'] = array( | |
'#type' => 'submit', | |
'#value' => $this->t('Save translations'), | |
); | |
} | |
} | |
$form['pager']['#type'] = 'pager'; | |
return $form; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function validateForm(array &$form, FormStateInterface $form_state) { | |
$langcode = $form_state->getValue('langcode'); | |
foreach ($form_state->getValue('strings') as $lid => $translations) { | |
foreach ($translations['translations'] as $key => $value) { | |
if (!locale_string_is_safe($value)) { | |
$form_state->setErrorByName("strings][$lid][translations][$key", $this->t('The submitted string contains disallowed HTML: %string', array('%string' => $value))); | |
$form_state->setErrorByName("translations][$langcode][$key", $this->t('The submitted string contains disallowed HTML: %string', array('%string' => $value))); | |
$this->logger('locale')->warning('Attempted submission of a translation string with disallowed HTML: %string', array('%string' => $value)); | |
} | |
} | |
} | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function submitForm(array &$form, FormStateInterface $form_state) { | |
$langcode = $form_state->getValue('langcode'); | |
$updated = array(); | |
// Preload all translations for strings in the form. | |
$lids = array_keys($form_state->getValue('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->getValue('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->setRedirect( | |
'locale.translate_page', | |
array(), | |
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); | |
} | |
} | |
} |