diff --git a/core/core.services.yml b/core/core.services.yml index 9f5d6fc325bb92791a1d5a20499cb144575a91b0..021ac1a31224e2aaa56e1f078c72faaf7b3b3347 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -936,6 +936,7 @@ services: arguments: ['@csrf_token'] transliteration: class: Drupal\Core\Transliteration\PhpTransliteration + arguments: [null, '@module_handler'] flood: class: Drupal\Core\Flood\DatabaseBackend arguments: ['@database', '@request_stack'] diff --git a/core/lib/Drupal/Core/Transliteration/PhpTransliteration.php b/core/lib/Drupal/Core/Transliteration/PhpTransliteration.php index 42ba3f0d7aae4f7b887b835e1aa618e0c5b9fd8c..fe699dd8de6e58690ac719f408602a99c15aed00 100644 --- a/core/lib/Drupal/Core/Transliteration/PhpTransliteration.php +++ b/core/lib/Drupal/Core/Transliteration/PhpTransliteration.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Transliteration; use Drupal\Component\Transliteration\PhpTransliteration as BaseTransliteration; +use Drupal\Core\Extension\ModuleHandlerInterface; /** * Enhances PhpTransliteration with an alter hook. @@ -17,6 +18,29 @@ */ class PhpTransliteration extends BaseTransliteration { + /** + * The module handler to execute the transliteration_overrides alter hook. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** + * Constructs a PhpTransliteration object. + * + * @param string $data_directory + * (optional) The directory where data files reside. If omitted, defaults + * to subdirectory 'data' underneath the directory where the class's PHP + * file resides. + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler to execute the transliteration_overrides alter hook. + */ + public function __construct($data_directory = NULL, ModuleHandlerInterface $module_handler) { + parent::__construct($data_directory); + + $this->moduleHandler = $module_handler; + } + /** * Overrides \Drupal\Component\Transliteration\PhpTransliteration::readLanguageOverrides(). * @@ -27,7 +51,7 @@ protected function readLanguageOverrides($langcode) { parent::readLanguageOverrides($langcode); // Let modules alter the language-specific overrides. - \Drupal::moduleHandler()->alter('transliteration_overrides', $this->languageOverrides[$langcode], $langcode); + $this->moduleHandler->alter('transliteration_overrides', $this->languageOverrides[$langcode], $langcode); } } diff --git a/core/modules/system/tests/modules/transliterate_test/transliterate_test.info.yml b/core/modules/system/tests/modules/transliterate_test/transliterate_test.info.yml deleted file mode 100644 index 9eeddd5a6eecd64ee342352731f1c6c39e6020d2..0000000000000000000000000000000000000000 --- a/core/modules/system/tests/modules/transliterate_test/transliterate_test.info.yml +++ /dev/null @@ -1,6 +0,0 @@ -name: 'Transliteration test' -type: module -description: 'Helper module for Transliteration system tests.' -package: Testing -version: VERSION -core: 8.x diff --git a/core/modules/system/tests/modules/transliterate_test/transliterate_test.module b/core/modules/system/tests/modules/transliterate_test/transliterate_test.module deleted file mode 100644 index 636fde8a188dd9eb594ac8e79e27c345986c8e18..0000000000000000000000000000000000000000 --- a/core/modules/system/tests/modules/transliterate_test/transliterate_test.module +++ /dev/null @@ -1,20 +0,0 @@ -transliterate($original, $langcode, $unknown_character, $max_length); + $this->assertSame($expected, $actual); + } /** - * Tests the PhpTransliteration class. + * Provides data for self::testPhpTransliteration(). + * + * @return array + * An array of arrays, each containing the parameters for + * self::testPhpTransliteration(). */ - public function testPhpTransliteration() { - $random = $this->randomMachineName(10); + public function providerTestPhpTransliteration() { + $random_generator = new Random(); + $random = $random_generator->string(10); // Make some strings with two, three, and four-byte characters for testing. // Note that the 3-byte character is overridden by the 'kg' language. $two_byte = 'Ä Ö Ü Å Ø äöüåøhello'; @@ -41,10 +68,8 @@ public function testPhpTransliteration() { // http://en.wikipedia.org/wiki/Gothic_alphabet // They are not in our tables, but should at least give us '?' (unknown). $five_byte = html_entity_decode('𐌰𐌸', ENT_NOQUOTES, 'UTF-8'); - // Five-byte characters do not work in MySQL, so make a printable version. - $five_byte_printable = '𐌰𐌸'; - $cases = array( + return array( // Each test case is (language code, input, output). // Test ASCII in English. array('en', $random, $random), @@ -57,7 +82,7 @@ public function testPhpTransliteration() { array('fr', $three_byte, 'c'), array('fr', $four_byte, 'wii'), // Test 5-byte characters. - array('en', $five_byte, '??', $five_byte_printable), + array('en', $five_byte, '??'), // Test a language with no overrides. array('en', $two_byte, 'A O U A O aouaohello'), // Test language overrides provided by core. @@ -66,47 +91,29 @@ public function testPhpTransliteration() { array('dk', $two_byte, 'A O U Aa Oe aouaaoehello'), array('dk', $random, $random), array('kg', $three_byte, 'ts'), - // Test the language override hook in the test module, which changes - // the transliteration of Ä to Z and provides for the 5-byte characters. - array('zz', $two_byte, 'Z O U A O aouaohello'), - array('zz', $random, $random), - array('zz', $five_byte, 'ATh', $five_byte_printable), // Test strings in some other languages. // Turkish, provided by drupal.org user Kartagis. array('tr', 'Abayı serdiler bize. Söyleyeceğim yüzlerine. Sanırım hepimiz aynı şeyi düşünüyoruz.', 'Abayi serdiler bize. Soyleyecegim yuzlerine. Sanirim hepimiz ayni seyi dusunuyoruz.'), + // Illegal/unknown unicode. + array('en', chr(0xF8) . chr(0x80) . chr(0x80) . chr(0x80) . chr(0x80), '?'), + // Max length. + array('de', $two_byte, 'Ae Oe', '?', 5), ); + } - // Test each case both with a new instance of the transliteration class, - // and with one that builds as it goes. - $transliterator_service = $this->container->get('transliteration'); - - foreach($cases as $case) { - list($langcode, $original, $expected) = $case; - $printable = (isset($case[3])) ? $case[3] : $original; - $transliterator_class = new PhpTransliteration(); - $actual = $transliterator_class->transliterate($original, $langcode); - $this->assertIdentical($actual, $expected, format_string('@original transliteration to @actual is identical to @expected for language @langcode in new class instance.', array( - '@original' => $printable, - '@langcode' => $langcode, - '@expected' => $expected, - '@actual' => $actual, - ))); - - $actual = $transliterator_service->transliterate($original, $langcode); - $this->assertIdentical($actual, $expected, format_string('@original transliteration to @actual is identical to @expected for language @langcode in service instance.', array( - '@original' => $printable, - '@langcode' => $langcode, - '@expected' => $expected, - '@actual' => $actual, - ))); - } + /** + * Tests the transliteration with max length. + */ + public function testTransliterationWithMaxLength() { + $transliteration = new PhpTransliteration(); // Test with max length, using German. It should never split up the // transliteration of a single character. $input = 'Ä Ö Ü Å Ø äöüåøhello'; $trunc_output = 'Ae Oe Ue A O aeoe'; - $this->assertIdentical($trunc_output, $transliterator_service->transliterate($input, 'de', '?', 17), 'Truncating to 17 characters works'); - $this->assertIdentical($trunc_output, $transliterator_service->transliterate($input, 'de', '?', 18), 'Truncating to 18 characters works'); + $this->assertSame($trunc_output, $transliteration->transliterate($input, 'de', '?', 17), 'Truncating to 17 characters works'); + $this->assertSame($trunc_output, $transliteration->transliterate($input, 'de', '?', 18), 'Truncating to 18 characters works'); } + } diff --git a/core/tests/Drupal/Tests/Core/Block/BlockBaseTest.php b/core/tests/Drupal/Tests/Core/Block/BlockBaseTest.php index fdf878772728062eced488366c29bf6d829e1479..b9434120a7dc4efd44a68c3c6aafe3bfc00be6e8 100644 --- a/core/tests/Drupal/Tests/Core/Block/BlockBaseTest.php +++ b/core/tests/Drupal/Tests/Core/Block/BlockBaseTest.php @@ -22,8 +22,9 @@ class BlockBaseTest extends UnitTestCase { * @see \Drupal\Core\Block\BlockBase::getMachineNameSuggestion(). */ public function testGetMachineNameSuggestion() { + $module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); $transliteration = $this->getMockBuilder('Drupal\Core\Transliteration\PhpTransliteration') - // @todo Inject the module handler into PhpTransliteration. + ->setConstructorArgs(array(NULL, $module_handler)) ->setMethods(array('readLanguageOverrides')) ->getMock(); diff --git a/core/tests/Drupal/Tests/Core/Transliteration/PhpTransliterationTest.php b/core/tests/Drupal/Tests/Core/Transliteration/PhpTransliterationTest.php new file mode 100644 index 0000000000000000000000000000000000000000..44d5d9538adfbe8a0a742a10be4df3b3187dbe6f --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Transliteration/PhpTransliterationTest.php @@ -0,0 +1,99 @@ +getMock('Drupal\Core\Extension\ModuleHandlerInterface'); + $module_handler->expects($this->any()) + ->method('alter') + ->will($this->returnCallback(function($hook, &$overrides, $langcode) { + if ($langcode == 'zz') { + // The default transliteration of Ä is A, but change it to Z for testing. + $overrides[0xC4] = 'Z'; + // Also provide transliterations of two 5-byte characters from + // http://en.wikipedia.org/wiki/Gothic_alphabet. + $overrides[0x10330] = 'A'; + $overrides[0x10338] = 'Th'; + } + })); + $transliteration = new PhpTransliteration(NULL, $module_handler); + + $actual = $transliteration->transliterate($original, $langcode); + $this->assertSame($expected, $actual, String::format('@original transliteration to @actual is identical to @expected for language @langcode in service instance.', array( + '@original' => $printable, + '@langcode' => $langcode, + '@expected' => $expected, + '@actual' => $actual, + ))); + } + + /** + * Provides test data for testPhpTransliterationWithAlter. + * + * @return array + */ + public function providerTestPhpTransliterationWithAlter() { + $random_generator = new Random(); + $random = $random_generator->string(10); + // Make some strings with two, three, and four-byte characters for testing. + // Note that the 3-byte character is overridden by the 'kg' language. + $two_byte = 'Ä Ö Ü Å Ø äöüåøhello'; + // These are two Gothic alphabet letters. See + // http://en.wikipedia.org/wiki/Gothic_alphabet + // They are not in our tables, but should at least give us '?' (unknown). + $five_byte = html_entity_decode('𐌰𐌸', ENT_NOQUOTES, 'UTF-8'); + // Five-byte characters do not work in MySQL, so make a printable version. + $five_byte_printable = '𐌰𐌸'; + + $cases = array( + // Test the language override hook in the test module, which changes + // the transliteration of Ä to Z and provides for the 5-byte characters. + array('zz', $two_byte, 'Z O U A O aouaohello'), + array('zz', $random, $random), + array('zz', $five_byte, 'ATh', $five_byte_printable), + ); + + return $cases; + } + +}