Inflector   B
last analyzed

Complexity

Total Complexity 50

Size/Duplication

Total Lines 576
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 0

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 576
rs 8.6206
c 1
b 0
f 0
wmc 50
lcom 2
cbo 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A _cache() 0 17 3
A reset() 0 14 4
D rules() 0 39 10
D pluralize() 0 37 10
C singularize() 0 48 10
A camelize() 0 8 2
A underscore() 0 9 2
A humanize() 0 9 2
A tableize() 0 9 2
A classify() 0 9 2
A variable() 0 11 2
A slug() 0 14 1

How to fix   Complexity   

Complex Class

Complex classes like Inflector often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Inflector, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types=1);
2
/**
3
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
 *
6
 * Licensed under The MIT License
7
 * For full copyright and license information, please see the LICENSE.txt
8
 * Redistributions of files must retain the above copyright notice.
9
 *
10
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
11
 * @link          http://cakephp.org CakePHP(tm) Project
12
 * @package       Cake.Utility
13
 * @since         CakePHP(tm) v 0.2.9
14
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
15
 */
16
namespace Terah\FluentPdoModel;
17
18
/**
19
 * Pluralize and singularize English words.
20
 *
21
 * Inflector pluralizes and singularizes English nouns.
22
 * Used by CakePHP's naming conventions throughout the framework.
23
 *
24
 * @package       Cake.Utility
25
 * @link          http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html
26
 */
27
class Inflector {
28
29
    /**
30
     * Plural inflector rules
31
     *
32
     * @var array
33
     */
34
    protected static $_plural = [
35
        'rules' => [
36
            '/(s)tatus$/i' => '\1tatuses',
37
            '/(quiz)$/i' => '\1zes',
38
            '/^(ox)$/i' => '\1\2en',
39
            '/([m|l])ouse$/i' => '\1ice',
40
            '/(matr|vert|ind)(ix|ex)$/i' => '\1ices',
41
            '/(x|ch|ss|sh)$/i' => '\1es',
42
            '/([^aeiouy]|qu)y$/i' => '\1ies',
43
            '/(hive)$/i' => '\1s',
44
            '/(?:([^f])fe|([lre])f)$/i' => '\1\2ves',
45
            '/sis$/i' => 'ses',
46
            '/([ti])um$/i' => '\1a',
47
            '/(p)erson$/i' => '\1eople',
48
            '/(?<!u)(m)an$/i' => '\1en',
49
            '/(c)hild$/i' => '\1hildren',
50
            '/(buffal|tomat)o$/i' => '\1\2oes',
51
            '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
52
            '/us$/i' => 'uses',
53
            '/(alias)$/i' => '\1es',
54
            '/(ax|cris|test)is$/i' => '\1es',
55
            '/s$/' => 's',
56
            '/^$/' => '',
57
            '/$/' => 's',
58
        ],
59
        'uninflected' => [
60
            '.*[nrlm]ese',
61
            '.*data',
62
            '.*deer',
63
            '.*fish',
64
            '.*measles',
65
            '.*ois',
66
            '.*pox',
67
            '.*sheep',
68
            'people',
69
            'feedback',
70
            'stadia'
71
        ],
72
        'irregular' => [
73
            'atlas' => 'atlases',
74
            'beef' => 'beefs',
75
            'brief' => 'briefs',
76
            'brother' => 'brothers',
77
            'cafe' => 'cafes',
78
            'child' => 'children',
79
            'cookie' => 'cookies',
80
            'corpus' => 'corpuses',
81
            'cow' => 'cows',
82
            'criterion' => 'criteria',
83
            'ganglion' => 'ganglions',
84
            'genie' => 'genies',
85
            'genus' => 'genera',
86
            'graffito' => 'graffiti',
87
            'hoof' => 'hoofs',
88
            'loaf' => 'loaves',
89
            'man' => 'men',
90
            'money' => 'monies',
91
            'mongoose' => 'mongooses',
92
            'move' => 'moves',
93
            'mythos' => 'mythoi',
94
            'niche' => 'niches',
95
            'numen' => 'numina',
96
            'occiput' => 'occiputs',
97
            'octopus' => 'octopuses',
98
            'opus' => 'opuses',
99
            'ox' => 'oxen',
100
            'penis' => 'penises',
101
            'person' => 'people',
102
            'sex' => 'sexes',
103
            'soliloquy' => 'soliloquies',
104
            'testis' => 'testes',
105
            'trilby' => 'trilbys',
106
            'turf' => 'turfs',
107
            'potato' => 'potatoes',
108
            'hero' => 'heroes',
109
            'tooth' => 'teeth',
110
            'goose' => 'geese',
111
            'foot' => 'feet'
112
        ]
113
    ];
114
115
    /**
116
     * Singular inflector rules
117
     *
118
     * @var array
119
     */
120
    protected static $_singular = [
121
        'rules' => [
122
            '/(s)tatuses$/i' => '\1\2tatus',
123
            '/^(.*)(menu)s$/i' => '\1\2',
124
            '/(quiz)zes$/i' => '\\1',
125
            '/(matr)ices$/i' => '\1ix',
126
            '/(vert|ind)ices$/i' => '\1ex',
127
            '/^(ox)en/i' => '\1',
128
            '/(alias)(es)*$/i' => '\1',
129
            '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
130
            '/([ftw]ax)es/i' => '\1',
131
            '/(cris|ax|test)es$/i' => '\1is',
132
            '/(shoe)s$/i' => '\1',
133
            '/(o)es$/i' => '\1',
134
            '/ouses$/' => 'ouse',
135
            '/([^a])uses$/' => '\1us',
136
            '/([m|l])ice$/i' => '\1ouse',
137
            '/(x|ch|ss|sh)es$/i' => '\1',
138
            '/(m)ovies$/i' => '\1\2ovie',
139
            '/(s)eries$/i' => '\1\2eries',
140
            '/([^aeiouy]|qu)ies$/i' => '\1y',
141
            '/(tive)s$/i' => '\1',
142
            '/(hive)s$/i' => '\1',
143
            '/(drive)s$/i' => '\1',
144
            '/([le])ves$/i' => '\1f',
145
            '/([^rfoa])ves$/i' => '\1fe',
146
            '/(^analy)ses$/i' => '\1sis',
147
            '/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
148
            '/([ti])a$/i' => '\1um',
149
            '/(p)eople$/i' => '\1\2erson',
150
            '/(m)en$/i' => '\1an',
151
            '/(c)hildren$/i' => '\1\2hild',
152
            '/(n)ews$/i' => '\1\2ews',
153
            '/eaus$/' => 'eau',
154
            '/^(.*us)$/' => '\\1',
155
            '/s$/i' => ''
156
        ],
157
        'uninflected' => [
158
            '.*data',
159
            '.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', '.*ss', 'feedback'
160
        ],
161
        'irregular' => [
162
            'foes' => 'foe',
163
        ]
164
    ];
165
166
    /**
167
     * Words that should not be inflected
168
     *
169
     * @var array
170
     */
171
    protected static $_uninflected = [
172
        'Amoyese', 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus',
173
        'carp', 'chassis', 'clippers', 'cod', 'coitus', 'Congoese', 'contretemps', 'corps',
174
        'debris', 'diabetes', 'djinn', 'eland', 'elk', 'equipment', 'Faroese', 'flounder',
175
        'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
176
        'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings',
177
        'jackanapes', 'Kiplingese', 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', '.*?media',
178
        'mews', 'moose', 'mumps', 'Nankingese', 'news', 'nexus', 'Niasese',
179
        'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese',
180
        'proceedings', 'rabies', 'research', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors',
181
        'sea[- ]bass', 'series', 'Shavese', 'shears', 'siemens', 'species', 'swine', 'testes',
182
        'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese', 'whiting', 'wildebeest',
183
        'Yengeese'
184
    ];
185
186
    /**
187
     * Default map of accented and special characters to ASCII characters
188
     *
189
     * @var array
190
     */
191
    protected static $_transliteration = [
192
        '/À|Á|Â|Ã|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
193
        '/Æ|Ǽ/' => 'AE',
194
        '/Ä/' => 'Ae',
195
        '/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
196
        '/Ð|Ď|Đ/' => 'D',
197
        '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
198
        '/Ĝ|Ğ|Ġ|Ģ|Ґ/' => 'G',
199
        '/Ĥ|Ħ/' => 'H',
200
        '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|І/' => 'I',
201
        '/IJ/' => 'IJ',
202
        '/Ĵ/' => 'J',
203
        '/Ķ/' => 'K',
204
        '/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
205
        '/Ñ|Ń|Ņ|Ň/' => 'N',
206
        '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
207
        '/Œ/' => 'OE',
208
        '/Ö/' => 'Oe',
209
        '/Ŕ|Ŗ|Ř/' => 'R',
210
        '/Ś|Ŝ|Ş|Ș|Š/' => 'S',
211
        '/ẞ/' => 'SS',
212
        '/Ţ|Ț|Ť|Ŧ/' => 'T',
213
        '/Þ/' => 'TH',
214
        '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
215
        '/Ü/' => 'Ue',
216
        '/Ŵ/' => 'W',
217
        '/Ý|Ÿ|Ŷ/' => 'Y',
218
        '/Є/' => 'Ye',
219
        '/Ї/' => 'Yi',
220
        '/Ź|Ż|Ž/' => 'Z',
221
        '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
222
        '/ä|æ|ǽ/' => 'ae',
223
        '/ç|ć|ĉ|ċ|č/' => 'c',
224
        '/ð|ď|đ/' => 'd',
225
        '/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e',
226
        '/ƒ/' => 'f',
227
        '/ĝ|ğ|ġ|ģ|ґ/' => 'g',
228
        '/ĥ|ħ/' => 'h',
229
        '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|і/' => 'i',
230
        '/ij/' => 'ij',
231
        '/ĵ/' => 'j',
232
        '/ķ/' => 'k',
233
        '/ĺ|ļ|ľ|ŀ|ł/' => 'l',
234
        '/ñ|ń|ņ|ň|ʼn/' => 'n',
235
        '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
236
        '/ö|œ/' => 'oe',
237
        '/ŕ|ŗ|ř/' => 'r',
238
        '/ś|ŝ|ş|ș|š|ſ/' => 's',
239
        '/ß/' => 'ss',
240
        '/ţ|ț|ť|ŧ/' => 't',
241
        '/þ/' => 'th',
242
        '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
243
        '/ü/' => 'ue',
244
        '/ŵ/' => 'w',
245
        '/ý|ÿ|ŷ/' => 'y',
246
        '/є/' => 'ye',
247
        '/ї/' => 'yi',
248
        '/ź|ż|ž/' => 'z',
249
    ];
250
251
    /**
252
     * Method cache array.
253
     *
254
     * @var array
255
     */
256
    protected static $_cache = [];
257
258
    /**
259
     * The initial state of Inflector so reset() works.
260
     *
261
     * @var array
262
     */
263
    protected static $_initialState = [];
264
265
    /**
266
     * Cache inflected values, and return if already available
267
     *
268
     * @param string $type Inflection type
269
     * @param string $key Original value
270
     * @param string|bool $value Inflected value
271
     * @return string|bool Inflected value, from cache
272
     */
273
    protected static function _cache(string $type, string $key, string $value='')
274
    {
275
        $key        = '_' . $key;
276
        $type       = '_' . $type;
277
        if ( $value )
278
        {
279
            self::$_cache[$type][$key] = $value;
280
281
            return $value;
282
        }
283
        if ( !isset(self::$_cache[$type][$key]) )
284
        {
285
            return false;
286
        }
287
288
        return self::$_cache[$type][$key];
289
    }
290
291
    /**
292
     * Clears Inflectors inflected value caches. And resets the inflection
293
     * rules to the initial values.
294
     *
295
     * @return void
296
     */
297
    public static function reset()
298
    {
299
        if (empty(self::$_initialState))
300
        {
301
            self::$_initialState = get_class_vars('Inflector');
302
            return;
303
        }
304
        foreach (self::$_initialState as $key => $val)
305
        {
306
            if ($key !== '_initialState') {
307
                self::${$key} = $val;
308
            }
309
        }
310
    }
311
312
    /**
313
     * Adds custom inflection $rules, of either 'plural', 'singular' or 'transliteration' $type.
314
     *
315
     * ### Usage:
316
     *
317
     * ```
318
     * Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables'));
319
     * Inflector::rules('plural', array(
320
     *     'rules' => array('/^(inflect)ors$/i' => '\1ables'),
321
     *     'uninflected' => array('dontinflectme'),
322
     *     'irregular' => array('red' => 'redlings')
323
     * ));
324
     * Inflector::rules('transliteration', array('/å/' => 'aa'));
325
     * ```
326
     *
327
     * @param string $type The type of inflection, either 'plural', 'singular' or 'transliteration'
328
     * @param array $rules Array of rules to be added.
329
     * @param bool $reset If true, will unset default inflections for all
330
     *        new rules that are being defined in $rules.
331
     * @return void
332
     */
333
    public static function rules(string $type, array $rules, bool $reset=false)
334
    {
335
        $var = '_' . $type;
336
337
        switch ($type) {
338
            case 'transliteration':
339
                if ($reset) {
340
                    self::$_transliteration = $rules;
341
                } else {
342
                    self::$_transliteration = $rules + self::$_transliteration;
343
                }
344
                break;
345
346
            default:
347
                foreach ($rules as $rule => $pattern) {
348
                    if (is_array($pattern)) {
349
                        if ($reset) {
350
                            self::${$var}[$rule] = $pattern;
351
                        } else {
352
                            if ($rule === 'uninflected') {
353
                                self::${$var}[$rule] = array_merge($pattern, self::${$var}[$rule]);
354
                            } else {
355
                                self::${$var}[$rule] = $pattern + self::${$var}[$rule];
356
                            }
357
                        }
358
                        unset($rules[$rule], self::${$var}['cache' . ucfirst($rule)]);
359
                        if (isset(self::${$var}['merged'][$rule])) {
360
                            unset(self::${$var}['merged'][$rule]);
361
                        }
362
                        if ($type === 'plural') {
363
                            self::$_cache['pluralize'] = self::$_cache['tableize'] = [];
364
                        } elseif ($type === 'singular') {
365
                            self::$_cache['singularize'] = [];
366
                        }
367
                    }
368
                }
369
                self::${$var}['rules'] = $rules + self::${$var}['rules'];
370
        }
371
    }
372
373
    /**
374
     * Return $word in plural form.
375
     *
376
     * @param string $word Word in singular
377
     * @return string Word in plural
378
     * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::pluralize
379
     */
380
    public static function pluralize(string $word) : string
381
    {
382
        if (isset(self::$_cache['pluralize'][$word])) {
383
            return self::$_cache['pluralize'][$word];
384
        }
385
386
        if (!isset(self::$_plural['merged']['irregular'])) {
387
            self::$_plural['merged']['irregular'] = self::$_plural['irregular'];
388
        }
389
390
        if (!isset(self::$_plural['merged']['uninflected'])) {
391
            self::$_plural['merged']['uninflected'] = array_merge(self::$_plural['uninflected'], self::$_uninflected);
392
        }
393
394
        if (!isset(self::$_plural['cacheUninflected']) || !isset(self::$_plural['cacheIrregular'])) {
395
            self::$_plural['cacheUninflected'] = '(?:' . implode('|', self::$_plural['merged']['uninflected']) . ')';
396
            self::$_plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$_plural['merged']['irregular'])) . ')';
397
        }
398
399
        if (preg_match('/(.*)\\b(' . self::$_plural['cacheIrregular'] . ')$/i', $word, $regs)) {
400
            self::$_cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$_plural['merged']['irregular'][strtolower($regs[2])], 1);
401
            return self::$_cache['pluralize'][$word];
402
        }
403
404
        if (preg_match('/^(' . self::$_plural['cacheUninflected'] . ')$/i', $word, $regs)) {
405
            self::$_cache['pluralize'][$word] = $word;
406
            return $word;
407
        }
408
409
        foreach (self::$_plural['rules'] as $rule => $replacement) {
410
            if (preg_match($rule, $word)) {
411
                self::$_cache['pluralize'][$word] = preg_replace($rule, $replacement, $word);
412
                return self::$_cache['pluralize'][$word];
413
            }
414
        }
415
        return '';
416
    }
417
418
    /**
419
     * Return $word in singular form.
420
     *
421
     * @param string $word Word in plural
422
     * @return string Word in singular
423
     * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::singularize
424
     */
425
    public static function singularize(string $word) : string
426
    {
427
        if (isset(self::$_cache['singularize'][$word])) {
428
            return self::$_cache['singularize'][$word];
429
        }
430
431
        if (!isset(self::$_singular['merged']['uninflected'])) {
432
            self::$_singular['merged']['uninflected'] = array_merge(
433
                self::$_singular['uninflected'],
434
                self::$_uninflected
435
            );
436
        }
437
438
        if (!isset(self::$_singular['merged']['irregular'])) {
439
            self::$_singular['merged']['irregular'] = array_merge(
440
                self::$_singular['irregular'],
441
                array_flip(self::$_plural['irregular'])
442
            );
443
        }
444
445
        if (!isset(self::$_singular['cacheUninflected']) || !isset(self::$_singular['cacheIrregular'])) {
446
            self::$_singular['cacheUninflected'] = '(?:' . implode('|', self::$_singular['merged']['uninflected']) . ')';
447
            self::$_singular['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$_singular['merged']['irregular'])) . ')';
448
        }
449
450
        if (preg_match('/(.*)\\b(' . self::$_singular['cacheIrregular'] . ')$/i', $word, $regs)) {
451
            self::$_cache['singularize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$_singular['merged']['irregular'][strtolower($regs[2])], 1);
452
453
            return self::$_cache['singularize'][$word];
454
        }
455
456
        if (preg_match('/^(' . self::$_singular['cacheUninflected'] . ')$/i', $word, $regs)) {
457
            self::$_cache['singularize'][$word] = $word;
458
459
            return $word;
460
        }
461
462
        foreach (self::$_singular['rules'] as $rule => $replacement) {
463
            if (preg_match($rule, $word)) {
464
                self::$_cache['singularize'][$word] = preg_replace($rule, $replacement, $word);
465
466
                return self::$_cache['singularize'][$word];
467
            }
468
        }
469
        self::$_cache['singularize'][$word] = $word;
470
471
        return $word;
472
    }
473
474
    /**
475
     * Returns the given lower_case_and_underscored_word as a CamelCased word.
476
     *
477
     * @param string $lowerCaseAndUnderscoredWord Word to camelize
478
     * @return string Camelized word. LikeThis.
479
     * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::camelize
480
     */
481
    public static function camelize(string $lowerCaseAndUnderscoredWord) : string
482
    {
483
        if (!($result = self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord))) {
484
            $result = str_replace(' ', '', Inflector::humanize($lowerCaseAndUnderscoredWord));
485
            self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord, $result);
486
        }
487
        return $result;
488
    }
489
490
    /**
491
     * Returns the given camelCasedWord as an underscored_word.
492
     *
493
     * @param string $camelCasedWord Camel-cased word to be "underscorized"
494
     * @return string Underscore-syntaxed version of the $camelCasedWord
495
     * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::underscore
496
     */
497
    public static function underscore(string$camelCasedWord) : string
498
    {
499
        if (!($result = self::_cache(__FUNCTION__, $camelCasedWord))) {
500
            $result = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $camelCasedWord));
501
            self::_cache(__FUNCTION__, $camelCasedWord, $result);
502
        }
503
504
        return $result;
505
    }
506
507
    /**
508
     * Returns the given underscored_word_group as a Human Readable Word Group.
509
     * (Underscores are replaced by spaces and capitalized following words.)
510
     *
511
     * @param string $lowerCaseAndUnderscoredWord String to be made more readable
512
     * @return string Human-readable string
513
     * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::humanize
514
     */
515
    public static function humanize(string $lowerCaseAndUnderscoredWord) : string
516
    {
517
        if (!($result = self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord))) {
518
            $result = ucwords(str_replace('_', ' ', $lowerCaseAndUnderscoredWord));
519
            self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord, $result);
520
        }
521
522
        return $result;
523
    }
524
525
    /**
526
     * Returns corresponding table name for given model $className. ("people" for the model class "Person").
527
     *
528
     * @param string $className Name of class to get database table name for
529
     * @return string Name of the database table for given class
530
     * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::tableize
531
     */
532
    public static function tableize(string $className) : string
533
    {
534
        if (!($result = self::_cache(__FUNCTION__, $className))) {
535
            $result = Inflector::pluralize(Inflector::underscore($className));
536
            self::_cache(__FUNCTION__, $className, $result);
537
        }
538
539
        return $result;
540
    }
541
542
    /**
543
     * Returns Cake model class name ("Person" for the database table "people".) for given database table.
544
     *
545
     * @param string $tableName Name of database table to get class name for
546
     * @return string Class name
547
     * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::classify
548
     */
549
    public static function classify(string $tableName) : string
550
    {
551
        if (!($result = self::_cache(__FUNCTION__, $tableName))) {
552
            $result = Inflector::camelize(Inflector::singularize($tableName));
553
            self::_cache(__FUNCTION__, $tableName, $result);
554
        }
555
556
        return $result;
557
    }
558
559
    /**
560
     * Returns camelBacked version of an underscored string.
561
     *
562
     * @param string $string String to convert.
563
     * @return string in variable form
564
     * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::variable
565
     */
566
    public static function variable(string $string) : string
567
    {
568
        if (!($result = self::_cache(__FUNCTION__, $string))) {
569
            $camelized = Inflector::camelize(Inflector::underscore($string));
570
            $replace = strtolower(substr($camelized, 0, 1));
571
            $result = preg_replace('/\\w/', $replace, $camelized, 1);
572
            self::_cache(__FUNCTION__, $string, $result);
573
        }
574
575
        return $result;
576
    }
577
578
    /**
579
     * Returns a string with all spaces converted to underscores (by default), accented
580
     * characters converted to non-accented characters, and non word characters removed.
581
     *
582
     * @param string $string the string you want to slug
583
     * @param string $replacement will replace keys in map
584
     * @return string
585
     * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::slug
586
     */
587
    public static function slug(string $string, string $replacement = '_') : string
588
    {
589
        $quotedReplacement = preg_quote($replacement, '/');
590
591
        $merge = [
592
            '/[^\s\p{Zs}\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ',
593
            '/[\s\p{Zs}]+/mu' => $replacement,
594
            sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '',
595
        ];
596
597
        $map = self::$_transliteration + $merge;
598
599
        return preg_replace(array_keys($map), array_values($map), $string);
600
    }
601
602
}
603
604
// Store the initial state
605
Inflector::reset();
606