Source for file inflector.php

Documentation is available at inflector.php

  1. <?php
  2. /**
  3.  * @package     FrameworkOnFramework
  4.  * @subpackage  inflector
  5.  * @copyright   Copyright (C) 2010 - 2012 Akeeba Ltd. All rights reserved.
  6.  * @license     GNU General Public License version 2 or later; see LICENSE.txt
  7.  */
  8. defined('_JEXEC'or die;
  9.  
  10. /**
  11.  * The FOFInflector is an adaptation of the Akelos PHP Inflector which is a PHP
  12.  * port from a Ruby on Rails project.
  13.  */
  14.  
  15. /**
  16.  * FOFInflector to pluralize and singularize English nouns.
  17.  *
  18.  * @package  FrameworkOnFramework
  19.  * @since    1.0
  20.  */
  21. {
  22.     /**
  23.      * Rules for pluralizing and singularizing of nouns.
  24.      *
  25.      * @var array 
  26.      */
  27.     protected static $_rules array
  28.     (
  29.         'pluralization'   => array(
  30.             '/move$/i'                      => 'moves',
  31.             '/sex$/i'                       => 'sexes',
  32.             '/child$/i'                     => 'children',
  33.             '/man$/i'                       => 'men',
  34.             '/foot$/i'                      => 'feet',
  35.             '/person$/i'                    => 'people',
  36.             '/taxon$/i'                     => 'taxa',
  37.             '/(quiz)$/i'                    => '$1zes',
  38.             '/^(ox)$/i'                     => '$1en',
  39.             '/(m|l)ouse$/i'                 => '$1ice',
  40.             '/(matr|vert|ind|suff)ix|ex$/i' => '$1ices',
  41.             '/(x|ch|ss|sh)$/i'              => '$1es',
  42.             '/([^aeiouy]|qu)y$/i'           => '$1ies',
  43.             '/(?:([^f])fe|([lr])f)$/i'      => '$1$2ves',
  44.             '/sis$/i'                       => 'ses',
  45.             '/([ti]|addend)um$/i'           => '$1a',
  46.             '/(alumn|formul)a$/i'           => '$1ae',
  47.             '/(buffal|tomat|her)o$/i'       => '$1oes',
  48.             '/(bu)s$/i'                     => '$1ses',
  49.             '/(alias|status)$/i'            => '$1es',
  50.             '/(octop|vir)us$/i'             => '$1i',
  51.             '/(gen)us$/i'                   => '$1era',
  52.             '/(ax|test)is$/i'               => '$1es',
  53.             '/s$/i'                         => 's',
  54.             '/$/'                           => 's',
  55.         ),
  56.         'singularization' => array(
  57.             '/cookies$/i'                                                      => 'cookie',
  58.             '/moves$/i'                                                        => 'move',
  59.             '/sexes$/i'                                                        => 'sex',
  60.             '/children$/i'                                                     => 'child',
  61.             '/men$/i'                                                          => 'man',
  62.             '/feet$/i'                                                         => 'foot',
  63.             '/people$/i'                                                       => 'person',
  64.             '/taxa$/i'                                                         => 'taxon',
  65.             '/databases$/i'                                                    => 'database',
  66.             '/(quiz)zes$/i'                                                    => '\1',
  67.             '/(matr|suff)ices$/i'                                              => '\1ix',
  68.             '/(vert|ind)ices$/i'                                               => '\1ex',
  69.             '/^(ox)en/i'                                                       => '\1',
  70.             '/(alias|status)es$/i'                                             => '\1',
  71.             '/(tomato|hero|buffalo)es$/i'                                      => '\1',
  72.             '/([octop|vir])i$/i'                                               => '\1us',
  73.             '/(gen)era$/i'                                                     => '\1us',
  74.             '/(cris|^ax|test)es$/i'                                            => '\1is',
  75.             '/(shoe)s$/i'                                                      => '\1',
  76.             '/(o)es$/i'                                                        => '\1',
  77.             '/(bus)es$/i'                                                      => '\1',
  78.             '/([m|l])ice$/i'                                                   => '\1ouse',
  79.             '/(x|ch|ss|sh)es$/i'                                               => '\1',
  80.             '/(m)ovies$/i'                                                     => '\1ovie',
  81.             '/(s)eries$/i'                                                     => '\1eries',
  82.             '/([^aeiouy]|qu)ies$/i'                                            => '\1y',
  83.             '/([lr])ves$/i'                                                    => '\1f',
  84.             '/(tive)s$/i'                                                      => '\1',
  85.             '/(hive)s$/i'                                                      => '\1',
  86.             '/([^f])ves$/i'                                                    => '\1fe',
  87.             '/(^analy)ses$/i'                                                  => '\1sis',
  88.             '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
  89.             '/([ti]|addend)a$/i'                                               => '\1um',
  90.             '/(alumn|formul)ae$/i'                                             => '$1a',
  91.             '/(n)ews$/i'                                                       => '\1ews',
  92.             '/(.*)ss$/i'                                                       => '\1ss',
  93.             '/(.*)s$/i'                                                        => '\1',
  94.         ),
  95.         'countable'       => array(
  96.             'aircraft',
  97.             'cannon',
  98.             'deer',
  99.             'equipment',
  100.             'fish',
  101.             'information',
  102.             'money',
  103.             'moose',
  104.             'rice',
  105.             'series',
  106.             'sheep',
  107.             'species',
  108.             'swine',
  109.         )
  110.     );
  111.  
  112.     /**
  113.      * Cache of pluralized and singularized nouns.
  114.      *
  115.      * @var array 
  116.      */
  117.     protected static $_cache array(
  118.         'singularized' => array(),
  119.         'pluralized'   => array()
  120.     );
  121.  
  122.     /**
  123.      * Constructor
  124.      *
  125.      * Prevent creating instances of this class by making the contructor private
  126.      */
  127.     private function __construct()
  128.     {
  129.     }
  130.  
  131.     /**
  132.      * Add a word to the cache, useful to make exceptions or to add words in other languages.
  133.      *
  134.      * @param   string  $singular  word.
  135.      * @param   string  $plural    word.
  136.      *
  137.      * @return  void 
  138.      */
  139.     public static function addWord($singular$plural)
  140.     {
  141.         self::$_cache['pluralized'][$singular$plural;
  142.         self::$_cache['singularized'][$plural$singular;
  143.     }
  144.  
  145.     /**
  146.      * Singular English word to plural.
  147.      *
  148.      * @param   string  $word  word to pluralize.
  149.      *
  150.      * @return  string Plural noun.
  151.      */
  152.     public static function pluralize($word)
  153.     {
  154.         // Get the cached noun of it exists
  155.         if (isset(self::$_cache['pluralized'][$word]))
  156.         {
  157.             return self::$_cache['pluralized'][$word];
  158.         }
  159.  
  160.         // Create the plural noun
  161.         if (in_array($wordself::$_rules['countable']))
  162.         {
  163.             $_cache['pluralized'][$word$word;
  164.  
  165.             return $word;
  166.         }
  167.  
  168.         foreach (self::$_rules['pluralization'as $regexp => $replacement)
  169.         {
  170.             $matches null;
  171.             $plural  preg_replace($regexp$replacement$word-1$matches);
  172.  
  173.             if ($matches 0)
  174.             {
  175.                 $_cache['pluralized'][$word$plural;
  176.  
  177.                 return $plural;
  178.             }
  179.         }
  180.  
  181.         return $word;
  182.     }
  183.  
  184.     /**
  185.      * Plural English word to singular.
  186.      *
  187.      * @param   string  $word  Word to singularize.
  188.      *
  189.      * @return  string Singular noun.
  190.      */
  191.     public static function singularize($word)
  192.     {
  193.         // Get the cached noun of it exists
  194.         if (isset(self::$_cache['singularized'][$word]))
  195.         {
  196.             return self::$_cache['singularized'][$word];
  197.         }
  198.  
  199.         // Create the singular noun
  200.         if (in_array($wordself::$_rules['countable']))
  201.         {
  202.             $_cache['singularized'][$word$word;
  203.  
  204.             return $word;
  205.         }
  206.  
  207.         foreach (self::$_rules['singularization'as $regexp => $replacement)
  208.         {
  209.             $matches  null;
  210.             $singular preg_replace($regexp$replacement$word-1$matches);
  211.  
  212.             if ($matches 0)
  213.             {
  214.                 $_cache['singularized'][$word$singular;
  215.  
  216.                 return $singular;
  217.             }
  218.         }
  219.  
  220.         return $word;
  221.     }
  222.  
  223.     /**
  224.      * Returns given word as CamelCased.
  225.      *
  226.      * Converts a word like "foo_bar" or "foo bar" to "FooBar". It
  227.      * will remove non alphanumeric characters from the word, so
  228.      * "who's online" will be converted to "WhoSOnline"
  229.      *
  230.      * @param   string  $word  Word to convert to camel case.
  231.      *
  232.      * @return  string  UpperCamelCasedWord
  233.      */
  234.     public static function camelize($word)
  235.     {
  236.         $word preg_replace('/[^a-zA-Z0-9\s]/'' '$word);
  237.         $word str_replace(' '''ucwords(strtolower(str_replace('_'' '$word))));
  238.  
  239.         return $word;
  240.     }
  241.  
  242.     /**
  243.      * Converts a word "into_it_s_underscored_version"
  244.      *
  245.      * Convert any "CamelCased" or "ordinary Word" into an "underscored_word".
  246.      *
  247.      * @param   string  $word  Word to underscore
  248.      *
  249.      * @return string Underscored word
  250.      */
  251.     public static function underscore($word)
  252.     {
  253.         $word preg_replace('/(\s)+/''_'$word);
  254.         $word strtolower(preg_replace('/(?<=\\w)([A-Z])/''_\\1'$word));
  255.  
  256.         return $word;
  257.     }
  258.  
  259.     /**
  260.      * Convert any "CamelCased" word into an array of strings
  261.      *
  262.      * Returns an array of strings each of which is a substring of string formed
  263.      * by splitting it at the camelcased letters.
  264.      *
  265.      * @param   string  $word  Word to explode
  266.      *
  267.      * @return  array   Array of strings
  268.      */
  269.     public static function explode($word)
  270.     {
  271.         $result explode('_'self::underscore($word));
  272.  
  273.         return $result;
  274.     }
  275.  
  276.     /**
  277.      * Convert  an array of strings into a "CamelCased" word.
  278.      *
  279.      * @param   array  $words  Array to implode
  280.      *
  281.      * @return  string UpperCamelCasedWord
  282.      */
  283.     public static function implode($words)
  284.     {
  285.         $result self::camelize(implode('_'$words));
  286.  
  287.         return $result;
  288.     }
  289.  
  290.     /**
  291.      * Returns a human-readable string from $word.
  292.      *
  293.      * Returns a human-readable string from $word, by replacing
  294.      * underscores with a space, and by upper-casing the initial
  295.      * character by default.
  296.      *
  297.      * @param   string  $word  String to "humanize"
  298.      *
  299.      * @return string Human-readable word
  300.      */
  301.     public static function humanize($word)
  302.     {
  303.         $result ucwords(strtolower(str_replace("_"" "$word)));
  304.  
  305.         return $result;
  306.     }
  307.  
  308.     /**
  309.      * Converts a class name to its table name according to Koowa
  310.      * naming conventions.
  311.      *
  312.      * Converts "Person" to "people"
  313.      *
  314.      * @param   string  $className  Class name for getting related table_name.
  315.      *
  316.      * @return  string  plural_table_name
  317.      *
  318.      * @see classify
  319.      */
  320.     public static function tableize($className)
  321.     {
  322.         $result self::underscore($className);
  323.  
  324.         if (!self::isPlural($className))
  325.         {
  326.             $result self::pluralize($result);
  327.         }
  328.  
  329.         return $result;
  330.     }
  331.  
  332.     /**
  333.      * Converts a table name to its class name according to Koowa naming conventions.
  334.      *
  335.      * @param   string  $tableName  Table name for getting related ClassName.
  336.      *
  337.      * @return string SingularClassName
  338.      *
  339.      * @example  Converts "people" to "Person"
  340.      * @see tableize
  341.      */
  342.     public static function classify($tableName)
  343.     {
  344.         $result self::camelize(self::singularize($tableName));
  345.  
  346.         return $result;
  347.     }
  348.  
  349.     /**
  350.      * Returns camelBacked version of a string. Same as camelize but first char is lowercased.
  351.      *
  352.      * @param   string  $string  String to be camelBacked.
  353.      *
  354.      * @return string 
  355.      *
  356.      * @see camelize
  357.      */
  358.     public static function variablize($string)
  359.     {
  360.         $string   self::camelize(self::underscore($string));
  361.         $result   strtolower(substr($string01));
  362.         $variable preg_replace('/\\w/'$result$string1);
  363.  
  364.         return $variable;
  365.     }
  366.  
  367.     /**
  368.      * Check to see if an English word is singular
  369.      *
  370.      * @param   string  $string  The word to check
  371.      *
  372.      * @return boolean 
  373.      */
  374.     public static function isSingular($string)
  375.     {
  376.         // Check cache assuming the string is plural.
  377.         $singular = isset(self::$_cache['singularized'][$string]self::$_cache['singularized'][$stringnull;
  378.         $plural   $singular && isset(self::$_cache['pluralized'][$singular]self::$_cache['pluralized'][$singularnull;
  379.  
  380.         if ($singular && $plural)
  381.         {
  382.             return $plural != $string;
  383.         }
  384.  
  385.         // If string is not in the cache, try to pluralize and singularize it.
  386.         return self::singularize(self::pluralize($string)) == $string;
  387.     }
  388.  
  389.     /**
  390.      * Check to see if an Enlish word is plural.
  391.      *
  392.      * @param   string  $string  String to be checked.
  393.      *
  394.      * @return boolean 
  395.      */
  396.     public static function isPlural($string)
  397.     {
  398.         // Check cache assuming the string is singular.
  399.         $plural   = isset(self::$_cache['pluralized'][$string]self::$_cache['pluralized'][$stringnull;
  400.         $singular $plural && isset(self::$_cache['singularized'][$plural]self::$_cache['singularized'][$pluralnull;
  401.  
  402.         if ($plural && $singular)
  403.         {
  404.             return $singular != $string;
  405.         }
  406.  
  407.         // If string is not in the cache, try to singularize and pluralize it.
  408.         return self::pluralize(self::singularize($string)) == $string;
  409.     }
  410.  
  411.     /**
  412.      * Gets a part of a CamelCased word by index.
  413.      *
  414.      * Use a negative index to start at the last part of the word (-1 is the
  415.      * last part)
  416.      *
  417.      * @param   string   $string   Word
  418.      * @param   integer  $index    Index of the part
  419.      * @param   string   $default  Default value
  420.      *
  421.      * @return string 
  422.      */
  423.     public static function getPart($string$index$default null)
  424.     {
  425.         $parts self::explode($string);
  426.  
  427.         if ($index 0)
  428.         {
  429.             $index count($parts$index;
  430.         }
  431.  
  432.         return isset($parts[$index]$parts[$index$default;
  433.     }
  434. }

Documentation generated on Tue, 19 Nov 2013 15:05:33 +0100 by phpDocumentor 1.4.3