blob: 1c14f4a3e4e330621a8e8c9dbe9383da5307defc [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02005 * An open source application development framework for PHP
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +02007 * This content is released under the MIT License (MIT)
Eric Barnescde712c2011-12-09 11:27:51 -05008 *
Instructor, BCIT0e59db62019-01-01 08:34:36 -08009 * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
Eric Barnescde712c2011-12-09 11:27:51 -050010 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020011 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
Derek Jonesf4a4bd82011-10-20 12:18:42 -050017 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020018 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 * @package CodeIgniter
30 * @author EllisLab Dev Team
Andrey Andreev1924e872016-01-11 12:55:34 +020031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
Instructor, BCIT0e59db62019-01-01 08:34:36 -080032 * @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
33 * @license https://opensource.org/licenses/MIT MIT License
Andrey Andreevbd202c92016-01-11 12:50:18 +020034 * @link https://codeigniter.com
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020035 * @since Version 1.0.0
Derek Allard2067d1a2008-11-13 22:59:24 +000036 * @filesource
37 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020038defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000039
Derek Allard2067d1a2008-11-13 22:59:24 +000040/**
41 * CodeIgniter Inflector Helpers
42 *
43 * @package CodeIgniter
44 * @subpackage Helpers
45 * @category Helpers
Derek Jonesf4a4bd82011-10-20 12:18:42 -050046 * @author EllisLab Dev Team
Andrey Andreevbd202c92016-01-11 12:50:18 +020047 * @link https://codeigniter.com/user_guide/helpers/inflector_helper.html
Derek Allard2067d1a2008-11-13 22:59:24 +000048 */
49
Derek Allard2067d1a2008-11-13 22:59:24 +000050// --------------------------------------------------------------------
51
Derek Allard2067d1a2008-11-13 22:59:24 +000052if ( ! function_exists('singular'))
Barry Mienydd671972010-10-04 16:33:58 +020053{
Timothy Warrenb75faa12012-04-27 12:03:32 -040054 /**
55 * Singular
56 *
57 * Takes a plural word and makes it singular
58 *
Andrey Andreev53b8ef52012-11-08 21:38:53 +020059 * @param string $str Input string
Timothy Warren16642c72012-05-17 08:20:16 -040060 * @return string
Timothy Warrenb75faa12012-04-27 12:03:32 -040061 */
Derek Allard2067d1a2008-11-13 22:59:24 +000062 function singular($str)
63 {
Phil Sturgeon50e57bc2011-08-13 10:26:04 -060064 $result = strval($str);
Barry Mienydd671972010-10-04 16:33:58 +020065
Andrey Andreev12ee9842018-06-01 18:07:34 +030066 if ( ! word_is_countable($result))
Phil Sturgeon002b4be2012-02-29 12:12:49 +000067 {
68 return $result;
69 }
Andrey Andreev52a31ba2012-03-10 15:38:49 +020070
Phil Sturgeon50e57bc2011-08-13 10:26:04 -060071 $singular_rules = array(
Andrey Andreev838a9d62012-12-03 14:37:47 +020072 '/(matr)ices$/' => '\1ix',
73 '/(vert|ind)ices$/' => '\1ex',
74 '/^(ox)en/' => '\1',
75 '/(alias)es$/' => '\1',
76 '/([octop|vir])i$/' => '\1us',
77 '/(cris|ax|test)es$/' => '\1is',
78 '/(shoe)s$/' => '\1',
79 '/(o)es$/' => '\1',
80 '/(bus|campus)es$/' => '\1',
81 '/([m|l])ice$/' => '\1ouse',
82 '/(x|ch|ss|sh)es$/' => '\1',
83 '/(m)ovies$/' => '\1\2ovie',
84 '/(s)eries$/' => '\1\2eries',
85 '/([^aeiouy]|qu)ies$/' => '\1y',
86 '/([lr])ves$/' => '\1f',
87 '/(tive)s$/' => '\1',
88 '/(hive)s$/' => '\1',
89 '/([^f])ves$/' => '\1fe',
90 '/(^analy)ses$/' => '\1sis',
Phil Sturgeon50e57bc2011-08-13 10:26:04 -060091 '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/' => '\1\2sis',
Andrey Andreev838a9d62012-12-03 14:37:47 +020092 '/([ti])a$/' => '\1um',
93 '/(p)eople$/' => '\1\2erson',
94 '/(m)en$/' => '\1an',
95 '/(s)tatuses$/' => '\1\2tatus',
96 '/(c)hildren$/' => '\1\2hild',
97 '/(n)ews$/' => '\1\2ews',
Andrey Andreev8a0f4402017-05-09 09:40:49 +030098 '/(quiz)zes$/' => '\1',
Andrey Andreev838a9d62012-12-03 14:37:47 +020099 '/([^us])s$/' => '\1'
Phil Sturgeon50e57bc2011-08-13 10:26:04 -0600100 );
Eric Barnescde712c2011-12-09 11:27:51 -0500101
Phil Sturgeon002b4be2012-02-29 12:12:49 +0000102 foreach ($singular_rules as $rule => $replacement)
103 {
104 if (preg_match($rule, $result))
105 {
106 $result = preg_replace($rule, $replacement, $result);
107 break;
108 }
109 }
110
111 return $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000112 }
113}
114
115// --------------------------------------------------------------------
116
Derek Allard2067d1a2008-11-13 22:59:24 +0000117if ( ! function_exists('plural'))
Barry Mienydd671972010-10-04 16:33:58 +0200118{
Timothy Warrenb75faa12012-04-27 12:03:32 -0400119 /**
120 * Plural
121 *
122 * Takes a singular word and makes it plural
123 *
Andrey Andreev53b8ef52012-11-08 21:38:53 +0200124 * @param string $str Input string
Timothy Warren16642c72012-05-17 08:20:16 -0400125 * @return string
Timothy Warrenb75faa12012-04-27 12:03:32 -0400126 */
Andrey Andreev53b8ef52012-11-08 21:38:53 +0200127 function plural($str)
Andrey Andreev52a31ba2012-03-10 15:38:49 +0200128 {
Phil Sturgeon50e57bc2011-08-13 10:26:04 -0600129 $result = strval($str);
Eric Barnescde712c2011-12-09 11:27:51 -0500130
Andrey Andreev12ee9842018-06-01 18:07:34 +0300131 if ( ! word_is_countable($result))
Phil Sturgeon002b4be2012-02-29 12:12:49 +0000132 {
133 return $result;
134 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000135
Phil Sturgeon002b4be2012-02-29 12:12:49 +0000136 $plural_rules = array(
ftwbzhao1a973c32015-04-14 16:59:44 +0800137 '/(quiz)$/' => '\1zes', // quizzes
Phil Sturgeon002b4be2012-02-29 12:12:49 +0000138 '/^(ox)$/' => '\1\2en', // ox
139 '/([m|l])ouse$/' => '\1ice', // mouse, louse
140 '/(matr|vert|ind)ix|ex$/' => '\1ices', // matrix, vertex, index
141 '/(x|ch|ss|sh)$/' => '\1es', // search, switch, fix, box, process, address
142 '/([^aeiouy]|qu)y$/' => '\1ies', // query, ability, agency
143 '/(hive)$/' => '\1s', // archive, hive
144 '/(?:([^f])fe|([lr])f)$/' => '\1\2ves', // half, safe, wife
145 '/sis$/' => 'ses', // basis, diagnosis
146 '/([ti])um$/' => '\1a', // datum, medium
147 '/(p)erson$/' => '\1eople', // person, salesperson
148 '/(m)an$/' => '\1en', // man, woman, spokesman
149 '/(c)hild$/' => '\1hildren', // child
150 '/(buffal|tomat)o$/' => '\1\2oes', // buffalo, tomato
151 '/(bu|campu)s$/' => '\1\2ses', // bus, campus
152 '/(alias|status|virus)$/' => '\1es', // alias
153 '/(octop)us$/' => '\1i', // octopus
154 '/(ax|cris|test)is$/' => '\1es', // axis, crisis
155 '/s$/' => 's', // no change (compatibility)
156 '/$/' => 's',
157 );
Andrey Andreev52a31ba2012-03-10 15:38:49 +0200158
Phil Sturgeon002b4be2012-02-29 12:12:49 +0000159 foreach ($plural_rules as $rule => $replacement)
160 {
161 if (preg_match($rule, $result))
162 {
163 $result = preg_replace($rule, $replacement, $result);
164 break;
165 }
166 }
167
168 return $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000169 }
170}
171
172// --------------------------------------------------------------------
173
Derek Allard2067d1a2008-11-13 22:59:24 +0000174if ( ! function_exists('camelize'))
Barry Mienydd671972010-10-04 16:33:58 +0200175{
Timothy Warrenb75faa12012-04-27 12:03:32 -0400176 /**
177 * Camelize
178 *
179 * Takes multiple words separated by spaces or underscores and camelizes them
180 *
Andrey Andreev53b8ef52012-11-08 21:38:53 +0200181 * @param string $str Input string
Timothy Warren16642c72012-05-17 08:20:16 -0400182 * @return string
Timothy Warrenb75faa12012-04-27 12:03:32 -0400183 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000184 function camelize($str)
Barry Mienydd671972010-10-04 16:33:58 +0200185 {
Phil Sturgeone40c7632012-03-10 13:05:08 +0000186 return strtolower($str[0]).substr(str_replace(' ', '', ucwords(preg_replace('/[\s_]+/', ' ', $str))), 1);
Derek Allard2067d1a2008-11-13 22:59:24 +0000187 }
188}
189
190// --------------------------------------------------------------------
191
Derek Allard2067d1a2008-11-13 22:59:24 +0000192if ( ! function_exists('underscore'))
193{
Timothy Warrenb75faa12012-04-27 12:03:32 -0400194 /**
195 * Underscore
196 *
197 * Takes multiple words separated by spaces and underscores them
198 *
Andrey Andreev53b8ef52012-11-08 21:38:53 +0200199 * @param string $str Input string
Timothy Warren16642c72012-05-17 08:20:16 -0400200 * @return string
Timothy Warrenb75faa12012-04-27 12:03:32 -0400201 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000202 function underscore($str)
203 {
Andrey Andreev6ce47462014-02-13 03:28:00 +0200204 return preg_replace('/[\s]+/', '_', trim(MB_ENABLED ? mb_strtolower($str) : strtolower($str)));
Derek Allard2067d1a2008-11-13 22:59:24 +0000205 }
206}
207
208// --------------------------------------------------------------------
209
Derek Allard2067d1a2008-11-13 22:59:24 +0000210if ( ! function_exists('humanize'))
Barry Mienydd671972010-10-04 16:33:58 +0200211{
Timothy Warrenb75faa12012-04-27 12:03:32 -0400212 /**
213 * Humanize
214 *
215 * Takes multiple words separated by the separator and changes them to spaces
216 *
Andrey Andreev53b8ef52012-11-08 21:38:53 +0200217 * @param string $str Input string
218 * @param string $separator Input separator
Timothy Warren16642c72012-05-17 08:20:16 -0400219 * @return string
Timothy Warrenb75faa12012-04-27 12:03:32 -0400220 */
Eric Barnescde712c2011-12-09 11:27:51 -0500221 function humanize($str, $separator = '_')
Derek Allard2067d1a2008-11-13 22:59:24 +0000222 {
Ivan Tcholakov9fee9e42016-02-07 21:33:46 +0200223 return ucwords(preg_replace('/['.preg_quote($separator).']+/', ' ', trim(MB_ENABLED ? mb_strtolower($str) : strtolower($str))));
Derek Allard2067d1a2008-11-13 22:59:24 +0000224 }
225}
Barry Mienydd671972010-10-04 16:33:58 +0200226
Timothy Warrenb75faa12012-04-27 12:03:32 -0400227// --------------------------------------------------------------------
228
Andrey Andreev12ee9842018-06-01 18:07:34 +0300229if ( ! function_exists('word_is_countable'))
Phil Sturgeon002b4be2012-02-29 12:12:49 +0000230{
Timothy Warrenb75faa12012-04-27 12:03:32 -0400231 /**
232 * Checks if the given word has a plural version.
233 *
Andrey Andreev53b8ef52012-11-08 21:38:53 +0200234 * @param string $word Word to check
235 * @return bool
Timothy Warrenb75faa12012-04-27 12:03:32 -0400236 */
Andrey Andreev12ee9842018-06-01 18:07:34 +0300237 function word_is_countable($word)
Phil Sturgeon002b4be2012-02-29 12:12:49 +0000238 {
Andrey Andreev6ce47462014-02-13 03:28:00 +0200239 return ! in_array(
240 strtolower($word),
241 array(
Andrey Andreev72705122016-10-11 15:18:40 +0300242 'audio',
243 'bison',
244 'chassis',
245 'compensation',
246 'coreopsis',
247 'data',
248 'deer',
249 'education',
250 'emoji',
251 'equipment',
252 'fish',
253 'furniture',
254 'gold',
255 'information',
256 'knowledge',
257 'love',
258 'rain',
259 'money',
260 'moose',
261 'nutrition',
262 'offspring',
263 'plankton',
264 'pokemon',
265 'police',
266 'rice',
267 'series',
268 'sheep',
269 'species',
270 'swine',
271 'traffic',
Andrey Andreev4c7323e2016-10-28 13:18:17 +0300272 'wheat'
Andrey Andreev6ce47462014-02-13 03:28:00 +0200273 )
274 );
Phil Sturgeon002b4be2012-02-29 12:12:49 +0000275 }
276}
Andrey Andreev12ee9842018-06-01 18:07:34 +0300277
278// --------------------------------------------------------------------
279
280if ( ! function_exists('is_countable'))
281{
282 function is_countable($word)
283 {
284 trigger_error('is_countable() is a native PHP function since version 7.3.0; use word_is_countable() instead', E_USER_WARNING);
285 return word_is_countable($word);
286 }
287}