Skip to content

Commit

Permalink
Make \Cake\Utility\Text accept \Transliterator objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
ndm2 committed May 22, 2018
1 parent d0d014a commit b29fd68
Show file tree
Hide file tree
Showing 2 changed files with 228 additions and 32 deletions.
94 changes: 80 additions & 14 deletions src/Utility/Text.php
Expand Up @@ -25,9 +25,18 @@ class Text
/**
* Default transliterator id string.
*
* @param string $_defaultTransliteratorId Transliterator identifier string.
* @deprecated 3.7.0 Use $_defaultTransliterator instead.
* @var string $_defaultTransliteratorId Transliterator identifier string.
*/
protected static $_defaultTransliteratorId = 'Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove';
protected static $_defaultTransliteratorId;

/**
* Default transliterator.
*
* @var \Transliterator|string Either a Transliterator instance, or a
* transliterator identifier string.
*/
protected static $_defaultTransliterator = 'Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove';

/**
* Default html tags who must not be count for truncate text.
Expand Down Expand Up @@ -1054,38 +1063,86 @@ public static function parseFileSize($size, $default = false)
/**
* Get default transliterator identifier string.
*
* @deprecated 3.7.0 Use getTransliterator() instead.
* @return string Transliterator identifier.
*/
public static function getTransliteratorId()
{
return static::$_defaultTransliteratorId;
deprecationWarning(
'Text::getTransliteratorId() is deprecated. ' .
'Use Text::getTransliterator() instead.'
);

return static::getTransliterator();
}

/**
* Set default transliterator identifier string.
*
* @deprecated 3.7.0 Use setTransliterator() instead.
* @param string $transliteratorId Transliterator identifier.
* @return void
*/
public static function setTransliteratorId($transliteratorId)
{
static::$_defaultTransliteratorId = $transliteratorId;
deprecationWarning(
'Text::setTransliteratorId() is deprecated. ' .
'Use Text::setTransliterator() instead.'
);

static::setTransliterator($transliteratorId);
}

/**
* Get the default transliterator.
*
* @return \Transliterator|string Either a Transliterator instance, or a
* transliterator identifier string.
* @since 3.7.0
*/
public static function getTransliterator()
{
return static::$_defaultTransliterator;
}

/**
* Set default transliterator identifier string.
*
* @param \Transliterator|string $transliterator Either a Transliterator
* instance, or a transliterator identifier string.
* @return void
* @since 3.7.0
*/
public static function setTransliterator($transliterator)
{
static::$_defaultTransliterator = $transliterator;
}

/**
* Transliterate string.
*
* @param string $string String to transliterate.
* @param string|null $transliteratorId Transliterator identifier. If null
* Text::$_defaultTransliteratorId will be used.
* @param \Transliterator|string|null $transliterator Either a Transliterator
* instance, or a transliterator identifier string. If `null`
* `Text::$_defaultTransliterator` will be used.
* @return string
* @see https://secure.php.net/manual/en/transliterator.transliterate.php
*/
public static function transliterate($string, $transliteratorId = null)
public static function transliterate($string, $transliterator = null)
{
$transliteratorId = $transliteratorId ?: static::$_defaultTransliteratorId;
if (!$transliterator) {
if (static::$_defaultTransliteratorId !== null) {
deprecationWarning(
'`Text::$_defaultTransliteratorId` is deprecated. ' .
'Use `Text::$_defaultTransliterator` instead.'
);
$transliterator = static::$_defaultTransliteratorId;
} else {
$transliterator = static::$_defaultTransliterator;
}
}

return transliterator_transliterate($transliteratorId, $string);
return transliterator_transliterate($transliterator, $string);
}

/**
Expand All @@ -1095,9 +1152,11 @@ public static function transliterate($string, $transliteratorId = null)
* ### Options:
*
* - `replacement`: Replacement string. Default '-'.
* - `transliteratorId`: A valid tranliterator id string.
* If default `null` Text::$_defaultTransliteratorId to be used.
* - `transliterator`: A Transliterator instance, or a transliterator id string.
* If `null` (default) `Text::$_defaultTransliterator` will be used.
* If `false` no transliteration will be done, only non words will be removed.
* - `transliteratorId`: Deprecated as of 3.7.0, use the `transliterator` option
* instead.
* - `preserve`: Specific non-word character to preserve. Default `null`.
* For e.g. this option can be set to '.' to generate clean file names.
*
Expand All @@ -1113,12 +1172,19 @@ public static function slug($string, $options = [])
}
$options += [
'replacement' => '-',
'transliteratorId' => null,
'transliterator' => null,
'preserve' => null
];

if ($options['transliteratorId'] !== false) {
$string = static::transliterate($string, $options['transliteratorId']);
if (array_key_exists('transliteratorId', $options)) {
deprecationWarning(
'The `transliteratorId` option is deprecated. ' .
'Use `transliterator` instead.'
);
$options['transliterator'] = $options['transliteratorId'];
}
if ($options['transliterator'] !== false) {
$string = static::transliterate($string, $options['transliterator']);
}

$regex = '^\s\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}';
Expand Down
166 changes: 148 additions & 18 deletions tests/TestCase/Utility/TextTest.php
Expand Up @@ -17,6 +17,14 @@
use Cake\TestSuite\TestCase;
use Cake\Utility\Text;

/**
* Helper class that assists with testing overloading of a deprecated property.
*/
class TextOverloadDeprecatedTransliteratorIdProperty extends Text
{
protected static $_defaultTransliteratorId = 'Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove';
}

/**
* TextTest class
*/
Expand Down Expand Up @@ -1685,16 +1693,44 @@ public function filesizes()
*
* @return void
*/
public function testGetSetTransliteratorId()
public function testDeprecatedGetSetTransliteratorId()
{
$defaultTransliteratorId = 'Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove';
$this->assertEquals($defaultTransliteratorId, Text::getTransliteratorId());
$this->deprecated(function () {
$defaultTransliteratorId = 'Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove';
$this->assertEquals($defaultTransliteratorId, Text::getTransliteratorId());

$expected = 'Latin-ASCII; [\u0080-\u7fff] remove';
Text::setTransliteratorId($expected);
$this->assertEquals($expected, Text::getTransliteratorId());
$expected = 'Latin-ASCII; [\u0080-\u7fff] remove';
Text::setTransliteratorId($expected);
$this->assertEquals($expected, Text::getTransliteratorId());

Text::setTransliteratorId($defaultTransliteratorId);
Text::setTransliteratorId($defaultTransliteratorId);
});
}

/**
* Test getting/setting default transliterator.
*
* @return void
*/
public function testGetSetTransliterator()
{
$defaultTransliterator = 'Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove';
$this->assertEquals($defaultTransliterator, Text::getTransliterator());

$expected = 'Latin-ASCII; [\u0080-\u7fff] remove';
Text::setTransliterator($expected);
$this->assertEquals($expected, Text::getTransliterator());

$transliterator = \Transliterator::createFromRules('
$nonletter = [:^Letter:];
$nonletter → \'*\';
::Latin-ASCII;
');
$this->assertInstanceOf(\Transliterator::class, $transliterator);
Text::setTransliterator($transliterator);
$this->assertSame($transliterator, Text::getTransliterator());

Text::setTransliterator($defaultTransliterator);
}

/**
Expand Down Expand Up @@ -1748,17 +1784,35 @@ public function transliterateInputProvider()
* testTransliterate method
*
* @param string $string String
* @param string $transliteratorId Transliterator Id
* @param String $expected Exepected string
* @param \Transliterator|string|null $transliterator Transliterator
* @param String $expected Expected string
* @return void
* @dataProvider transliterateInputProvider
*/
public function testTransliterate($string, $transliteratorId, $expected)
public function testTransliterate($string, $transliterator, $expected)
{
$result = Text::transliterate($string, $transliteratorId);
$result = Text::transliterate($string, $transliterator);
$this->assertEquals($expected, $result);
}

/**
* testTransliterateOverloadDeprecatedTransliteratorIdProperty method
*
* Tests that extending classes that overload the deprecated `$_defaultTransliteratorId`
* property still work as expected, and trigger a deprecation notice.
*
* @return void
*/
public function testTransliterateOverloadDeprecatedTransliteratorIdProperty()
{
$this->deprecated(function () {
$this->assertEquals(
'ringo',
TextOverloadDeprecatedTransliteratorIdProperty::transliterate('りんご')
);
});
}

public function slugInputProvider()
{
return [
Expand All @@ -1779,12 +1833,29 @@ public function slugInputProvider()
'A-ae-Ubermensch-pa-hoyeste-niva-I-a-lublu-PHP-est-fi'
],
[
'A æ Übérmensch på høyeste nivå! И я люблю PHP! есть. fi ¦', ['transliteratorId' => 'Latin-ASCII'],
'A æ Übérmensch på høyeste nivå! И я люблю PHP! есть. fi ¦', ['transliterator' => 'Latin-ASCII'],
'A-ae-Ubermensch-pa-hoyeste-niva-И-я-люблю-PHP-есть-fi'
],
[
'Äpfel Über Öl grün ärgert groß öko', [],
'Apfel-Uber-Ol-grun-argert-gross-oko'
'Äpfel Über Öl grün ärgert groß öko',
[
'transliterator' => \Transliterator::createFromRules('
$AE = [Ä {A \u0308}];
$OE = [Ö {O \u0308}];
$UE = [Ü {U \u0308}];
[ä {a \u0308}] → ae;
[ö {o \u0308}] → oe;
[ü {u \u0308}] → ue;
{$AE} [:Lowercase:] → Ae;
{$OE} [:Lowercase:] → Oe;
{$UE} [:Lowercase:] → Ue;
$AE → AE;
$OE → OE;
$UE → UE;
::Latin-ASCII;
'),
],
'Aepfel-Ueber-Oel-gruen-aergert-gross-oeko'
],
[
'The truth - and- more- news', [],
Expand All @@ -1811,15 +1882,15 @@ public function slugInputProvider()
'this-melts-your-face1-2-3'
],
[
'controller/action/りんご/1', ['transliteratorId' => false],
'controller/action/りんご/1', ['transliterator' => false],
'controller-action-りんご-1'
],
[
'の話が出たので大丈夫かなあと', ['transliteratorId' => false],
'の話が出たので大丈夫かなあと', ['transliterator' => false],
'の話が出たので大丈夫かなあと'
],
[
'posts/view/한국어/page:1/sort:asc', ['transliteratorId' => false],
'posts/view/한국어/page:1/sort:asc', ['transliterator' => false],
'posts-view-한국어-page-1-sort-asc'
],
[
Expand Down Expand Up @@ -1850,7 +1921,7 @@ public function slugInputProvider()
*
* @param string $string String
* @param array $options Options
* @param String $expected Exepected string
* @param String $expected Expected string
* @return void
* @dataProvider slugInputProvider
*/
Expand All @@ -1860,6 +1931,65 @@ public function testSlug($string, $options, $expected)
$this->assertEquals($expected, $result);
}

public function slugDeprecatedTransliteratorIdOptionInputProvider()
{
return [
[
'A æ Übérmensch på høyeste nivå! И я люблю PHP! есть. fi ¦',
['transliteratorId' => 'Latin-ASCII'],
'A-ae-Ubermensch-pa-hoyeste-niva-И-я-люблю-PHP-есть-fi'
],
[
'Äpfel Über Öl grün ärgert groß öko',
[
'transliterator' => \Transliterator::createFromRules('
$AE = [Ä {A \u0308}];
$OE = [Ö {O \u0308}];
$UE = [Ü {U \u0308}];
[ä {a \u0308}] → ae;
[ö {o \u0308}] → oe;
[ü {u \u0308}] → ue;
{$AE} [:Lowercase:] → Ae;
{$OE} [:Lowercase:] → Oe;
{$UE} [:Lowercase:] → Ue;
$AE → AE;
$OE → OE;
$UE → UE;
::Latin-ASCII;
'),
],
'Aepfel-Ueber-Oel-gruen-aergert-gross-oeko'
],
[
'controller/action/りんご/1',
['transliteratorId' => false],
'controller-action-りんご-1'
],
[
'cl#ean(me',
['transliteratorId' => null],
'cl-ean-me'
]
];
}

/**
* testSlugDeprecatedTransliteratorIdOption method
*
* @param string $string String
* @param array $options Options
* @param String $expected Expected string
* @return void
* @dataProvider slugDeprecatedTransliteratorIdOptionInputProvider
*/
public function testSlugDeprecatedTransliteratorIdOption($string, $options, $expected)
{
$this->deprecated(function () use ($string, $options, $expected) {
$result = Text::slug($string, $options);
$this->assertEquals($expected, $result);
});
}

/**
* Text truncateByWidth method
*
Expand Down

0 comments on commit b29fd68

Please sign in to comment.