Skip to content

Commit d8ae47c

Browse files
Geordiefabpot
Geordie
authored andcommitted
[String] Fix #54611 pluralization of -on ending words + singularization of -a ending foreign words
1 parent dd2c915 commit d8ae47c

File tree

2 files changed

+55
-32
lines changed

2 files changed

+55
-32
lines changed

Inflector/EnglishInflector.php

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,32 @@ final class EnglishInflector implements InflectorInterface
2525
// Fourth entry: Whether the suffix may succeed a consonant
2626
// Fifth entry: singular suffix, normal
2727

28-
// bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
29-
['a', 1, true, true, ['on', 'um']],
28+
// bacteria (bacterium)
29+
['airetcab', 8, true, true, 'bacterium'],
30+
31+
// corpora (corpus)
32+
['aroproc', 7, true, true, 'corpus'],
33+
34+
// criteria (criterion)
35+
['airetirc', 8, true, true, 'criterion'],
36+
37+
// curricula (curriculum)
38+
['alucirruc', 9, true, true, 'curriculum'],
39+
40+
// genera (genus)
41+
['areneg', 6, true, true, 'genus'],
42+
43+
// media (medium)
44+
['aidem', 5, true, true, 'medium'],
45+
46+
// memoranda (memorandum)
47+
['adnaromem', 9, true, true, 'memorandum'],
48+
49+
// phenomena (phenomenon)
50+
['anemonehp', 9, true, true, 'phenomenon'],
51+
52+
// strata (stratum)
53+
['atarts', 6, true, true, 'stratum'],
3054

3155
// nebulae (nebula)
3256
['ea', 2, true, true, 'a'],
@@ -141,7 +165,7 @@ final class EnglishInflector implements InflectorInterface
141165
// shoes (shoe)
142166
['se', 2, true, true, ['', 'e']],
143167

144-
// status (status)
168+
// status (status)
145169
['sutats', 6, true, true, 'status'],
146170

147171
// tags (tag)
@@ -241,7 +265,7 @@ final class EnglishInflector implements InflectorInterface
241265
// albums (album)
242266
['mubla', 5, true, true, 'albums'],
243267

244-
// bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
268+
// bacteria (bacterium), curricula (curriculum), media (medium), memoranda (memorandum), phenomena (phenomenon), strata (stratum)
245269
['mu', 2, true, true, 'a'],
246270

247271
// men (man), women (woman)
@@ -250,20 +274,11 @@ final class EnglishInflector implements InflectorInterface
250274
// people (person)
251275
['nosrep', 6, true, true, ['persons', 'people']],
252276

253-
// bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
254-
['noi', 3, true, true, 'ions'],
255-
256-
// coupon (coupons)
257-
['nop', 3, true, true, 'pons'],
258-
259-
// seasons (season), treasons (treason), poisons (poison), lessons (lesson)
260-
['nos', 3, true, true, 'sons'],
261-
262-
// icons (icon)
263-
['noc', 3, true, true, 'cons'],
277+
// criteria (criterion)
278+
['noiretirc', 9, true, true, 'criteria'],
264279

265-
// bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
266-
['no', 2, true, true, 'a'],
280+
// phenomena (phenomenon)
281+
['nonemonehp', 10, true, true, 'phenomena'],
267282

268283
// echoes (echo)
269284
['ohce', 4, true, true, 'echoes'],
@@ -404,9 +419,6 @@ final class EnglishInflector implements InflectorInterface
404419
'erawdrah',
405420
];
406421

407-
/**
408-
* {@inheritdoc}
409-
*/
410422
public function singularize(string $plural): array
411423
{
412424
$pluralRev = strrev($plural);
@@ -438,7 +450,7 @@ public function singularize(string $plural): array
438450
if ($j === $suffixLength) {
439451
// Is there any character preceding the suffix in the plural string?
440452
if ($j < $pluralLength) {
441-
$nextIsVowel = false !== strpos('aeiou', $lowerPluralRev[$j]);
453+
$nextIsVowel = str_contains('aeiou', $lowerPluralRev[$j]);
442454

443455
if (!$map[2] && $nextIsVowel) {
444456
// suffix may not succeed a vowel but next char is one
@@ -483,9 +495,6 @@ public function singularize(string $plural): array
483495
return [$plural];
484496
}
485497

486-
/**
487-
* {@inheritdoc}
488-
*/
489498
public function pluralize(string $singular): array
490499
{
491500
$singularRev = strrev($singular);
@@ -518,7 +527,7 @@ public function pluralize(string $singular): array
518527
if ($j === $suffixLength) {
519528
// Is there any character preceding the suffix in the plural string?
520529
if ($j < $singularLength) {
521-
$nextIsVowel = false !== strpos('aeiou', $lowerSingularRev[$j]);
530+
$nextIsVowel = str_contains('aeiou', $lowerSingularRev[$j]);
522531

523532
if (!$map[2] && $nextIsVowel) {
524533
// suffix may not succeed a vowel but next char is one

Tests/Inflector/EnglishInflectorTest.php

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public static function singularizeProvider()
3535
['atlases', ['atlas', 'atlase', 'atlasis']],
3636
['axes', ['ax', 'axe', 'axis']],
3737
['babies', 'baby'],
38-
['bacteria', ['bacterion', 'bacterium']],
38+
['bacteria', 'bacterium'],
3939
['bases', ['bas', 'base', 'basis']],
4040
['batches', ['batch', 'batche']],
4141
['beaux', 'beau'],
@@ -46,6 +46,7 @@ public static function singularizeProvider()
4646
['bureaux', 'bureau'],
4747
['buses', ['bus', 'buse', 'busis']],
4848
['bushes', ['bush', 'bushe']],
49+
['buttons', 'button'],
4950
['calves', ['calf', 'calve', 'calff']],
5051
['cars', 'car'],
5152
['cassettes', ['cassett', 'cassette']],
@@ -57,10 +58,12 @@ public static function singularizeProvider()
5758
['cliffs', 'cliff'],
5859
['codes', 'code'],
5960
['committee', 'committee'],
61+
['corpora', 'corpus'],
62+
['coupons', 'coupon'],
6063
['crises', ['cris', 'crise', 'crisis']],
61-
['criteria', ['criterion', 'criterium']],
64+
['criteria', 'criterion'],
6265
['cups', 'cup'],
63-
['coupons', 'coupon'],
66+
['curricula', 'curriculum'],
6467
['data', 'data'],
6568
['days', 'day'],
6669
['discos', 'disco'],
@@ -86,6 +89,7 @@ public static function singularizeProvider()
8689
['funguses', ['fungus', 'funguse', 'fungusis']],
8790
['garages', ['garag', 'garage']],
8891
['geese', 'goose'],
92+
['genera', 'genus'],
8993
['halves', ['half', 'halve', 'halff']],
9094
['hats', 'hat'],
9195
['heroes', ['hero', 'heroe']],
@@ -106,6 +110,8 @@ public static function singularizeProvider()
106110
['lives', 'life'],
107111
['matrices', ['matrex', 'matrix', 'matrice']],
108112
['matrixes', 'matrix'],
113+
['media', 'medium'],
114+
['memoranda', 'memorandum'],
109115
['men', 'man'],
110116
['mice', 'mouse'],
111117
['moves', 'move'],
@@ -120,7 +126,7 @@ public static function singularizeProvider()
120126
['parties', 'party'],
121127
['people', 'person'],
122128
['persons', 'person'],
123-
['phenomena', ['phenomenon', 'phenomenum']],
129+
['phenomena', 'phenomenon'],
124130
['photos', 'photo'],
125131
['pianos', 'piano'],
126132
['plateaux', 'plateau'],
@@ -146,7 +152,7 @@ public static function singularizeProvider()
146152
['status', 'status'],
147153
['statuses', 'status'],
148154
['stories', 'story'],
149-
['strata', ['straton', 'stratum']],
155+
['strata', 'stratum'],
150156
['suitcases', ['suitcas', 'suitcase', 'suitcasis']],
151157
['syllabi', 'syllabus'],
152158
['tags', 'tag'],
@@ -200,7 +206,9 @@ public static function pluralizeProvider()
200206
['bureau', ['bureaus', 'bureaux']],
201207
['bus', 'buses'],
202208
['bush', 'bushes'],
209+
['button', 'buttons'],
203210
['calf', ['calfs', 'calves']],
211+
['campus', 'campuses'],
204212
['car', 'cars'],
205213
['cassette', 'cassettes'],
206214
['cave', 'caves'],
@@ -210,10 +218,11 @@ public static function pluralizeProvider()
210218
['circus', 'circuses'],
211219
['cliff', 'cliffs'],
212220
['committee', 'committees'],
221+
['coupon', 'coupons'],
213222
['crisis', 'crises'],
214-
['criteria', 'criterion'],
223+
['criterion', 'criteria'],
215224
['cup', 'cups'],
216-
['coupon', 'coupons'],
225+
['curriculum', 'curricula'],
217226
['data', 'data'],
218227
['day', 'days'],
219228
['disco', 'discos'],
@@ -237,10 +246,12 @@ public static function pluralizeProvider()
237246
['half', ['halfs', 'halves']],
238247
['hat', 'hats'],
239248
['hero', 'heroes'],
249+
['hippocampus', 'hippocampi'],
240250
['hippopotamus', 'hippopotami'], // hippopotamuses
241251
['hoax', 'hoaxes'],
242252
['hoof', ['hoofs', 'hooves']],
243253
['house', 'houses'],
254+
['icon', 'icons'],
244255
['index', ['indicies', 'indexes']],
245256
['ion', 'ions'],
246257
['iris', 'irises'],
@@ -253,6 +264,8 @@ public static function pluralizeProvider()
253264
['louse', 'lice'],
254265
['man', 'men'],
255266
['matrix', ['matricies', 'matrixes']],
267+
['medium', 'media'],
268+
['memorandum', 'memoranda'],
256269
['mouse', 'mice'],
257270
['move', 'moves'],
258271
['movie', 'movies'],
@@ -286,6 +299,7 @@ public static function pluralizeProvider()
286299
['shoe', 'shoes'],
287300
['species', 'species'],
288301
['status', ['status', 'statuses']],
302+
['stratum', 'strata'],
289303
['spy', 'spies'],
290304
['staff', 'staves'],
291305
['story', 'stories'],

0 commit comments

Comments
 (0)