Smutty
MVC Framework
View Code: Smutty_Inflector
Browse: All · Classes · Plugins
1
<?php
2
3
/**
4
* Inflector for pluralize and singularize English nouns.
5
*
6
* This Inflector is a port of Ruby on Rails Inflector.
7
*
8
* It can be really helpful for developers that want to
9
* create frameworks based on naming conventions rather than
10
* configurations.
11
*
12
* It was ported to PHP for the Akelos Framework, a
13
* multilingual Ruby on Rails like framework for PHP that will
14
* be launched soon.
15
*
16
* Modifications have been made for the Smutty Framework
17
*
18
* @author Bermi Ferrer Martinez <bermi akelos com>
19
* @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
20
* @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
21
* @since 0.1
22
* @version $Revision 0.1 $
23
*
24
*/
25
26
class Smutty_Inflector extends Smutty_Object
27
{
28
29
private static $pluralizeCache = array();
30
31
/**
32
* Pluralizes English nouns.
33
*
34
* @access public
35
* @static
36
*
37
* @param String $word English noun to pluralize
38
* @return string Plural noun
39
*
40
*/
41
43
44
if ( isset(self::$pluralizeCache[$word]) )
45
return self::$pluralizeCache[$word];
46
47
$value = self::_pluralize($word);
48
self::$pluralizeCache[ $word ] = $value;
49
return $value;
50
51
}
52
54
{
55
56
$uncountable = array('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep');
57
58
$lowercased_word = strtolower($word);
59
60
foreach ($uncountable as $_uncountable){
61
if(substr($lowercased_word,(-1*strlen($_uncountable))) == $_uncountable){
62
return $word;
63
}
64
}
65
66
$irregular = array(
67
'person' => 'people',
68
'man' => 'men',
69
'child' => 'children',
70
'sex' => 'sexes',
71
'move' => 'moves');
72
73
foreach ($irregular as $_plural=> $_singular){
74
if (preg_match('/('.$_plural.')$/i', $word, $arr)) {
75
return preg_replace('/('.$_plural.')$/i', substr($arr[0],0,1).substr($_singular,1), $word);
76
}
77
}
78
79
$plural = array(
80
'/(quiz)$/i' => '\1zes',
81
'/^(ox)$/i' => '\1en',
82
'/([m|l])ouse$/i' => '\1ice',
83
'/(matr|vert|ind)ix|ex$/i' => '\1ices',
84
'/(x|ch|ss|sh)$/i' => '\1es',
85
'/([^aeiouy]|qu)ies$/i' => '\1y',
86
'/([^aeiouy]|qu)y$/i' => '\1ies',
87
'/(hive)$/i' => '\1s',
88
'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
89
'/sis$/i' => 'ses',
90
'/([ti])um$/i' => '\1a',
91
'/(buffal|tomat)o$/i' => '\1oes',
92
'/(bu)s$/i' => '\1ses',
93
'/(alias|status)/i'=> '\1es',
94
'/(octop|vir)us$/i'=> '\1i',
95
'/(ax|test)is$/i'=> '\1es',
96
'/s$/i'=> 's',
97
'/$/'=> 's');
98
99
foreach ($plural as $rule => $replacement) {
100
if (preg_match($rule, $word)) {
101
return preg_replace($rule, $replacement, $word);
102
}
103
}
104
return false;
105
106
}
107
108
/**
109
* Singularizes English nouns.
110
*
111
* @access public
112
* @static
113
* @param string $word English noun to singularize
114
* @return string Singular noun.
115
*/
117
{
118
$singular = array (
119
'/(quiz)zes$/i' => '\\1',
120
'/(matr)ices$/i' => '\\1ix',
121
'/(vert|ind)ices$/i' => '\\1ex',
122
'/^(ox)en/i' => '\\1',
123
'/(alias|status)es$/i' => '\\1',
124
'/([octop|vir])i$/i' => '\\1us',
125
'/(cris|ax|test)es$/i' => '\\1is',
126
'/(shoe)s$/i' => '\\1',
127
'/(o)es$/i' => '\\1',
128
'/(bus)es$/i' => '\\1',
129
'/([m|l])ice$/i' => '\\1ouse',
130
'/(x|ch|ss|sh)es$/i' => '\\1',
131
'/(m)ovies$/i' => '\\1ovie',
132
'/(s)eries$/i' => '\\1eries',
133
'/([^aeiouy]|qu)ies$/i' => '\\1y',
134
'/([lr])ves$/i' => '\\1f',
135
'/(tive)s$/i' => '\\1',
136
'/(hive)s$/i' => '\\1',
137
'/([^f])ves$/i' => '\\1fe',
138
'/(^analy)ses$/i' => '\\1sis',
139
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\\1\\2sis',
140
'/([ti])a$/i' => '\\1um',
141
'/(n)ews$/i' => '\\1ews',
142
'/s$/i' => '',
143
);
144
145
$uncountable = array('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep');
146
147
$irregular = array(
148
'person' => 'people',
149
'man' => 'men',
150
'child' => 'children',
151
'sex' => 'sexes',
152
'move' => 'moves');
153
154
$lowercased_word = strtolower($word);
155
foreach ($uncountable as $_uncountable){
156
if(substr($lowercased_word,(-1*strlen($_uncountable))) == $_uncountable){
157
return $word;
158
}
159
}
160
161
foreach ($irregular as $_plural=> $_singular){
162
if (preg_match('/('.$_singular.')$/i', $word, $arr)) {
163
return preg_replace('/('.$_singular.')$/i', substr($arr[0],0,1).substr($_plural,1), $word);
164
}
165
}
166
167
foreach ($singular as $rule => $replacement) {
168
if (preg_match($rule, $word)) {
169
return preg_replace($rule, $replacement, $word);
170
}
171
}
172
173
return $word;
174
}
175
176
/**
177
* Converts an underscored or CamelCase word into a English
178
* sentence.
179
*
180
* The titleize function converts text like "WelcomePage",
181
* "welcome_page" or "welcome page" to this "Welcome
182
* Page".
183
* If second parameter is set to 'first' it will only
184
* capitalize the first character of the title.
185
*
186
* @access public
187
* @static
188
* @param string $word Word to format as tile
189
* @param string $uppercase If set to 'first' it will only uppercase the
190
* first character. Otherwise it will uppercase all
191
* the words in the title.
192
* @return string Text formatted as title
193
*/
195
{
196
$uppercase = $uppercase == 'first' ? 'ucfirst' : 'ucwords';
197
return $uppercase(self::humanize(self::underscore($word)));
198
}
199
200
/**
201
* Returns given word as CamelCased
202
*
203
* Converts a word like "send_email" to "SendEmail". It
204
* will remove non alphanumeric character from the word, so
205
* "who's online" will be converted to "WhoSOnline"
206
*
207
* @access public
208
* @static
209
* @see variablize
210
* @param string $word Word to convert to camel case
211
* @return string UpperCamelCasedWord
212
*/
214
{
215
return str_replace(' ','',ucwords(preg_replace('/[^A-Z^a-z^0-9]+/',' ',$word)));
216
}
217
218
/**
219
* Converts a word "into_it_s_underscored_version"
220
*
221
* Convert any "CamelCased" or "ordinary Word" into an
222
* "underscored_word".
223
*
224
* This can be really useful for creating friendly URLs.
225
*
226
* @access public
227
* @static
228
* @param string $word Word to underscore
229
* @return string Underscored word
230
*/
232
{
233
return strtolower(preg_replace('/[^A-Z^a-z^0-9]+/','_',
234
preg_replace('/([a-z\d])([A-Z])/','\1_\2',
235
preg_replace('/([A-Z]+)([A-Z][a-z])/','\1_\2',$word))));
236
}
237
238
/**
239
* Returns a human-readable string from $word
240
*
241
* Returns a human-readable string from $word, by replacing
242
* underscores with a space, and by upper-casing the initial
243
* character by default.
244
*
245
* If you need to uppercase all the words you just have to
246
* pass 'all' as a second parameter.
247
*
248
* @access public
249
* @static
250
* @param string $word String to "humanize"
251
* @param string $uppercase If set to 'all' it will uppercase all the words
252
* instead of just the first one.
253
* @return string Human-readable word
254
*/
256
{
257
$uppercase = $uppercase == 'all' ? 'ucwords' : 'ucfirst';
258
return $uppercase(str_replace('_',' ',preg_replace('/_id$/', '',$word)));
259
}
260
261
/**
262
* Same as camelize but first char is underscored
263
*
264
* Converts a word like "send_email" to "sendEmail". It
265
* will remove non alphanumeric character from the word, so
266
* "who's online" will be converted to "whoSOnline"
267
*
268
* @access public
269
* @static
270
* @param string $word Word to lowerCamelCase
271
* @return string Returns a lowerCamelCasedWord
272
*/
274
{
275
$word = self::camelize($word);
276
return strtolower($word[0]).substr($word,1);
277
}
278
279
/**
280
* Converts a class name to its table name according to rails
281
* naming conventions.
282
*
283
* Converts "Person" to "people"
284
*
285
* @access public
286
* @static
287
* @see classify
288
* @param string $class_name Class name for getting related table_name.
289
* @return string plural_table_name
290
*/
292
{
293
return self::pluralize(self::underscore($class_name));
294
}
295
296
/**
297
* Converts a table name to its class name according to rails
298
* naming conventions.
299
*
300
* Converts "people" to "Person"
301
*
302
* @access public
303
* @static
304
* @see tableize
305
* @param string $table_name Table name for getting related ClassName.
306
* @return string SingularClassName
307
*/
309
{
310
return self::camelize(self::singularize($table_name));
311
}
312
313
/**
314
* Converts number to its ordinal English form.
315
*
316
* This method converts 13 to 13th, 2 to 2nd ...
317
*
318
* @access public
319
* @static
320
* @param integer $number Number to get its ordinal value
321
* @return string Ordinal representation of given string.
322
*/
324
{
325
if (in_array(($number % 100),range(11,13))){
326
return $number.'th';
327
}else{
328
switch (($number % 10)) {
329
case 1:
330
return $number.'st';
331
break;
332
case 2:
333
return $number.'nd';
334
break;
335
case 3:
336
return $number.'rd';
337
default:
338
return $number.'th';
339
break;
340
}
341
}
342
}
343
344
}
345
346
?>
The code shown here is the code that is currently running this site. If you want to view the latest SVN version of the code then go to the Subversion repository.