Update Composer, update everything

This commit is contained in:
Oliver Davies 2018-11-23 12:29:20 +00:00
parent ea3e94409f
commit dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions

View file

@ -5,7 +5,7 @@ javascript:
translation:
use_source: remote_and_local
default_filename: '%project-%version.%language.po'
default_server_pattern: 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po'
default_server_pattern: 'https://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po'
overwrite_customized: false
overwrite_not_customized: true
update_interval_days: 0

View file

@ -37,7 +37,7 @@
table-layout: fixed;
}
.locale-translate-edit-form td {
vertical-align: top
vertical-align: top;
}
.locale-translate-edit-form tr.changed {
@ -49,7 +49,7 @@
}
.locale-translate-filter-form .form-wrapper {
margin-bottom:0;
margin-bottom: 0;
}
.locale-translate-edit-form table.changed {
@ -68,18 +68,16 @@
#locale-translation-status-form th.title {
width: 25%;
}
#locale-translation-status-form th.description {
}
#locale-translation-status-form td {
vertical-align: top;
}
.locale-translation-update__wrapper {
background: transparent url(../../../misc/menu-collapsed.png) left .6em no-repeat;
background: transparent url(../../../misc/menu-collapsed.png) left 0.6em no-repeat;
margin-left: -12px;
padding-left: 12px;
}
.expanded .locale-translation-update__wrapper {
background: transparent url(../../../misc/menu-expanded.png) left .6em no-repeat;
background: transparent url(../../../misc/menu-expanded.png) left 0.6em no-repeat;
}
#locale-translation-status-form .description {
cursor: pointer;
@ -125,6 +123,7 @@
margin: 0 0 0.25em 1.5em;
padding: 0;
}
@media screen and (max-width: 40em) {
#locale-translation-status-form th.title {
width: 20%;

View file

@ -0,0 +1,129 @@
/**
* @file
* Locale admin behavior.
*/
(function($, Drupal) {
/**
* Marks changes of translations.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches behavior to show the user if translations has changed.
* @prop {Drupal~behaviorDetach} detach
* Detach behavior to show the user if translations has changed.
*/
Drupal.behaviors.localeTranslateDirty = {
attach() {
const $form = $('#locale-translate-edit-form').once(
'localetranslatedirty',
);
if ($form.length) {
// Display a notice if any row changed.
$form.one('formUpdated.localeTranslateDirty', 'table', function() {
const $marker = $(
Drupal.theme('localeTranslateChangedWarning'),
).hide();
$(this)
.addClass('changed')
.before($marker);
$marker.fadeIn('slow');
});
// Highlight changed row.
$form.on('formUpdated.localeTranslateDirty', 'tr', function() {
const $row = $(this);
const $rowToMark = $row.once('localemark');
const marker = Drupal.theme('localeTranslateChangedMarker');
$row.addClass('changed');
// Add an asterisk only once if row changed.
if ($rowToMark.length) {
$rowToMark.find('td:first-child .js-form-item').append(marker);
}
});
}
},
detach(context, settings, trigger) {
if (trigger === 'unload') {
const $form = $('#locale-translate-edit-form').removeOnce(
'localetranslatedirty',
);
if ($form.length) {
$form.off('formUpdated.localeTranslateDirty');
}
}
},
};
/**
* Show/hide the description details on Available translation updates page.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches behavior for toggling details on the translation update page.
*/
Drupal.behaviors.hideUpdateInformation = {
attach(context, settings) {
const $table = $('#locale-translation-status-form').once(
'expand-updates',
);
if ($table.length) {
const $tbodies = $table.find('tbody');
// Open/close the description details by toggling a tr class.
$tbodies.on('click keydown', '.description', function(e) {
if (e.keyCode && (e.keyCode !== 13 && e.keyCode !== 32)) {
return;
}
e.preventDefault();
const $tr = $(this).closest('tr');
$tr.toggleClass('expanded');
// Change screen reader text.
$tr.find('.locale-translation-update__prefix').text(() => {
if ($tr.hasClass('expanded')) {
return Drupal.t('Hide description');
}
return Drupal.t('Show description');
});
});
$table.find('.requirements, .links').hide();
}
},
};
$.extend(
Drupal.theme,
/** @lends Drupal.theme */ {
/**
* Creates markup for a changed translation marker.
*
* @return {string}
* Markup for the marker.
*/
localeTranslateChangedMarker() {
return `<abbr class="warning ajax-changed" title="${Drupal.t(
'Changed',
)}">*</abbr>`;
},
/**
* Creates markup for the translation changed warning.
*
* @return {string}
* Markup for the warning.
*/
localeTranslateChangedWarning() {
return `<div class="clearfix messages messages--warning">${Drupal.theme(
'localeTranslateChangedMarker',
)} ${Drupal.t(
'Changes made in this table will not be saved until the form is submitted.',
)}</div>`;
},
},
);
})(jQuery, Drupal);

View file

@ -1,47 +1,35 @@
/**
* @file
* Locale admin behavior.
*/
* DO NOT EDIT THIS FILE.
* See the following change record for more information,
* https://www.drupal.org/node/2815083
* @preserve
**/
(function ($, Drupal) {
'use strict';
/**
* Marks changes of translations.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches behavior to show the user if translations has changed.
* @prop {Drupal~behaviorDetach} detach
* Detach behavior to show the user if translations has changed.
*/
Drupal.behaviors.localeTranslateDirty = {
attach: function () {
attach: function attach() {
var $form = $('#locale-translate-edit-form').once('localetranslatedirty');
if ($form.length) {
// Display a notice if any row changed.
$form.one('formUpdated.localeTranslateDirty', 'table', function () {
var $marker = $(Drupal.theme('localeTranslateChangedWarning')).hide();
$(this).addClass('changed').before($marker);
$marker.fadeIn('slow');
});
// Highlight changed row.
$form.on('formUpdated.localeTranslateDirty', 'tr', function () {
var $row = $(this);
var $rowToMark = $row.once('localemark');
var marker = Drupal.theme('localeTranslateChangedMarker');
$row.addClass('changed');
// Add an asterisk only once if row changed.
if ($rowToMark.length) {
$rowToMark.find('td:first-child .js-form-item').append(marker);
}
});
}
},
detach: function (context, settings, trigger) {
detach: function detach(context, settings, trigger) {
if (trigger === 'unload') {
var $form = $('#locale-translate-edit-form').removeOnce('localetranslatedirty');
if ($form.length) {
@ -51,23 +39,14 @@
}
};
/**
* Show/hide the description details on Available translation updates page.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches behavior for toggling details on the translation update page.
*/
Drupal.behaviors.hideUpdateInformation = {
attach: function (context, settings) {
attach: function attach(context, settings) {
var $table = $('#locale-translation-status-form').once('expand-updates');
if ($table.length) {
var $tbodies = $table.find('tbody');
// Open/close the description details by toggling a tr class.
$tbodies.on('click keydown', '.description', function (e) {
if (e.keyCode && (e.keyCode !== 13 && e.keyCode !== 32)) {
if (e.keyCode && e.keyCode !== 13 && e.keyCode !== 32) {
return;
}
e.preventDefault();
@ -75,14 +54,12 @@
$tr.toggleClass('expanded');
// Change screen reader text.
$tr.find('.locale-translation-update__prefix').text(function () {
if ($tr.hasClass('expanded')) {
return Drupal.t('Hide description');
}
else {
return Drupal.t('Show description');
}
return Drupal.t('Show description');
});
});
$table.find('.requirements, .links').hide();
@ -90,27 +67,12 @@
}
};
$.extend(Drupal.theme, /** @lends Drupal.theme */{
/**
* Creates markup for a changed translation marker.
*
* @return {string}
* Markup for the marker.
*/
localeTranslateChangedMarker: function () {
$.extend(Drupal.theme, {
localeTranslateChangedMarker: function localeTranslateChangedMarker() {
return '<abbr class="warning ajax-changed" title="' + Drupal.t('Changed') + '">*</abbr>';
},
/**
* Creates markup for the translation changed warning.
*
* @return {string}
* Markup for the warning.
*/
localeTranslateChangedWarning: function () {
localeTranslateChangedWarning: function localeTranslateChangedWarning() {
return '<div class="clearfix messages messages--warning">' + Drupal.theme('localeTranslateChangedMarker') + ' ' + Drupal.t('Changes made in this table will not be saved until the form is submitted.') + '</div>';
}
});
})(jQuery, Drupal);
})(jQuery, Drupal);

View file

@ -104,22 +104,22 @@ function locale_translation_batch_status_finished($success, $results) {
else {
$message = \Drupal::translation()->formatPlural(count($results['failed_files']), 'One translation files could not be checked. See the log for details.', '@count translation files could not be checked. See the log for details.');
}
drupal_set_message($message, 'error');
\Drupal::messenger()->addError($message);
}
if (isset($results['files'])) {
drupal_set_message(\Drupal::translation()->formatPlural(
\Drupal::messenger()->addStatus(\Drupal::translation()->formatPlural(
count($results['files']),
'Checked available interface translation updates for one project.',
'Checked available interface translation updates for @count projects.'
));
}
if (!isset($results['failed_files']) && !isset($results['files'])) {
drupal_set_message(t('Nothing to check.'));
\Drupal::messenger()->addStatus(t('Nothing to check.'));
}
\Drupal::state()->set('locale.translation_last_checked', REQUEST_TIME);
}
else {
drupal_set_message(t('An error occurred trying to check available interface translation updates.'), 'error');
\Drupal::messenger()->addError(t('An error occurred trying to check available interface translation updates.'));
}
}
@ -238,11 +238,13 @@ function locale_translation_http_check($uri) {
$logger = \Drupal::logger('locale');
try {
$actual_uri = NULL;
$response = \Drupal::service('http_client_factory')->fromOptions(['allow_redirects' => [
'on_redirect' => function(RequestInterface $request, ResponseInterface $response, UriInterface $request_uri) use (&$actual_uri) {
$actual_uri = (string) $request_uri;
}
]])->head($uri);
$response = \Drupal::service('http_client_factory')->fromOptions([
'allow_redirects' => [
'on_redirect' => function (RequestInterface $request, ResponseInterface $response, UriInterface $request_uri) use (&$actual_uri) {
$actual_uri = (string) $request_uri;
},
],
])->head($uri);
$result = [];
// Return the effective URL if it differs from the requested.
@ -290,7 +292,7 @@ function locale_translation_http_check($uri) {
* File object if download was successful. FALSE on failure.
*/
function locale_translation_download_source($source_file, $directory = 'temporary://') {
if ($uri = system_retrieve_file($source_file->uri, $directory)) {
if ($uri = system_retrieve_file($source_file->uri, $directory, FALSE, FILE_EXISTS_REPLACE)) {
$file = clone($source_file);
$file->type = LOCALE_TRANSLATION_LOCAL;
$file->uri = $uri;

View file

@ -0,0 +1,38 @@
/**
* @file
* Locale behavior.
*/
(function($, Drupal) {
/**
* Select the language code of an imported file based on its filename.
*
* This only works if the file name ends with "LANGCODE.po".
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches behavior for preselecting language code based on filename.
*/
Drupal.behaviors.importLanguageCodeSelector = {
attach(context, settings) {
const $form = $('#locale-translate-import-form').once('autodetect-lang');
if ($form.length) {
const $langcode = $form.find('.langcode-input');
$form.find('.file-import-input').on('change', function() {
// If the filename is fully the language code or the filename
// ends with a language code, pre-select that one.
const matches = $(this)
.val()
.match(/([^.][.]*)([\w-]+)\.po$/);
if (
matches &&
$langcode.find(`option[value="${matches[2]}"]`).length
) {
$langcode.val(matches[2]);
}
});
}
},
};
})(jQuery, Drupal);

View file

@ -200,7 +200,7 @@ function locale_translate_batch_import($file, array $options, &$context) {
try {
if (empty($context['sandbox'])) {
$context['sandbox']['parse_state'] = [
'filesize' => filesize(drupal_realpath($file->uri)),
'filesize' => filesize(\Drupal::service('file_system')->realpath($file->uri)),
'chunk_size' => 200,
'seek' => 0,
];
@ -372,7 +372,7 @@ function locale_translate_batch_finished($success, array $results) {
else {
$message = \Drupal::translation()->formatPlural(count($results['failed_files']), 'One translation file could not be imported. See the log for details.', '@count translation files could not be imported. See the log for details.');
}
drupal_set_message($message, 'error');
\Drupal::messenger()->addError($message);
}
if (isset($results['files'])) {
$skipped_files = [];
@ -389,7 +389,7 @@ function locale_translate_batch_finished($success, array $results) {
}
}
}
drupal_set_message(\Drupal::translation()->formatPlural(count($results['files']),
\Drupal::messenger()->addStatus(\Drupal::translation()->formatPlural(count($results['files']),
'One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.',
'@count translation files imported. %number translations were added, %update translations were updated and %delete translations were removed.',
['%number' => $additions, '%update' => $updates, '%delete' => $deletes]
@ -403,7 +403,7 @@ function locale_translate_batch_finished($success, array $results) {
else {
$message = \Drupal::translation()->formatPlural($skips, 'One translation string was skipped because of disallowed or malformed HTML. See the log for details.', '@count translation strings were skipped because of disallowed or malformed HTML. See the log for details.');
}
drupal_set_message($message, 'warning');
\Drupal::messenger()->addWarning($message);
$logger->warning('@count disallowed HTML string(s) in files: @files.', ['@count' => $skips, '@files' => implode(',', $skipped_files)]);
}
}
@ -630,11 +630,11 @@ function locale_config_batch_finished($success, array $results) {
if ($success) {
$configuration = isset($results['stats']['config']) ? $results['stats']['config'] : 0;
if ($configuration) {
drupal_set_message(t('The configuration was successfully updated. There are %number configuration objects updated.', ['%number' => $configuration]));
\Drupal::messenger()->addStatus(t('The configuration was successfully updated. There are %number configuration objects updated.', ['%number' => $configuration]));
\Drupal::logger('locale')->notice('The configuration was successfully updated. %number configuration objects updated.', ['%number' => $configuration]);
}
else {
drupal_set_message(t('No configuration objects have been updated.'));
\Drupal::messenger()->addStatus(t('No configuration objects have been updated.'));
\Drupal::logger('locale')->warning('No configuration objects have been updated.');
}
}

View file

@ -1,38 +1,23 @@
/**
* @file
* Locale behavior.
*/
* DO NOT EDIT THIS FILE.
* See the following change record for more information,
* https://www.drupal.org/node/2815083
* @preserve
**/
(function ($, Drupal) {
'use strict';
/**
* Select the language code of an imported file based on its filename.
*
* This only works if the file name ends with "LANGCODE.po".
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches behavior for preselecting language code based on filename.
*/
Drupal.behaviors.importLanguageCodeSelector = {
attach: function (context, settings) {
attach: function attach(context, settings) {
var $form = $('#locale-translate-import-form').once('autodetect-lang');
if ($form.length) {
var $langcode = $form.find('.langcode-input');
$form.find('.file-import-input')
.on('change', function () {
// If the filename is fully the language code or the filename
// ends with a language code, pre-select that one.
var matches = $(this).val().match(/([^.][\.]*)([\w-]+)\.po$/);
if (matches && $langcode.find('option[value="' + matches[2] + '"]').length) {
$langcode.val(matches[2]);
}
});
$form.find('.file-import-input').on('change', function () {
var matches = $(this).val().match(/([^.][.]*)([\w-]+)\.po$/);
if (matches && $langcode.find('option[value="' + matches[2] + '"]').length) {
$langcode.val(matches[2]);
}
});
}
}
};
})(jQuery, Drupal);
})(jQuery, Drupal);

View file

@ -161,7 +161,7 @@ function locale_translation_default_translation_server() {
// An additional check is required here. During the upgrade process
// \Drupal::config()->get() returns NULL. We use the defined value as
// fallback.
$pattern = $pattern ? $pattern : LOCALE_TRANSLATION_DEFAULT_SERVER_PATTERN;
$pattern = $pattern ? $pattern : LOCALE_TRANSLATION_DEFAULT_SERVER_PATTERN;
return [
'pattern' => $pattern,

View file

@ -0,0 +1,87 @@
/**
* @file
* Datepicker JavaScript for the Locale module.
*/
(function($, Drupal, drupalSettings) {
/**
* Attaches language support to the jQuery UI datepicker component.
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.localeDatepicker = {
attach(context, settings) {
// This code accesses drupalSettings and localized strings via Drupal.t().
// So this code should run after these are initialized. By placing it in an
// attach behavior this is assured.
$.datepicker.regional['drupal-locale'] = $.extend(
{
closeText: Drupal.t('Done'),
prevText: Drupal.t('Prev'),
nextText: Drupal.t('Next'),
currentText: Drupal.t('Today'),
monthNames: [
Drupal.t('January', {}, { context: 'Long month name' }),
Drupal.t('February', {}, { context: 'Long month name' }),
Drupal.t('March', {}, { context: 'Long month name' }),
Drupal.t('April', {}, { context: 'Long month name' }),
Drupal.t('May', {}, { context: 'Long month name' }),
Drupal.t('June', {}, { context: 'Long month name' }),
Drupal.t('July', {}, { context: 'Long month name' }),
Drupal.t('August', {}, { context: 'Long month name' }),
Drupal.t('September', {}, { context: 'Long month name' }),
Drupal.t('October', {}, { context: 'Long month name' }),
Drupal.t('November', {}, { context: 'Long month name' }),
Drupal.t('December', {}, { context: 'Long month name' }),
],
monthNamesShort: [
Drupal.t('Jan'),
Drupal.t('Feb'),
Drupal.t('Mar'),
Drupal.t('Apr'),
Drupal.t('May'),
Drupal.t('Jun'),
Drupal.t('Jul'),
Drupal.t('Aug'),
Drupal.t('Sep'),
Drupal.t('Oct'),
Drupal.t('Nov'),
Drupal.t('Dec'),
],
dayNames: [
Drupal.t('Sunday'),
Drupal.t('Monday'),
Drupal.t('Tuesday'),
Drupal.t('Wednesday'),
Drupal.t('Thursday'),
Drupal.t('Friday'),
Drupal.t('Saturday'),
],
dayNamesShort: [
Drupal.t('Sun'),
Drupal.t('Mon'),
Drupal.t('Tue'),
Drupal.t('Wed'),
Drupal.t('Thu'),
Drupal.t('Fri'),
Drupal.t('Sat'),
],
dayNamesMin: [
Drupal.t('Su'),
Drupal.t('Mo'),
Drupal.t('Tu'),
Drupal.t('We'),
Drupal.t('Th'),
Drupal.t('Fr'),
Drupal.t('Sa'),
],
dateFormat: Drupal.t('mm/dd/yy'),
firstDay: 0,
isRTL: 0,
},
drupalSettings.jquery.ui.datepicker,
);
$.datepicker.setDefaults($.datepicker.regional['drupal-locale']);
},
};
})(jQuery, Drupal, drupalSettings);

View file

@ -1,82 +1,23 @@
/**
* @file
* Datepicker JavaScript for the Locale module.
*/
* DO NOT EDIT THIS FILE.
* See the following change record for more information,
* https://www.drupal.org/node/2815083
* @preserve
**/
(function ($, Drupal, drupalSettings) {
'use strict';
/**
* Attaches language support to the jQuery UI datepicker component.
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.localeDatepicker = {
attach: function (context, settings) {
// This code accesses drupalSettings and localized strings via Drupal.t().
// So this code should run after these are initialized. By placing it in an
// attach behavior this is assured.
attach: function attach(context, settings) {
$.datepicker.regional['drupal-locale'] = $.extend({
closeText: Drupal.t('Done'),
prevText: Drupal.t('Prev'),
nextText: Drupal.t('Next'),
currentText: Drupal.t('Today'),
monthNames: [
Drupal.t('January', {}, {context: 'Long month name'}),
Drupal.t('February', {}, {context: 'Long month name'}),
Drupal.t('March', {}, {context: 'Long month name'}),
Drupal.t('April', {}, {context: 'Long month name'}),
Drupal.t('May', {}, {context: 'Long month name'}),
Drupal.t('June', {}, {context: 'Long month name'}),
Drupal.t('July', {}, {context: 'Long month name'}),
Drupal.t('August', {}, {context: 'Long month name'}),
Drupal.t('September', {}, {context: 'Long month name'}),
Drupal.t('October', {}, {context: 'Long month name'}),
Drupal.t('November', {}, {context: 'Long month name'}),
Drupal.t('December', {}, {context: 'Long month name'})
],
monthNamesShort: [
Drupal.t('Jan'),
Drupal.t('Feb'),
Drupal.t('Mar'),
Drupal.t('Apr'),
Drupal.t('May'),
Drupal.t('Jun'),
Drupal.t('Jul'),
Drupal.t('Aug'),
Drupal.t('Sep'),
Drupal.t('Oct'),
Drupal.t('Nov'),
Drupal.t('Dec')
],
dayNames: [
Drupal.t('Sunday'),
Drupal.t('Monday'),
Drupal.t('Tuesday'),
Drupal.t('Wednesday'),
Drupal.t('Thursday'),
Drupal.t('Friday'),
Drupal.t('Saturday')
],
dayNamesShort: [
Drupal.t('Sun'),
Drupal.t('Mon'),
Drupal.t('Tue'),
Drupal.t('Wed'),
Drupal.t('Thu'),
Drupal.t('Fri'),
Drupal.t('Sat')
],
dayNamesMin: [
Drupal.t('Su'),
Drupal.t('Mo'),
Drupal.t('Tu'),
Drupal.t('We'),
Drupal.t('Th'),
Drupal.t('Fr'),
Drupal.t('Sa')
],
monthNames: [Drupal.t('January', {}, { context: 'Long month name' }), Drupal.t('February', {}, { context: 'Long month name' }), Drupal.t('March', {}, { context: 'Long month name' }), Drupal.t('April', {}, { context: 'Long month name' }), Drupal.t('May', {}, { context: 'Long month name' }), Drupal.t('June', {}, { context: 'Long month name' }), Drupal.t('July', {}, { context: 'Long month name' }), Drupal.t('August', {}, { context: 'Long month name' }), Drupal.t('September', {}, { context: 'Long month name' }), Drupal.t('October', {}, { context: 'Long month name' }), Drupal.t('November', {}, { context: 'Long month name' }), Drupal.t('December', {}, { context: 'Long month name' })],
monthNamesShort: [Drupal.t('Jan'), Drupal.t('Feb'), Drupal.t('Mar'), Drupal.t('Apr'), Drupal.t('May'), Drupal.t('Jun'), Drupal.t('Jul'), Drupal.t('Aug'), Drupal.t('Sep'), Drupal.t('Oct'), Drupal.t('Nov'), Drupal.t('Dec')],
dayNames: [Drupal.t('Sunday'), Drupal.t('Monday'), Drupal.t('Tuesday'), Drupal.t('Wednesday'), Drupal.t('Thursday'), Drupal.t('Friday'), Drupal.t('Saturday')],
dayNamesShort: [Drupal.t('Sun'), Drupal.t('Mon'), Drupal.t('Tue'), Drupal.t('Wed'), Drupal.t('Thu'), Drupal.t('Fri'), Drupal.t('Sat')],
dayNamesMin: [Drupal.t('Su'), Drupal.t('Mo'), Drupal.t('Tu'), Drupal.t('We'), Drupal.t('Th'), Drupal.t('Fr'), Drupal.t('Sa')],
dateFormat: Drupal.t('mm/dd/yy'),
firstDay: 0,
isRTL: 0
@ -84,5 +25,4 @@
$.datepicker.setDefaults($.datepicker.regional['drupal-locale']);
}
};
})(jQuery, Drupal, drupalSettings);
})(jQuery, Drupal, drupalSettings);

View file

@ -6,5 +6,5 @@ package: Multilingual
version: VERSION
core: 8.x
dependencies:
- language
- file
- drupal:language
- drupal:file

View file

@ -111,7 +111,8 @@ function locale_schema() {
'customized' => [
'type' => 'int',
'not null' => TRUE,
'default' => 0, // LOCALE_NOT_CUSTOMIZED
// LOCALE_NOT_CUSTOMIZED
'default' => 0,
'description' => 'Boolean indicating whether the translation is custom to this site.',
],
],
@ -259,7 +260,7 @@ function locale_requirements($phase) {
if ($available_updates || $untranslated) {
if ($available_updates) {
$requirements['locale_translation'] = [
'title' => 'Translation update status',
'title' => t('Translation update status'),
'value' => \Drupal::l(t('Updates available'), new Url('locale.translate_status')),
'severity' => REQUIREMENT_WARNING,
'description' => t('Updates available for: @languages. See the <a href=":updates">Available translation updates</a> page for more information.', ['@languages' => implode(', ', $available_updates), ':updates' => \Drupal::url('locale.translate_status')]),
@ -267,7 +268,7 @@ function locale_requirements($phase) {
}
else {
$requirements['locale_translation'] = [
'title' => 'Translation update status',
'title' => t('Translation update status'),
'value' => t('Missing translations'),
'severity' => REQUIREMENT_INFO,
'description' => t('Missing translations for: @languages. See the <a href=":updates">Available translation updates</a> page for more information.', ['@languages' => implode(', ', $untranslated), ':updates' => \Drupal::url('locale.translate_status')]),
@ -276,7 +277,7 @@ function locale_requirements($phase) {
}
else {
$requirements['locale_translation'] = [
'title' => 'Translation update status',
'title' => t('Translation update status'),
'value' => t('Up to date'),
'severity' => REQUIREMENT_OK,
];
@ -284,7 +285,7 @@ function locale_requirements($phase) {
}
else {
$requirements['locale_translation'] = [
'title' => 'Translation update status',
'title' => t('Translation update status'),
'value' => \Drupal::l(t('Can not determine status'), new Url('locale.translate_status')),
'severity' => REQUIREMENT_WARNING,
'description' => t('No translation status is available. See the <a href=":updates">Available translation updates</a> page for more information.', [':updates' => \Drupal::url('locale.translate_status')]),
@ -303,3 +304,15 @@ function locale_update_8300() {
// the new key value collection.
\Drupal::state()->delete('locale.translation_status');
}
/**
* Update default server pattern value to use https.
*/
function locale_update_8500() {
$update_url = \Drupal::config('locale.settings')->get('translation.default_server_pattern');
if ($update_url == 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po') {
\Drupal::configFactory()->getEditable('locale.settings')
->set('translation.default_server_pattern', 'https://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po')
->save();
}
}

View file

@ -25,6 +25,6 @@ translations:
# any time.
js:
# This file does not actually exist; it's a placeholder file that will be
# overriden by locale_js_alter(), to use the file that contains the actual
# overridden by locale_js_alter(), to use the file that contains the actual
# translations, for the language used in the current request.
locale.translation.js: {}

View file

@ -99,7 +99,7 @@ const LOCALE_TRANSLATION_USE_SOURCE_REMOTE_AND_LOCAL = 'remote_and_local';
*
* @see locale_translation_default_translation_server().
*/
const LOCALE_TRANSLATION_DEFAULT_SERVER_PATTERN = 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po';
const LOCALE_TRANSLATION_DEFAULT_SERVER_PATTERN = 'https://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po';
/**
* The number of seconds that the translations status entry should be considered.
@ -261,13 +261,13 @@ function locale_translatable_language_list() {
*
* The index is computed from the formula of this language.
*
* @param $count
* @param int $count
* Number to return plural for.
* @param $langcode
* Optional language code to translate to a language other than
* what is used to display the page.
* @param string|null $langcode
* (optional) Language code to translate to a language other than what is used
* to display the page, or NULL for current language. Defaults to NULL.
*
* @return
* @return int
* The numeric index of the plural variant to use for this $langcode and
* $count combination or -1 if the language was not found or does not have a
* plural formula.
@ -308,7 +308,6 @@ function locale_get_plural($count, $langcode = NULL) {
return $plural_indexes[$langcode][$count];
}
/**
* Implements hook_modules_installed().
*/
@ -1113,9 +1112,6 @@ function _locale_strip_quotes($string) {
* @param string $filepath
* File name to parse.
*
* @return array
* Array of string objects to update indexed by context and source.
*
* @throws Exception
* If a non-local file is attempted to be parsed.
*/
@ -1217,10 +1213,11 @@ function _locale_parse_js_file($filepath) {
* files are rebuilt (with locale_update_js_files()) the next time a
* request is served in that language.
*
* @param $langcode
* The language code for which the file needs to be refreshed.
* @param string|null $langcode
* (optional) The language code for which the file needs to be refreshed, or
* NULL to refresh all languages. Defaults to NULL.
*
* @return
* @return array
* New content of the 'system.javascript_parsed' variable.
*/
function _locale_invalidate_js($langcode = NULL) {
@ -1245,8 +1242,9 @@ function _locale_invalidate_js($langcode = NULL) {
/**
* (Re-)Creates the JavaScript translation file for a language.
*
* @param $langcode
* The language, the translation file should be (re)created for.
* @param string|null $langcode
* (optional) The language that the translation file should be (re)created
* for, or NULL for the current language. Defaults to NULL.
*
* @return bool
* TRUE if translation file exists, FALSE otherwise.
@ -1373,6 +1371,7 @@ function _locale_rebuild_js($langcode = NULL) {
return TRUE;
}
}
/**
* Form element callback: After build changes to the language update table.
*

View file

@ -13,9 +13,14 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
*
* Manually checks the translation status without the use of cron.
*
* @see locale_menu()
* @deprecated in Drupal 8.5.0 and will be removed before 9.0.0. It is unused by
* Drupal core. Duplicate this function in your own extension if you need its
* behavior.
*
* @see https://www.drupal.org/node/2931188
*/
function locale_translation_manual_status() {
@trigger_error('locale_translation_manual_status() is deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. It is unused by Drupal core. Duplicate this function in your own extension if you need its behavior.', E_USER_DEPRECATED);
module_load_include('compare.inc', 'locale');
// Check the translation status of all translatable projects in all languages.

View file

@ -0,0 +1,13 @@
<?php
/**
* @file
* Post-update functions for Locale module.
*/
/**
* Clear cache to ensure plural translations are removed from it.
*/
function locale_post_update_clear_cache_for_old_translations() {
// Remove cache of translations, like '@count[2] words'.
}

View file

@ -67,7 +67,7 @@ function locale_translation_get_projects(array $project_names = []) {
locale_translation_build_projects();
}
$projects = \Drupal::service('locale.project')->getAll();
array_walk($projects, function(&$project) {
array_walk($projects, function (&$project) {
$project = (object) $project;
});
}
@ -329,7 +329,7 @@ function locale_cron_fill_queue() {
// Determine which project+language should be updated.
$last = REQUEST_TIME - $config->get('translation.update_interval_days') * 3600 * 24;
$projects = \Drupal::service('locale.project')->getAll();
$projects = array_filter($projects, function($project) {
$projects = array_filter($projects, function ($project) {
return $project['status'] == 1;
});
$files = db_select('locale_file', 'f')
@ -377,7 +377,7 @@ function locale_cron_fill_queue() {
function _locale_translation_file_is_remote($uri) {
$scheme = file_uri_scheme($uri);
if ($scheme) {
return !drupal_realpath($scheme . '://');
return !\Drupal::service('file_system')->realpath($scheme . '://');
}
return FALSE;
}

View file

@ -3,11 +3,13 @@ label: Locale configuration
migration_tags:
- Drupal 6
- Drupal 7
- Configuration
source:
plugin: variable
variables:
- locale_cache_strings
- locale_js_directory
source_module: locale
process:
cache_strings: locale_cache_strings
'javascript/directory': locale_js_directory

View file

@ -14,6 +14,8 @@ use Symfony\Component\HttpFoundation\BinaryFileResponse;
/**
* Form for the Gettext translation files export form.
*
* @internal
*/
class ExportForm extends FormBase {
@ -165,7 +167,7 @@ class ExportForm extends FormBase {
$header->setLanguageName($language_name);
$writer = new PoStreamWriter();
$writer->setUri($uri);
$writer->setURI($uri);
$writer->setHeader($header);
$writer->open();
@ -178,7 +180,7 @@ class ExportForm extends FormBase {
$form_state->setResponse($response);
}
else {
drupal_set_message($this->t('Nothing to export.'));
$this->messenger()->addStatus($this->t('Nothing to export.'));
}
}

View file

@ -11,6 +11,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Form constructor for the translation import screen.
*
* @internal
*/
class ImportForm extends FormBase {
@ -44,6 +46,7 @@ class ImportForm extends FormBase {
$container->get('language_manager')
);
}
/**
* Constructs a form for language import.
*
@ -108,6 +111,7 @@ class ImportForm extends FormBase {
],
'#size' => 50,
'#upload_validators' => $validators,
'#upload_location' => 'translations://',
'#attributes' => ['class' => ['file-import-input']],
];
$form['langcode'] = [
@ -154,7 +158,7 @@ class ImportForm extends FormBase {
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
$this->file = file_save_upload('file', $form['file']['#upload_validators'], 'translations://', 0);
$this->file = _file_save_upload_from_form($form['file'], $form_state, 0);
// Ensure we have the file uploaded.
if (!$this->file) {
@ -166,13 +170,13 @@ class ImportForm extends FormBase {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
\Drupal::moduleHandler()->loadInclude('locale', 'translation.inc');
$this->moduleHandler->loadInclude('locale', 'translation.inc');
// Add language, if not yet supported.
$language = $this->languageManager->getLanguage($form_state->getValue('langcode'));
if (empty($language)) {
$language = ConfigurableLanguage::createFromLangcode($form_state->getValue('langcode'));
$language->save();
drupal_set_message($this->t('The language %language has been created.', ['%language' => $this->t($language->label())]));
$this->messenger()->addStatus($this->t('The language %language has been created.', ['%language' => $this->t($language->label())]));
}
$options = array_merge(_locale_translation_default_update_options(), [
'langcode' => $form_state->getValue('langcode'),
@ -185,7 +189,6 @@ class ImportForm extends FormBase {
batch_set($batch);
// Create or update all configuration translations for this language.
\Drupal::moduleHandler()->loadInclude('locale', 'bulk.inc');
if ($batch = locale_config_batch_update_components($options, [$form_state->getValue('langcode')])) {
batch_set($batch);
}

View file

@ -7,6 +7,8 @@ use Drupal\Core\Form\FormStateInterface;
/**
* Configure locale settings for this site.
*
* @internal
*/
class LocaleSettingsForm extends ConfigFormBase {

View file

@ -8,6 +8,8 @@ use Drupal\locale\SourceString;
/**
* Defines a translation edit form.
*
* @internal
*/
class TranslateEditForm extends TranslateFormBase {
@ -217,7 +219,7 @@ class TranslateEditForm extends TranslateFormBase {
}
}
drupal_set_message($this->t('The strings have been saved.'));
$this->messenger()->addStatus($this->t('The strings have been saved.'));
// Keep the user on the current pager page.
$page = $this->getRequest()->query->get('page');

View file

@ -6,6 +6,8 @@ use Drupal\Core\Form\FormStateInterface;
/**
* Provides a filtered translation edit form.
*
* @internal
*/
class TranslateFilterForm extends TranslateFormBase {

View file

@ -10,6 +10,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a translation status form.
*
* @internal
*/
class TranslationStatusForm extends FormBase {
@ -40,7 +42,7 @@ class TranslationStatusForm extends FormBase {
/**
* Constructs a TranslationStatusForm object.
*
* @param ModuleHandlerInterface $module_handler
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* A module handler.
* @param \Drupal\Core\State\StateInterface $state
* The state service.

View file

@ -43,7 +43,7 @@ class LocaleConfigManager {
/**
* The string storage for reading and writing translations.
*
* @var \Drupal\locale\StringStorageInterface;
* @var \Drupal\locale\StringStorageInterface
*/
protected $localeStorage;
@ -140,9 +140,7 @@ class LocaleConfigManager {
if ($this->isSupported($name)) {
// Create typed configuration wrapper based on install storage data.
$data = $this->defaultConfigStorage->read($name);
$type_definition = $this->typedConfigManager->getDefinition($name);
$data_definition = $this->typedConfigManager->buildDataDefinition($type_definition, $data);
$typed_config = $this->typedConfigManager->create($data_definition, $data);
$typed_config = $this->typedConfigManager->createFromNameAndData($name, $data);
if ($typed_config instanceof TraversableTypedDataInterface) {
return $this->getTranslatableData($typed_config);
}

View file

@ -7,6 +7,7 @@ use Drupal\Core\Cache\CacheCollector;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
use Symfony\Component\HttpFoundation\RequestStack;
/**
@ -172,6 +173,12 @@ class LocaleLookup extends CacheCollector {
}
}
if (is_string($value) && strpos($value, PluralTranslatableMarkup::DELIMITER) !== FALSE) {
// Community translations imported from localize.drupal.org as well as
// migrated translations may contain @count[number].
$value = preg_replace('!@count\[\d+\]!', '@count', $value);
}
$this->storage[$offset] = $value;
// Disabling the usage of string caching allows a module to watch for
// the exact list of strings used on a page. From a performance

View file

@ -99,7 +99,7 @@ class LocaleTranslation extends QueueWorkerBase implements ContainerFactoryPlugi
}
else {
$batch_context = $args[$last];
unset ($args[$last]);
unset($args[$last]);
}
$args = array_merge($args, [&$batch_context]);

View file

@ -36,7 +36,7 @@ class PluralFormula implements PluralFormulaInterface {
* ],
* ]
* @endcode
* @var []
* @var array
*/
protected $formulae;

View file

@ -16,7 +16,7 @@ class PoDatabaseWriter implements PoWriterInterface {
* An associative array indicating what data should be overwritten, if any.
*
* Elements of the array:
* - override_options
* - overwrite_options
* - not_customized: boolean indicating that not customized strings should
* be overwritten.
* - customized: boolean indicating that customized strings should be
@ -109,6 +109,16 @@ class PoDatabaseWriter implements PoWriterInterface {
/**
* Set the options for the current writer.
*
* @param array $options
* An associative array containing:
* - overwrite_options: An array of options. Each option contains:
* - not_customized: Boolean indicating that not customized strings should
* be overwritten.
* - customized: Boolean indicating that customized strings should be
* overwritten.
* - customized: The strings being imported should be saved as customized.
* One of LOCALE_CUSTOMIZED or LOCALE_NOT_CUSTOMIZED.
*/
public function setOptions(array $options) {
if (!isset($options['overwrite_options'])) {

View file

@ -10,6 +10,7 @@ namespace Drupal\locale;
* value, and is assumed to be in English language.
*/
class SourceString extends StringBase {
/**
* {@inheritdoc}
*/

View file

@ -3,6 +3,7 @@
namespace Drupal\locale;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Query\Condition;
/**
* Defines a class to store localized strings in the database.
@ -416,7 +417,7 @@ class StringDatabaseStorage implements StringStorageInterface {
elseif ($table_alias == 't' && $join === 'leftJoin') {
// Conditions for target fields when doing an outer join only make
// sense if we add also OR field IS NULL.
$query->condition(db_or()
$query->condition((new Condition('OR'))
->condition($field_alias, (array) $value, 'IN')
->isNull($field_alias)
);
@ -429,7 +430,7 @@ class StringDatabaseStorage implements StringStorageInterface {
// Process other options, string filter, query limit, etc.
if (!empty($options['filters'])) {
if (count($options['filters']) > 1) {
$filter = db_or();
$filter = new Condition('OR');
$query->condition($filter);
}
else {

View file

@ -1,145 +0,0 @@
<?php
namespace Drupal\locale\Tests;
use Drupal\Core\Language\LanguageInterface;
use Drupal\simpletest\WebTestBase;
use Drupal\Component\Utility\SafeMarkup;
/**
* Tests parsing js files for translatable strings.
*
* @group locale
*/
class LocaleJavascriptTranslationTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['locale', 'locale_test'];
public function testFileParsing() {
$filename = __DIR__ . '/../../tests/locale_test.js';
// Parse the file to look for source strings.
_locale_parse_js_file($filename);
// Get all of the source strings that were found.
$strings = $this->container
->get('locale.storage')
->getStrings([
'type' => 'javascript',
'name' => $filename,
]);
$source_strings = [];
foreach ($strings as $string) {
$source_strings[$string->source] = $string->context;
}
$etx = LOCALE_PLURAL_DELIMITER;
// List of all strings that should be in the file.
$test_strings = [
'Standard Call t' => '',
'Whitespace Call t' => '',
'Single Quote t' => '',
"Single Quote \\'Escaped\\' t" => '',
'Single Quote Concat strings t' => '',
'Double Quote t' => '',
"Double Quote \\\"Escaped\\\" t" => '',
'Double Quote Concat strings t' => '',
'Context !key Args t' => 'Context string',
'Context Unquoted t' => 'Context string unquoted',
'Context Single Quoted t' => 'Context string single quoted',
'Context Double Quoted t' => 'Context string double quoted',
"Standard Call plural{$etx}Standard Call @count plural" => '',
"Whitespace Call plural{$etx}Whitespace Call @count plural" => '',
"Single Quote plural{$etx}Single Quote @count plural" => '',
"Single Quote \\'Escaped\\' plural{$etx}Single Quote \\'Escaped\\' @count plural" => '',
"Double Quote plural{$etx}Double Quote @count plural" => '',
"Double Quote \\\"Escaped\\\" plural{$etx}Double Quote \\\"Escaped\\\" @count plural" => '',
"Context !key Args plural{$etx}Context !key Args @count plural" => 'Context string',
"Context Unquoted plural{$etx}Context Unquoted @count plural" => 'Context string unquoted',
"Context Single Quoted plural{$etx}Context Single Quoted @count plural" => 'Context string single quoted',
"Context Double Quoted plural{$etx}Context Double Quoted @count plural" => 'Context string double quoted',
];
// Assert that all strings were found properly.
foreach ($test_strings as $str => $context) {
$args = ['%source' => $str, '%context' => $context];
// Make sure that the string was found in the file.
$this->assertTrue(isset($source_strings[$str]), SafeMarkup::format('Found source string: %source', $args));
// Make sure that the proper context was matched.
$message = $context ? SafeMarkup::format('Context for %source is %context', $args) : SafeMarkup::format('Context for %source is blank', $args);
$this->assertTrue(isset($source_strings[$str]) && $source_strings[$str] === $context, $message);
}
$this->assertEqual(count($source_strings), count($test_strings), 'Found correct number of source strings.');
}
/**
* Assert translations JS is added before drupal.js, because it depends on it.
*/
public function testLocaleTranslationJsDependencies() {
// User to add and remove language.
$admin_user = $this->drupalCreateUser(['administer languages', 'access administration pages', 'translate interface']);
// Add custom language.
$this->drupalLogin($admin_user);
// Code for the language.
$langcode = 'es';
// The English name for the language.
$name = $this->randomMachineName(16);
// The domain prefix.
$prefix = $langcode;
$edit = [
'predefined_langcode' => 'custom',
'langcode' => $langcode,
'label' => $name,
'direction' => LanguageInterface::DIRECTION_LTR,
];
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
// Set path prefix.
$edit = ["prefix[$langcode]" => $prefix];
$this->drupalPostForm('admin/config/regional/language/detection/url', $edit, t('Save configuration'));
// This forces locale.admin.js string sources to be imported, which contains
// the next translation.
$this->drupalGet($prefix . '/admin/config/regional/translate');
// Translate a string in locale.admin.js to our new language.
$strings = \Drupal::service('locale.storage')
->getStrings([
'source' => 'Show description',
'type' => 'javascript',
'name' => 'core/modules/locale/locale.admin.js',
]);
$string = $strings[0];
$this->drupalPostForm(NULL, ['string' => 'Show description'], t('Filter'));
$edit = ['strings[' . $string->lid . '][translations][0]' => $this->randomString(16)];
$this->drupalPostForm(NULL, $edit, t('Save translations'));
// Calculate the filename of the JS including the translations.
$js_translation_files = \Drupal::state()->get('locale.translation.javascript');
$js_filename = $prefix . '_' . $js_translation_files[$prefix] . '.js';
// Assert translations JS is included before drupal.js.
$this->assertTrue(strpos($this->content, $js_filename) < strpos($this->content, 'core/misc/drupal.js'), 'Translations are included before Drupal.t.');
}
}

View file

@ -0,0 +1,52 @@
/**
* @file
* JavaScript for locale_test.module.
*
* @ignore
*/
Drupal.t("Standard Call t");
Drupal
.
t
(
"Whitespace Call t"
)
;
Drupal.t('Single Quote t');
Drupal.t('Single Quote \'Escaped\' t');
Drupal.t('Single Quote ' + 'Concat ' + 'strings ' + 't');
Drupal.t("Double Quote t");
Drupal.t("Double Quote \"Escaped\" t");
Drupal.t("Double Quote " + "Concat " + "strings " + "t");
Drupal.t("Context Unquoted t", {}, {context: "Context string unquoted"});
Drupal.t("Context Single Quoted t", {}, {'context': "Context string single quoted"});
Drupal.t("Context Double Quoted t", {}, {"context": "Context string double quoted"});
Drupal.t("Context !key Args t", {'!key': 'value'}, {context: "Context string"});
Drupal.formatPlural(1, "Standard Call plural", "Standard Call @count plural");
Drupal
.
formatPlural
(
1,
"Whitespace Call plural",
"Whitespace Call @count plural"
)
;
Drupal.formatPlural(1, 'Single Quote plural', 'Single Quote @count plural');
Drupal.formatPlural(1, 'Single Quote \'Escaped\' plural', 'Single Quote \'Escaped\' @count plural');
Drupal.formatPlural(1, "Double Quote plural", "Double Quote @count plural");
Drupal.formatPlural(1, "Double Quote \"Escaped\" plural", "Double Quote \"Escaped\" @count plural");
Drupal.formatPlural(1, "Context Unquoted plural", "Context Unquoted @count plural", {}, {context: "Context string unquoted"});
Drupal.formatPlural(1, "Context Single Quoted plural", "Context Single Quoted @count plural", {}, {'context': "Context string single quoted"});
Drupal.formatPlural(1, "Context Double Quoted plural", "Context Double Quoted @count plural", {}, {"context": "Context string double quoted"});
Drupal.formatPlural(1, "Context !key Args plural", "Context !key Args @count plural", {'!key': 'value'}, {context: "Context string"});

View file

@ -1,18 +1,12 @@
/**
* @file
* JavaScript for locale_test.module.
*
* @ignore
*/
* DO NOT EDIT THIS FILE.
* See the following change record for more information,
* https://www.drupal.org/node/2815083
* @preserve
**/
Drupal.t("Standard Call t");
Drupal
.
t
(
"Whitespace Call t"
)
;
Drupal.t("Whitespace Call t");
Drupal.t('Single Quote t');
Drupal.t('Single Quote \'Escaped\' t');
@ -22,22 +16,14 @@ Drupal.t("Double Quote t");
Drupal.t("Double Quote \"Escaped\" t");
Drupal.t("Double Quote " + "Concat " + "strings " + "t");
Drupal.t("Context Unquoted t", {}, {context: "Context string unquoted"});
Drupal.t("Context Single Quoted t", {}, {'context': "Context string single quoted"});
Drupal.t("Context Double Quoted t", {}, {"context": "Context string double quoted"});
Drupal.t("Context Unquoted t", {}, { context: "Context string unquoted" });
Drupal.t("Context Single Quoted t", {}, { 'context': "Context string single quoted" });
Drupal.t("Context Double Quoted t", {}, { "context": "Context string double quoted" });
Drupal.t("Context !key Args t", {'!key': 'value'}, {context: "Context string"});
Drupal.t("Context !key Args t", { '!key': 'value' }, { context: "Context string" });
Drupal.formatPlural(1, "Standard Call plural", "Standard Call @count plural");
Drupal
.
formatPlural
(
1,
"Whitespace Call plural",
"Whitespace Call @count plural"
)
;
Drupal.formatPlural(1, "Whitespace Call plural", "Whitespace Call @count plural");
Drupal.formatPlural(1, 'Single Quote plural', 'Single Quote @count plural');
Drupal.formatPlural(1, 'Single Quote \'Escaped\' plural', 'Single Quote \'Escaped\' @count plural');
@ -45,8 +31,8 @@ Drupal.formatPlural(1, 'Single Quote \'Escaped\' plural', 'Single Quote \'Escape
Drupal.formatPlural(1, "Double Quote plural", "Double Quote @count plural");
Drupal.formatPlural(1, "Double Quote \"Escaped\" plural", "Double Quote \"Escaped\" @count plural");
Drupal.formatPlural(1, "Context Unquoted plural", "Context Unquoted @count plural", {}, {context: "Context string unquoted"});
Drupal.formatPlural(1, "Context Single Quoted plural", "Context Single Quoted @count plural", {}, {'context': "Context string single quoted"});
Drupal.formatPlural(1, "Context Double Quoted plural", "Context Double Quoted @count plural", {}, {"context": "Context string double quoted"});
Drupal.formatPlural(1, "Context Unquoted plural", "Context Unquoted @count plural", {}, { context: "Context string unquoted" });
Drupal.formatPlural(1, "Context Single Quoted plural", "Context Single Quoted @count plural", {}, { 'context': "Context string single quoted" });
Drupal.formatPlural(1, "Context Double Quoted plural", "Context Double Quoted @count plural", {}, { "context": "Context string double quoted" });
Drupal.formatPlural(1, "Context !key Args plural", "Context !key Args @count plural", {'!key': 'value'}, {context: "Context string"});
Drupal.formatPlural(1, "Context !key Args plural", "Context !key Args @count plural", { '!key': 'value' }, { context: "Context string" });

View file

@ -4,4 +4,3 @@ description: 'Support module for testing early bootstrap getting of annotations
core: 8.x
package: Testing
version: VERSION

View file

@ -1,9 +1,9 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\locale\Locale;
use Drupal\simpletest\WebTestBase;
use Drupal\Tests\BrowserTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
/**
@ -11,7 +11,7 @@ use Drupal\language\Entity\ConfigurableLanguage;
*
* @group locale
*/
class LocaleConfigTranslationImportTest extends WebTestBase {
class LocaleConfigTranslationImportTest extends BrowserTestBase {
/**
* Modules to enable.
@ -20,6 +20,13 @@ class LocaleConfigTranslationImportTest extends WebTestBase {
*/
public static $modules = ['language', 'locale_test_translate'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
}
/**
* Test update changes configuration translations if enabled after language.
*/
@ -39,6 +46,7 @@ class LocaleConfigTranslationImportTest extends WebTestBase {
// tests.
$this->config('locale.settings')
->set('translation.import_enabled', TRUE)
->set('translation.use_source', LOCALE_TRANSLATION_USE_SOURCE_LOCAL)
->save();
// Add translation permissions now that the locale module has been enabled.
@ -84,6 +92,7 @@ class LocaleConfigTranslationImportTest extends WebTestBase {
// tests.
$this->config('locale.settings')
->set('translation.import_enabled', TRUE)
->set('translation.use_source', LOCALE_TRANSLATION_USE_SOURCE_LOCAL)
->save();
// Add predefined language.
@ -122,7 +131,7 @@ class LocaleConfigTranslationImportTest extends WebTestBase {
$expected = [
'translatable_no_default' => 'This translation is preserved',
'translatable_default_with_translation' => 'This translation is preserved',
'translatable_default_with_no_translation' => 'This translation is preserved'
'translatable_default_with_no_translation' => 'This translation is preserved',
];
$this->assertEqual($expected, $override->get());
}
@ -142,6 +151,7 @@ class LocaleConfigTranslationImportTest extends WebTestBase {
// tests.
$this->config('locale.settings')
->set('translation.import_enabled', TRUE)
->set('translation.use_source', LOCALE_TRANSLATION_USE_SOURCE_LOCAL)
->save();
// Add predefined language.
@ -179,6 +189,7 @@ class LocaleConfigTranslationImportTest extends WebTestBase {
// tests.
$this->config('locale.settings')
->set('translation.import_enabled', TRUE)
->set('translation.use_source', LOCALE_TRANSLATION_USE_SOURCE_LOCAL)
->save();
// Add predefined language.
@ -193,7 +204,7 @@ class LocaleConfigTranslationImportTest extends WebTestBase {
$expected = [
'translatable_default_with_translation' => 'Locale can translate Afrikaans',
'translatable_no_default' => 'This translation is preserved',
'translatable_default_with_no_translation' => 'This translation is preserved'
'translatable_default_with_no_translation' => 'This translation is preserved',
];
$this->assertEqual($expected, $override->get());
@ -206,7 +217,7 @@ class LocaleConfigTranslationImportTest extends WebTestBase {
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textareas = $this->xpath('//textarea');
$textarea = current($textareas);
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => '',
];
@ -215,7 +226,7 @@ class LocaleConfigTranslationImportTest extends WebTestBase {
$override = \Drupal::languageManager()->getLanguageConfigOverride('af', 'locale_test_translate.settings');
$expected = [
'translatable_no_default' => 'This translation is preserved',
'translatable_default_with_no_translation' => 'This translation is preserved'
'translatable_default_with_no_translation' => 'This translation is preserved',
];
$this->assertEqual($expected, $override->get());
}

View file

@ -1,8 +1,8 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\simpletest\WebTestBase;
use Drupal\Tests\BrowserTestBase;
use Drupal\Core\Language\LanguageInterface;
/**
@ -10,7 +10,7 @@ use Drupal\Core\Language\LanguageInterface;
*
* @group locale
*/
class LocaleConfigTranslationTest extends WebTestBase {
class LocaleConfigTranslationTest extends BrowserTestBase {
/**
* The language code used.
@ -38,6 +38,7 @@ class LocaleConfigTranslationTest extends WebTestBase {
// tests.
$this->config('locale.settings')
->set('translation.import_enabled', TRUE)
->set('translation.use_source', LOCALE_TRANSLATION_USE_SOURCE_LOCAL)
->save();
// Add custom language.
@ -76,7 +77,7 @@ class LocaleConfigTranslationTest extends WebTestBase {
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textareas = $this->xpath('//textarea');
$textarea = current($textareas);
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => $message,
];
@ -100,7 +101,7 @@ class LocaleConfigTranslationTest extends WebTestBase {
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textareas = $this->xpath('//textarea');
$textarea = current($textareas);
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => 'D',
];
@ -143,7 +144,7 @@ class LocaleConfigTranslationTest extends WebTestBase {
];
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => $image_style_label,
];
@ -175,7 +176,7 @@ class LocaleConfigTranslationTest extends WebTestBase {
];
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => $category_label,
];
@ -231,7 +232,7 @@ class LocaleConfigTranslationTest extends WebTestBase {
}
// Check the optional default configuration in node module.
$string = $this->storage->findString(['source' => 'No front page content has been created yet.', 'context' => '', 'type' => 'configuration']);
$string = $this->storage->findString(['source' => 'No front page content has been created yet.<br/>Follow the <a target="_blank" href="https://www.drupal.org/docs/user_guide/en/index.html">User Guide</a> to start building your site.', 'context' => '', 'type' => 'configuration']);
if ($optional) {
$this->assertFalse($this->config('views.view.frontpage')->isNew());
$this->assertTrue($string, 'Node view text can be found with node and views modules.');

View file

@ -1,15 +1,15 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\simpletest\WebTestBase;
use Drupal\Tests\BrowserTestBase;
/**
* Tests the exportation of locale files.
*
* @group locale
*/
class LocaleExportTest extends WebTestBase {
class LocaleExportTest extends BrowserTestBase {
/**
* Modules to enable.

View file

@ -1,15 +1,15 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\simpletest\WebTestBase;
use Drupal\Tests\BrowserTestBase;
/**
* Tests the locale functionality in the altered file settings form.
*
* @group locale
*/
class LocaleFileSystemFormTest extends WebTestBase {
class LocaleFileSystemFormTest extends BrowserTestBase {
/**
* Modules to enable.
@ -21,7 +21,7 @@ class LocaleFileSystemFormTest extends WebTestBase {
/**
* {@inheritdoc}
*/
protected function setUp(){
protected function setUp() {
parent::setUp();
$account = $this->drupalCreateUser(['administer site configuration']);
$this->drupalLogin($account);
@ -45,7 +45,7 @@ class LocaleFileSystemFormTest extends WebTestBase {
// The setting should persist.
$translation_path = $this->publicFilesDirectory . '/translations_changed';
$fields = [
'translation_path' => $translation_path
'translation_path' => $translation_path,
];
$this->drupalPostForm(NULL, $fields, t('Save configuration'));
$this->drupalGet('admin/config/media/file-system');

View file

@ -1,8 +1,8 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\simpletest\WebTestBase;
use Drupal\Tests\BrowserTestBase;
use Drupal\Core\Language\LanguageInterface;
/**
@ -10,7 +10,7 @@ use Drupal\Core\Language\LanguageInterface;
*
* @group locale
*/
class LocaleImportFunctionalTest extends WebTestBase {
class LocaleImportFunctionalTest extends BrowserTestBase {
/**
* Modules to enable.
@ -52,6 +52,7 @@ class LocaleImportFunctionalTest extends WebTestBase {
// tests.
$this->config('locale.settings')
->set('translation.import_enabled', TRUE)
->set('translation.use_source', LOCALE_TRANSLATION_USE_SOURCE_LOCAL)
->save();
}
@ -341,7 +342,8 @@ class LocaleImportFunctionalTest extends WebTestBase {
// Import a .po file to translate.
$this->importPoFile($this->getPoFileWithConfigDe(), [
'langcode' => $langcode]);
'langcode' => $langcode,
]);
// Check that the 'Anonymous' string is translated.
$config = \Drupal::languageManager()->getLanguageConfigOverride($langcode, 'user.settings');

View file

@ -0,0 +1,159 @@
<?php
namespace Drupal\Tests\locale\Functional;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Tests\BrowserTestBase;
use Drupal\Component\Render\FormattableMarkup;
/**
* Tests parsing js files for translatable strings.
*
* @group locale
*/
class LocaleJavascriptTranslationTest extends BrowserTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['locale', 'locale_test'];
public function testFileParsing() {
// This test is for ensuring that the regular expression in
// _locale_parse_js_file() finds translatable source strings in all valid
// JavaScript syntax regardless of the coding style used, especially with
// respect to optional whitespace, line breaks, etc.
// - We test locale_test.es6.js, because that is the one that contains a
// variety of whitespace styles.
// - We also test the transpiled locale_test.js as an extra double-check
// that JavaScript transpilation doesn't change what
// _locale_parse_js_file() finds.
$files[] = __DIR__ . '/../../locale_test.es6.js';
$files[] = __DIR__ . '/../../locale_test.js';
foreach ($files as $filename) {
// Parse the file to look for source strings.
_locale_parse_js_file($filename);
// Get all of the source strings that were found.
$strings = $this->container
->get('locale.storage')
->getStrings([
'type' => 'javascript',
'name' => $filename,
]);
$source_strings = [];
foreach ($strings as $string) {
$source_strings[$string->source] = $string->context;
}
$etx = LOCALE_PLURAL_DELIMITER;
// List of all strings that should be in the file.
$test_strings = [
'Standard Call t' => '',
'Whitespace Call t' => '',
'Single Quote t' => '',
"Single Quote \\'Escaped\\' t" => '',
'Single Quote Concat strings t' => '',
'Double Quote t' => '',
"Double Quote \\\"Escaped\\\" t" => '',
'Double Quote Concat strings t' => '',
'Context !key Args t' => 'Context string',
'Context Unquoted t' => 'Context string unquoted',
'Context Single Quoted t' => 'Context string single quoted',
'Context Double Quoted t' => 'Context string double quoted',
"Standard Call plural{$etx}Standard Call @count plural" => '',
"Whitespace Call plural{$etx}Whitespace Call @count plural" => '',
"Single Quote plural{$etx}Single Quote @count plural" => '',
"Single Quote \\'Escaped\\' plural{$etx}Single Quote \\'Escaped\\' @count plural" => '',
"Double Quote plural{$etx}Double Quote @count plural" => '',
"Double Quote \\\"Escaped\\\" plural{$etx}Double Quote \\\"Escaped\\\" @count plural" => '',
"Context !key Args plural{$etx}Context !key Args @count plural" => 'Context string',
"Context Unquoted plural{$etx}Context Unquoted @count plural" => 'Context string unquoted',
"Context Single Quoted plural{$etx}Context Single Quoted @count plural" => 'Context string single quoted',
"Context Double Quoted plural{$etx}Context Double Quoted @count plural" => 'Context string double quoted',
];
// Assert that all strings were found properly.
foreach ($test_strings as $str => $context) {
$args = ['%source' => $str, '%context' => $context];
// Make sure that the string was found in the file.
$this->assertTrue(isset($source_strings[$str]), new FormattableMarkup('Found source string: %source', $args));
// Make sure that the proper context was matched.
$message = $context ? new FormattableMarkup('Context for %source is %context', $args) : new FormattableMarkup('Context for %source is blank', $args);
$this->assertTrue(isset($source_strings[$str]) && $source_strings[$str] === $context, $message);
}
$this->assertEqual(count($source_strings), count($test_strings), 'Found correct number of source strings.');
}
}
/**
* Assert translations JS is added before drupal.js, because it depends on it.
*/
public function testLocaleTranslationJsDependencies() {
// User to add and remove language.
$admin_user = $this->drupalCreateUser(['administer languages', 'access administration pages', 'translate interface']);
// Add custom language.
$this->drupalLogin($admin_user);
// Code for the language.
$langcode = 'es';
// The English name for the language.
$name = $this->randomMachineName(16);
// The domain prefix.
$prefix = $langcode;
$edit = [
'predefined_langcode' => 'custom',
'langcode' => $langcode,
'label' => $name,
'direction' => LanguageInterface::DIRECTION_LTR,
];
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
// Set path prefix.
$edit = ["prefix[$langcode]" => $prefix];
$this->drupalPostForm('admin/config/regional/language/detection/url', $edit, t('Save configuration'));
// This forces locale.admin.js string sources to be imported, which contains
// the next translation.
$this->drupalGet($prefix . '/admin/config/regional/translate');
// Translate a string in locale.admin.js to our new language.
$strings = \Drupal::service('locale.storage')
->getStrings([
'source' => 'Show description',
'type' => 'javascript',
'name' => 'core/modules/locale/locale.admin.js',
]);
$string = $strings[0];
$this->drupalPostForm(NULL, ['string' => 'Show description'], t('Filter'));
$edit = ['strings[' . $string->lid . '][translations][0]' => $this->randomString(16)];
$this->drupalPostForm(NULL, $edit, t('Save translations'));
// Calculate the filename of the JS including the translations.
$js_translation_files = \Drupal::state()->get('locale.translation.javascript');
$js_filename = $prefix . '_' . $js_translation_files[$prefix] . '.js';
$content = $this->getSession()->getPage()->getContent();
// Assert translations JS is included before drupal.js.
$this->assertTrue(strpos($content, $js_filename) < strpos($content, 'core/misc/drupal.js'), 'Translations are included before Drupal.t.');
}
}

View file

@ -1,9 +1,9 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\Core\Asset\AttachedAssets;
use Drupal\simpletest\WebTestBase;
use Drupal\Tests\BrowserTestBase;
/**
* Tests localization of the JavaScript libraries.
@ -12,7 +12,7 @@ use Drupal\simpletest\WebTestBase;
*
* @group locale
*/
class LocaleLibraryAlterTest extends WebTestBase {
class LocaleLibraryAlterTest extends BrowserTestBase {
/**
* Modules to enable.

View file

@ -2,6 +2,7 @@
namespace Drupal\Tests\locale\Functional;
use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\BrowserTestBase;
@ -55,4 +56,45 @@ class LocaleLocaleLookupTest extends BrowserTestBase {
$this->assertEqual($context['operation'], 'locale_lookup');
}
/**
* Test old plural style @count[number] fix.
*
* @dataProvider providerTestFixOldPluralStyle
*/
public function testFixOldPluralStyle($translation_value, $expected) {
$string_storage = \Drupal::service('locale.storage');
$string = $string_storage->findString(['source' => 'Member for', 'context' => '']);
$lid = $string->getId();
$string_storage->createTranslation([
'lid' => $lid,
'language' => 'fr',
'translation' => $translation_value,
])->save();
_locale_refresh_translations(['fr'], [$lid]);
// Check that 'count[2]' was fixed for render value.
$this->drupalGet('');
$this->assertSession()->pageTextContains($expected);
// Check that 'count[2]' was saved for source value.
$translation = $string_storage->findTranslation(['language' => 'fr', 'lid' => $lid])->translation;
$this->assertSame($translation_value, $translation, 'Source value not changed');
$this->assertNotFalse(strpos($translation, '@count[2]'), 'Source value contains @count[2]');
}
/**
* Provides data for testFixOldPluralStyle().
*
* @return array
* An array of test data:
* - translation value
* - expected result
*/
public function providerTestFixOldPluralStyle() {
return [
'non-plural translation' => ['@count[2] non-plural test', '@count[2] non-plural test'],
'plural translation' => ['@count[2] plural test' . PluralTranslatableMarkup::DELIMITER, '@count plural test'],
];
}
}

View file

@ -0,0 +1,21 @@
<?php
namespace Drupal\Tests\locale\Functional;
/**
* Tests installing in a different language with a dev version string.
*
* @group locale
*/
class LocaleNonInteractiveDevInstallTest extends LocaleNonInteractiveInstallTest {
/**
* {@inheritdoc}
*/
protected function getVersionStringToTest() {
include_once $this->root . '/core/includes/install.core.inc';
$version = _install_get_version_info(\Drupal::VERSION);
return $version['major'] . '.' . $version['minor'] . '.x';
}
}

View file

@ -0,0 +1,57 @@
<?php
namespace Drupal\Tests\locale\Functional;
use Drupal\Tests\BrowserTestBase;
/**
* Tests installing in a different language with a non-dev version string.
*
* @group locale
*/
class LocaleNonInteractiveInstallTest extends BrowserTestBase {
/**
* Gets the version string to use in the translation file.
*
* @return string
* The version string to test, for example, '8.0.0' or '8.6.x'.
*/
protected function getVersionStringToTest() {
include_once $this->root . '/core/includes/install.core.inc';
$version = _install_get_version_info(\Drupal::VERSION);
return $version['major'] . '.0.0';
}
/**
* {@inheritdoc}
*/
protected function installParameters() {
$parameters = parent::installParameters();
// Install Drupal in German.
$parameters['parameters']['langcode'] = 'de';
// Create a po file so we don't attempt to download one from
// localize.drupal.org and to have a test translation that will not change.
\Drupal::service('file_system')->mkdir($this->publicFilesDirectory . '/translations', NULL, TRUE);
$contents = <<<ENDPO
msgid ""
msgstr ""
msgid "Enter the password that accompanies your username."
msgstr "Geben sie das Passwort für ihren Benutzernamen ein."
ENDPO;
$version = $this->getVersionStringToTest();
file_put_contents($this->publicFilesDirectory . "/translations/drupal-{$version}.de.po", $contents);
return $parameters;
}
/**
* Tests that the expected translated text appears on the login screen.
*/
public function testInstallerTranslations() {
$this->drupalGet('user/login');
$this->assertSession()->responseContains('Geben sie das Passwort für ihren Benutzernamen ein.');
}
}

View file

@ -1,16 +1,16 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
use Drupal\simpletest\WebTestBase;
use Drupal\Tests\BrowserTestBase;
/**
* Tests plural handling for various languages.
*
* @group locale
*/
class LocalePluralFormatTest extends WebTestBase {
class LocalePluralFormatTest extends BrowserTestBase {
/**
* An admin user.

View file

@ -1,8 +1,8 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\tour\Tests\TourTestBase;
use Drupal\Tests\tour\Functional\TourTestBase;
/**
* Tests the Translate Interface tour.

View file

@ -0,0 +1,65 @@
<?php
namespace Drupal\Tests\locale\Functional;
use Drupal\Core\StreamWrapper\PublicStream;
use Drupal\language\Entity\ConfigurableLanguage;
use org\bovigo\vfs\vfsStream;
/**
* Tests locale translation download.
*
* @group locale
*/
class LocaleTranslationDownloadTest extends LocaleUpdateBase {
/**
* The virtual file stream for storing translations.
*
* @var \org\bovigo\vfs\vfsStreamDirectory
*/
protected $translationsStream;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$moduleHandler = $this->container->get('module_handler');
$moduleHandler->loadInclude('locale', 'inc', 'locale.batch');
ConfigurableLanguage::createFromLangcode('de')->save();
// Let the translations:// stream wrapper point to a virtual file system to
// make it independent from the test environment.
$this->translationsStream = vfsStream::setup('translations');
\Drupal::configFactory()->getEditable('locale.settings')
->set('translation.path', $this->translationsStream->url())
->save();
}
/**
* Tests translation download from remote sources.
*/
public function testUpdateImportSourceRemote() {
// Provide remote and 'previously' downloaded translation file.
$this->setTranslationFiles();
vfsStream::create([
'contrib_module_one-8.x-1.1.de._po' => '__old_content__',
], $this->translationsStream);
$url = \Drupal::service('url_generator')->generateFromRoute('<front>', [], ['absolute' => TRUE]);
$uri = $url . PublicStream::basePath() . '/remote/8.x/contrib_module_one/contrib_module_one-8.x-1.1.de._po';
$source_file = (object) [
'uri' => $uri,
];
$result = locale_translation_download_source($source_file, 'translations://');
$this->assertEquals('translations://contrib_module_one-8.x-1.1.de._po', $result->uri);
$this->assertFalse(file_exists('translations://contrib_module_one-8.x-1.1.de_0._po'));
$this->assertTrue(file_exists('translations://contrib_module_one-8.x-1.1.de._po'));
$this->assertNotContains('__old_content__', file_get_contents('translations://contrib_module_one-8.x-1.1.de._po'));
}
}

View file

@ -1,11 +1,11 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\simpletest\WebTestBase;
use Drupal\Tests\BrowserTestBase;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Render\FormattableMarkup;
/**
* Adds a new locale and translates its name. Checks the validation of
@ -13,7 +13,7 @@ use Drupal\Component\Utility\SafeMarkup;
*
* @group locale
*/
class LocaleTranslationUiTest extends WebTestBase {
class LocaleTranslationUiTest extends BrowserTestBase {
/**
* Modules to enable.
@ -44,7 +44,7 @@ class LocaleTranslationUiTest extends WebTestBase {
// Code for the language.
$langcode = 'xx';
// The English name for the language. This will be translated.
$name = $this->randomMachineName(16);
$name = 'cucurbitaceae';
// This will be the translation of $name.
$translation = $this->randomMachineName(16);
$translation_to_en = $this->randomMachineName(16);
@ -89,7 +89,7 @@ class LocaleTranslationUiTest extends WebTestBase {
// Assume this is the only result, given the random name.
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => $translation,
];
@ -112,7 +112,7 @@ class LocaleTranslationUiTest extends WebTestBase {
];
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => $translation_to_en,
];
@ -155,7 +155,7 @@ class LocaleTranslationUiTest extends WebTestBase {
];
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => 'Please enter your Llama username.',
];
@ -189,7 +189,7 @@ class LocaleTranslationUiTest extends WebTestBase {
$this->drupalPostForm('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'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => '',
];
@ -248,7 +248,7 @@ class LocaleTranslationUiTest extends WebTestBase {
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => $this->randomMachineName(),
];
@ -259,13 +259,13 @@ class LocaleTranslationUiTest extends WebTestBase {
$locale_javascripts = \Drupal::state()->get('locale.translation.javascript') ?: [];
$js_file = 'public://' . $config->get('javascript.directory') . '/' . $langcode . '_' . $locale_javascripts[$langcode] . '.js';
$this->assertTrue($result = file_exists($js_file), SafeMarkup::format('JavaScript file created: %file', ['%file' => $result ? $js_file : 'not found']));
$this->assertTrue($result = file_exists($js_file), new FormattableMarkup('JavaScript file created: %file', ['%file' => $result ? $js_file : 'not found']));
// Test JavaScript translation rebuilding.
file_unmanaged_delete($js_file);
$this->assertTrue($result = !file_exists($js_file), SafeMarkup::format('JavaScript file deleted: %file', ['%file' => $result ? $js_file : 'found']));
$this->assertTrue($result = !file_exists($js_file), new FormattableMarkup('JavaScript file deleted: %file', ['%file' => $result ? $js_file : 'found']));
_locale_rebuild_js($langcode);
$this->assertTrue($result = file_exists($js_file), SafeMarkup::format('JavaScript file rebuilt: %file', ['%file' => $result ? $js_file : 'not found']));
$this->assertTrue($result = file_exists($js_file), new FormattableMarkup('JavaScript file rebuilt: %file', ['%file' => $result ? $js_file : 'not found']));
}
/**
@ -309,7 +309,7 @@ class LocaleTranslationUiTest extends WebTestBase {
// Find the edit path.
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
foreach ($bad_translations as $translation) {
$edit = [
$lid => $translation,
@ -317,7 +317,7 @@ class LocaleTranslationUiTest extends WebTestBase {
$this->drupalPostForm('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.');
$this->assertContains('error', $form_class[0]->getText(), 'The string was rejected as unsafe.');
$this->assertNoText(t('The string has been saved.'), 'The string was not saved.');
}
}
@ -399,7 +399,7 @@ class LocaleTranslationUiTest extends WebTestBase {
// Assume this is the only result, given the random name.
// We save the lid from the path.
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => $translation,
];
@ -503,7 +503,7 @@ class LocaleTranslationUiTest extends WebTestBase {
// Submit the translations without changing the translation.
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => $translation->getString(),
];
@ -522,7 +522,7 @@ class LocaleTranslationUiTest extends WebTestBase {
// Submit the translations with a new translation.
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$lid = $textarea->getAttribute('name');
$edit = [
$lid => $this->randomMachineName(100),
];

View file

@ -1,16 +1,16 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\Core\StreamWrapper\PublicStream;
use Drupal\file\Entity\File;
use Drupal\simpletest\WebTestBase;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Tests\BrowserTestBase;
use Drupal\Component\Render\FormattableMarkup;
/**
* Base class for testing updates to string translations.
*/
abstract class LocaleUpdateBase extends WebTestBase {
abstract class LocaleUpdateBase extends BrowserTestBase {
/**
* Timestamp for an old translation.
@ -63,6 +63,7 @@ abstract class LocaleUpdateBase extends WebTestBase {
// tests.
$this->config('locale.settings')
->set('translation.import_enabled', TRUE)
->set('translation.use_source', LOCALE_TRANSLATION_USE_SOURCE_LOCAL)
->save();
}
@ -88,7 +89,7 @@ abstract class LocaleUpdateBase extends WebTestBase {
$edit = ['predefined_langcode' => $langcode];
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
$this->container->get('language_manager')->reset();
$this->assertTrue(\Drupal::languageManager()->getLanguage($langcode), SafeMarkup::format('Language %langcode added.', ['%langcode' => $langcode]));
$this->assertTrue(\Drupal::languageManager()->getLanguage($langcode), new FormattableMarkup('Language %langcode added.', ['%langcode' => $langcode]));
}
/**
@ -138,7 +139,7 @@ EOF;
'status' => FILE_STATUS_PERMANENT,
]);
file_put_contents($file->getFileUri(), $po_header . $text);
touch(drupal_realpath($file->getFileUri()), $timestamp);
touch(\Drupal::service('file_system')->realpath($file->getFileUri()), $timestamp);
$file->save();
}

View file

@ -1,6 +1,8 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\Tests\Traits\Core\CronRunTrait;
/**
* Tests for using cron to update project interface translations.
@ -9,6 +11,8 @@ namespace Drupal\locale\Tests;
*/
class LocaleUpdateCronTest extends LocaleUpdateBase {
use CronRunTrait;
protected $batchOutput = [];
/**
@ -43,7 +47,7 @@ class LocaleUpdateCronTest extends LocaleUpdateBase {
// Prepare for test: Simulate new translations being available.
// Change the last updated timestamp of a translation file.
$contrib_module_two_uri = 'public://local/contrib_module_two-8.x-2.0-beta4.de._po';
touch(drupal_realpath($contrib_module_two_uri), REQUEST_TIME);
touch(\Drupal::service('file_system')->realpath($contrib_module_two_uri), REQUEST_TIME);
// Prepare for test: Simulate that the file has not been checked for a long
// time. Set the last_check timestamp to zero.
@ -80,7 +84,7 @@ class LocaleUpdateCronTest extends LocaleUpdateBase {
// Check whether tasks are added to the queue.
$queue = \Drupal::queue('locale_translation', TRUE);
$this->assertEqual($queue->numberOfItems(), 3, 'Queue holds tasks for one project.');
$this->assertEqual($queue->numberOfItems(), 2, 'Queue holds tasks for one project.');
$item = $queue->claimItem();
$queue->releaseItem($item);
$this->assertEqual($item->data[1][0], 'contrib_module_two', 'Queue holds tasks for contrib module one.');
@ -91,7 +95,7 @@ class LocaleUpdateCronTest extends LocaleUpdateBase {
// Check whether no more tasks are added to the queue.
$queue = \Drupal::queue('locale_translation', TRUE);
$this->assertEqual($queue->numberOfItems(), 3, 'Queue holds tasks for one project.');
$this->assertEqual($queue->numberOfItems(), 2, 'Queue holds tasks for one project.');
// Ensure last checked is updated to a greater time than the initial value.
sleep(1);

View file

@ -1,15 +1,15 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\simpletest\WebTestBase;
use Drupal\Tests\BrowserTestBase;
/**
* Test for proper version fallback in case of a development release.
*
* @group language
*/
class LocaleUpdateDevelopmentReleaseTest extends WebTestBase {
class LocaleUpdateDevelopmentReleaseTest extends BrowserTestBase {
public static $modules = ['locale', 'locale_test_development_release'];

View file

@ -1,9 +1,8 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\SafeMarkup;
/**
* Tests for the user interface of project interface translations.
@ -86,7 +85,7 @@ class LocaleUpdateInterfaceTest extends LocaleUpdateBase {
$release_details = new FormattableMarkup('@module (@version). @info', [
'@module' => 'Locale test translate',
'@version' => '1.3-dev',
'@info' => t('File not found at %local_path', ['%local_path' => 'core/modules/locale/tests/test.de.po'])
'@info' => t('File not found at %local_path', ['%local_path' => 'core/modules/locale/tests/test.de.po']),
]);
$this->assertRaw($release_details->__toString(), 'Release details');
@ -112,7 +111,7 @@ class LocaleUpdateInterfaceTest extends LocaleUpdateBase {
// Check if translations are available for Drupal core.
$this->drupalGet('admin/reports/translations');
$this->assertText(t('Updates for: @project', ['@project' => t('Drupal core')]), 'Translations found');
$this->assertText(SafeMarkup::format('@module (@date)', ['@module' => t('Drupal core'), '@date' => format_date(REQUEST_TIME, 'html_date')]), 'Core translation update');
$this->assertText(new FormattableMarkup('@module (@date)', ['@module' => t('Drupal core'), '@date' => format_date(REQUEST_TIME, 'html_date')]), 'Core translation update');
$update_button = $this->xpath('//input[@type="submit"][@value="' . t('Update translations') . '"]');
$this->assertTrue($update_button, 'Update translations button');
}

View file

@ -1,6 +1,6 @@
<?php
namespace Drupal\locale\Tests;
namespace Drupal\Tests\locale\Functional;
use Drupal\Core\Language\LanguageInterface;

View file

@ -37,7 +37,7 @@ class LocaleConfigSubscriberTest extends KernelTestBase {
/**
* The string storage used in this test.
*
* @var \Drupal\locale\StringStorageInterface;
* @var \Drupal\locale\StringStorageInterface
*/
protected $stringStorage;
@ -187,7 +187,6 @@ class LocaleConfigSubscriberTest extends KernelTestBase {
$this->assertNoTranslation($config_name, $langcode);
}
/**
* Sets up a configuration string with a translation.
*

View file

@ -6,7 +6,6 @@ use Drupal\Core\Language\LanguageInterface;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests that the configurable language manager and locale operate correctly.
*

View file

@ -0,0 +1,30 @@
<?php
namespace Drupal\Tests\locale\Kernel;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests deprecations in the locale module.
*
* @group locale
* @group legacy
*/
class LocaleDeprecationsTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['locale', 'system'];
/**
* @expectedDeprecation locale_translation_manual_status() is deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. It is unused by Drupal core. Duplicate this function in your own extension if you need its behavior.
*/
public function testLocaleTranslationManualStatusDeprecation() {
module_load_include('pages.inc', 'locale');
$this->assertNotNull(\locale_translation_manual_status());
}
}

View file

@ -41,7 +41,6 @@ class LocaleTranslationProjectsTest extends KernelTestBase {
\Drupal::state()->set('locale.remove_core_project', TRUE);
}
/**
* Tests locale_translation_clear_cache_projects().
*/

View file

@ -3,6 +3,7 @@
namespace Drupal\Tests\locale\Unit;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
use Drupal\locale\LocaleLookup;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\HttpFoundation\Request;
@ -266,4 +267,66 @@ class LocaleLookupTest extends UnitTestCase {
$this->assertTrue($locale_lookup->get('test'));
}
/**
* Tests locale lookups with old plural style of translations.
*
* @param array $translations
* The source with translations.
* @param string $langcode
* The language code of translation string.
* @param string $string
* The string for translation.
* @param bool $is_fix
* The flag about expected fix translation.
*
* @covers ::resolveCacheMiss
* @dataProvider providerFixOldPluralTranslationProvider
*/
public function testFixOldPluralStyleTranslations($translations, $langcode, $string, $is_fix) {
$this->storage->expects($this->any())
->method('findTranslation')
->will($this->returnCallback(function ($argument) use ($translations) {
if (isset($translations[$argument['language']][$argument['source']])) {
return (object) ['translation' => $translations[$argument['language']][$argument['source']]];
}
return TRUE;
}));
$this->languageManager->expects($this->any())
->method('getFallbackCandidates')
->will($this->returnCallback(function (array $context = []) {
switch ($context['langcode']) {
case 'by':
return ['ru'];
}
}));
$this->cache->expects($this->once())
->method('get')
->with('locale:' . $langcode . '::anonymous', FALSE);
$locale_lookup = new LocaleLookup($langcode, '', $this->storage, $this->cache, $this->lock, $this->configFactory, $this->languageManager, $this->requestStack);
$this->assertSame($is_fix, strpos($locale_lookup->get($string), '@count[2]') === FALSE);
}
/**
* Provides test data for testResolveCacheMissWithFallback().
*/
public function providerFixOldPluralTranslationProvider() {
$translations = [
'by' => [
'word1' => '@count[2] word-by',
'word2' => implode(PluralTranslatableMarkup::DELIMITER, ['word-by', '@count[2] word-by']),
],
'ru' => [
'word3' => '@count[2] word-ru',
'word4' => implode(PluralTranslatableMarkup::DELIMITER, ['word-ru', '@count[2] word-ru']),
],
];
return [
'no-plural' => [$translations, 'by', 'word1', FALSE],
'no-plural from other language' => [$translations, 'by', 'word3', FALSE],
'plural' => [$translations, 'by', 'word2', TRUE],
'plural from other language' => [$translations, 'by', 'word4', TRUE],
];
}
}

View file

@ -21,7 +21,6 @@ class StringBaseTest extends UnitTestCase {
$string->save();
}
/**
* @covers ::delete
*/