123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- <?php
- /**
- * Part of the Fuel framework.
- *
- * @package Fuel
- * @version 1.5
- * @author Fuel Development Team
- * @license MIT License
- * @copyright 2010 - 2013 Fuel Development Team
- * @link http://fuelphp.com
- */
- namespace Fuel\Core;
- /**
- * Some of this code was written by Flinn Mueller.
- *
- * @package Fuel
- * @category Core
- * @copyright Flinn Mueller
- * @link http://docs.fuelphp.com/classes/inlector.html
- */
- class Inflector
- {
- protected static $uncountable_words = array(
- 'equipment', 'information', 'rice', 'money',
- 'species', 'series', 'fish', 'meta'
- );
- protected static $plural_rules = array(
- '/^(ox)$/i' => '\1\2en', // ox
- '/([m|l])ouse$/i' => '\1ice', // mouse, louse
- '/(matr|vert|ind)ix|ex$/i' => '\1ices', // matrix, vertex, index
- '/(x|ch|ss|sh)$/i' => '\1es', // search, switch, fix, box, process, address
- '/([^aeiouy]|qu)y$/i' => '\1ies', // query, ability, agency
- '/(hive)$/i' => '\1s', // archive, hive
- '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', // half, safe, wife
- '/sis$/i' => 'ses', // basis, diagnosis
- '/([ti])um$/i' => '\1a', // datum, medium
- '/(p)erson$/i' => '\1eople', // person, salesperson
- '/(m)an$/i' => '\1en', // man, woman, spokesman
- '/(c)hild$/i' => '\1hildren', // child
- '/(buffal|tomat)o$/i' => '\1\2oes', // buffalo, tomato
- '/(bu|campu)s$/i' => '\1\2ses', // bus, campus
- '/(alias|status|virus)$/i' => '\1es', // alias
- '/(octop)us$/i' => '\1i', // octopus
- '/(ax|cris|test)is$/i' => '\1es', // axis, crisis
- '/s$/' => 's', // no change (compatibility)
- '/$/' => 's',
- );
- protected static $singular_rules = array(
- '/(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|campus)es$/i' => '\1',
- '/([m|l])ice$/i' => '\1ouse',
- '/(x|ch|ss|sh)es$/i' => '\1',
- '/(m)ovies$/i' => '\1\2ovie',
- '/(s)eries$/i' => '\1\2eries',
- '/([^aeiouy]|qu)ies$/i' => '\1y',
- '/([lr])ves$/i' => '\1f',
- '/(tive)s$/i' => '\1',
- '/(hive)s$/i' => '\1',
- '/([^f])ves$/i' => '\1fe',
- '/(^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',
- '/(p)eople$/i' => '\1\2erson',
- '/(m)en$/i' => '\1an',
- '/(s)tatuses$/i' => '\1\2tatus',
- '/(c)hildren$/i' => '\1\2hild',
- '/(n)ews$/i' => '\1\2ews',
- '/([^us])s$/i' => '\1',
- );
- /**
- * Add order suffix to numbers ex. 1st 2nd 3rd 4th 5th
- *
- * @param int the number to ordinalize
- * @return string the ordinalized version of $number
- * @link http://snipplr.com/view/4627/a-function-to-add-a-prefix-to-numbers-ex-1st-2nd-3rd-4th-5th/
- */
- public static function ordinalize($number)
- {
- if ( ! is_numeric($number))
- {
- return $number;
- }
- if (in_array(($number % 100), range(11, 13)))
- {
- return $number . 'th';
- }
- else
- {
- switch ($number % 10)
- {
- case 1:
- return $number . 'st';
- break;
- case 2:
- return $number . 'nd';
- break;
- case 3:
- return $number . 'rd';
- break;
- default:
- return $number . 'th';
- break;
- }
- }
- }
- /**
- * Gets the plural version of the given word
- *
- * @param string the word to pluralize
- * @param int number of instances
- * @return string the plural version of $word
- */
- public static function pluralize($word, $count = 0)
- {
- $result = strval($word);
- // If a counter is provided, and that equals 1
- // return as singular.
- if ($count === 1)
- {
- return $result;
- }
- if ( ! static::is_countable($result))
- {
- return $result;
- }
- foreach (static::$plural_rules as $rule => $replacement)
- {
- if (preg_match($rule, $result))
- {
- $result = preg_replace($rule, $replacement, $result);
- break;
- }
- }
- return $result;
- }
- /**
- * Gets the singular version of the given word
- *
- * @param string the word to singularize
- * @return string the singular version of $word
- */
- public static function singularize($word)
- {
- $result = strval($word);
- if ( ! static::is_countable($result))
- {
- return $result;
- }
- foreach (static::$singular_rules as $rule => $replacement)
- {
- if (preg_match($rule, $result))
- {
- $result = preg_replace($rule, $replacement, $result);
- break;
- }
- }
- return $result;
- }
- /**
- * Takes a string that has words seperated by underscores and turns it into
- * a CamelCased string.
- *
- * @param string the underscored word
- * @return string the CamelCased version of $underscored_word
- */
- public static function camelize($underscored_word)
- {
- return preg_replace('/(^|_)(.)/e', "strtoupper('\\2')", strval($underscored_word));
- }
- /**
- * Takes a CamelCased string and returns an underscore separated version.
- *
- * @param string the CamelCased word
- * @return string an underscore separated version of $camel_cased_word
- */
- public static function underscore($camel_cased_word)
- {
- return \Str::lower(preg_replace('/([A-Z]+)([A-Z])/', '\1_\2', preg_replace('/([a-z\d])([A-Z])/', '\1_\2', strval($camel_cased_word))));
- }
- /**
- * Translate string to 7-bit ASCII
- * Only works with UTF-8.
- *
- * @param string $str string to translate
- * @param bool $allow_non_ascii wether to remove non ascii
- * @return string translated string
- */
- public static function ascii($str, $allow_non_ascii = false)
- {
- // Translate unicode characters to their simpler counterparts
- \Config::load('ascii', true);
- $foreign_characters = \Config::get('ascii');
- $str = preg_replace(array_keys($foreign_characters), array_values($foreign_characters), $str);
- if ( ! $allow_non_ascii)
- {
- return preg_replace('/[^\x09\x0A\x0D\x20-\x7E]/', '', $str);
- }
- return $str;
- }
- /**
- * Converts your text to a URL-friendly title so it can be used in the URL.
- * Only works with UTF8 input and and only outputs 7 bit ASCII characters.
- *
- * @param string $str the text
- * @param string $sep the separator (either - or _)
- * @param bool $lowercase wether to convert to lowercase
- * @param bool $allow_non_ascii wether to allow non ascii
- * @return string the new title
- */
- public static function friendly_title($str, $sep = '-', $lowercase = false, $allow_non_ascii = false)
- {
- // Allow underscore, otherwise default to dash
- $sep = $sep === '_' ? '_' : '-';
- // Remove tags
- $str = \Security::strip_tags($str);
- // Decode all entities to their simpler forms
- $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8');
- // Remove all quotes.
- $str = preg_replace("#[\"\']#", '', $str);
- // Only allow 7bit characters
- $str = static::ascii($str, $allow_non_ascii);
- if ($allow_non_ascii)
- {
- // Strip regular special chars.
- $str = preg_replace("#[\.;:'\"\]\}\[\{\+\)\(\*&\^\$\#@\!±`%~']#iu", '', $str);
- }
- else
- {
- // Strip unwanted characters
- $str = preg_replace("#[^a-z0-9]#i", $sep, $str);
- }
- $str = preg_replace("#[/_|+ -]+#u", $sep, $str);
- $str = trim($str, $sep);
- if ($lowercase === true)
- {
- $str = \Str::lower($str);
- }
- return $str;
- }
- /**
- * Turns an underscore or dash separated word and turns it into a human looking string.
- *
- * @param string the word
- * @param string the separator (either _ or -)
- * @param bool lowercare string and upper case first
- * @return string the human version of given string
- */
- public static function humanize($str, $sep = '_', $lowercase = true)
- {
- // Allow dash, otherwise default to underscore
- $sep = $sep != '-' ? '_' : $sep;
- if ($lowercase === true)
- {
- $str = \Str::ucfirst($str);
- }
- return str_replace($sep, " ", strval($str));
- }
- /**
- * Takes the class name out of a modulized string.
- *
- * @param string the modulized class
- * @return string the string without the class name
- */
- public static function demodulize($class_name_in_module)
- {
- return preg_replace('/^.*::/', '', strval($class_name_in_module));
- }
- /**
- * Takes the namespace off the given class name.
- *
- * @param string the class name
- * @return string the string without the namespace
- */
- public static function denamespace($class_name)
- {
- $class_name = trim($class_name, '\\');
- if ($last_separator = strrpos($class_name, '\\'))
- {
- $class_name = substr($class_name, $last_separator + 1);
- }
- return $class_name;
- }
- /**
- * Returns the namespace of the given class name.
- *
- * @param string $class_name the class name
- * @return string the string without the namespace
- */
- public static function get_namespace($class_name)
- {
- $class_name = trim($class_name, '\\');
- if ($last_separator = strrpos($class_name, '\\'))
- {
- return substr($class_name, 0, $last_separator + 1);
- }
- return '';
- }
- /**
- * Takes a class name and determines the table name. The table name is a
- * pluralized version of the class name.
- *
- * @param string the table name
- * @return string the table name
- */
- public static function tableize($class_name)
- {
- $class_name = static::denamespace($class_name);
- if (strncasecmp($class_name, 'Model_', 6) === 0)
- {
- $class_name = substr($class_name, 6);
- }
- return \Str::lower(static::pluralize(static::underscore($class_name)));
- }
- /**
- * Takes an underscored classname and uppercases all letters after the underscores.
- *
- * @param string classname
- * @param string separator
- * @return string
- */
- public static function words_to_upper($class, $sep = '_')
- {
- return str_replace(' ', $sep, ucwords(str_replace($sep, ' ', $class)));
- }
- /**
- * Takes a table name and creates the class name.
- *
- * @param string the table name
- * @param bool whether to singularize the table name or not
- * @return string the class name
- */
- public static function classify($name, $force_singular = true)
- {
- $class = ($force_singular) ? static::singularize($name) : $name;
- return static::words_to_upper($class);
- }
- /**
- * Gets the foreign key for a given class.
- *
- * @param string the class name
- * @param bool $use_underscore whether to use an underscore or not
- * @return string the foreign key
- */
- public static function foreign_key($class_name, $use_underscore = true)
- {
- $class_name = static::denamespace(\Str::lower($class_name));
- if (strncasecmp($class_name, 'Model_', 6) === 0)
- {
- $class_name = substr($class_name, 6);
- }
- return static::underscore(static::demodulize($class_name)).($use_underscore ? "_id" : "id");
- }
- /**
- * Checks if the given word has a plural version.
- *
- * @param string the word to check
- * @return bool if the word is countable
- */
- public static function is_countable($word)
- {
- return ! (\in_array(\Str::lower(\strval($word)), static::$uncountable_words));
- }
- }
|