<?php namespace Laravel; class Inflector { /** * The words that have been converted to singular. * * @var array */ private static $singular_cache = array(); /** * The words that have been converted to plural. * * @var array */ private static $plural_cache = array(); /** * Plural word forms. * * @var array */ private static $plural = array( '/(quiz)$/i' => "$1zes", '/^(ox)$/i' => "$1en", '/([m|l])ouse$/i' => "$1ice", '/(matr|vert|ind)ix|ex$/i' => "$1ices", '/(x|ch|ss|sh)$/i' => "$1es", '/([^aeiouy]|qu)y$/i' => "$1ies", '/(hive)$/i' => "$1s", '/(?:([^f])fe|([lr])f)$/i' => "$1$2ves", '/(shea|lea|loa|thie)f$/i' => "$1ves", '/sis$/i' => "ses", '/([ti])um$/i' => "$1a", '/(tomat|potat|ech|her|vet)o$/i' => "$1oes", '/(bu)s$/i' => "$1ses", '/(alias)$/i' => "$1es", '/(octop)us$/i' => "$1i", '/(ax|test)is$/i' => "$1es", '/(us)$/i' => "$1es", '/s$/i' => "s", '/$/' => "s" ); /** * Singular word forms. * * @var array */ private static $singular = array( '/(quiz)zes$/i' => "$1", '/(matr)ices$/i' => "$1ix", '/(vert|ind)ices$/i' => "$1ex", '/^(ox)en$/i' => "$1", '/(alias)es$/i' => "$1", '/(octop|vir)i$/i' => "$1us", '/(cris|ax|test)es$/i' => "$1is", '/(shoe)s$/i' => "$1", '/(o)es$/i' => "$1", '/(bus)es$/i' => "$1", '/([m|l])ice$/i' => "$1ouse", '/(x|ch|ss|sh)es$/i' => "$1", '/(m)ovies$/i' => "$1ovie", '/(s)eries$/i' => "$1eries", '/([^aeiouy]|qu)ies$/i' => "$1y", '/([lr])ves$/i' => "$1f", '/(tive)s$/i' => "$1", '/(hive)s$/i' => "$1", '/(li|wi|kni)ves$/i' => "$1fe", '/(shea|loa|lea|thie)ves$/i' => "$1f", '/(^analy)ses$/i' => "$1sis", '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => "$1$2sis", '/([ti])a$/i' => "$1um", '/(n)ews$/i' => "$1ews", '/(h|bl)ouses$/i' => "$1ouse", '/(corpse)s$/i' => "$1", '/(us)es$/i' => "$1", '/(us|ss)$/i' => "$1", '/s$/i' => "", ); /** * Irregular word forms. * * @var array */ private static $irregular = array( 'child' => 'children', 'foot' => 'feet', 'goose' => 'geese', 'man' => 'men', 'move' => 'moves', 'person' => 'people', 'sex' => 'sexes', 'tooth' => 'teeth', ); /** * Uncountable word forms. * * @var array */ private static $uncountable = array( 'equipment', 'data', 'deer', 'fish', 'information', 'money', 'rice', 'series', 'sheep', 'species', ); /** * Get the plural form of a word if the specified count is greater than one. * * @param string $value * @param int $count * @return string */ public static function plural_if($value, $count) { return ($count > 1) ? static::plural($value) : $value; } /** * Convert a word to its plural form. * * @param string $value * @return string */ public static function plural($value) { $irregular = array_flip(static::$irregular); $plural = static::inflect($value, static::$plural_cache, $irregular, static::$plural); return static::$plural_cache[$value] = $plural; } /** * Convert a word to its singular form. * * @param string $value * @return string */ public static function singular($value) { $singular = static::inflect($value, static::$singular_cache, static::$irregular, static::$singular); return static::$singular_cache[$value] = $singular; } /** * Convert a word to its singular or plural form. * * @param string $value * @param array $cache * @param array $irregular * @param array $source * @return string */ private static function inflect($value, $cache, $irregular, $source) { if (array_key_exists($value, $cache)) { return $cache[$value]; } if (in_array(strtolower($value), static::$uncountable)) { return $value; } foreach ($irregular as $irregular => $pattern) { if (preg_match($pattern = '/'.$pattern.'$/i', $value)) { return preg_replace($pattern, $irregular, $value); } } foreach ($source as $pattern => $inflected) { if (preg_match($pattern, $value)) { return preg_replace($pattern, $inflected, $value); } } return $value; } }