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

Source for file KeySwap.php

Documentation is available at KeySwap.php

  1. <?php
  2. /**
  3.  * ----------------------------------------------------------------------
  4.  *  
  5.  * Copyright (c) 2006-2016 Khaled Al-Sham'aa
  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: Arabic Keyboard Swapping Language
  31.  *  
  32.  * Filename:   KeySwap.php
  33.  *  
  34.  * Original    Author(s): Khaled Al-Sham'aa <khaled@ar-php.org>
  35.  *  
  36.  * Purpose:    Convert keyboard language programmatically (English - Arabic)
  37.  *  
  38.  * ----------------------------------------------------------------------
  39.  *  
  40.  * Arabic Keyboard Swapping Language
  41.  *
  42.  * PHP class to convert keyboard language between English and Arabic
  43.  * programmatically. This function can be helpful in dual language forms when
  44.  * users miss change keyboard language while they are entering data.
  45.  * 
  46.  * If you wrote an Arabic sentence while your keyboard stays in English mode by
  47.  * mistake, you will get a non-sense English text on your PC screen. In that case
  48.  * you can use this class to make a kind of magic conversion to swap that odd text
  49.  * by original Arabic sentence you meant when you type on your keyboard.
  50.  * 
  51.  * Please note that magic conversion in the opposite direction (if you type English
  52.  * sentences while your keyboard stays in Arabic mode) is also available in this
  53.  * class, but it is not reliable as much as previous case because in Arabic keyboard
  54.  * we have some keys provide a short-cut to type two chars in one click (those keys
  55.  * include: b, B, G and T).
  56.  * 
  57.  * Well, we try in this class to come over this issue by suppose that user used
  58.  * optimum way by using short-cut keys when available instead of assemble chars
  59.  * using stand alone keys, but if (s)he does not then you may have some typo chars
  60.  * in converted text.
  61.  * 
  62.  * Example:
  63.  * <code>
  64.  *     include('./I18N/Arabic.php');
  65.  *     $obj = new I18N_Arabic('KeySwap');
  66.  * 
  67.  *     $str = "Hpf lk hgkhs hglj'vtdkK Hpf hg`dk dldg,k f;gdjil Ygn ,p]hkdm ...";
  68.  * 
  69.  *     echo "<p><u><i>Before:</i></u><br />$str<br /><br />";
  70.  *     
  71.  *     $text = $obj->swapEa($str);
  72.  *        
  73.  *     echo "<u><i>After:</i></u><br />$text<br /><br />";
  74.  * </code>
  75.  *
  76.  * @category  I18N
  77.  * @package   I18N_Arabic
  78.  * @author    Khaled Al-Sham'aa <khaled@ar-php.org>
  79.  * @copyright 2006-2016 Khaled Al-Sham'aa
  80.  *    
  81.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  82.  * @link      http://www.ar-php.org
  83.  */
  84.  
  85. /**
  86.  * This PHP class convert keyboard language programmatically (English - Arabic)
  87.  *  
  88.  * @category  I18N
  89.  * @package   I18N_Arabic
  90.  * @author    Khaled Al-Sham'aa <khaled@ar-php.org>
  91.  * @copyright 2006-2016 Khaled Al-Sham'aa
  92.  *    
  93.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  94.  * @link      http://www.ar-php.org
  95.  */ 
  96. {
  97.     private $_transliteration = array();
  98.     private $_arLogodd;
  99.     private $_enLogodd;
  100.     
  101.     private $_arKeyboard;
  102.     private $_enKeyboard;
  103.     private $_frKeyboard;
  104.     
  105.     /**
  106.      * Loads initialize values
  107.      *
  108.      * @ignore
  109.      */         
  110.     public function __construct()
  111.     {
  112.         $xml = simplexml_load_file(dirname(__FILE__).'/data/charset/arabizi.xml');
  113.         
  114.         foreach ($xml->transliteration->item as $item) {
  115.             $index = $item['id'];
  116.             $this->_transliteration["$index"] = (string)$item;
  117.         } 
  118.  
  119.         $xml = simplexml_load_file(dirname(__FILE__).'/data/ArKeySwap.xml');
  120.         
  121.         foreach ($xml->arabic->key as $key) {
  122.             $index = (int)$key['id'];
  123.             $this->_arKeyboard[$index] = (string)$key;
  124.         } 
  125.         
  126.         foreach ($xml->english->key as $key) {
  127.             $index = (int)$key['id'];
  128.             $this->_enKeyboard[$index] = (string)$key;
  129.         } 
  130.         
  131.         foreach ($xml->french->key as $key) {
  132.             $index = (int)$key['id'];
  133.             $this->_frKeyboard[$index] = (string)$key;
  134.         } 
  135.  
  136.         $this->_arLogodd = file(dirname(__FILE__).'/data/ar-logodd.php');
  137.         $this->_enLogodd = file(dirname(__FILE__).'/data/en-logodd.php');
  138.     }
  139.     
  140.     /**
  141.      * Make conversion to swap that odd Arabic text by original English sentence
  142.      * you meant when you type on your keyboard (if keyboard language was
  143.      * incorrect)
  144.      *          
  145.      * @param string $text Odd Arabic string
  146.      *                    
  147.      * @return string Normal English string
  148.      * @author Khaled Al-Sham'aa
  149.      */
  150.     public function swapAe($text)
  151.     {
  152.         $output = $this->_swapCore($text, 'ar', 'en');
  153.         
  154.         return $output;
  155.     }
  156.     
  157.     /**
  158.      * Make conversion to swap that odd English text by original Arabic sentence
  159.      * you meant when you type on your keyboard (if keyboard language was
  160.      * incorrect)
  161.      *           
  162.      * @param string $text Odd English string
  163.      *                    
  164.      * @return string Normal Arabic string
  165.      * @author Khaled Al-Sham'aa
  166.      */
  167.     public function swapEa($text)
  168.     {
  169.         $output = $this->_swapCore($text, 'en', 'ar');
  170.         
  171.         return $output;
  172.     }
  173.     
  174.     /**
  175.      * Make conversion to swap that odd Arabic text by original French sentence
  176.      * you meant when you type on your keyboard (if keyboard language was
  177.      * incorrect)
  178.      *          
  179.      * @param string $text Odd Arabic string
  180.      *                    
  181.      * @return string Normal French string
  182.      * @author Khaled Al-Sham'aa
  183.      */
  184.     public function swapAf($text)
  185.     {
  186.         $output = $this->_swapCore($text, 'ar', 'fr');
  187.         
  188.         return $output;
  189.     }
  190.     
  191.     /**
  192.      * Make conversion to swap that odd French text by original Arabic sentence
  193.      * you meant when you type on your keyboard (if keyboard language was
  194.      * incorrect)
  195.      *           
  196.      * @param string $text Odd French string
  197.      *                    
  198.      * @return string Normal Arabic string
  199.      * @author Khaled Al-Sham'aa
  200.      */
  201.     public function swapFa($text)
  202.     {
  203.         $output = $this->_swapCore($text, 'fr', 'ar');
  204.         
  205.         return $output;
  206.     }
  207.     
  208.     /**
  209.      * Make conversion between different keyboard maps to swap odd text in
  210.      * one language by original meaningful text in another language that
  211.      * you meant when you type on your keyboard (if keyboard language was
  212.      * incorrect)
  213.      *           
  214.      * @param string $text Odd string
  215.      * @param string $in   Input language [ar|en|fr]
  216.      * @param string $out  Output language [ar|en|fr]
  217.      *                    
  218.      * @return string Normal string
  219.      * @author Khaled Al-Sham'aa
  220.      */
  221.     private function _swapCore($text, $in, $out)
  222.     {
  223.         $output = '';
  224.         $text   = stripslashes($text);
  225.         $max    = mb_strlen($text);
  226.         
  227.         switch ($in) {
  228.         case 'ar':
  229.             $inputMap = $this->_arKeyboard;
  230.             break;
  231.         case 'en':
  232.             $inputMap = $this->_enKeyboard;
  233.             break;
  234.         case 'fr':
  235.             $inputMap = $this->_frKeyboard;
  236.             break;
  237.         }
  238.         
  239.         switch ($out) {
  240.         case 'ar':
  241.             $outputMap = $this->_arKeyboard;
  242.             break;
  243.         case 'en':
  244.             $outputMap = $this->_enKeyboard;
  245.             break;
  246.         case 'fr':
  247.             $outputMap = $this->_frKeyboard;
  248.             break;
  249.         }
  250.         
  251.         for ($i=0; $i<$max; $i++) {
  252.             $chr = mb_substr($text, $i, 1);
  253.             $key = array_search($chr, $inputMap);
  254.             
  255.             if ($key === false) {
  256.                 $output .= $chr;
  257.             } else {
  258.                 $output .= $outputMap[$key];
  259.             }
  260.         }
  261.         
  262.         return $output;
  263.     }
  264.     
  265.     /**
  266.      * Calculate the log odd probability that inserted string from keyboard
  267.      * is in English language
  268.      *           
  269.      * @param string $str Inserted string from the keyboard
  270.      *                    
  271.      * @return float Calculated score for input string as English language
  272.      * @author Khaled Al-Sham'aa
  273.      */
  274.     protected function checkEn($str) 
  275.     {
  276.         $lines  = $this->_enLogodd;
  277.         $logodd = array();
  278.         
  279.         $line   = array_shift($lines);
  280.         $line   = rtrim($line);
  281.         $second = preg_split("/\t/", $line);
  282.         $temp   = array_shift($second);
  283.         
  284.         foreach ($lines as $line) {
  285.             $line   = rtrim($line);
  286.             $values = preg_split("/\t/", $line);
  287.             $first  = array_shift($values);
  288.             
  289.             for ($i=0; $i<28; $i++) {
  290.                 $logodd["$first"]["{$second[$i]}"] = $values[$i];
  291.             }
  292.         }
  293.         
  294.         $str  = mb_strtolower($str);
  295.         $max  = mb_strlen($str, 'UTF-8');
  296.         $rank = 0;
  297.         
  298.         for ($i=1; $i<$max; $i++) {
  299.             $first  = mb_substr($str, $i-1, 1, 'UTF-8');
  300.             $second = mb_substr($str, $i, 1, 'UTF-8');
  301.      
  302.             if (isset($logodd["$first"]["$second"])) {
  303.                 $rank += $logodd["$first"]["$second"]; 
  304.             } else {
  305.                 $rank -= 10;
  306.             }
  307.         }
  308.         
  309.         return $rank;
  310.     }
  311.  
  312.     /**
  313.      * Calculate the log odd probability that inserted string from keyboard
  314.      * is in Arabic language
  315.      *           
  316.      * @param string $str Inserted string from the keyboard
  317.      *                    
  318.      * @return float Calculated score for input string as Arabic language
  319.      * @author Khaled Al-Sham'aa
  320.      */
  321.     protected function checkAr($str) 
  322.     {
  323.         $lines  = $this->_arLogodd;
  324.         $logodd = array();
  325.         
  326.         $line   = array_shift($lines);
  327.         $line   = rtrim($line);
  328.         $second = preg_split("/\t/", $line);
  329.         $temp   = array_shift($second);
  330.         
  331.         foreach ($lines as $line) {
  332.             $line   = rtrim($line);
  333.             $values = preg_split("/\t/", $line);
  334.             $first  = array_shift($values);
  335.             
  336.             for ($i=0; $i<37; $i++) {
  337.                 $logodd["$first"]["{$second[$i]}"] = $values[$i];
  338.             }
  339.         }
  340.         
  341.         $max  = mb_strlen($str, 'UTF-8');
  342.         $rank = 0;
  343.         
  344.         for ($i=1; $i<$max; $i++) {
  345.             $first  = mb_substr($str, $i-1, 1, 'UTF-8');
  346.             $second = mb_substr($str, $i, 1, 'UTF-8');
  347.      
  348.             if (isset($logodd["$first"]["$second"])) {
  349.                 $rank += $logodd["$first"]["$second"]; 
  350.             } else {
  351.                 $rank -= 10;
  352.             }
  353.         }
  354.  
  355.         return $rank;
  356.     }
  357.     
  358.     /**
  359.      * This method will automatically detect the language of content supplied
  360.      * in the input string. It will return the suggestion of correct inserted text.
  361.      * The accuracy of the automatic language detection increases with the amount
  362.      * of text entered.
  363.      *           
  364.      * @param string $str Inserted string from the keyboard
  365.      *                    
  366.      * @return string Fixed string language and letter case to the better guess
  367.      * @author Khaled Al-Sham'aa
  368.      */
  369.     public function fixKeyboardLang($str) 
  370.     {
  371.         preg_match_all("/([\x{0600}-\x{06FF}])/u", $str, $matches);
  372.  
  373.         $arNum    = count($matches[0]);
  374.         $nonArNum = mb_strlen(str_replace(' ', '', $str), 'UTF-8') - $arNum;
  375.  
  376.         $capital = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  377.         $small   = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  378.  
  379.         if ($arNum > $nonArNum) {
  380.             $arStr = $str;
  381.             $enStr = $this->swapAe($str);
  382.             $isAr  = true;
  383.         } else {            
  384.             $arStr = $this->swapEa($str);
  385.             $enStr = $str;
  386.  
  387.             $strCaps   = strtr($str, $capital, $small);
  388.             $arStrCaps = $this->swapEa($strCaps);
  389.  
  390.             $isAr = false;
  391.         }
  392.  
  393.         $enRank = $this->checkEn($enStr);
  394.         $arRank = $this->checkAr($arStr);
  395.         
  396.         if ($arNum > $nonArNum) {
  397.             $arCapsRank = $arRank;
  398.         } else {
  399.             $arCapsRank = $this->checkAr($arStrCaps);
  400.         }
  401.  
  402.         if ($enRank > $arRank && $enRank > $arCapsRank) {
  403.             if ($isAr) {
  404.                 $fix = $enStr;
  405.             } else {
  406.                 preg_match_all("/([A-Z])/u", $enStr, $matches);
  407.                 $capsNum = count($matches[0]);
  408.                 
  409.                 preg_match_all("/([a-z])/u", $enStr, $matches);
  410.                 $nonCapsNum = count($matches[0]);
  411.                 
  412.                 if ($capsNum > $nonCapsNum && $nonCapsNum > 0) {
  413.                     $enCapsStr = strtr($enStr, $capital, $small);
  414.                     $fix       = $enCapsStr;
  415.                 } else {
  416.                     $fix = '';
  417.                 }
  418.             }
  419.         } else {
  420.             if ($arCapsRank > $arRank) {
  421.                 $arStr  = $arStrCaps;
  422.                 $arRank = $arCapsRank;
  423.             }
  424.             
  425.             if (!$isAr) {
  426.                 $fix = $arStr;
  427.             } else {
  428.                 $fix = '';
  429.             }
  430.         }
  431.  
  432.         return $fix;
  433.     }
  434. }

Documentation generated on Fri, 01 Jan 2016 10:26:06 +0200 by phpDocumentor 1.4.0