From 16f779c8f519355125f8f5cff0fa335c2d1b54ac Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 24 Jul 2015 10:26:54 -0600 Subject: [PATCH] changed Inflector from static to class + added multilang support --- system/languages/en.yaml | 58 +++++++ system/src/Grav/Common/GPM/GPM.php | 4 +- system/src/Grav/Common/Grav.php | 2 + system/src/Grav/Common/Inflector.php | 163 ++++++------------ system/src/Grav/Common/Language/Language.php | 34 ++-- system/src/Grav/Common/Plugins.php | 4 +- system/src/Grav/Common/Themes.php | 5 +- system/src/Grav/Common/Twig/TwigExtension.php | 8 +- 8 files changed, 147 insertions(+), 131 deletions(-) create mode 100644 system/languages/en.yaml diff --git a/system/languages/en.yaml b/system/languages/en.yaml new file mode 100644 index 000000000..7ee1ca42b --- /dev/null +++ b/system/languages/en.yaml @@ -0,0 +1,58 @@ +INFLECTOR_PLURALS: + '/(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)ies$/i': '\1y' + '/([^aeiouy]|qu)y$/i': '\1ies' + '/(hive)$/i': '\1s' + '/(?:([^f])fe|([lr])f)$/i': '\1\2ves' + '/sis$/i': 'ses' + '/([ti])um$/i': '\1a' + '/(buffal|tomat)o$/i': '\1oes' + '/(bu)s$/i': '\1ses' + '/(alias|status)/i': '\1es' + '/(octop|vir)us$/i': '\1i' + '/(ax|test)is$/i': '\1es' + '/s$/i': 's' + '/$/': 's' +INFLECTOR_SINGULAR: + '/(quiz)zes$/i': '\1' + '/(matr)ices$/i': '\1ix' + '/(vert|ind)ices$/i': '\1ex' + '/^(ox)en/i': '\1' + '/(alias|status)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' + '/([^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' + '/(n)ews$/i': '\1ews' + '/s$/i': '' +INFLECTOR_UNCOUNTABLE: ['equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep'] +INFLECTOR_IRREGULAR: + 'person': 'people' + 'man': 'men' + 'child': 'children' + 'sex': 'sexes' + 'move': 'moves' +INFLECTOR_ORDINALS: + 'default': 'th' + 'first': 'st' + 'second': 'nd' + 'third': 'rd' + + diff --git a/system/src/Grav/Common/GPM/GPM.php b/system/src/Grav/Common/GPM/GPM.php index a6eefce5a..049f0ec8c 100644 --- a/system/src/Grav/Common/GPM/GPM.php +++ b/system/src/Grav/Common/GPM/GPM.php @@ -349,6 +349,8 @@ class GPM extends Iterator public function findPackages($searches = []) { $packages = ['total' => 0, 'not_found' => []]; + $inflector = $this->grav['inflector']; + foreach ($searches as $search) { $repository = ''; @@ -380,7 +382,7 @@ class GPM extends Iterator } $not_found = new \stdClass(); - $not_found->name = Inflector::camelize($search); + $not_found->name = $inflector->camelize($search); $not_found->slug = $search; $not_found->package_type = $type; $not_found->install_path = str_replace('%name%', $search, $this->install_paths[$type]); diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index c145192e4..2bcb9e9cd 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -159,6 +159,8 @@ class Grav extends Container $container->register(new StreamsServiceProvider); $container->register(new ConfigServiceProvider); + $container['inflector'] = new Inflector(); + $container['debugger']->stopTimer('_init'); return $container; diff --git a/system/src/Grav/Common/Inflector.php b/system/src/Grav/Common/Inflector.php index d707448c4..2c89f7313 100644 --- a/system/src/Grav/Common/Inflector.php +++ b/system/src/Grav/Common/Inflector.php @@ -4,6 +4,7 @@ namespace Grav\Common; /** * This file was originally part of the Akelos Framework */ +use Grav\Common\Language\Language; /** * Inflector for pluralize and singularize English nouns. @@ -20,65 +21,55 @@ namespace Grav\Common; class Inflector { + use GravTrait; + + protected $plural; + protected $singular; + protected $uncountable; + protected $irregular; + protected $ordinals; + + public function init() + { + if (empty($this->plural)) { + $language = self::getGrav()['language']; + $this->plural = $language->translate('INFLECTOR_PLURALS', null, true); + $this->singular = $language->translate('INFLECTOR_SINGULAR', null, true); + $this->uncountable = $language->translate('INFLECTOR_UNCOUNTABLE', null, true); + $this->irregular = $language->translate('INFLECTOR_IRREGULAR', null, true); + $this->ordinals = $language->translate('INFLECTOR_ORDINALS', null, true); + } + } /** * Pluralizes English nouns. * - * @access static public - * @static * @param string $word English noun to pluralize * @return string Plural noun */ - public static function pluralize($word, $count = 2) + public function pluralize($word, $count = 2) { + $this->init(); + if ($count == 1) { return $word; } - $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)ies$/i' => '\1y', - '/([^aeiouy]|qu)y$/i' => '\1ies', - '/(hive)$/i' => '\1s', - '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', - '/sis$/i' => 'ses', - '/([ti])um$/i' => '\1a', - '/(buffal|tomat)o$/i' => '\1oes', - '/(bu)s$/i' => '\1ses', - '/(alias|status)/i'=> '\1es', - '/(octop|vir)us$/i'=> '\1i', - '/(ax|test)is$/i'=> '\1es', - '/s$/i'=> 's', - '/$/'=> 's'); - - $uncountable = array('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep'); - - $irregular = array( - 'person' => 'people', - 'man' => 'men', - 'child' => 'children', - 'sex' => 'sexes', - 'move' => 'moves'); - $lowercased_word = strtolower($word); - foreach ($uncountable as $_uncountable) { + foreach ($this->uncountable as $_uncountable) { if (substr($lowercased_word, (-1*strlen($_uncountable))) == $_uncountable) { return $word; } } - foreach ($irregular as $_plural => $_singular) { + foreach ($this->irregular as $_plural => $_singular) { if (preg_match('/('.$_plural.')$/i', $word, $arr)) { return preg_replace('/('.$_plural.')$/i', substr($arr[0], 0, 1).substr($_singular, 1), $word); } } - foreach ($plural as $rule => $replacement) { + foreach ($this->plural as $rule => $replacement) { if (preg_match($rule, $word)) { return preg_replace($rule, $replacement, $word); } @@ -94,62 +85,26 @@ class Inflector * @param int $count * @return string Singular noun. */ - public static function singularize($word, $count = 1) + public function singularize($word, $count = 1) { if ($count != 1) { return $word; } - $singular = array ( - '/(quiz)zes$/i' => '\1', - '/(matr)ices$/i' => '\1ix', - '/(vert|ind)ices$/i' => '\1ex', - '/^(ox)en/i' => '\1', - '/(alias|status)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', - '/([^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', - '/(n)ews$/i' => '\1ews', - '/s$/i' => '', - ); - - $uncountable = array('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep'); - - $irregular = array( - 'person' => 'people', - 'man' => 'men', - 'child' => 'children', - 'sex' => 'sexes', - 'move' => 'moves'); - $lowercased_word = strtolower($word); - foreach ($uncountable as $_uncountable) { + foreach ($this->uncountable as $_uncountable) { if (substr($lowercased_word, (-1*strlen($_uncountable))) == $_uncountable) { return $word; } } - foreach ($irregular as $_plural => $_singular) { + foreach ($this->irregular as $_plural => $_singular) { if (preg_match('/('.$_singular.')$/i', $word, $arr)) { return preg_replace('/('.$_singular.')$/i', substr($arr[0], 0, 1).substr($_plural, 1), $word); } } - foreach ($singular as $rule => $replacement) { + foreach ($this->singular as $rule => $replacement) { if (preg_match($rule, $word)) { return preg_replace($rule, $replacement, $word); } @@ -162,24 +117,22 @@ class Inflector * Converts an underscored or CamelCase word into a English * sentence. * - * The titleize static public function converts text like "WelcomePage", + * The titleize public function converts text like "WelcomePage", * "welcome_page" or "welcome page" to this "Welcome * Page". * If second parameter is set to 'first' it will only * capitalize the first character of the title. * - * @access static public - * @static * @param string $word Word to format as tile * @param string $uppercase If set to 'first' it will only uppercase the * first character. Otherwise it will uppercase all * the words in the title. * @return string Text formatted as title */ - public static function titleize($word, $uppercase = '') + public function titleize($word, $uppercase = '') { $uppercase = $uppercase == 'first' ? 'ucfirst' : 'ucwords'; - return $uppercase(static::humanize(static::underscorize($word))); + return $uppercase($this->humanize($this->underscorize($word))); } /** @@ -189,13 +142,11 @@ class Inflector * will remove non alphanumeric character from the word, so * "who's online" will be converted to "WhoSOnline" * - * @access static public - * @static * @see variablize * @param string $word Word to convert to camel case * @return string UpperCamelCasedWord */ - public static function camelize($word) + public function camelize($word) { return str_replace(' ', '', ucwords(preg_replace('/[^A-Z^a-z^0-9]+/', ' ', $word))); } @@ -208,12 +159,10 @@ class Inflector * * This can be really useful for creating friendly URLs. * - * @access static public - * @static * @param string $word Word to underscore * @return string Underscored word */ - public static function underscorize($word) + public function underscorize($word) { $regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1_\2', $word); $regex2 = preg_replace('/([a-zd])([A-Z])/', '\1_\2', $regex1); @@ -229,12 +178,10 @@ class Inflector * * This can be really useful for creating friendly URLs. * - * @access static public - * @static * @param string $word Word to hyphenate * @return string hyphenized word */ - public static function hyphenize($word) + public function hyphenize($word) { $regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1-\2', $word); $regex2 = preg_replace('/([a-zd])([A-Z])/', '\1-\2', $regex1); @@ -252,14 +199,12 @@ class Inflector * If you need to uppercase all the words you just have to * pass 'all' as a second parameter. * - * @access static public - * @static * @param string $word String to "humanize" * @param string $uppercase If set to 'all' it will uppercase all the words * instead of just the first one. * @return string Human-readable word */ - public static function humanize($word, $uppercase = '') + public function humanize($word, $uppercase = '') { $uppercase = $uppercase == 'all' ? 'ucwords' : 'ucfirst'; return $uppercase(str_replace('_', ' ', preg_replace('/_id$/', '', $word))); @@ -272,15 +217,13 @@ class Inflector * will remove non alphanumeric character from the word, so * "who's online" will be converted to "whoSOnline" * - * @access static public - * @static * @see camelize * @param string $word Word to lowerCamelCase * @return string Returns a lowerCamelCasedWord */ - public static function variablize($word) + public function variablize($word) { - $word = static::camelize($word); + $word = $this->camelize($word); return strtolower($word[0]).substr($word, 1); } @@ -290,15 +233,13 @@ class Inflector * * Converts "Person" to "people" * - * @access static public - * @static * @see classify * @param string $class_name Class name for getting related table_name. * @return string plural_table_name */ - public static function tableize($class_name) + public function tableize($class_name) { - return static::pluralize(static::underscore($class_name)); + return $this->pluralize($this->underscore($class_name)); } /** @@ -307,15 +248,13 @@ class Inflector * * Converts "people" to "Person" * - * @access static public - * @static * @see tableize * @param string $table_name Table name for getting related ClassName. * @return string SingularClassName */ - public static function classify($table_name) + public function classify($table_name) { - return static::camelize(static::singularize($table_name)); + return $this->camelize($this->singularize($table_name)); } /** @@ -323,34 +262,32 @@ class Inflector * * This method converts 13 to 13th, 2 to 2nd ... * - * @access static public - * @static * @param integer $number Number to get its ordinal value * @return string Ordinal representation of given string. */ - public static function ordinalize($number) + public function ordinalize($number) { if (in_array(($number % 100), range(11, 13))) { - return $number.'th'; + return $number.$this->ordinals['default']; } else { switch (($number % 10)) { case 1: - return $number.'st'; + return $number.$this->ordinals['first']; break; case 2: - return $number.'nd'; + return $number.$this->ordinals['second']; break; case 3: - return $number.'rd'; + return $number.$this->ordinals['third']; break; default: - return $number.'th'; + return $number.$this->ordinals['default']; break; } } } - public static function monthize($days) + public function monthize($days) { $now = new \DateTime(); $end = new \DateTime(); diff --git a/system/src/Grav/Common/Language/Language.php b/system/src/Grav/Common/Language/Language.php index 9069c2a10..6c890b1bc 100644 --- a/system/src/Grav/Common/Language/Language.php +++ b/system/src/Grav/Common/Language/Language.php @@ -276,13 +276,15 @@ class Language /** * Translate a key and possibly arguments into a string using current lang and fallbacks * - * @param $args first argument is the lookup key value - * other arguments can be passed and replaced in the translation with sprintf syntax + * @param $args first argument is the lookup key value + * other arguments can be passed and replaced in the translation with sprintf syntax * @param Array $languages + * @param bool $array_support + * @param bool $html_out * * @return string */ - public function translate($args, Array $languages = null) + public function translate($args, Array $languages = null, $array_support = false, $html_out = false) { if (is_array($args)) { $lookup = array_shift($args); @@ -306,7 +308,7 @@ class Language } foreach ((array)$languages as $lang) { - $translation = $this->getTranslation($lang, $lookup); + $translation = $this->getTranslation($lang, $lookup, $array_support); if ($translation) { if (count($args) >= 1) { @@ -318,7 +320,11 @@ class Language } } - return '' . $lookup . ''; + if ($html_out) { + return '' . $lookup . ''; + } else { + return $lookup; + } } /** @@ -327,10 +333,11 @@ class Language * @param $key * @param $index * @param null $languages + * @param bool $html_out * * @return string */ - public function translateArray($key, $index, $languages = null) + public function translateArray($key, $index, $languages = null, $html_out = false) { if ($this->config->get('system.languages.translations', true)) { if ($this->enabled() && $key) { @@ -353,21 +360,26 @@ class Language } } - return '' . $key . '[' . $index . ']'; + if ($html_out) { + return '' . $key . '[' . $index . ']'; + } else { + return $key . '[' . $index . ']'; + } } /** * Lookup the translation text for a given lang and key * - * @param $lang lang code - * @param $key key to lookup with + * @param $lang lang code + * @param $key key to lookup with + * @param bool $array_support * * @return string */ - public function getTranslation($lang, $key) + public function getTranslation($lang, $key, $array_support = false) { $translation = $this->config->getLanguages()->get($lang . '.' . $key, null); - if (is_array($translation)) { + if (!$array_support && is_array($translation)) { return (string)array_shift($translation); } diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index 77a2afa2e..dd5fb74a0 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -32,6 +32,8 @@ class Plugins extends Iterator $config = self::getGrav()['config']; $plugins = (array) $config->get('plugins'); + $inflector = self::getGrav()['inflector']; + /** @var EventDispatcher $events */ $events = self::getGrav()['events']; @@ -52,7 +54,7 @@ class Plugins extends Iterator $pluginClassFormat = [ 'Grav\\Plugin\\'.ucfirst($plugin).'Plugin', - 'Grav\\Plugin\\'.Inflector::camelize($plugin).'Plugin' + 'Grav\\Plugin\\'.$inflector->camelize($plugin).'Plugin' ]; $pluginClassName = false; diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index b27a32c87..516a9d2fb 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -141,15 +141,16 @@ class Themes extends Iterator $locator = $grav['locator']; $file = $locator('theme://theme.php') ?: $locator("theme://{$name}.php"); + $inflector = $grav['inflector']; + if ($file) { // Local variables available in the file: $grav, $config, $name, $file $class = include $file; if (!is_object($class)) { - $themeClassFormat = [ 'Grav\\Theme\\'.ucfirst($name), - 'Grav\\Theme\\'.Inflector::camelize($name) + 'Grav\\Theme\\'.$inflector->camelize($name) ]; $themeClassName = false; diff --git a/system/src/Grav/Common/Twig/TwigExtension.php b/system/src/Grav/Common/Twig/TwigExtension.php index f2cba017f..1e8ef609c 100644 --- a/system/src/Grav/Common/Twig/TwigExtension.php +++ b/system/src/Grav/Common/Twig/TwigExtension.php @@ -194,16 +194,18 @@ class TwigExtension extends \Twig_Extension // TODO: check this and fix the docblock if needed. $action = $action.'ize'; + $inflector = $this->grav['inflector']; + if (in_array( $action, ['titleize','camelize','underscorize','hyphenize', 'humanize','ordinalize','monthize'] )) { - return Inflector::$action($data); + return $inflector->$action($data); } elseif (in_array($action, ['pluralize','singularize'])) { if ($count) { - return Inflector::$action($data, $count); + return $inflector->$action($data, $count); } else { - return Inflector::$action($data); + return $inflector->$action($data); } } else { return $data;