Browse Source

Backport Inflector improvements for multi words. (#14678)

Mark Sch 5 years ago
parent
commit
ae22fceb73
2 changed files with 36 additions and 8 deletions
  1. 24 8
      src/Utility/Inflector.php
  2. 12 0
      tests/TestCase/Utility/InflectorTest.php

+ 24 - 8
src/Utility/Inflector.php

@@ -507,10 +507,17 @@ class Inflector
         }
 
         if (!isset(static::$_cache['irregular']['pluralize'])) {
-            static::$_cache['irregular']['pluralize'] = '(?:' . implode('|', array_keys(static::$_irregular)) . ')';
+            $words = array_keys(static::$_irregular);
+            static::$_cache['irregular']['pluralize'] = '/(.*?(?:\\b|_))(' . implode('|', $words) . ')$/i';
+
+            $upperWords = array_map('ucfirst', $words);
+            static::$_cache['irregular']['upperPluralize'] = '/(.*?(?:\\b|[a-z]))(' . implode('|', $upperWords) . ')$/';
         }
 
-        if (preg_match('/(.*?(?:\\b|_))(' . static::$_cache['irregular']['pluralize'] . ')$/i', $word, $regs)) {
+        if (
+            preg_match(static::$_cache['irregular']['pluralize'], $word, $regs) ||
+            preg_match(static::$_cache['irregular']['upperPluralize'], $word, $regs)
+        ) {
             static::$_cache['pluralize'][$word] = $regs[1] . substr($regs[2], 0, 1) .
                 substr(static::$_irregular[strtolower($regs[2])], 1);
 
@@ -518,10 +525,10 @@ class Inflector
         }
 
         if (!isset(static::$_cache['uninflected'])) {
-            static::$_cache['uninflected'] = '(?:' . implode('|', static::$_uninflected) . ')';
+            static::$_cache['uninflected'] = '/^(' . implode('|', static::$_uninflected) . ')$/i';
         }
 
-        if (preg_match('/^(' . static::$_cache['uninflected'] . ')$/i', $word, $regs)) {
+        if (preg_match(static::$_cache['uninflected'], $word, $regs)) {
             static::$_cache['pluralize'][$word] = $word;
 
             return $word;
@@ -550,10 +557,19 @@ class Inflector
         }
 
         if (!isset(static::$_cache['irregular']['singular'])) {
-            static::$_cache['irregular']['singular'] = '(?:' . implode('|', static::$_irregular) . ')';
+            $wordList = array_values(static::$_irregular);
+            static::$_cache['irregular']['singular'] = '/(.*?(?:\\b|_))(' . implode('|', $wordList) . ')$/i';
+
+            $upperWordList = array_map('ucfirst', $wordList);
+            static::$_cache['irregular']['singularUpper'] = '/(.*?(?:\\b|[a-z]))(' .
+                implode('|', $upperWordList) .
+                ')$/';
         }
 
-        if (preg_match('/(.*?(?:\\b|_))(' . static::$_cache['irregular']['singular'] . ')$/i', $word, $regs)) {
+        if (
+            preg_match(static::$_cache['irregular']['singular'], $word, $regs) ||
+            preg_match(static::$_cache['irregular']['singularUpper'], $word, $regs)
+        ) {
             static::$_cache['singularize'][$word] = $regs[1] . substr($regs[2], 0, 1) .
                 substr(array_search(strtolower($regs[2]), static::$_irregular, true), 1);
 
@@ -561,10 +577,10 @@ class Inflector
         }
 
         if (!isset(static::$_cache['uninflected'])) {
-            static::$_cache['uninflected'] = '(?:' . implode('|', static::$_uninflected) . ')';
+            static::$_cache['uninflected'] = '/^(' . implode('|', static::$_uninflected) . ')$/i';
         }
 
-        if (preg_match('/^(' . static::$_cache['uninflected'] . ')$/i', $word, $regs)) {
+        if (preg_match(static::$_cache['uninflected'], $word, $regs)) {
             static::$_cache['pluralize'][$word] = $word;
 
             return $word;

+ 12 - 0
tests/TestCase/Utility/InflectorTest.php

@@ -630,6 +630,12 @@ class InflectorTest extends TestCase
         $this->assertEquals('alertables', Inflector::pluralize('alert'));
         $this->assertEquals('amazable', Inflector::pluralize('amaze'));
         $this->assertEquals('phonezes', Inflector::pluralize('phone'));
+
+        $this->assertSame('criteria', Inflector::pluralize('criterion'));
+        $this->assertSame('test_criteria', Inflector::pluralize('test_criterion'));
+        $this->assertSame('Criteria', Inflector::pluralize('Criterion'));
+        $this->assertSame('TestCriteria', Inflector::pluralize('TestCriterion'));
+        $this->assertSame('Test Criteria', Inflector::pluralize('Test Criterion'));
     }
 
     /**
@@ -652,6 +658,12 @@ class InflectorTest extends TestCase
         $this->assertEquals('inflecta', Inflector::singularize('inflectors'));
         $this->assertEquals('contributa', Inflector::singularize('contributors'));
         $this->assertEquals('singulars', Inflector::singularize('singulars'));
+
+        $this->assertSame('criterion', Inflector::singularize('criteria'));
+        $this->assertSame('test_criterion', Inflector::singularize('test_criteria'));
+        $this->assertSame('Criterion', Inflector::singularize('Criteria'));
+        $this->assertSame('TestCriterion', Inflector::singularize('TestCriteria'));
+        $this->assertSame('Test Criterion', Inflector::singularize('Test Criteria'));
     }
 
     /**