Source for file cmd_spell.php

Documentation is available at cmd_spell.php

  1. <?php
  2. /**
  3.  * Command line spellcheck class
  4.  *
  5.  * ---
  6.  *  Quick brownn fox brownn
  7.  *
  8.  *  brownn squirrel.
  9.  *  twentytwo owttnewt
  10.  * ---
  11.  * @(#) International Ispell Version 3.1.20 10/10/95, patch 1
  12.   *
  13.  *  & brownn 5 7: brown, Browne, browns, brown n, brown-n
  14.   *
  15.  *  & brownn 5 18: brown, Browne, browns, brown n, brown-n
  16.  * 
  17.  * 
  18.  *  & brownn 5 1: brown, Browne, browns, brown n, brown-n
  19.   *
  20.  * 
  21.  *  & twentytwo 2 1: twenty two, twenty-two
  22.  *  # owttnewt 11
  23.  * 
  24.  * 
  25.  *  ---
  26.  *  $params = array();
  27.  *  $params['spell_command'] = 'ispell -d american -a';
  28.  *  $params['use_proc_open'] = false; // (check_php_version(4,3))
  29.  *  $params['temp_dir'] = '/tmp/'; // $attachment_dir
  30.  *  $params['userdic'] = array(); // user's dictionary
  31.  *  $params['debug'] = true;
  32.  * 
  33.  *  $spell = new cmd_spell($params);
  34.  *  // check $spell->error buffer
  35.  * 
  36.  *  $text = "Quick brownn fox brownn\n\nbrownn squirrel.\ntwentytwo owttnewt";
  37.  * 
  38.  *  $results = $spell->check_text($text);
  39.  *  // check $spell->error buffer
  40.  *  // parse $results
  41.  *
  42.  * @copyright &copy; 1999-2006 The SquirrelMail Project Team
  43.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  44.  * @version $Id: cmd_spell.php,v 1.1 2006/09/30 17:35:20 tokul Exp $
  45.  * @package plugins
  46.  * @subpackage squirrelspell
  47.  */
  48.  
  49. /**
  50.  * Command line spellcheck class, compatible with ispell and aspell.
  51.  * @package plugins
  52.  * @subpackage squirrelspell
  53.  */
  54. class cmd_spell extends squirrelspell {
  55.     /**
  56.      * @var string 
  57.      */
  58.     var $spell_command = '';
  59.     var $userdic = array();
  60.     /**
  61.      * Controls which function is used to execute ispell. proc_open()
  62.      * should be used in PHP 4.3+. exec() can be used in older PHP versions.
  63.      * @var boolean 
  64.      */
  65.     var $use_proc_open = false;
  66.     /**
  67.      * @var string 
  68.      */
  69.     var $temp_dir = '';
  70.     /**
  71.      */
  72.     var $debug = false;
  73.  
  74.     var $missed_words = array();
  75.  
  76.     /**
  77.      * Constructor function
  78.      * @param array $aParams 
  79.      */
  80.     function cmd_spell($aParams=array()) {
  81.         if (isset($aParams['spell_command'])) {
  82.             return $this->set_error('Spellcheck command is not set.');
  83.         else {
  84.             $this->spell_command = $aParams['spell_command'];
  85.         }
  86.  
  87.         if (isset($aParams['userdic'])) {
  88.             $this->userdic = $aParams['userdic'];
  89.         }
  90.  
  91.         if (isset($aParams['use_proc_open'])) {
  92.             $this->use_proc_open = (bool) $aParams['use_proc_open'];
  93.         }
  94.  
  95.         if (isset($aParams['temp_dir'])) {
  96.             $this->temp_dir = $aParams['temp_dir'];
  97.             // add slash to attachment directory, if it does not end with slash. 
  98.             if (substr($this->temp_dir-1!= '/'{
  99.                 $this->temp_dir = $this->temp_dir . '/';
  100.             }
  101.         elseif (!$this->use_proc_open{
  102.             return $this->set_error('Temporally directory is not set.');
  103.         }
  104.  
  105.         if (isset($aParams['debug']&& (bool) $aParams['debug']{
  106.             $this->debug = true;
  107.             error_reporting(E_ALL);
  108.             ini_set('display_errors',1);
  109.         }
  110.  
  111.     }
  112.  
  113.     /**
  114.      * @param string $sText 
  115.      * @return mixed array with command output or false.
  116.      */
  117.     function proc_open_spell($sText{
  118.         $descriptorspec array(
  119.              => array('pipe''r'),  // stdin is a pipe that the child will read from
  120.              => array('pipe''w'),  // stdout is a pipe that the child will write to
  121.              => array('pipe''w')// stderr is a pipe that the child will write to
  122.              );
  123.  
  124.         if ($this->debug{
  125.             $spell_proc proc_open($this->spell_command$descriptorspec$pipes);
  126.         else {
  127.             $spell_proc @proc_open($this->spell_command$descriptorspec$pipes);
  128.         }
  129.  
  130.         if is_resource($spell_proc) ) {
  131.             return $this->set_error(sprintf(_("Could not run the spellchecker command (%s)."),
  132.                                             $this->spell_command));
  133.         }
  134.  
  135.         if @fwrite($pipes[0],$sText) ) {
  136.             $this->set_error(_("Error while writing to pipe."));
  137.             // close all three $pipes here.
  138.             for($i=0$i<=2$i++{
  139.                 // disable all fclose error messages
  140.                 @fclose($pipes[$i]);
  141.             }
  142.             return false;
  143.         }
  144.  
  145.         fclose($pipes[0]);
  146.  
  147.         $sqspell_output array();
  148.         for($i=1$i<=2$i++{
  149.             while(!feof($pipes[$i])) {
  150.                 array_push($sqspell_outputrtrim(fgetss($pipes[$i],999),"\r\n"));
  151.             }
  152.             fclose($pipes[$i]);
  153.         }
  154.  
  155.         if (proc_close($spell_proc)) {
  156.             $error '';
  157.             foreach ($sqspell_output as $line{
  158.                 $error.= $line "\n";
  159.             }
  160.             return $this->set_error($error);
  161.         else {
  162.             return $sqspell_output;
  163.         }
  164.     }
  165.  
  166.     /**
  167.      * @param string $sText 
  168.      * @return mixed array with command output or false.
  169.      */
  170.     function exec_spell($sText{
  171.         // find unused file in attachment directory
  172.         do {
  173.             $floc $this->temp_dir . md5($sText microtime());
  174.         while (file_exists($floc));
  175.  
  176.         if ($this->debug{
  177.             $fp fopen($floc'w');
  178.         else {
  179.             $fp @fopen($floc'w');
  180.         }
  181.         if is_resource($fp) ) {
  182.             return $this->set_error(sprintf(_("Could not open temporary file '%s'."),
  183.                                      $floc) );
  184.         }
  185.  
  186.         if @fwrite($fp$sText) ) {
  187.             $this->set_error(sprintf(_("Error while writing to temporary file '%s'."),
  188.                                      $floc) );
  189.             // close file descriptor
  190.             fclose($fp);
  191.             return false;
  192.         }
  193.         fclose($fp);
  194.  
  195.         exec("$this->spell_command < $floc 2>&1"$sqspell_output$exitcode);
  196.  
  197.         unlink($floc);
  198.  
  199.         if ($exitcode{
  200.             $error '';
  201.             foreach ($sqspell_output as $line{
  202.                 $error.= $line "\n";
  203.             }
  204.             return $this->set_error($error);
  205.         else {
  206.             return $sqspell_output;
  207.         }
  208.     }
  209.  
  210.     /**
  211.      * Prepares string for ispell/aspell parsing
  212.      * 
  213.      * Function adds an extra space at the beginning of each line. This way
  214.      * ispell/aspell don't treat these as command characters.
  215.      * @param string $sText 
  216.      * @return string 
  217.      */
  218.     function prepare_text($sText{
  219.         // prepend space to every sqspell_new_text line
  220.         $sText str_replace("\r\n","\n",$sText);
  221.         $ret '';
  222.         foreach (explode("\n",$sTextas $line{
  223.             $ret.= ' ' $line "\n";
  224.         }
  225.         return $ret;
  226.     }
  227.  
  228.     /**
  229.      * Checks block of text
  230.      * @param string $sText text
  231.      * @return array 
  232.      */
  233.     function check_text($sText{
  234.         $this->missed_words = array();
  235.  
  236.         $sText $this->prepare_text($sText);
  237.  
  238.         if ($this->use_proc_open{
  239.             $sqspell_output $this->proc_open_spell($sText);
  240.         else {
  241.             $sqspell_output $this->exec_spell($sText);
  242.         }
  243.  
  244.         /**
  245.          * Define some variables to be used during the processing.
  246.          */
  247.         $current_line=0;
  248.         /**
  249.          * Now we process the output of sqspell_command (ispell or aspell in
  250.          * ispell compatibility mode, whichever). I'm going to be scarce on
  251.          * comments here, since you can just look at the ispell/aspell output
  252.          * and figure out what's going on. ;) The best way to describe this is
  253.          * "Dark Magic".
  254.          */
  255.         for ($i=0$i<sizeof($sqspell_output)$i++){
  256.             switch (substr($sqspell_output[$i]01)){
  257.             /**
  258.              * Line is empty.
  259.              * Ispell adds empty lines when an end of line is reached
  260.              */
  261.             case '':
  262.                 $current_line++;
  263.                 break;
  264.             /**
  265.              * Line begins with "&".
  266.              * This means there's a misspelled word and a few suggestions.
  267.              */
  268.             case '&':
  269.                 list($left$rightexplode(": "$sqspell_output[$i]);
  270.                 $tmparray explode(" "$left);
  271.                 $sqspell_word=$tmparray[1];
  272.                 /**
  273.                  * Check if the word is in user dictionary.
  274.                  */
  275.                 if (in_array($sqspell_word,$this->userdic)){
  276.                     $sqspell_symb=intval($tmparray[3])-1;
  277.                     // add suggestions
  278.                     if (!isset($this->missed_words[$sqspell_word])) {
  279.                         foreach(explode(',',$rightas $word{
  280.                             $this->missed_words[$sqspell_word]['suggestions'][trim($word);
  281.                         }
  282.                     }
  283.                     // add location
  284.                     $this->missed_words[$sqspell_word]['locations']["$current_line:$sqspell_symb";
  285.                 }
  286.                 break;
  287.             /**
  288.              * Line begins with "#".
  289.              * This means a misspelled word and no suggestions.
  290.              */
  291.             case '#':
  292.                 $tmparray explode(" "$sqspell_output[$i]);
  293.                 $sqspell_word=$tmparray[1];
  294.                 /**
  295.                  *
  296.                  * Check if the word is in user dictionary.
  297.                  */
  298.                 if (!in_array($sqspell_word,$this->userdic)){
  299.                     $sqspell_symb=intval($tmparray[2])-1;
  300.                     // no suggestions
  301.                     $this->missed_words[$sqspell_word]['suggestions'array();
  302.                     // add location
  303.                     $this->missed_words[$sqspell_word]['locations']["$current_line:$sqspell_symb";
  304.                 }
  305.                 break;
  306.             }
  307.         }
  308.         return $this->missed_words;
  309.     }
  310. }
  311.  
  312.  
  313. /**
  314.  * Define the command used to spellcheck the document.
  315.  */
  316. #$sqspell_command=$SQSPELL_APP[$sqspell_use_app];

Documentation generated on Sat, 07 Oct 2006 16:09:13 +0300 by phpDocumentor 1.3.0RC6