source: Dev/branches/cakephp/cake/libs/inflector.php @ 126

Last change on this file since 126 was 126, checked in by fpvanagthoven, 14 years ago

Cakephp branch.

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