I18N_Arabic
[ class tree: I18N_Arabic ] [ index: I18N_Arabic ] [ all elements ]

Source for file Arabic.php

Documentation is available at Arabic.php

  1. <?php
  2. /**
  3.  * ----------------------------------------------------------------------
  4.  *  
  5.  * Copyright (c) 2006-2013 Khaled Al-Shamaa.
  6.  *  
  7.  * http://www.ar-php.org
  8.  *  
  9.  * PHP Version 5
  10.  *  
  11.  * ----------------------------------------------------------------------
  12.  *  
  13.  * LICENSE
  14.  *
  15.  * This program is open source product; you can redistribute it and/or
  16.  * modify it under the terms of the GNU Lesser General Public License (LGPL)
  17.  * as published by the Free Software Foundation; either version 3
  18.  * of the License, or (at your option) any later version.
  19.  *  
  20.  * This program is distributed in the hope that it will be useful,
  21.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23.  * GNU Lesser General Public License for more details.
  24.  *  
  25.  * You should have received a copy of the GNU Lesser General Public License
  26.  * along with this program.  If not, see <http://www.gnu.org/licenses/lgpl.txt>.
  27.  *  
  28.  * ----------------------------------------------------------------------
  29.  *  
  30.  * Class Name: PHP and Arabic Language
  31.  *  
  32.  * Filename:   Arabic.php
  33.  *  
  34.  * Original    Author(s): Khaled Al-Sham'aa <khaled@ar-php.org>
  35.  *  
  36.  * Purpose:    Set of PHP classes developed to enhance Arabic web
  37.  *             applications by providing set of tools includes stem-based searching,
  38.  *             translitiration, soundex, Hijri calendar, charset detection and
  39.  *             converter, spell numbers, keyboard language, Muslim prayer time,
  40.  *             auto-summarization, and more...
  41.  *              
  42.  * ----------------------------------------------------------------------
  43.  *
  44.  * @desc   Set of PHP classes developed to enhance Arabic web
  45.  *          applications by providing set of tools includes stem-based searching,
  46.  *          translitiration, soundex, Hijri calendar, charset detection and
  47.  *          converter, spell numbers, keyboard language, Muslim prayer time,
  48.  *          auto-summarization, and more...
  49.  *          
  50.  * @category  I18N
  51.  * @package   I18N_Arabic
  52.  * @author    Khaled Al-Shamaa <khaled@ar-php.org>
  53.  * @copyright 2006-2013 Khaled Al-Shamaa
  54.  *    
  55.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  56.  * @version   3.6.0 released in Jan 20, 2013
  57.  * @link      http://www.ar-php.org
  58.  */
  59.  
  60. // New in PHP V5.3: Namespaces
  61. // namespace I18N\Arabic;
  62.  
  63. // error_reporting(E_STRICT);
  64.  
  65. /**
  66.  * Core PHP and Arabic language class
  67.  *  
  68.  * @category  I18N
  69.  * @package   I18N_Arabic
  70.  * @author    Khaled Al-Shamaa <khaled@ar-php.org>
  71.  * @copyright 2006-2013 Khaled Al-Shamaa
  72.  *    
  73.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  74.  * @link      http://www.ar-php.org
  75.  */  
  76. {
  77.     private $_inputCharset  'utf-8';
  78.     private $_outputCharset 'utf-8';
  79.     private $_useAutoload;
  80.     private $_useException;
  81.     private $_compatibleMode;
  82.     
  83.     private $_compatible array('EnTransliteration'=>'Transliteration'
  84.                                   'ArTransliteration'=>'Transliteration',
  85.                                   'ArAutoSummarize'=>'AutoSummarize',
  86.                                   'ArCharsetC'=>'CharsetC',
  87.                                   'ArCharsetD'=>'CharsetD',
  88.                                   'ArDate'=>'Date',
  89.                                   'ArGender'=>'Gender',
  90.                                   'ArGlyphs'=>'Glyphs',
  91.                                   'ArIdentifier'=>'Identifier',
  92.                                   'ArKeySwap'=>'KeySwap',
  93.                                   'ArNumbers'=>'Numbers',
  94.                                   'ArQuery'=>'Query',
  95.                                   'ArSoundex'=>'Soundex',
  96.                                   'ArStrToTime'=>'StrToTime',
  97.                                   'ArWordTag'=>'WordTag',
  98.                                   'ArCompressStr'=>'CompressStr',
  99.                                   'ArMktime'=>'Mktime',
  100.                                   'ArStemmer'=>'Stemmer',
  101.                                   'ArStandard'=>'Standard',
  102.                                   'ArNormalise'=>'Normalise',
  103.                                   'a4_max_chars'=>'a4MaxChars',
  104.                                   'a4_lines'=>'a4Lines',
  105.                                   'swap_ea'=>'swapEa',
  106.                                   'swap_ae'=>'swapAe');
  107.     
  108.     /**
  109.      * @ignore
  110.      */
  111.     public $myObject;
  112.     
  113.     /**
  114.      * @ignore
  115.      */
  116.     public $myClass;
  117.     
  118.     /**
  119.      * @ignore
  120.      */
  121.     public $myFile;
  122.  
  123.     /**
  124.      * Load selected library/Arabic class you would like to use its functionality
  125.      *          
  126.      * @param string  $library        [AutoSummarize|CharsetC|CharsetD|Date|Gender|
  127.      *                                 Glyphs|Identifier|KeySwap|Numbers|Query|Salat|
  128.      *                                 Soundex|StrToTime|WordTag|CompressStr|Mktime|
  129.      *                                 Transliteration|Stemmer|Standard|Normalise]
  130.      * @param boolean $useAutoload    True to use Autoload (default is false)
  131.      * @param boolean $useException   True to use Exception (default is false)
  132.      * @param boolean $compatibleMode True to support old naming style before
  133.      *                                 version 3.0 (default is true)
  134.      *
  135.      * @desc Load selected library/class you would like to use its functionality
  136.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  137.      */
  138.     public function __construct(
  139.         $library$useAutoload=false$useException=false$compatibleMode=true
  140.     {
  141.         $this->_useAutoload    $useAutoload;
  142.         $this->_useException   $useException;
  143.         $this->_compatibleMode $compatibleMode;
  144.  
  145.         /* Set internal character encoding to UTF-8 */
  146.         mb_internal_encoding("utf-8");
  147.  
  148.         if ($this->_useAutoload{
  149.             // It is critical to remember that as soon as spl_autoload_register() is
  150.             // called, __autoload() functions elsewhere in the application may fail 
  151.             // to be called. This is safer initial call (PHP 5 >= 5.1.2):
  152.             if (false === spl_autoload_functions()) {
  153.                 if (function_exists('__autoload')) {
  154.                     spl_autoload_register('__autoload'false);
  155.                 }
  156.             }
  157.             
  158.             spl_autoload_extensions('.php,.inc,.class');
  159.             spl_autoload_register('I18N_Arabic::autoload'false);
  160.         }
  161.         
  162.         if ($this->_useException{
  163.             set_error_handler('I18N_Arabic::myErrorHandler');
  164.         }
  165.         
  166.         if ($library{
  167.             if ($this->_compatibleMode 
  168.                 && array_key_exists($library$this->_compatible)
  169.             {
  170.                 $library $this->_compatible[$library];
  171.             }
  172.  
  173.             $this->load($library);
  174.         }
  175.     }
  176.  
  177.     /**
  178.      * Include file that include requested class
  179.      * 
  180.      * @param string $className Class name
  181.      * 
  182.      * @return null 
  183.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  184.      */ 
  185.     public static function autoload($className
  186.     {
  187.         include self::getClassFile($className);
  188.     }
  189.  
  190.     /**
  191.      * Error handler function
  192.      * 
  193.      * @param int    $errno   The level of the error raised
  194.      * @param string $errstr  The error message
  195.      * @param string $errfile The filename that the error was raised in
  196.      * @param int    $errline The line number the error was raised at
  197.      * 
  198.      * @return boolean FALSE
  199.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  200.      */ 
  201.     public static function myErrorHandler($errno$errstr$errfile$errline)
  202.     {
  203.         if ($errfile == __FILE__ 
  204.             || file_exists(
  205.                 dirname(__FILE__).DIRECTORY_SEPARATOR.'Arabic'.
  206.                 DIRECTORY_SEPARATOR.basename($errfile)
  207.             )
  208.         {
  209.             $msg  '<b>Arabic Class Exception:</b> ';
  210.             $msg .= $errstr;
  211.             $msg .= " in <b>$errfile</b>";
  212.             $msg .= " on line <b>$errline</b><br />";
  213.     
  214.             throw new ArabicException($msg$errno);
  215.         }
  216.         
  217.         // If the function returns false then the normal error handler continues
  218.         return false;
  219.     }
  220.  
  221.     /**
  222.      * Load selected Arabic library and create an instance of its class
  223.      * 
  224.      * @param string $library Library name
  225.      * 
  226.      * @return null 
  227.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  228.      */ 
  229.     public function load($library)
  230.     {
  231.         if ($this->_compatibleMode 
  232.             && array_key_exists($library$this->_compatible)
  233.         {
  234.             
  235.             $library $this->_compatible[$library];
  236.         }
  237.  
  238.         $this->myFile  $library;
  239.         $this->myClass 'I18N_Arabic_' $library;
  240.         $class         'I18N_Arabic_' $library;
  241.  
  242.         if (!$this->_useAutoload{
  243.             include self::getClassFile($this->myFile)
  244.         }
  245.  
  246.         $this->myObject   new $class();
  247.         $this->{$library&$this->myObject;
  248.     }
  249.     
  250.     /**
  251.      * Magic method __call() allows to capture invocation of non existing methods.
  252.      * That way __call() can be used to implement user defined method handling that
  253.      * depends on the name of the actual method being called.
  254.      *
  255.      * @param string $methodName Method name
  256.      * @param array  $arguments  Array of arguments
  257.      * 
  258.      * @method Call a method from loaded sub class and take care of needed
  259.      *          character set conversion for both input and output values.
  260.      *
  261.      * @return The value returned from the __call() method will be returned to
  262.      *          the caller of the method.
  263.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  264.      */                                  
  265.     public function __call($methodName$arguments)
  266.     {
  267.         if ($this->_compatibleMode 
  268.             && array_key_exists($methodName$this->_compatible)
  269.         {
  270.             
  271.             $methodName $this->_compatible[$methodName];
  272.         }
  273.  
  274.         // Create an instance of the ReflectionMethod class
  275.         $method new ReflectionMethod($this->myClass$methodName);
  276.         
  277.         $params     array();
  278.         $parameters $method->getParameters();
  279.  
  280.         foreach ($parameters as $parameter{
  281.             $name  $parameter->getName();
  282.             $value array_shift($arguments);
  283.             
  284.             if (is_null($value&& $parameter->isDefaultValueAvailable()) {
  285.                 $value $parameter->getDefaultValue();
  286.             }
  287.             
  288.             $params[$name$this->coreConvert(
  289.                 $value
  290.                 $this->getInputCharset()
  291.                 'utf-8'
  292.             );
  293.         }
  294.  
  295.         $value call_user_func_array(array(&$this->myObject$methodName)$params);
  296.  
  297.         if ($methodName == 'tagText'{
  298.             foreach ($value as $key=>$text{
  299.                 $value[$key][0$this->coreConvert(
  300.                     $text[0]'utf-8'$this->getOutputCharset()
  301.                 );
  302.             }
  303.         else {
  304.             $value $this->coreConvert($value'utf-8'$this->getOutputCharset());
  305.         }
  306.  
  307.         return $value;
  308.     }
  309.  
  310.     /**
  311.      * Garbage collection, release child objects directly
  312.      *          
  313.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  314.      */
  315.     public function __destruct(
  316.     {
  317.         $this->_inputCharset  null;
  318.         $this->_outputCharset null;
  319.         $this->myObject      null;
  320.         $this->myClass       null;
  321.     }
  322.  
  323.     /**
  324.      * Set charset used in class input Arabic strings
  325.      *          
  326.      * @param string $charset Input charset [utf-8|windows-1256|iso-8859-6]
  327.      *      
  328.      * @return TRUE if success, or FALSE if fail
  329.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  330.      */
  331.     public function setInputCharset($charset)
  332.     {
  333.         $flag true;
  334.         
  335.         $charset strtolower($charset);
  336.         
  337.         if (in_array($charsetarray('utf-8''windows-1256''iso-8859-6'))) {
  338.             $this->_inputCharset $charset;
  339.         else {
  340.             $flag false;
  341.         }
  342.         
  343.         return $flag;
  344.     }
  345.     
  346.     /**
  347.      * Set charset used in class output Arabic strings
  348.      *          
  349.      * @param string $charset Output charset [utf-8|windows-1256|iso-8859-6]
  350.      *      
  351.      * @return boolean TRUE if success, or FALSE if fail
  352.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  353.      */
  354.     public function setOutputCharset($charset)
  355.     {
  356.         $flag true;
  357.         
  358.         $charset strtolower($charset);
  359.         
  360.         if (in_array($charsetarray('utf-8''windows-1256''iso-8859-6'))) {
  361.             $this->_outputCharset $charset;
  362.         else {
  363.             $flag false;
  364.         }
  365.         
  366.         return $flag;
  367.     }
  368.  
  369.     /**
  370.      * Get the charset used in the input Arabic strings
  371.      *      
  372.      * @return string return current setting for class input Arabic charset
  373.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  374.      */
  375.     public function getInputCharset()
  376.     {
  377.         return $this->_inputCharset;
  378.     }
  379.     
  380.     /**
  381.      * Get the charset used in the output Arabic strings
  382.      *         
  383.      * @return string return current setting for class output Arabic charset
  384.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  385.      */
  386.     public function getOutputCharset()
  387.     {
  388.         return $this->_outputCharset;
  389.     }
  390.     
  391.     /**
  392.      * Convert Arabic string from one charset to another
  393.      *          
  394.      * @param string $str           Original Arabic string that you would like
  395.      *                               to convert
  396.      * @param string $inputCharset  Input charset
  397.      * @param string $outputCharset Output charset
  398.      *      
  399.      * @return string Converted Arabic string in defined charset
  400.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  401.      */
  402.     public function coreConvert($str$inputCharset$outputCharset)
  403.     {
  404.         if ($inputCharset != $outputCharset{
  405.             if ($inputCharset == 'windows-1256'{
  406.                 $inputCharset 'cp1256';
  407.             }
  408.             
  409.             if ($outputCharset == 'windows-1256'{
  410.                 $outputCharset 'cp1256';
  411.             }
  412.             
  413.             $convStr iconv($inputCharset"$outputCharset"$str);
  414.  
  415.             if ($convStr == '' && $str != ''{
  416.                 include self::getClassFile('CharsetC');
  417.  
  418.                 $c I18N_Arabic_CharsetC::singleton();
  419.                 
  420.                 if ($inputCharset == 'cp1256'{
  421.                     $convStr $c->win2utf($str);
  422.                 else {
  423.                     $convStr $c->utf2win($str);
  424.                 }
  425.             }
  426.         else {
  427.             $convStr $str;
  428.         }
  429.         
  430.         return $convStr;
  431.     }
  432.  
  433.     /**
  434.      * Convert Arabic string from one format to another
  435.      *          
  436.      * @param string $str           Arabic string in the format set by setInput
  437.      *                               Charset
  438.      * @param string $inputCharset  (optional) Input charset
  439.      *                               [utf-8|windows-1256|iso-8859-6]
  440.      *                               default value is NULL (use set input charset)
  441.      * @param string $outputCharset (optional) Output charset
  442.      *                               [utf-8|windows-1256|iso-8859-6]
  443.      *                               default value is NULL (use set output charset)
  444.      *                                  
  445.      * @return string Arabic string in the format set by method setOutputCharset
  446.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  447.      */
  448.     public function convert($str$inputCharset null$outputCharset null)
  449.     {
  450.         if ($inputCharset == null{
  451.             $inputCharset $this->_inputCharset;
  452.         }
  453.         
  454.         if ($outputCharset == null{
  455.             $outputCharset $this->_outputCharset;
  456.         }
  457.         
  458.         $str $this->coreConvert($str$inputCharset$outputCharset);
  459.  
  460.         return $str;
  461.     }
  462.  
  463.     /**
  464.      * Get sub class file path to be included (mapping between class name and
  465.      * file name/path become independent now)
  466.      *          
  467.      * @param string $class Sub class name
  468.      *                                  
  469.      * @return string Sub class file path
  470.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  471.      */
  472.     protected static function getClassFile($class)
  473.     {
  474.         $dir  dirname(__FILE__DIRECTORY_SEPARATOR 'Arabic';
  475.         $file $dir DIRECTORY_SEPARATOR $class '.php';
  476.  
  477.         return $file;
  478.     }
  479.     
  480.     /**
  481.      * Send/set output charset in several output media in a proper way
  482.      *
  483.      * @param string   $mode [http|html|mysql|mysqli|pdo|text_email|html_email]
  484.      * @param resource $conn The MySQL connection handler/the link identifier
  485.      *                                  
  486.      * @return string header formula if there is any (in cases of html,
  487.      *                 text_email, and html_email)
  488.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  489.      */
  490.     public static function header($mode 'http'$conn null)
  491.     {
  492.         $mode strtolower($mode);
  493.         $head '';
  494.         
  495.         switch ($mode{
  496.         case 'http':
  497.             header('Content-Type: text/html; charset=' $this->_outputCharset);
  498.             break;
  499.         
  500.         case 'html':
  501.             $head .= '<meta http-equiv="Content-type" content="text/html; charset=';
  502.             $head .= $this->_outputCharset '" />'
  503.             break;
  504.         
  505.         case 'text_email':
  506.             $head .= 'MIME-Version: 1.0\r\nContent-type: text/plain; charset=';
  507.             $head .= $this->_outputCharset '\r\n'
  508.             break;
  509.  
  510.         case 'html_email':
  511.             $head .= 'MIME-Version: 1.0\r\nContent-type: text/html; charset=';
  512.             $head .= $this->_outputCharset '\r\n'
  513.             break;
  514.         
  515.         case 'mysql':
  516.             if ($this->_outputCharset == 'utf-8'{
  517.                 mysql_set_charset('utf8');
  518.             elseif ($this->_outputCharset == 'windows-1256'{
  519.                 mysql_set_charset('cp1256');
  520.             }
  521.             break;
  522.  
  523.         case 'mysqli':
  524.             if ($this->_outputCharset == 'utf-8'{
  525.                 $conn->set_charset('utf8');
  526.             elseif ($this->_outputCharset == 'windows-1256'{
  527.                 $conn->set_charset('cp1256');
  528.             }
  529.             break;
  530.  
  531.         case 'pdo':
  532.             if ($this->_outputCharset == 'utf-8'{
  533.                 $conn->exec('SET NAMES utf8');
  534.             elseif ($this->_outputCharset == 'windows-1256'{
  535.                 $conn->exec('SET NAMES cp1256');
  536.             }
  537.             break;
  538.         }
  539.         
  540.         return $head;
  541.     }
  542.  
  543.     /**
  544.      * Get web browser chosen/default language using ISO 639-1 codes (2-letter)
  545.      *          
  546.      * @return string Language using ISO 639-1 codes (2-letter)
  547.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  548.      */
  549.     public static function getBrowserLang()
  550.     {
  551.         $lang substr($_SERVER['HTTP_ACCEPT_LANGUAGE']02)// ar, en, etc...
  552.  
  553.         return $lang;
  554.     }
  555.  
  556.     /**
  557.      * There is still a lack of original, localized, high-quality content and
  558.      * well-structured Arabic websites; This method help in tag HTML result pages
  559.      * from Arabic forum to enable filter it in/out.
  560.      *
  561.      * @param string $html The HTML content of the page in question
  562.      *
  563.      * @return boolean True if the input HTML is belong to a forum page
  564.      * @author Khaled Al-Shamaa <khaled@ar-php.org>
  565.      */
  566.     public static function isForum($html)
  567.     {
  568.         $forum false;
  569.         
  570.         if (strpos($html'vBulletin_init();'!== false{
  571.             $forum true;
  572.         }
  573.         
  574.         return $forum;
  575.     }
  576. }
  577.  
  578. /**
  579.  * Arabic Exception class defined by extending the built-in Exception class.
  580.  *  
  581.  * @category  I18N
  582.  * @package   I18N_Arabic
  583.  * @author    Khaled Al-Shamaa <khaled@ar-php.org>
  584.  * @copyright 2006-2013 Khaled Al-Shamaa
  585.  *    
  586.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  587.  * @link      http://www.ar-php.org
  588.  */  
  589. class ArabicException extends Exception
  590. {
  591.     /**
  592.      * Make sure everything is assigned properly
  593.      * 
  594.      * @param string $message Exception message
  595.      * @param int    $code    User defined exception code
  596.      */         
  597.     public function __construct($message$code=0)
  598.     {
  599.         parent::__construct($message$code);
  600.     }
  601. }

Documentation generated on Mon, 14 Jan 2013 17:48:34 +0100 by phpDocumentor 1.4.0