[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/horde/framework/Horde/Support/ -> Inflector.php (source)

   1  <?php
   2  /**
   3   * Horde Inflector class.
   4   *
   5   * Copyright 2007-2014 Horde LLC (http://www.horde.org/)
   6   *
   7   * @todo Add the locale-bubbling pattern from
   8   *       Horde_Date_Parser/Horde_Support_Numerizer
   9   *
  10   * @category   Horde
  11   * @package    Support
  12   * @license    http://www.horde.org/licenses/bsd
  13   */
  14  class Horde_Support_Inflector
  15  {
  16      /**
  17       * Inflection cache
  18       *
  19       * @var array
  20       */
  21      protected $_cache = array();
  22  
  23      /**
  24       * Rules for pluralizing English nouns.
  25       *
  26       * @var array
  27       */
  28      protected $_pluralizationRules = array(
  29          '/move$/i' => 'moves',
  30          '/sex$/i' => 'sexes',
  31          '/child$/i' => 'children',
  32          '/man$/i' => 'men',
  33          '/foot$/i' => 'feet',
  34          '/person$/i' => 'people',
  35          '/(quiz)$/i' => '$1zes',
  36          '/^(ox)$/i' => '$1en',
  37          '/(m|l)ouse$/i' => '$1ice',
  38          '/(matr|vert|ind)ix|ex$/i' => '$1ices',
  39          '/(x|ch|ss|sh)$/i' => '$1es',
  40          '/([^aeiouy]|qu)ies$/i' => '$1y',
  41          '/([^aeiouy]|qu)y$/i' => '$1ies',
  42          '/(?:([^f])fe|([lr])f)$/i' => '$1$2ves',
  43          '/sis$/i' => 'ses',
  44          '/([ti])um$/i' => '$1a',
  45          '/(buffal|tomat)o$/i' => '$1oes',
  46          '/(bu)s$/i' => '$1ses',
  47          '/(alias|status)$/i' => '$1es',
  48          '/(octop|vir)us$/i' => '$1i',
  49          '/(ax|test)is$/i' => '$1es',
  50          '/s$/i' => 's',
  51          '/$/' => 's',
  52      );
  53  
  54      /**
  55       * Rules for singularizing English nouns.
  56       *
  57       * @var array
  58       */
  59      protected $_singularizationRules = array(
  60          '/cookies$/i' => 'cookie',
  61          '/moves$/i' => 'move',
  62          '/sexes$/i' => 'sex',
  63          '/children$/i' => 'child',
  64          '/men$/i' => 'man',
  65          '/feet$/i' => 'foot',
  66          '/people$/i' => 'person',
  67          '/databases$/i'=> 'database',
  68          '/(quiz)zes$/i' => '\1',
  69          '/(matr)ices$/i' => '\1ix',
  70          '/(vert|ind)ices$/i' => '\1ex',
  71          '/^(ox)en/i' => '\1',
  72          '/(alias|status)es$/i' => '\1',
  73          '/([octop|vir])i$/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])a$/i' => '\1um',
  90          '/(n)ews$/i' => '\1ews',
  91          '/(.*)s$/i' => '\1',
  92      );
  93  
  94      /**
  95       * An array of words with the same singular and plural spellings.
  96       *
  97       * @var array
  98       */
  99      protected $_uncountables = array(
 100          'aircraft',
 101          'cannon',
 102          'deer',
 103          'equipment',
 104          'fish',
 105          'information',
 106          'money',
 107          'moose',
 108          'rice',
 109          'series',
 110          'sheep',
 111          'species',
 112          'swine',
 113      );
 114  
 115      /**
 116       * Constructor.
 117       *
 118       * Stores a map of the uncountable words for quicker checks.
 119       */
 120      public function __construct()
 121      {
 122          $this->_uncountables_keys = array_flip($this->_uncountables);
 123      }
 124  
 125      /**
 126       * Adds an uncountable word.
 127       *
 128       * @param string $word The uncountable word.
 129       */
 130      public function uncountable($word)
 131      {
 132          $this->_uncountables[] = $word;
 133          $this->_uncountables_keys[$word] = true;
 134      }
 135  
 136      /**
 137       * Singular English word to pluralize.
 138       *
 139       * @param string $word Word to pluralize.
 140       *
 141       * @return string Plural form of $word.
 142       */
 143      public function pluralize($word)
 144      {
 145          if ($plural = $this->getCache($word, 'pluralize')) {
 146              return $plural;
 147          }
 148  
 149          if (isset($this->_uncountables_keys[$word])) {
 150              return $word;
 151          }
 152  
 153          foreach ($this->_pluralizationRules as $regexp => $replacement) {
 154              $plural = preg_replace($regexp, $replacement, $word, -1, $matches);
 155              if ($matches > 0) {
 156                  return $this->setCache($word, 'pluralize', $plural);
 157              }
 158          }
 159  
 160          return $this->setCache($word, 'pluralize', $word);
 161      }
 162  
 163      /**
 164       * Plural English word to singularize.
 165       *
 166       * @param string $word Word to singularize.
 167       *
 168       * @return string Singular form of $word.
 169       */
 170      public function singularize($word)
 171      {
 172          if ($singular = $this->getCache($word, 'singularize')) {
 173              return $singular;
 174          }
 175  
 176          if (isset($this->_uncountables_keys[$word])) {
 177              return $word;
 178          }
 179  
 180          foreach ($this->_singularizationRules as $regexp => $replacement) {
 181              $singular = preg_replace($regexp, $replacement, $word, -1, $matches);
 182              if ($matches > 0) {
 183                  return $this->setCache($word, 'singularize', $singular);
 184              }
 185          }
 186  
 187          return $this->setCache($word, 'singularize', $word);
 188      }
 189  
 190      /**
 191       * Camel-cases a word.
 192       *
 193       * @param string $word         The word to camel-case.
 194       * @param string $firstLetter  Whether to upper or lower case the first.
 195       *                             letter of each slash-separated section.
 196       *
 197       * @return string Camelized $word
 198       */
 199      public function camelize($word, $firstLetter = 'upper')
 200      {
 201          if ($camelized = $this->getCache($word, 'camelize' . $firstLetter)) {
 202              return $camelized;
 203          }
 204  
 205          $camelized = $word;
 206          if (strtolower($camelized) != $camelized &&
 207              strpos($camelized, '_') !== false) {
 208              $camelized = str_replace('_', '/', $camelized);
 209          }
 210          if (strpos($camelized, '/') !== false) {
 211              $camelized = str_replace('/', '/ ', $camelized);
 212          }
 213          if (strpos($camelized, '_') !== false) {
 214              $camelized = strtr($camelized, '_', ' ');
 215          }
 216  
 217          $camelized = str_replace(' ', '', ucwords($camelized));
 218  
 219          if ($firstLetter == 'lower') {
 220              $parts = array();
 221              foreach (explode('/', $camelized) as $part) {
 222                  $part[0] = strtolower($part[0]);
 223                  $parts[] = $part;
 224              }
 225              $camelized = implode('/', $parts);
 226          }
 227  
 228          return $this->setCache($word, 'camelize' . $firstLetter, $camelized);
 229      }
 230  
 231      /**
 232       * Capitalizes all the words and replaces some characters in the string to
 233       * create a nicer looking title.
 234       *
 235       * Titleize is meant for creating pretty output.
 236       *
 237       * See:
 238       * - http://daringfireball.net/2008/05/title_case
 239       * - http://daringfireball.net/2008/08/title_case_update
 240       *
 241       * Examples:
 242       * 1. titleize("man from the boondocks") => "Man From The Boondocks"
 243       * 2. titleize("x-men: the last stand")  => "X Men: The Last Stand"
 244       */
 245      public function titleize($word)
 246      {
 247          throw new Exception('not implemented yet');
 248      }
 249  
 250      /**
 251       * The reverse of camelize().
 252       *
 253       * Makes an underscored form from the expression in the string.
 254       *
 255       * Examples:
 256       * 1. underscore("ActiveRecord")        => "active_record"
 257       * 2. underscore("ActiveRecord_Errors") => "active_record_errors"
 258       */
 259      public function underscore($camelCasedWord)
 260      {
 261          $word = $camelCasedWord;
 262          if ($result = $this->getCache($word, 'underscore')) {
 263              return $result;
 264          }
 265          $result = strtolower(preg_replace('/([a-z])([A-Z])/', "\$1}_\$2}", $word));
 266          return $this->setCache($word, 'underscore', $result);
 267      }
 268  
 269      /**
 270       * Replaces underscores with dashes in the string.
 271       *
 272       * Example:
 273       * 1. dasherize("puni_puni") => "puni-puni"
 274       */
 275      public function dasherize($underscoredWord)
 276      {
 277          if ($result = $this->getCache($underscoredWord, 'dasherize')) {
 278              return $result;
 279          }
 280  
 281          $result = str_replace('_', '-', $this->underscore($underscoredWord));
 282          return $this->setCache($underscoredWord, 'dasherize', $result);
 283      }
 284  
 285      /**
 286       * Capitalizes the first word and turns underscores into spaces and strips
 287       * _id.
 288       *
 289       * Like titleize(), this is meant for creating pretty output.
 290       *
 291       * Examples:
 292       * 1. humanize("employee_salary") => "Employee salary"
 293       * 2. humanize("author_id")       => "Author"
 294       */
 295      public function humanize($lowerCaseAndUnderscoredWord)
 296      {
 297          $word = $lowerCaseAndUnderscoredWord;
 298          if ($result = $this->getCache($word, 'humanize')) {
 299              return $result;
 300          }
 301  
 302          $result = ucfirst(str_replace('_', ' ', $this->underscore($word)));
 303          if (substr($result, -3, 3) == ' id') {
 304              $result = str_replace(' id', '', $result);
 305          }
 306          return $this->setCache($word, 'humanize', $result);
 307      }
 308  
 309      /**
 310       * Removes the module part from the expression in the string.
 311       *
 312       * Examples:
 313       * 1. demodulize("Fax_Job") => "Job"
 314       * 1. demodulize("User")    => "User"
 315       */
 316      public function demodulize($classNameInModule)
 317      {
 318          $result = explode('_', $classNameInModule);
 319          return array_pop($result);
 320      }
 321  
 322      /**
 323       * Creates the name of a table like Rails does for models to table names.
 324       *
 325       * This method uses the pluralize() method on the last word in the string.
 326       *
 327       * Examples:
 328       * 1. tableize("RawScaledScorer") => "raw_scaled_scorers"
 329       * 2. tableize("egg_and_ham")     => "egg_and_hams"
 330       * 3. tableize("fancyCategory")   => "fancy_categories"
 331       */
 332      public function tableize($className)
 333      {
 334          if ($result = $this->getCache($className, 'tableize')) {
 335              return $result;
 336          }
 337  
 338          $result = $this->pluralize($this->underscore($className));
 339          $result = str_replace('/', '_', $result);
 340          return $this->setCache($className, 'tableize', $result);
 341      }
 342  
 343      /**
 344       * Creates a class name from a table name like Rails does for table names
 345       * to models.
 346       *
 347       * Examples:
 348       * 1. classify("egg_and_hams") => "EggAndHam"
 349       * 2. classify("post")         => "Post"
 350       */
 351      public function classify($tableName)
 352      {
 353          if ($result = $this->getCache($tableName, 'classify')) {
 354              return $result;
 355          }
 356          $result = $this->camelize($this->singularize($tableName));
 357  
 358          // classes use underscores instead of slashes for namespaces
 359          $result = str_replace('/', '_', $result);
 360          return $this->setCache($tableName, 'classify', $result);
 361      }
 362  
 363      /**
 364       * Creates a foreign key name from a class name.
 365       *
 366       * $separateClassNameAndIdWithUnderscore sets whether the method should put
 367       * '_' between the name and 'id'.
 368       *
 369       * Examples:
 370       * 1. foreignKey("Message")        => "message_id"
 371       * 2. foreignKey("Message", false) => "messageid"
 372       * 3. foreignKey("Fax_Job")        => "fax_job_id"
 373       */
 374      public function foreignKey($className, $separateClassNameAndIdWithUnderscore = true)
 375      {
 376          throw new Exception('not implemented yet');
 377      }
 378  
 379      /**
 380       * Turns a number into an ordinal string used to denote the position in an
 381       * ordered sequence such as 1st, 2nd, 3rd, 4th.
 382       *
 383       * Examples:
 384       * 1. ordinalize(1)      => "1st"
 385       * 2. ordinalize(2)      => "2nd"
 386       * 3. ordinalize(1002)   => "1002nd"
 387       * 4. ordinalize(1003)   => "1003rd"
 388       */
 389      public function ordinalize($number)
 390      {
 391          throw new Exception('not implemented yet');
 392      }
 393  
 394      /**
 395       * Clears the inflection cache.
 396       */
 397      public function clearCache()
 398      {
 399          $this->_cache = array();
 400      }
 401  
 402      /**
 403       * Retuns a cached inflection.
 404       *
 405       * @return string | false
 406       */
 407      public function getCache($word, $rule)
 408      {
 409          return isset($this->_cache[$word . '|' . $rule]) ?
 410              $this->_cache[$word . '|' . $rule] : false;
 411      }
 412  
 413      /**
 414       * Caches an inflection.
 415       *
 416       * @param string $word   The word being inflected.
 417       * @param string $rule   The inflection rule.
 418       * @param string $value  The inflected value of $word.
 419       *
 420       * @return string The inflected value
 421       */
 422      public function setCache($word, $rule, $value)
 423      {
 424          $this->_cache[$word . '|' . $rule] = $value;
 425          return $value;
 426      }
 427  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1