diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d25a209 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# To use this file simply copy it to .gitignore, and it will cause files like +# your settings.php and user-uploaded files to be excluded from git source +# control. This is a common strategy to avoid accidentally including private +# information in public repositories and patch files. +# +# A .gitignore file was included in Drupal core for versions 7.2 through 7.8. +# As of Drupal 7.9, this is no longer the case, and any changes made to your +# .gitignore file will no longer be overwritten by core updates. + +# Ignore configuration files that may contain sensitive information. +sites/*/settings*.php + +# Ignore paths that contain user-generated content. +sites/*/files +sites/*/private + +# If you prefer to store your .gitignore file in the sites/ folder, comment +# or delete the previous settings and uncomment the following ones, instead. + +# Ignore configuration files that may contain sensitive information. +# */settings*.php + +# Ignore paths that contain user-generated content. +# */files +# */private diff --git a/core/includes/form.inc b/core/includes/form.inc index 19993c6..45f8eec 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -3756,6 +3756,9 @@ function form_validate_table($element, &$form_state) { * name must not be changed after initial creation. */ function form_process_machine_name($element, &$form_state) { + // We need to pass the langcode to the client. + $language = language(LANGUAGE_TYPE_INTERFACE); + // Apply default form element properties. $element += array( '#title' => t('Machine-readable name'), @@ -3822,6 +3825,7 @@ function form_process_machine_name($element, &$form_state) { 'machineName' => array( '#' . $source['#id'] => $element['#machine_name'], ), + 'langcode' => $language->langcode, ), ); $element['#attached']['library'][] = array('system', 'drupal.machine-name'); diff --git a/core/misc/machine-name.js b/core/misc/machine-name.js index 9862ee3..3ba7463 100644 --- a/core/misc/machine-name.js +++ b/core/misc/machine-name.js @@ -1,4 +1,4 @@ -(function ($) { +(function ($, Drupal, drupalSettings) { "use strict"; @@ -42,19 +42,19 @@ Drupal.behaviors.machineName = { function machineNameHandler(e) { var data = e.data; - machine = self.transliterate($(e.target).val(), data.options); - // Set the machine name to the transliterated value. - if (machine !== '') { - if (machine !== data.options.replace) { - data.$target.val(machine); - data.$preview.html(data.options.field_prefix + Drupal.checkPlain(machine) + data.options.field_suffix); - } - data.$suffix.show(); + var settings = data.options; + var baseValue = $(e.target).val(); + + var rx = new RegExp(settings.replace_pattern, 'g'); + var expected = baseValue.toLowerCase().replace(rx, settings.replace).substr(0, settings.maxlength); + + if(baseValue.toLowerCase() !== expected) { + self.transliterate(baseValue, settings).done(function (machine) { + self.showMachineName(machine.substr(0, settings.maxlength), data); + }); } else { - data.$suffix.hide(); - data.$target.val(machine); - data.$preview.empty(); + self.showMachineName(expected, data); } } @@ -124,6 +124,23 @@ Drupal.behaviors.machineName = { } }, + showMachineName: function (machine, data) { + var settings = data.options; + // Set the machine name to the transliterated value. + if (machine !== '') { + if (machine !== settings.replace) { + data.$target.val(machine); + data.$preview.html(settings.field_prefix + Drupal.checkPlain(machine) + settings.field_suffix); + } + data.$suffix.show(); + } + else { + data.$suffix.hide(); + data.$target.val(machine); + data.$preview.empty(); + } + }, + /** * Transliterate a human-readable name to a machine name. * @@ -141,9 +158,14 @@ Drupal.behaviors.machineName = { * The transliterated source string. */ transliterate: function (source, settings) { - var rx = new RegExp(settings.replace_pattern, 'g'); - return source.toLowerCase().replace(rx, settings.replace).substr(0, settings.maxlength); + return $.get(drupalSettings.basePath + 'machine_name/transliterate', { + text: source, + langcode: drupalSettings.langcode, + replace_pattern: settings.replace_pattern, + replace: settings.replace, + lowercase: true + }); } }; -})(jQuery); +})(jQuery, Drupal, drupalSettings); diff --git a/core/modules/system/lib/Drupal/system/MachineNameController.php b/core/modules/system/lib/Drupal/system/MachineNameController.php new file mode 100644 index 0000000..0d6dcef --- /dev/null +++ b/core/modules/system/lib/Drupal/system/MachineNameController.php @@ -0,0 +1,74 @@ +transliteration = $transliteration; + } + + /** + * Implements \Drupal\Core\ControllerInterface::create(). + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('transliteration') + ); + } + + /** + * Transliterates a string in given language. Various postprocessing possible. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The input string and language for the transliteration. + * Optionally may contain the replace_pattern, replace, lowercase parameters. + * + * @return \Symfony\Component\HttpFoundation\JsonResponse + * The transliterated string. + */ + public function transliterate(Request $request) { + $text = $request->query->get('text'); + $langcode = $request->query->get('langcode'); + $replace_pattern = $request->query->get('replace_pattern'); + $replace = $request->query->get('replace'); + $lowercase = $request->query->get('lowercase'); + + $transliterated = $this->transliteration->transliterate($text, $langcode, '_'); + if($lowercase) { + $transliterated = drupal_strtolower($transliterated); + } + if(isset($replace_pattern) && isset($replace)) { + $transliterated = preg_replace('@' . $replace_pattern . '@', $replace, $transliterated); + } + return new JsonResponse($transliterated); + } + +} diff --git a/core/modules/system/lib/Drupal/system/SystemBundle.php b/core/modules/system/lib/Drupal/system/SystemBundle.php index 2b937c0..97b2eb2 100644 --- a/core/modules/system/lib/Drupal/system/SystemBundle.php +++ b/core/modules/system/lib/Drupal/system/SystemBundle.php @@ -8,6 +8,7 @@ namespace Drupal\system; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\Bundle\Bundle; /** diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml index 085895e..69a3eae 100644 --- a/core/modules/system/system.routing.yml +++ b/core/modules/system/system.routing.yml @@ -4,3 +4,9 @@ system.cron: _controller: '\Drupal\system\CronController::run' requirements: _access_system_cron: 'TRUE' +system.machine_name_transliterate: + pattern: '/machine_name/transliterate' + defaults: + _controller: '\Drupal\system\MachineNameController::transliterate' + requirements: + _permission: 'access content' diff --git a/d8-machinename-1842718-48.patch b/d8-machinename-1842718-48.patch new file mode 100644 index 0000000..a6b95c3 --- /dev/null +++ b/d8-machinename-1842718-48.patch @@ -0,0 +1,209 @@ +diff --git a/core/includes/form.inc b/core/includes/form.inc +index 27f450e..ec07d6e 100644 +--- a/core/includes/form.inc ++++ b/core/includes/form.inc +@@ -3765,6 +3765,9 @@ function form_validate_table($element, &$form_state) { + * name must not be changed after initial creation. + */ + function form_process_machine_name($element, &$form_state) { ++ // We need to pass the langcode to the client. ++ $language = language(LANGUAGE_TYPE_INTERFACE); ++ + // Apply default form element properties. + $element += array( + '#title' => t('Machine-readable name'), +@@ -3831,6 +3834,7 @@ function form_process_machine_name($element, &$form_state) { + 'machineName' => array( + '#' . $source['#id'] => $element['#machine_name'], + ), ++ 'langcode' => $language->langcode, + ), + ); + $element['#attached']['library'][] = array('system', 'drupal.machine-name'); +diff --git a/core/misc/machine-name.js b/core/misc/machine-name.js +index 9ef6e47..31c89af 100644 +--- a/core/misc/machine-name.js ++++ b/core/misc/machine-name.js +@@ -1,4 +1,4 @@ +-(function ($) { ++(function ($, Drupal, drupalSettings) { + + "use strict"; + +@@ -42,19 +42,19 @@ Drupal.behaviors.machineName = { + + function machineNameHandler(e) { + var data = e.data; +- machine = self.transliterate($(e.target).val(), data.options); +- // Set the machine name to the transliterated value. +- if (machine !== '') { +- if (machine !== data.options.replace) { +- data.$target.val(machine); +- data.$preview.html(data.options.field_prefix + Drupal.checkPlain(machine) + data.options.field_suffix); +- } +- data.$suffix.show(); ++ var settings = data.options; ++ var baseValue = $(e.target).val(); ++ ++ var rx = new RegExp(settings.replace_pattern, 'g'); ++ var expected = baseValue.toLowerCase().replace(rx, settings.replace).substr(0, settings.maxlength); ++ ++ if(baseValue.toLowerCase() !== expected) { ++ self.transliterate(baseValue, settings).done(function (machine) { ++ self.showMachineName(machine.substr(0, settings.maxlength), data); ++ }); + } + else { +- data.$suffix.hide(); +- data.$target.val(machine); +- data.$preview.empty(); ++ self.showMachineName(expected, data); + } + } + +@@ -124,6 +124,23 @@ Drupal.behaviors.machineName = { + } + }, + ++ showMachineName: function (machine, data) { ++ var settings = data.options; ++ // Set the machine name to the transliterated value. ++ if (machine !== '') { ++ if (machine !== settings.replace) { ++ data.$target.val(machine); ++ data.$preview.html(settings.field_prefix + Drupal.checkPlain(machine) + settings.field_suffix); ++ } ++ data.$suffix.show(); ++ } ++ else { ++ data.$suffix.hide(); ++ data.$target.val(machine); ++ data.$preview.empty(); ++ } ++ }, ++ + /** + * Transliterate a human-readable name to a machine name. + * +@@ -141,9 +158,14 @@ Drupal.behaviors.machineName = { + * The transliterated source string. + */ + transliterate: function (source, settings) { +- var rx = new RegExp(settings.replace_pattern, 'g'); +- return source.toLowerCase().replace(rx, settings.replace).substr(0, settings.maxlength); ++ return $.get(drupalSettings.basePath + 'machine_name/transliterate', { ++ text: source, ++ langcode: drupalSettings.langcode, ++ replace_pattern: settings.replace_pattern, ++ replace: settings.replace, ++ lowercase: true ++ }); + } + }; + +-})(jQuery); ++})(jQuery, Drupal, drupalSettings); +diff --git a/core/modules/system/lib/Drupal/system/MachineNameController.php b/core/modules/system/lib/Drupal/system/MachineNameController.php +new file mode 100644 +index 0000000..69cd888 +--- /dev/null ++++ b/core/modules/system/lib/Drupal/system/MachineNameController.php +@@ -0,0 +1,63 @@ ++transliteration = $transliteration; ++ } ++ ++ /** ++ * Transliterates a string in given language. Various postprocessing possible. ++ * ++ * @param \Symfony\Component\HttpFoundation\Request $request ++ * The input string and language for the transliteration. ++ * Optionally may contain the replace_pattern, replace, lowercase parameters. ++ * ++ * @return \Symfony\Component\HttpFoundation\JsonResponse ++ * The transliterated string. ++ */ ++ public function transliterate(Request $request) { ++ $text = $request->query->get('text'); ++ $langcode = $request->query->get('langcode'); ++ $replace_pattern = $request->query->get('replace_pattern'); ++ $replace = $request->query->get('replace'); ++ $lowercase = $request->query->get('lowercase'); ++ ++ $transliterated = $this->transliteration->transliterate($text, $langcode, '_'); ++ if($lowercase) { ++ $transliterated = drupal_strtolower($transliterated); ++ } ++ if(isset($replace_pattern) && isset($replace)) { ++ $transliterated = preg_replace('@' . $replace_pattern . '@', $replace, $transliterated); ++ } ++ return new JsonResponse($transliterated); ++ } ++ ++} +diff --git a/core/modules/system/lib/Drupal/system/SystemBundle.php b/core/modules/system/lib/Drupal/system/SystemBundle.php +index 2b937c0..fc303ef 100644 +--- a/core/modules/system/lib/Drupal/system/SystemBundle.php ++++ b/core/modules/system/lib/Drupal/system/SystemBundle.php +@@ -8,6 +8,7 @@ + namespace Drupal\system; + + use Symfony\Component\DependencyInjection\ContainerBuilder; ++use Symfony\Component\DependencyInjection\Reference; + use Symfony\Component\HttpKernel\Bundle\Bundle; + + /** +@@ -21,6 +22,8 @@ class SystemBundle extends Bundle { + public function build(ContainerBuilder $container) { + $container->register('access_check.cron', 'Drupal\system\Access\CronAccessCheck') + ->addTag('access_check'); ++ $container->register('system.machine_name_controller', 'Drupal\system\MachineNameController') ++ ->addArgument(new Reference('transliteration')); + + // Register the various system plugin manager classes with the dependency + // injection container. +diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml +index 085895e..f8452c3 100644 +--- a/core/modules/system/system.routing.yml ++++ b/core/modules/system/system.routing.yml +@@ -4,3 +4,9 @@ system.cron: + _controller: '\Drupal\system\CronController::run' + requirements: + _access_system_cron: 'TRUE' ++system.machine_name_transliterate: ++ pattern: '/machine_name/transliterate' ++ defaults: ++ _controller: 'system.machine_name_controller:transliterate' ++ requirements: ++ _permission: 'access content'