[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/ -> AkInflector.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
   3  
   4  // +----------------------------------------------------------------------+
   5  // | Akelos Framework - http://www.akelos.org                             |
   6  // +----------------------------------------------------------------------+
   7  // | Copyright (c) 2002-2006, Akelos Media, S.L.  & Bermi Ferrer Martinez |
   8  // | Released under the GNU Lesser General Public License, see LICENSE.txt|
   9  // +----------------------------------------------------------------------+
  10  
  11  /**
  12   * @package ActiveSupport
  13   * @subpackage Inflector
  14   * @author Bermi Ferrer <bermi a.t akelos c.om>
  15   * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
  16   * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
  17   */
  18  
  19  /**
  20  * AkInflector for pluralize and singularize English nouns.
  21  * 
  22  * This AkInflector is a port of Ruby on Rails AkInflector.
  23  * 
  24  * It can be really helpful for developers that want to
  25  * create frameworks based on naming conventions rather than
  26  * configurations.
  27  * 
  28  * You can find the inflector rules in config/inflector.yml
  29  * To add your own inflector rules, please do so in config/inflector/mydictionary.yml
  30  * 
  31  * Using it:
  32  * 
  33  * AkInflector::pluralize('inglés',null,'es'); // ingleses, see config/inflector/es.yml
  34  * 
  35  * @author Bermi Ferrer Martinez <bermi a.t akelos c.om>
  36  * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
  37  * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
  38  */
  39  class AkInflector
  40  {
  41      // ------ CLASS METHODS ------ //
  42  
  43      // ---- Public methods ---- //
  44  
  45      // {{{ pluralize()
  46      function _loadConfig($dictionary)
  47      {
  48          static $_loaded = array();
  49          if (!($return=Ak::getStaticVar('AkInflectorConfig::'.$dictionary))) {
  50              $return = Ak::getSettings($dictionary,false);
  51              
  52              if ($return !== false) {
  53                  Ak::setStaticVar('AkInflectorConfig::'.$dictionary,$return);
  54                  $_loaded[$dictionary] = true;
  55              } else {
  56                  trigger_error(Ak::t('Could not load inflector rules file: %file',array('%file'=>'config'.DS.$dictionary.'.yml')),E_USER_ERROR);
  57              }
  58              
  59          }
  60          return $return;
  61      }
  62      
  63      function _inflect($word, $new_value, $type, $dictionary = null)
  64      {
  65          static $_cached;
  66          static $_loaded;
  67          
  68          if ($dictionary == null || $dictionary=='inflector') {
  69              $dictionary = 'inflector';
  70          } else {
  71              $dictionary = 'inflector/'.$dictionary;
  72          }
  73          if (!isset($_loaded[$dictionary])) {
  74              
  75              $_loaded[$dictionary] = true;
  76              $_cached[$dictionary] = array('singularize'=>array(),'pluralize'=>array()); 
  77          }
  78          
  79          $config = AkInflector::_loadConfig($dictionary);
  80          if (!in_array($type,array('singularize','pluralize'))) {
  81              return $word;
  82          }
  83          if(isset($new_value)){
  84              $_cached[$dictionary][$type][$word] = $new_value;
  85              return;
  86          }
  87          $_original_word = $word;
  88          if(!isset($_cached[$dictionary][$type][$_original_word])){
  89              $lowercased_word = strtolower($word);
  90              if (in_array($lowercased_word,$config[$type]['uncountable'])){
  91                  return $word;
  92              }
  93              foreach ($config[$type]['irregular'] as $_plural=> $_singular){
  94                  if ($type == 'singularize') {
  95                      if (preg_match('/('.$_singular.')$/iu', $word, $arr)) {
  96                          $_cached[$dictionary][$type][$_original_word] = preg_replace('/('.$_singular.')$/i', substr($arr[0],0,1).substr($_plural,1), $word);
  97                          return $_cached[$dictionary][$type][$_original_word];
  98                      }
  99                  } else {
 100                      if (preg_match('/('.$_plural.')$/iu', $word, $arr)) {
 101                          $_cached[$dictionary][$type][$_original_word] = preg_replace('/('.$_plural.')$/i', substr($arr[0],0,1).substr($_singular,1), $word);
 102                          return $_cached[$dictionary][$type][$_original_word];
 103                      }
 104                  }
 105              }
 106              
 107              $replacements = isset($config[$type]['replacements'])?$config[$type]['replacements']:false;
 108              if ($replacements!==false) {
 109                  $replacements_keys = array_keys($replacements);
 110                  foreach ($replacements_keys as $idx=>$key) {
 111                      $replacements_keys[$idx]  = '/'.$key.'/u';
 112                  }
 113                  $replacements_values = array_values($replacements);
 114              }
 115              foreach ($config[$type]['rules'] as $rule => $replacement) {
 116                  if (preg_match($rule.'u', $word, $match)) {
 117                      if(strstr($replacement,'@') && $replacements){
 118                          foreach ($match as $k=>$v){
 119                              $replacement = preg_replace("/(@$k)/u",preg_replace($replacements_keys,$replacements_values, $v), $replacement);
 120                          }
 121                      }
 122                      $_cached[$dictionary][$type][$_original_word] = preg_replace($rule.'u', $replacement, $word);
 123                      return $_cached[$dictionary][$type][$_original_word];
 124                  }
 125              }
 126              $_cached[$dictionary][$type][$_original_word] = $word;
 127              return $_cached[$dictionary][$type][$_original_word];
 128          }
 129          return $_cached[$dictionary][$type][$_original_word];
 130      }
 131      
 132      /**
 133      * Pluralizes English nouns.
 134      * 
 135      * @access public
 136      * @static
 137      * @param    string    $word    English noun to pluralize
 138      * @return string Plural noun
 139      */
 140      function pluralize($word, $new_plural = null, $dictionary = null)
 141      {
 142          return AkInflector::_inflect($word,$new_plural,'pluralize',$dictionary);
 143      }
 144  
 145      // }}}
 146      // {{{ singularize()
 147  
 148      /**
 149      * Singularizes English nouns.
 150      * 
 151      * @access public
 152      * @static
 153      * @param    string    $word    English noun to singularize
 154      * @return string Singular noun.
 155      */
 156      function singularize($word, $new_singular = null, $dictionary = null)
 157      {
 158          return AkInflector::_inflect($word,$new_singular,'singularize',$dictionary);
 159      }
 160  
 161      // }}}
 162      // {{{ conditionalPlural()
 163  
 164      /**
 165       * Get the plural form of a word if first parameter is greater than 1
 166       *
 167       * @param integer $numer_of_records
 168       * @param string $word
 169       * @return string Pluralized string when number of items is greater than 1
 170       */
 171      function conditionalPlural($numer_of_records, $word)
 172      {
 173          return $numer_of_records > 1 ? AkInflector::pluralize($word) : $word;
 174      }
 175  
 176      // }}}
 177      // {{{ titleize()
 178  
 179      /**
 180      * Converts an underscored or CamelCase word into a English
 181      * sentence.
 182      * 
 183      * The titleize function converts text like "WelcomePage",
 184      * "welcome_page" or  "welcome page" to this "Welcome
 185      * Page".
 186      * If second parameter is set to 'first' it will only
 187      * capitalize the first character of the title.
 188      * 
 189      * @access public
 190      * @static
 191      * @param    string    $word    Word to format as tile
 192      * @param    string    $uppercase    If set to 'first' it will only uppercase the
 193      * first character. Otherwise it will uppercase all
 194      * the words in the title.
 195      * @return string Text formatted as title
 196      */
 197      function titleize($word, $uppercase = '')
 198      {
 199          $uppercase = $uppercase == 'first' ? 'ucfirst' : 'ucwords';
 200          return $uppercase(AkInflector::humanize(AkInflector::underscore($word)));
 201      }
 202  
 203      // }}}
 204      // {{{ camelize()
 205  
 206      /**
 207      * Returns given word as CamelCased
 208      * 
 209      * Converts a word like "send_email" to "SendEmail". It
 210      * will remove non alphanumeric character from the word, so
 211      * "who's online" will be converted to "WhoSOnline"
 212      * 
 213      * @access public
 214      * @static
 215      * @see variablize
 216      * @param    string    $word    Word to convert to camel case
 217      * @return string UpperCamelCasedWord
 218      */
 219      function camelize($word)
 220      {
 221          static $_cached;
 222          if(!isset($_cached[$word])){
 223              if(preg_match_all('/\/(.?)/',$word,$got)){
 224                  foreach ($got[1] as $k=>$v){
 225                      $got[1][$k] = '::'.strtoupper($v);
 226                  }
 227                  $word = str_replace($got[0],$got[1],$word);
 228              }
 229              $_cached[$word] = str_replace(' ','',ucwords(preg_replace('/[^A-Z^a-z^0-9^:]+/',' ',$word)));
 230          }
 231          return $_cached[$word];
 232      }
 233  
 234      // }}}
 235      // {{{ underscore()
 236  
 237      /**
 238      * Converts a word "into_it_s_underscored_version"
 239      * 
 240      * Convert any "CamelCased" or "ordinary Word" into an
 241      * "underscored_word".
 242      * 
 243      * This can be really useful for creating friendly URLs.
 244      * 
 245      * @access public
 246      * @static
 247      * @param    string    $word    Word to underscore
 248      * @return string Underscored word
 249      */
 250      function underscore($word)
 251      {
 252          static $_cached;
 253          if(!isset($_cached[$word])){
 254              $_cached[$word] = strtolower(preg_replace(
 255              array('/[^A-Z^a-z^0-9^\/]+/','/([a-z\d])([A-Z])/','/([A-Z]+)([A-Z][a-z])/'),
 256              array('_','\1_\2','\1_\2'), $word));
 257          }
 258          return $_cached[$word];
 259      }
 260  
 261  
 262      // }}}
 263      // {{{ humanize()
 264  
 265      /**
 266      * Returns a human-readable string from $word
 267      * 
 268      * Returns a human-readable string from $word, by replacing
 269      * underscores with a space, and by upper-casing the initial
 270      * character by default.
 271      * 
 272      * If you need to uppercase all the words you just have to
 273      * pass 'all' as a second parameter.
 274      * 
 275      * @access public
 276      * @static
 277      * @param    string    $word    String to "humanize"
 278      * @param    string    $uppercase    If set to 'all' it will uppercase all the words
 279      * instead of just the first one.
 280      * @return string Human-readable word
 281      */
 282      function humanize($word, $uppercase = '')
 283      {
 284          $uppercase = $uppercase == 'all' ? 'ucwords' : 'ucfirst';
 285          return $uppercase(str_replace('_',' ',preg_replace('/_id$/', '',$word)));
 286      }
 287  
 288      // }}}
 289      // {{{ variablize()
 290  
 291      /**
 292      * Same as camelize but first char is lowercased
 293      * 
 294      * Converts a word like "send_email" to "sendEmail". It
 295      * will remove non alphanumeric character from the word, so
 296      * "who's online" will be converted to "whoSOnline"
 297      * 
 298      * @access public
 299      * @static
 300      * @see camelize
 301      * @param    string    $word    Word to lowerCamelCase
 302      * @return string Returns a lowerCamelCasedWord
 303      */
 304      function variablize($word)
 305      {
 306          $word = AkInflector::camelize($word);
 307          return strtolower($word[0]).substr($word,1);
 308      }
 309  
 310      // }}}
 311      // {{{ tableize()
 312  
 313      /**
 314      * Converts a class name to its table name according to rails
 315      * naming conventions.
 316      * 
 317      * Converts "Person" to "people"
 318      * 
 319      * @access public
 320      * @static
 321      * @see classify
 322      * @param    string    $class_name    Class name for getting related table_name.
 323      * @return string plural_table_name
 324      */
 325      function tableize($class_name)
 326      {
 327          return AkInflector::pluralize(AkInflector::underscore($class_name));
 328      }
 329  
 330      // }}}
 331      // {{{ classify()
 332  
 333      /**
 334      * Converts a table name to its class name according to Akelos
 335      * naming conventions.
 336      * 
 337      * Converts "people" to "Person"
 338      * 
 339      * @access public
 340      * @static
 341      * @see tableize
 342      * @param    string    $table_name    Table name for getting related ClassName.
 343      * @return string SingularClassName
 344      */
 345      function classify($table_name)
 346      {
 347          return AkInflector::camelize(AkInflector::singularize($table_name));
 348      }
 349  
 350      // }}}
 351      // {{{ ordinalize()
 352  
 353      /**
 354      * Converts number to its ordinal English form.
 355      * 
 356      * This method converts 13 to 13th, 2 to 2nd ...
 357      * 
 358      * @access public
 359      * @static
 360      * @param    integer    $number    Number to get its ordinal value
 361      * @return string Ordinal representation of given string.
 362      */
 363      function ordinalize($number)
 364      {
 365          if (in_array(($number % 100),range(11,13))){
 366              return $number.'th';
 367          }else{
 368              switch (($number % 10)) {
 369                  case 1:
 370                      return $number.'st';
 371                      break;
 372                  case 2:
 373                      return $number.'nd';
 374                      break;
 375                  case 3:
 376                      return $number.'rd';
 377                  default:
 378                      return $number.'th';
 379                      break;
 380              }
 381          }
 382      }
 383  
 384      // }}}
 385  
 386      /**
 387      * Removes the module name from a module/path, Module::name or Module_ControllerClassName.
 388      *
 389      *   Example:    AkInflector::demodulize('admin/dashboard_controller');  //=> dashboard_controller
 390      *               AkInflector::demodulize('Admin_DashboardController');  //=> DashboardController
 391      *               AkInflector::demodulize('Admin::Dashboard');  //=> Dashboard
 392      */
 393      function demodulize($module_name)
 394      {
 395          $module_name = str_replace('::', '/', $module_name);
 396          return (strstr($module_name, '/') ? preg_replace('/^.*\//', '', $module_name) : (strstr($module_name, '_') ? substr($module_name, 1+strrpos($module_name,'_')) : $module_name));
 397      }
 398      
 399      /**
 400       * Transforms a string to its unaccented version. 
 401       * This might be useful for generating "friendly" URLs
 402       */
 403      function unaccent($text)
 404      {
 405          $map = array(
 406          'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C',
 407          'È'=>'E', 'É'=>'E', 'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I',
 408          'Ð'=>'D', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O',
 409          'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'T', 'ß'=>'s', 'à'=>'a',
 410          'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e',
 411          'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'e',
 412          'ñ'=>'n', 'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u',
 413          'ú'=>'u', 'û'=>'u', 'ü'=>'u', 'ý'=>'y', 'þ'=>'t', 'ÿ'=>'y');
 414          return str_replace(array_keys($map), array_values($map), $text);
 415      }
 416  
 417  
 418      function urlize($text)
 419      {
 420          return trim(AkInflector::underscore(AkInflector::unaccent($text)),'_');
 421      }
 422  
 423      /**
 424      * Returns $class_name in underscored form, with "_id" tacked on at the end. 
 425      * This is for use in dealing with the database.
 426      * 
 427      * @param string $class_name
 428      * @return string
 429      */
 430      function foreignKey($class_name, $separate_class_name_and_id_with_underscore = true)
 431      {
 432          return AkInflector::underscore(AkInflector::humanize(AkInflector::underscore($class_name))).($separate_class_name_and_id_with_underscore ? "_id" : "id");
 433      }
 434  
 435      function toControllerFilename($name)
 436      {
 437          $name = str_replace('::', '/', $name);
 438          return AK_CONTROLLERS_DIR.DS.join(DS, array_map(array('AkInflector','underscore'), strstr($name, '/') ? explode('/', $name) : array($name))).'_controller.php';
 439      }
 440  
 441      function toModelFilename($name)
 442      {
 443          return AK_MODELS_DIR.DS.AkInflector::underscore($name).'.php';
 444      }
 445  
 446      function toHelperFilename($name)
 447      {
 448          return AK_APP_DIR.DS.'helpers'.DS.AkInflector::underscore($name).'_helper.php';
 449      }
 450  
 451      function toFullName($name, $correct)
 452      {
 453          if (strstr($name, '_') && (strtolower($name) == $name)){
 454              return AkInflector::camelize($name);
 455          }
 456  
 457          if (preg_match("/^(.    * )({$correct})$/i", $name, $reg)){
 458              if ($reg[2] == $correct){
 459                  return $name;
 460              }else{
 461                  return ucfirst($reg[1].$correct);
 462              }
 463          }else{
 464              return ucfirst($name.$correct);
 465          }
 466      }
 467  
 468      function is_singular($singular)
 469      {
 470          return AkInflector::singularize(AkInflector::pluralize($singular)) == $singular;
 471      }
 472      
 473      function is_plural($plural)
 474      {
 475          return AkInflector::pluralize(AkInflector::singularize($plural)) == $plural;
 476      }
 477  
 478  }
 479  
 480  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6