Source for file porteren.php

Documentation is available at porteren.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Platform
  4.  * @subpackage  Language
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @copyright   Copyright (C) 2005 Richard Heyes (http://www.phpguru.org/). All rights reserved.
  8.  * @license     GNU General Public License version 2 or later; see LICENSE
  9.  */
  10.  
  11. defined('JPATH_PLATFORM'or die;
  12.  
  13. /**
  14.  * Porter English stemmer class.
  15.  *
  16.  * This class was adapted from one written by Richard Heyes.
  17.  * See copyright and link information above.
  18.  *
  19.  * @package     Joomla.Platform
  20.  * @subpackage  Language
  21.  * @since       12.1
  22.  */
  23. {
  24.     /**
  25.      * Regex for matching a consonant.
  26.      *
  27.      * @var    string 
  28.      * @since  12.1
  29.      */
  30.     private static $_regex_consonant '(?:[bcdfghjklmnpqrstvwxz]|(?<=[aeiou])y|^y)';
  31.  
  32.     /**
  33.      * Regex for matching a vowel
  34.      * @var    string 
  35.      * @since  12.1
  36.      */
  37.     private static $_regex_vowel '(?:[aeiou]|(?<![aeiou])y)';
  38.  
  39.     /**
  40.      * Method to stem a token and return the root.
  41.      *
  42.      * @param   string  $token  The token to stem.
  43.      * @param   string  $lang   The language of the token.
  44.      *
  45.      * @return  string  The root token.
  46.      *
  47.      * @since   12.1
  48.      */
  49.     public function stem($token$lang)
  50.     {
  51.         // Check if the token is long enough to merit stemming.
  52.         if (strlen($token<= 2)
  53.         {
  54.             return $token;
  55.         }
  56.  
  57.         // Check if the language is English or All.
  58.         if ($lang !== 'en')
  59.         {
  60.             return $token;
  61.         }
  62.  
  63.         // Stem the token if it is not in the cache.
  64.         if (!isset($this->cache[$lang][$token]))
  65.         {
  66.             // Stem the token.
  67.             $result $token;
  68.             $result self::_step1ab($result);
  69.             $result self::_step1c($result);
  70.             $result self::_step2($result);
  71.             $result self::_step3($result);
  72.             $result self::_step4($result);
  73.             $result self::_step5($result);
  74.  
  75.             // Add the token to the cache.
  76.             $this->cache[$lang][$token$result;
  77.         }
  78.  
  79.         return $this->cache[$lang][$token];
  80.     }
  81.  
  82.     /**
  83.      * Step 1
  84.      *
  85.      * @param   string  $word  The token to stem.
  86.      *
  87.      * @return  string 
  88.      *
  89.      * @since   12.1
  90.      */
  91.     private static function _step1ab($word)
  92.     {
  93.         // Part a
  94.         if (substr($word-1== 's')
  95.         {
  96.                 self::_replace($word'sses''ss')
  97.             or self::_replace($word'ies''i')
  98.             or self::_replace($word'ss''ss')
  99.             or self::_replace($word's''');
  100.         }
  101.  
  102.         // Part b
  103.         if (substr($word-21!= 'e' or !self::_replace($word'eed''ee'0))
  104.         {
  105.             // First rule
  106.             $v self::$_regex_vowel;
  107.  
  108.             // Check ing and ed
  109.             // Note use of && and OR, for precedence reasons
  110.             if (preg_match("#$v+#"substr($word0-3)) && self::_replace($word'ing''')
  111.                 or preg_match("#$v+#"substr($word0-2)) && self::_replace($word'ed'''))
  112.             {
  113.                 // If one of above two test successful
  114.                 if (!self::_replace($word'at''ate'and !self::_replace($word'bl''ble'and !self::_replace($word'iz''ize'))
  115.                 {
  116.                     // Double consonant ending
  117.                     if (self::_doubleConsonant($wordand substr($word-2!= 'll' and substr($word-2!= 'ss' and substr($word-2!= 'zz')
  118.                     {
  119.                         $word substr($word0-1);
  120.                     }
  121.                     elseif (self::_m($word== and self::_cvc($word))
  122.                     {
  123.                         $word .= 'e';
  124.                     }
  125.                 }
  126.             }
  127.         }
  128.  
  129.         return $word;
  130.     }
  131.  
  132.     /**
  133.      * Step 1c
  134.      *
  135.      * @param   string  $word  The token to stem.
  136.      *
  137.      * @return  string 
  138.      *
  139.      * @since   12.1
  140.      */
  141.     private static function _step1c($word)
  142.     {
  143.         $v self::$_regex_vowel;
  144.  
  145.         if (substr($word-1== 'y' && preg_match("#$v+#"substr($word0-1)))
  146.         {
  147.             self::_replace($word'y''i');
  148.         }
  149.  
  150.         return $word;
  151.     }
  152.  
  153.     /**
  154.      * Step 2
  155.      *
  156.      * @param   string  $word  The token to stem.
  157.      *
  158.      * @return  string 
  159.      *
  160.      * @since   12.1
  161.      */
  162.     private static function _step2($word)
  163.     {
  164.         switch (substr($word-21))
  165.         {
  166.             case 'a':
  167.                     self::_replace($word'ational''ate'0)
  168.                 or self::_replace($word'tional''tion'0);
  169.                 break;
  170.             case 'c':
  171.                     self::_replace($word'enci''ence'0)
  172.                 or self::_replace($word'anci''ance'0);
  173.                 break;
  174.             case 'e':
  175.                 self::_replace($word'izer''ize'0);
  176.                 break;
  177.             case 'g':
  178.                 self::_replace($word'logi''log'0);
  179.                 break;
  180.             case 'l':
  181.                     self::_replace($word'entli''ent'0)
  182.                 or self::_replace($word'ousli''ous'0)
  183.                 or self::_replace($word'alli''al'0)
  184.                 or self::_replace($word'bli''ble'0)
  185.                 or self::_replace($word'eli''e'0);
  186.                 break;
  187.             case 'o':
  188.                     self::_replace($word'ization''ize'0)
  189.                 or self::_replace($word'ation''ate'0)
  190.                 or self::_replace($word'ator''ate'0);
  191.                 break;
  192.             case 's':
  193.                     self::_replace($word'iveness''ive'0)
  194.                 or self::_replace($word'fulness''ful'0)
  195.                 or self::_replace($word'ousness''ous'0)
  196.                 or self::_replace($word'alism''al'0);
  197.                 break;
  198.             case 't':
  199.                     self::_replace($word'biliti''ble'0)
  200.                 or self::_replace($word'aliti''al'0)
  201.                 or self::_replace($word'iviti''ive'0);
  202.                 break;
  203.         }
  204.  
  205.         return $word;
  206.     }
  207.  
  208.     /**
  209.      * Step 3
  210.      *
  211.      * @param   string  $word  The token to stem.
  212.      *
  213.      * @return  string 
  214.      *
  215.      * @since   12.1
  216.      */
  217.     private static function _step3($word)
  218.     {
  219.         switch (substr($word-21))
  220.         {
  221.             case 'a':
  222.                 self::_replace($word'ical''ic'0);
  223.                 break;
  224.             case 's':
  225.                 self::_replace($word'ness'''0);
  226.                 break;
  227.             case 't':
  228.                     self::_replace($word'icate''ic'0)
  229.                 or self::_replace($word'iciti''ic'0);
  230.                 break;
  231.             case 'u':
  232.                 self::_replace($word'ful'''0);
  233.                 break;
  234.             case 'v':
  235.                 self::_replace($word'ative'''0);
  236.                 break;
  237.             case 'z':
  238.                 self::_replace($word'alize''al'0);
  239.                 break;
  240.         }
  241.  
  242.         return $word;
  243.     }
  244.  
  245.     /**
  246.      * Step 4
  247.      *
  248.      * @param   string  $word  The token to stem.
  249.      *
  250.      * @return  string 
  251.      *
  252.      * @since   12.1
  253.      */
  254.     private static function _step4($word)
  255.     {
  256.         switch (substr($word-21))
  257.         {
  258.             case 'a':
  259.                 self::_replace($word'al'''1);
  260.                 break;
  261.             case 'c':
  262.                     self::_replace($word'ance'''1)
  263.                 or self::_replace($word'ence'''1);
  264.                 break;
  265.             case 'e':
  266.                 self::_replace($word'er'''1);
  267.                 break;
  268.             case 'i':
  269.                 self::_replace($word'ic'''1);
  270.                 break;
  271.             case 'l':
  272.                     self::_replace($word'able'''1)
  273.                 or self::_replace($word'ible'''1);
  274.                 break;
  275.             case 'n':
  276.                     self::_replace($word'ant'''1)
  277.                 or self::_replace($word'ement'''1)
  278.                 or self::_replace($word'ment'''1)
  279.                 or self::_replace($word'ent'''1);
  280.                 break;
  281.             case 'o':
  282.                 if (substr($word-4== 'tion' or substr($word-4== 'sion')
  283.                 {
  284.                     self::_replace($word'ion'''1);
  285.                 }
  286.                 else
  287.                 {
  288.                     self::_replace($word'ou'''1);
  289.                 }
  290.                 break;
  291.             case 's':
  292.                 self::_replace($word'ism'''1);
  293.                 break;
  294.             case 't':
  295.                     self::_replace($word'ate'''1)
  296.                 or self::_replace($word'iti'''1);
  297.                 break;
  298.             case 'u':
  299.                 self::_replace($word'ous'''1);
  300.                 break;
  301.             case 'v':
  302.                 self::_replace($word'ive'''1);
  303.                 break;
  304.             case 'z':
  305.                 self::_replace($word'ize'''1);
  306.                 break;
  307.         }
  308.  
  309.         return $word;
  310.     }
  311.  
  312.     /**
  313.      * Step 5
  314.      *
  315.      * @param   string  $word  The token to stem.
  316.      *
  317.      * @return  string 
  318.      *
  319.      * @since   12.1
  320.      */
  321.     private static function _step5($word)
  322.     {
  323.         // Part a
  324.         if (substr($word-1== 'e')
  325.         {
  326.             if (self::_m(substr($word0-1)) 1)
  327.             {
  328.                 self::_replace($word'e''');
  329.             }
  330.             elseif (self::_m(substr($word0-1)) == 1)
  331.             {
  332.                 if (!self::_cvc(substr($word0-1)))
  333.                 {
  334.                     self::_replace($word'e''');
  335.                 }
  336.             }
  337.         }
  338.  
  339.         // Part b
  340.         if (self::_m($wordand self::_doubleConsonant($wordand substr($word-1== 'l')
  341.         {
  342.             $word substr($word0-1);
  343.         }
  344.  
  345.         return $word;
  346.     }
  347.  
  348.     /**
  349.      * Replaces the first string with the second, at the end of the string. If third
  350.      * arg is given, then the preceding string must match that m count at least.
  351.      *
  352.      * @param   string   &$str   String to check
  353.      * @param   string   $check  Ending to check for
  354.      * @param   string   $repl   Replacement string
  355.      * @param   integer  $m      Optional minimum number of m() to meet
  356.      *
  357.      * @return  boolean  Whether the $check string was at the end
  358.      *                    of the $str string. True does not necessarily mean
  359.      *                    that it was replaced.
  360.      *
  361.      * @since   12.1
  362.      */
  363.     private static function _replace(&$str$check$repl$m null)
  364.     {
  365.         $len strlen($check);
  366.  
  367.         if (substr($str$len== $check)
  368.         {
  369.             $substr substr($str0$len);
  370.  
  371.             if (is_null($mor self::_m($substr$m)
  372.             {
  373.                 $str $substr $repl;
  374.             }
  375.  
  376.             return true;
  377.         }
  378.  
  379.         return false;
  380.     }
  381.  
  382.     /**
  383.      * m() measures the number of consonant sequences in $str. if c is
  384.      * a consonant sequence and v a vowel sequence, and <..> indicates arbitrary
  385.      * presence,
  386.      *
  387.      * <c><v>       gives 0
  388.      * <c>vc<v>     gives 1
  389.      * <c>vcvc<v>   gives 2
  390.      * <c>vcvcvc<v> gives 3
  391.      *
  392.      * @param   string  $str  The string to return the m count for
  393.      *
  394.      * @return  integer  The m count
  395.      *
  396.      * @since   12.1
  397.      */
  398.     private static function _m($str)
  399.     {
  400.         $c self::$_regex_consonant;
  401.         $v self::$_regex_vowel;
  402.  
  403.         $str preg_replace("#^$c+#"''$str);
  404.         $str preg_replace("#$v+$#"''$str);
  405.  
  406.         preg_match_all("#($v+$c+)#"$str$matches);
  407.  
  408.         return count($matches[1]);
  409.     }
  410.  
  411.     /**
  412.      * Returns true/false as to whether the given string contains two
  413.      * of the same consonant next to each other at the end of the string.
  414.      *
  415.      * @param   string  $str  String to check
  416.      *
  417.      * @return  boolean  Result
  418.      *
  419.      * @since   12.1
  420.      */
  421.     private static function _doubleConsonant($str)
  422.     {
  423.         $c self::$_regex_consonant;
  424.  
  425.         return preg_match("#$c{2}$#"$str$matchesand $matches[0]{0== $matches[0]{1};
  426.     }
  427.  
  428.     /**
  429.      * Checks for ending CVC sequence where second C is not W, X or Y
  430.      *
  431.      * @param   string  $str  String to check
  432.      *
  433.      * @return  boolean  Result
  434.      *
  435.      * @since   12.1
  436.      */
  437.     private static function _cvc($str)
  438.     {
  439.         $c self::$_regex_consonant;
  440.         $v self::$_regex_vowel;
  441.  
  442.         $result preg_match("#($c$v$c)$#"$str$matches)
  443.             and strlen($matches[1]== 3
  444.             and $matches[1]{2!= 'w'
  445.             and $matches[1]{2!= 'x'
  446.             and $matches[1]{2!= 'y';
  447.  
  448.         return $result;
  449.     }
  450. }

Documentation generated on Tue, 19 Nov 2013 15:10:57 +0100 by phpDocumentor 1.4.3