class TranslateEditForm
Same name in other branches
- 9 core/modules/locale/src/Form/TranslateEditForm.php \Drupal\locale\Form\TranslateEditForm
- 8.9.x core/modules/locale/src/Form/TranslateEditForm.php \Drupal\locale\Form\TranslateEditForm
- 11.x core/modules/locale/src/Form/TranslateEditForm.php \Drupal\locale\Form\TranslateEditForm
Defines a translation edit form.
@internal
Hierarchy
- class \Drupal\Core\Form\FormBase implements \Drupal\Core\Form\FormInterface, \Drupal\Core\DependencyInjection\ContainerInjectionInterface uses \Drupal\Core\DependencyInjection\DependencySerializationTrait, \Drupal\Core\Logger\LoggerChannelTrait, \Drupal\Core\Messenger\MessengerTrait, \Drupal\Core\Routing\RedirectDestinationTrait, \Drupal\Core\StringTranslation\StringTranslationTrait
- class \Drupal\locale\Form\TranslateFormBase extends \Drupal\Core\Form\FormBase
- class \Drupal\locale\Form\TranslateEditForm extends \Drupal\locale\Form\TranslateFormBase
- class \Drupal\locale\Form\TranslateFormBase extends \Drupal\Core\Form\FormBase
Expanded class hierarchy of TranslateEditForm
File
-
core/
modules/ locale/ src/ Form/ TranslateEditForm.php, line 15
Namespace
Drupal\locale\FormView source
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();
$language_name = isset($langcode) ? $languages[$langcode]->getName() : "- None -";
$form['#attached']['library'][] = 'locale/drupal.locale.admin';
$form['langcode'] = [
'#type' => 'value',
'#value' => $filter_values['langcode'],
];
$form['strings'] = [
'#type' => 'table',
'#tree' => TRUE,
'#language' => $language_name,
'#header' => [
$this->t('Source string'),
$this->t('Translation for @language', [
'@language' => $language_name,
]),
],
'#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'] = [
'#type' => 'item',
'#title' => $this->t('Source string (@language)', [
'@language' => $this->t('Built-in English'),
]),
'#title_display' => 'invisible',
'#plain_text' => $source_array[0],
'#prefix' => '<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)', [
'@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],
'#prefix' => '<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] = [
'#type' => 'textarea',
'#title' => $this->t('Translated string (@language)', [
'@language' => $language_name,
]),
'#title_display' => 'invisible',
'#rows' => $rows,
'#default_value' => $translation_array[0],
'#attributes' => [
'lang' => $langcode,
],
];
}
else {
// Add a textarea for each plural variant.
for ($i = 0; $i < $plurals; $i++) {
$form['strings'][$string->lid]['translations'][$i] = [
'#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' => $translation_array[$i] ?? '',
'#attributes' => [
'lang' => $langcode,
],
'#prefix' => $i == 0 ? '<span class="visually-hidden">' . $this->t('Translated string (@language)', [
'@language' => $language_name,
]) . '</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'] = [
'#type' => 'actions',
];
$form['actions']['submit'] = [
'#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', [
'%string' => $value,
]));
$form_state->setErrorByName("translations][{$langcode}][{$key}", $this->t('The submitted string contains disallowed HTML: %string', [
'%string' => $value,
]));
$this->logger('locale')
->warning('Attempted submission of a translation string with disallowed HTML: %string', [
'%string' => $value,
]);
}
}
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$langcode = $form_state->getValue('langcode');
$updated = [];
// Preload all translations for strings in the form.
$lids = array_keys($form_state->getValue('strings'));
$existing_translation_objects = [];
foreach ($this->localeStorage
->getTranslations([
'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(PoItem::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 = $existing_translation_objects[$lid] ?? $this->localeStorage
->createTranslation([
'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;
}
}
$this->messenger()
->addStatus($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', [], [
'page' => $page,
]);
}
if ($updated) {
// Clear cache and force refresh of JavaScript translations.
_locale_refresh_translations([
$langcode,
], $updated);
_locale_refresh_configuration([
$langcode,
], $updated);
}
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title | Overrides |
---|---|---|---|---|---|
DependencySerializationTrait::$_entityStorages | protected | property | |||
DependencySerializationTrait::$_serviceIds | protected | property | |||
DependencySerializationTrait::__sleep | public | function | 1 | ||
DependencySerializationTrait::__wakeup | public | function | 2 | ||
FormBase::$configFactory | protected | property | The config factory. | 3 | |
FormBase::$requestStack | protected | property | The request stack. | 1 | |
FormBase::$routeMatch | protected | property | The route match. | ||
FormBase::config | protected | function | Retrieves a configuration object. | ||
FormBase::configFactory | protected | function | Gets the config factory for this form. | 3 | |
FormBase::container | private | function | Returns the service container. | ||
FormBase::currentUser | protected | function | Gets the current user. | 2 | |
FormBase::getRequest | protected | function | Gets the request object. | ||
FormBase::getRouteMatch | protected | function | Gets the route match. | ||
FormBase::logger | protected | function | Gets the logger for a specific channel. | ||
FormBase::redirect | protected | function | Returns a redirect response object for the specified route. | ||
FormBase::resetConfigFactory | public | function | Resets the configuration factory. | ||
FormBase::setConfigFactory | public | function | Sets the config factory for this form. | ||
FormBase::setRequestStack | public | function | Sets the request stack object to use. | ||
LoggerChannelTrait::$loggerFactory | protected | property | The logger channel factory service. | ||
LoggerChannelTrait::getLogger | protected | function | Gets the logger for a specific channel. | ||
LoggerChannelTrait::setLoggerFactory | public | function | Injects the logger channel factory. | ||
MessengerTrait::$messenger | protected | property | The messenger. | 16 | |
MessengerTrait::messenger | public | function | Gets the messenger. | 16 | |
MessengerTrait::setMessenger | public | function | Sets the messenger. | ||
RedirectDestinationTrait::$redirectDestination | protected | property | The redirect destination service. | 2 | |
RedirectDestinationTrait::getDestinationArray | protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | ||
RedirectDestinationTrait::getRedirectDestination | protected | function | Returns the redirect destination service. | ||
RedirectDestinationTrait::setRedirectDestination | public | function | Sets the redirect destination service. | ||
StringTranslationTrait::$stringTranslation | protected | property | The string translation service. | 3 | |
StringTranslationTrait::formatPlural | protected | function | Formats a string containing a count of items. | ||
StringTranslationTrait::getNumberOfPlurals | protected | function | Returns the number of plurals supported by a given language. | ||
StringTranslationTrait::getStringTranslation | protected | function | Gets the string translation service. | ||
StringTranslationTrait::setStringTranslation | public | function | Sets the string translation service to use. | 2 | |
StringTranslationTrait::t | protected | function | Translates a string to the current language or to a given language. | ||
TranslateEditForm::buildForm | public | function | Form constructor. | Overrides FormInterface::buildForm | |
TranslateEditForm::getFormId | public | function | Returns a unique string identifying the form. | Overrides FormInterface::getFormId | |
TranslateEditForm::submitForm | public | function | Form submission handler. | Overrides FormInterface::submitForm | |
TranslateEditForm::validateForm | public | function | Form validation handler. | Overrides FormBase::validateForm | |
TranslateFormBase::$filterValues | protected static | property | Filter values. Shared between objects that inherit this class. | ||
TranslateFormBase::$languageManager | protected | property | The language manager. | ||
TranslateFormBase::$localeStorage | protected | property | The locale storage. | ||
TranslateFormBase::$state | protected | property | The state store. | ||
TranslateFormBase::create | public static | function | Instantiates a new instance of this class. | Overrides FormBase::create | |
TranslateFormBase::translateFilterLoadStrings | protected | function | Builds a string search query and returns an array of string objects. | ||
TranslateFormBase::translateFilters | protected | function | Lists locale translation filters that can be applied. | ||
TranslateFormBase::translateFilterValues | protected | function | Builds an array out of search criteria specified in request variables. | ||
TranslateFormBase::__construct | public | function | Constructs a new TranslationFormBase object. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.