Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
15403 manish.sha 1
<?php
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
 
17
/**
18
 * Pluralize and singularize English words.
19
 *
20
 * Inflector pluralizes and singularizes English nouns.
21
 * Used by CakePHP's naming conventions throughout the framework.
22
 *
23
 * @package       Cake.Utility
24
 * @link          http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html
25
 */
26
class Inflector {
27
 
28
/**
29
 * Plural inflector rules
30
 *
31
 * @var array
32
 */
33
	protected static $_plural = array(
34
		'rules' => array(
35
			'/(s)tatus$/i' => '\1tatuses',
36
			'/(quiz)$/i' => '\1zes',
37
			'/^(ox)$/i' => '\1\2en',
38
			'/([m|l])ouse$/i' => '\1ice',
39
			'/(matr|vert|ind)(ix|ex)$/i' => '\1ices',
40
			'/(x|ch|ss|sh)$/i' => '\1es',
41
			'/([^aeiouy]|qu)y$/i' => '\1ies',
42
			'/(hive)$/i' => '\1s',
43
			'/(?:([^f])fe|([lre])f)$/i' => '\1\2ves',
44
			'/sis$/i' => 'ses',
45
			'/([ti])um$/i' => '\1a',
46
			'/(p)erson$/i' => '\1eople',
47
			'/(?<!u)(m)an$/i' => '\1en',
48
			'/(c)hild$/i' => '\1hildren',
49
			'/(buffal|tomat)o$/i' => '\1\2oes',
50
			'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
51
			'/us$/i' => 'uses',
52
			'/(alias)$/i' => '\1es',
53
			'/(ax|cris|test)is$/i' => '\1es',
54
			'/s$/' => 's',
55
			'/^$/' => '',
56
			'/$/' => 's',
57
		),
58
		'uninflected' => array(
59
			'.*[nrlm]ese',
60
			'.*data',
61
			'.*deer',
62
			'.*fish',
63
			'.*measles',
64
			'.*ois',
65
			'.*pox',
66
			'.*sheep',
67
			'people',
68
			'feedback',
69
			'stadia'
70
		),
71
		'irregular' => array(
72
			'atlas' => 'atlases',
73
			'beef' => 'beefs',
74
			'brief' => 'briefs',
75
			'brother' => 'brothers',
76
			'cafe' => 'cafes',
77
			'child' => 'children',
78
			'cookie' => 'cookies',
79
			'corpus' => 'corpuses',
80
			'cow' => 'cows',
81
			'criterion' => 'criteria',
82
			'ganglion' => 'ganglions',
83
			'genie' => 'genies',
84
			'genus' => 'genera',
85
			'graffito' => 'graffiti',
86
			'hoof' => 'hoofs',
87
			'loaf' => 'loaves',
88
			'man' => 'men',
89
			'money' => 'monies',
90
			'mongoose' => 'mongooses',
91
			'move' => 'moves',
92
			'mythos' => 'mythoi',
93
			'niche' => 'niches',
94
			'numen' => 'numina',
95
			'occiput' => 'occiputs',
96
			'octopus' => 'octopuses',
97
			'opus' => 'opuses',
98
			'ox' => 'oxen',
99
			'penis' => 'penises',
100
			'person' => 'people',
101
			'sex' => 'sexes',
102
			'soliloquy' => 'soliloquies',
103
			'testis' => 'testes',
104
			'trilby' => 'trilbys',
105
			'turf' => 'turfs',
106
			'potato' => 'potatoes',
107
			'hero' => 'heroes',
108
			'tooth' => 'teeth',
109
			'goose' => 'geese',
110
			'foot' => 'feet',
111
			'sieve' => 'sieves'
112
		)
113
	);
114
 
115
/**
116
 * Singular inflector rules
117
 *
118
 * @var array
119
 */
120
	protected static $_singular = array(
121
		'rules' => array(
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' => array(
158
			'.*data',
159
			'.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', '.*ss', 'feedback'
160
		),
161
		'irregular' => array(
162
			'foes' => 'foe',
163
		)
164
	);
165
 
166
/**
167
 * Words that should not be inflected
168
 *
169
 * @var array
170
 */
171
	protected static $_uninflected = array(
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 = array(
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 = array();
257
 
258
/**
259
 * The initial state of Inflector so reset() works.
260
 *
261
 * @var array
262
 */
263
	protected static $_initialState = array();
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 $value Inflected value
271
 * @return string Inflected value, from cache
272
 */
273
	protected static function _cache($type, $key, $value = false) {
274
		$key = '_' . $key;
275
		$type = '_' . $type;
276
		if ($value !== false) {
277
			self::$_cache[$type][$key] = $value;
278
			return $value;
279
		}
280
		if (!isset(self::$_cache[$type][$key])) {
281
			return false;
282
		}
283
		return self::$_cache[$type][$key];
284
	}
285
 
286
/**
287
 * Clears Inflectors inflected value caches. And resets the inflection
288
 * rules to the initial values.
289
 *
290
 * @return void
291
 */
292
	public static function reset() {
293
		if (empty(self::$_initialState)) {
294
			self::$_initialState = get_class_vars('Inflector');
295
			return;
296
		}
297
		foreach (self::$_initialState as $key => $val) {
298
			if ($key !== '_initialState') {
299
				self::${$key} = $val;
300
			}
301
		}
302
	}
303
 
304
/**
305
 * Adds custom inflection $rules, of either 'plural', 'singular' or 'transliteration' $type.
306
 *
307
 * ### Usage:
308
 *
309
 * ```
310
 * Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables'));
311
 * Inflector::rules('plural', array(
312
 *     'rules' => array('/^(inflect)ors$/i' => '\1ables'),
313
 *     'uninflected' => array('dontinflectme'),
314
 *     'irregular' => array('red' => 'redlings')
315
 * ));
316
 * Inflector::rules('transliteration', array('/å/' => 'aa'));
317
 * ```
318
 *
319
 * @param string $type The type of inflection, either 'plural', 'singular' or 'transliteration'
320
 * @param array $rules Array of rules to be added.
321
 * @param bool $reset If true, will unset default inflections for all
322
 *        new rules that are being defined in $rules.
323
 * @return void
324
 */
325
	public static function rules($type, $rules, $reset = false) {
326
		$var = '_' . $type;
327
 
328
		switch ($type) {
329
			case 'transliteration':
330
				if ($reset) {
331
					self::$_transliteration = $rules;
332
				} else {
333
					self::$_transliteration = $rules + self::$_transliteration;
334
				}
335
				break;
336
 
337
			default:
338
				foreach ($rules as $rule => $pattern) {
339
					if (is_array($pattern)) {
340
						if ($reset) {
341
							self::${$var}[$rule] = $pattern;
342
						} else {
343
							if ($rule === 'uninflected') {
344
								self::${$var}[$rule] = array_merge($pattern, self::${$var}[$rule]);
345
							} else {
346
								self::${$var}[$rule] = $pattern + self::${$var}[$rule];
347
							}
348
						}
349
						unset($rules[$rule], self::${$var}['cache' . ucfirst($rule)]);
350
						if (isset(self::${$var}['merged'][$rule])) {
351
							unset(self::${$var}['merged'][$rule]);
352
						}
353
						if ($type === 'plural') {
354
							self::$_cache['pluralize'] = self::$_cache['tableize'] = array();
355
						} elseif ($type === 'singular') {
356
							self::$_cache['singularize'] = array();
357
						}
358
					}
359
				}
360
				self::${$var}['rules'] = $rules + self::${$var}['rules'];
361
		}
362
	}
363
 
364
/**
365
 * Return $word in plural form.
366
 *
367
 * @param string $word Word in singular
368
 * @return string Word in plural
369
 * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::pluralize
370
 */
371
	public static function pluralize($word) {
372
		if (isset(self::$_cache['pluralize'][$word])) {
373
			return self::$_cache['pluralize'][$word];
374
		}
375
 
376
		if (!isset(self::$_plural['merged']['irregular'])) {
377
			self::$_plural['merged']['irregular'] = self::$_plural['irregular'];
378
		}
379
 
380
		if (!isset(self::$_plural['merged']['uninflected'])) {
381
			self::$_plural['merged']['uninflected'] = array_merge(self::$_plural['uninflected'], self::$_uninflected);
382
		}
383
 
384
		if (!isset(self::$_plural['cacheUninflected']) || !isset(self::$_plural['cacheIrregular'])) {
385
			self::$_plural['cacheUninflected'] = '(?:' . implode('|', self::$_plural['merged']['uninflected']) . ')';
386
			self::$_plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$_plural['merged']['irregular'])) . ')';
387
		}
388
 
389
		if (preg_match('/(.*(?:\\b|_))(' . self::$_plural['cacheIrregular'] . ')$/i', $word, $regs)) {
390
			self::$_cache['pluralize'][$word] = $regs[1] . substr($regs[2], 0, 1) . substr(self::$_plural['merged']['irregular'][strtolower($regs[2])], 1);
391
			return self::$_cache['pluralize'][$word];
392
		}
393
 
394
		if (preg_match('/^(' . self::$_plural['cacheUninflected'] . ')$/i', $word, $regs)) {
395
			self::$_cache['pluralize'][$word] = $word;
396
			return $word;
397
		}
398
 
399
		foreach (self::$_plural['rules'] as $rule => $replacement) {
400
			if (preg_match($rule, $word)) {
401
				self::$_cache['pluralize'][$word] = preg_replace($rule, $replacement, $word);
402
				return self::$_cache['pluralize'][$word];
403
			}
404
		}
405
	}
406
 
407
/**
408
 * Return $word in singular form.
409
 *
410
 * @param string $word Word in plural
411
 * @return string Word in singular
412
 * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::singularize
413
 */
414
	public static function singularize($word) {
415
		if (isset(self::$_cache['singularize'][$word])) {
416
			return self::$_cache['singularize'][$word];
417
		}
418
 
419
		if (!isset(self::$_singular['merged']['uninflected'])) {
420
			self::$_singular['merged']['uninflected'] = array_merge(
421
				self::$_singular['uninflected'],
422
				self::$_uninflected
423
			);
424
		}
425
 
426
		if (!isset(self::$_singular['merged']['irregular'])) {
427
			self::$_singular['merged']['irregular'] = array_merge(
428
				self::$_singular['irregular'],
429
				array_flip(self::$_plural['irregular'])
430
			);
431
		}
432
 
433
		if (!isset(self::$_singular['cacheUninflected']) || !isset(self::$_singular['cacheIrregular'])) {
434
			self::$_singular['cacheUninflected'] = '(?:' . implode('|', self::$_singular['merged']['uninflected']) . ')';
435
			self::$_singular['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$_singular['merged']['irregular'])) . ')';
436
		}
437
 
438
		if (preg_match('/(.*(?:\\b|_))(' . self::$_singular['cacheIrregular'] . ')$/i', $word, $regs)) {
439
			self::$_cache['singularize'][$word] = $regs[1] . substr($regs[2], 0, 1) . substr(self::$_singular['merged']['irregular'][strtolower($regs[2])], 1);
440
			return self::$_cache['singularize'][$word];
441
		}
442
 
443
		if (preg_match('/^(' . self::$_singular['cacheUninflected'] . ')$/i', $word, $regs)) {
444
			self::$_cache['singularize'][$word] = $word;
445
			return $word;
446
		}
447
 
448
		foreach (self::$_singular['rules'] as $rule => $replacement) {
449
			if (preg_match($rule, $word)) {
450
				self::$_cache['singularize'][$word] = preg_replace($rule, $replacement, $word);
451
				return self::$_cache['singularize'][$word];
452
			}
453
		}
454
		self::$_cache['singularize'][$word] = $word;
455
		return $word;
456
	}
457
 
458
/**
459
 * Returns the given lower_case_and_underscored_word as a CamelCased word.
460
 *
461
 * @param string $lowerCaseAndUnderscoredWord Word to camelize
462
 * @return string Camelized word. LikeThis.
463
 * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::camelize
464
 */
465
	public static function camelize($lowerCaseAndUnderscoredWord) {
466
		if (!($result = self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord))) {
467
			$result = str_replace(' ', '', Inflector::humanize($lowerCaseAndUnderscoredWord));
468
			self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord, $result);
469
		}
470
		return $result;
471
	}
472
 
473
/**
474
 * Returns the given camelCasedWord as an underscored_word.
475
 *
476
 * @param string $camelCasedWord Camel-cased word to be "underscorized"
477
 * @return string Underscore-syntaxed version of the $camelCasedWord
478
 * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::underscore
479
 */
480
	public static function underscore($camelCasedWord) {
481
		if (!($result = self::_cache(__FUNCTION__, $camelCasedWord))) {
482
			$result = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $camelCasedWord));
483
			self::_cache(__FUNCTION__, $camelCasedWord, $result);
484
		}
485
		return $result;
486
	}
487
 
488
/**
489
 * Returns the given underscored_word_group as a Human Readable Word Group.
490
 * (Underscores are replaced by spaces and capitalized following words.)
491
 *
492
 * @param string $lowerCaseAndUnderscoredWord String to be made more readable
493
 * @return string Human-readable string
494
 * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::humanize
495
 */
496
	public static function humanize($lowerCaseAndUnderscoredWord) {
497
		if (!($result = self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord))) {
498
			$result = ucwords(str_replace('_', ' ', $lowerCaseAndUnderscoredWord));
499
			self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord, $result);
500
		}
501
		return $result;
502
	}
503
 
504
/**
505
 * Returns corresponding table name for given model $className. ("people" for the model class "Person").
506
 *
507
 * @param string $className Name of class to get database table name for
508
 * @return string Name of the database table for given class
509
 * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::tableize
510
 */
511
	public static function tableize($className) {
512
		if (!($result = self::_cache(__FUNCTION__, $className))) {
513
			$result = Inflector::pluralize(Inflector::underscore($className));
514
			self::_cache(__FUNCTION__, $className, $result);
515
		}
516
		return $result;
517
	}
518
 
519
/**
520
 * Returns Cake model class name ("Person" for the database table "people".) for given database table.
521
 *
522
 * @param string $tableName Name of database table to get class name for
523
 * @return string Class name
524
 * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::classify
525
 */
526
	public static function classify($tableName) {
527
		if (!($result = self::_cache(__FUNCTION__, $tableName))) {
528
			$result = Inflector::camelize(Inflector::singularize($tableName));
529
			self::_cache(__FUNCTION__, $tableName, $result);
530
		}
531
		return $result;
532
	}
533
 
534
/**
535
 * Returns camelBacked version of an underscored string.
536
 *
537
 * @param string $string String to convert.
538
 * @return string in variable form
539
 * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::variable
540
 */
541
	public static function variable($string) {
542
		if (!($result = self::_cache(__FUNCTION__, $string))) {
543
			$camelized = Inflector::camelize(Inflector::underscore($string));
544
			$replace = strtolower(substr($camelized, 0, 1));
545
			$result = preg_replace('/\\w/', $replace, $camelized, 1);
546
			self::_cache(__FUNCTION__, $string, $result);
547
		}
548
		return $result;
549
	}
550
 
551
/**
552
 * Returns a string with all spaces converted to underscores (by default), accented
553
 * characters converted to non-accented characters, and non word characters removed.
554
 *
555
 * @param string $string the string you want to slug
556
 * @param string $replacement will replace keys in map
557
 * @return string
558
 * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::slug
559
 */
560
	public static function slug($string, $replacement = '_') {
561
		$quotedReplacement = preg_quote($replacement, '/');
562
 
563
		$merge = array(
564
			'/[^\s\p{Zs}\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ',
565
			'/[\s\p{Zs}]+/mu' => $replacement,
566
			sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '',
567
		);
568
 
569
		$map = self::$_transliteration + $merge;
570
		return preg_replace(array_keys($map), array_values($map), $string);
571
	}
572
 
573
}
574
 
575
// Store the initial state
576
Inflector::reset();