f47d622948ad1a8779ca9e6c900063ddb183f674
[squirrelmail.git] / plugins / squirrelspell / modules / check_me.mod
1 <?php
2
3 /**
4  * check_me.mod
5  *
6  * Squirrelspell module.
7  *
8  * This module is the main workhorse of SquirrelSpell. It submits
9  * the message to the spell-checker, parses the output, and loads
10  * the interface window.
11  *
12  * @author Konstantin Riabitsev <icon at duke.edu>
13  * @copyright 1999-2019 The SquirrelMail Project Team
14  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
15  * @version $Id$
16  * @package plugins
17  * @subpackage squirrelspell
18  */
19
20 /**
21  * This function makes a javascript-powered link. Not sure why
22  * Philippe decided to move it outside the main code, but hey. ;)
23  * I bet for the i18n reasons.
24  *
25  * @param  $jscode Javascript code to include in the link.
26  * @param  $title  A little pop-up title to provide for the links.
27  * @param  $link   The content of the link.
28  * @return         void, since this just draws the content.
29  */
30 function SpellLink($jscode, $title, $link) {
31   echo "<td><a href=\"javascript:$jscode\" "
32     . "title=\"$title\">$link</a>"
33     . '</td>';
34 }
35
36 /**
37  * Declaring globals for users with E_ALL set.
38  */
39 global $SQSPELL_APP_DEFAULT, $SQSPELL_APP, $SQSPELL_SPELLCHECKER,
40   $SQSPELL_FORCE_POPEN, $attachment_dir, $color;
41
42 if (! sqgetGlobalVar('sqspell_text',$sqspell_text,SQ_POST)) {
43   $sqspell_text = '';
44 }
45 if (! sqgetGlobalVar('sqspell_use_app',$sqspell_use_app,SQ_POST)) {
46   $sqspell_use_app = $SQSPELL_APP_DEFAULT;
47 }
48
49 /**
50  * Now we explode the lines for two reasons:
51  * 1) So we can ignore lines starting with ">" (reply's)
52  * 2) So we can stop processing when we get to "--" on a single line,
53  *    which means that the signature is starting
54  */
55 $sqspell_raw_lines = explode("\n", $sqspell_text);
56 for ($i=0; $i<sizeof($sqspell_raw_lines); $i++){
57   /**
58    * See if the signature is starting, which will be a "--" on the
59    * single line (after trimming).
60    */
61   if (trim($sqspell_raw_lines[$i]) == '--'){
62     break;
63   }
64   /**
65    * See if this is quoted text. Don't check the quoted text, since
66    * it's no business of ours how badly our correspondents misspell
67    * stuff.
68    */
69   if(substr($sqspell_raw_lines[$i], 0, 1) != '>'){
70     $sqspell_new_lines[$i] = $sqspell_raw_lines[$i];
71   } else {
72     $sqspell_new_lines[$i] = '';
73   }
74 }
75 /**
76  * $sqspell_new_lines array now contains the lines to submit to the
77  * spellchecker.
78  */
79 $sqspell_new_text=implode("\n", $sqspell_new_lines);
80
81 include_once(SM_PATH . 'plugins/squirrelspell/class/common.php');
82
83 $aParams = array();
84 $aParams['words'] = sqspell_getLang($sqspell_use_app);
85
86 if ($SQSPELL_SPELLCHECKER===1) {
87     include_once(SM_PATH . 'plugins/squirrelspell/class/php_pspell.php');
88     $aParams['dictionary'] = $SQSPELL_APP[$sqspell_use_app];
89     $aParams['charset'] = $default_charset;
90     $check = new php_pspell($aParams);
91 } else {
92     include_once(SM_PATH . 'plugins/squirrelspell/class/cmd_spell.php');
93     $aParams['spell_command'] = $SQSPELL_APP[$sqspell_use_app];
94     if ($SQSPELL_FORCE_POPEN) {
95         $aParams['use_proc_open'] = false;
96     } else {
97         $aParams['use_proc_open'] = check_php_version(4,3);
98     }
99     $aParams['temp_dir'] = $attachment_dir;
100     $aParams['debug'] = false;
101     $check = new cmd_spell($aParams);
102 }
103
104 /**
105  * Check for class constructor function errors
106  */
107 if (!empty($check->error)) {
108   $msg= '<div style="text-align: center;">'
109       . nl2br(sm_encode_html_special_chars($check->error))
110      . '<form onsubmit="return false">'
111      . '<input type="submit" value="  ' . _("Close")
112      . '  " onclick="self.close()" /></form></div>';
113   sqspell_makeWindow(null, _("SquirrelSpell is misconfigured."), null, $msg);
114   exit;
115 }
116
117 $missed_words=Array();
118 $misses = Array();
119 $locations = Array();
120 $errors=0;
121 $results = $check->check_text($sqspell_new_text);
122
123 /**
124  * Check for execution errors
125  */
126 if (!empty($check->error)) {
127   $msg= '<div style="text-align: center;">'
128       . nl2br(sm_encode_html_special_chars($check->error))
129      . '<form onsubmit="return false">'
130      . '<input type="submit" value="  ' . _("Close")
131      . '  " onclick="self.close()" /></form></div>';
132   sqspell_makeWindow(null, _("SquirrelSpell is misconfigured."), null, $msg);
133   exit;
134 }
135
136 if (is_array($results)) {
137     // convert variables to old style squirrelspell results
138     if (!empty($results)) {
139         foreach(array_keys($results) as $word) {
140             if (isset($results[$word]['locations'])) {
141                 $missed_words[] = $word;
142                 $locations[$word] = implode(', ',$results[$word]['locations']);
143                 if (isset($results[$word]['suggestions'])) {
144                     $misses[$word] = implode(', ',$results[$word]['suggestions']);
145                 } else {
146                     $misses[$word] = '_NONE';
147                 }
148             } else {
149                 // $word without 'locations'. ignore it
150             }
151         }
152         $errors = count($missed_words);
153     }
154 } else {
155     if (!empty($check->error)) {
156         $error_msg = nl2br(sm_encode_html_special_chars($check->error));
157     } else {
158         $error_msg = _("Unknown error");
159     }
160     $msg= '<div style="text-align: center;">'
161         . $error_msg
162      . '<form onsubmit="return false">'
163      . '<input type="submit" value="  ' . _("Close")
164      . '  " onclick="self.close()" /></form></div>';
165     sqspell_makeWindow(null, _("SquirrelSpell error."), null, $msg);
166     exit;
167 }
168
169 if ($errors){
170   /**
171    * Load the spelling errors into JavaScript arrays
172    * (More dark magic!)
173    */
174   $extrajs="<script type=\"text/javascript\">\n"
175     . "<!--\n";
176
177   $sqspell_lines = explode("\n", $sqspell_text);
178   /**
179    * The javascript array sqspell_lines[] contains all lines of
180    * the message we've been checking.
181    */
182   $extrajs.= "var sqspell_lines=new Array();\n";
183   for ($i=0; $i<sizeof($sqspell_lines); $i++){
184     // use addcslashes for compatibility with magic_quotes_sybase
185     $extrajs.= "sqspell_lines[$i] = \""
186       . chop(addcslashes($sqspell_lines[$i], ">'\"\\\x0")) . "\";\n";
187   }
188   $extrajs.= "\n\n";
189
190   /**
191    * The javascript array misses[] contais all misspelled words.
192    */
193   $extrajs.= "var misses=new Array();\n";
194   for ($i=0; $i<sizeof($missed_words); $i++){
195     $extrajs.= "misses[$i] = \"" . $missed_words[$i] . "\";\n";
196   }
197   $extrajs.= "\n\n";
198
199   /**
200    * Suggestions are (guess what!) suggestions for misspellings
201    */
202   $extrajs.= "var suggestions = new Array();\n";
203   $i=0;
204   while (list($word, $value) = each($misses)){
205     if ($value=='_NONE') $value='';
206     $extrajs.= "suggestions[$i] = \"$value\";\n";
207     $i++;
208   }
209   $extrajs.= "\n\n";
210
211   /**
212    * Locations are where those misspellings are located, line:symbol
213    */
214   $extrajs.= "var locations= new Array();\n";
215   $i=0;
216   while (list($word, $value) = each($locations)){
217     $extrajs.= "locations[$i] = \"$value\";\n";
218     $i++;
219   }
220
221   /**
222    * Add some strings so they can be i18n'd.
223    */
224   $extrajs.= "var ui_completed = \"" . _("Spellcheck completed. Commit changes?")
225     . "\";\n";
226   $extrajs.= "var ui_nochange = \"" . _("No changes were made.") . "\";\n";
227   $extrajs.= "var ui_wait = \""
228     . _("Now saving your personal dictionary... Please wait.")
229     . "\";\n";
230
231
232   /**
233    * Did I mention that I hate dots on the end of concatenated lines?
234    * Dots at the beginning make so much more sense!
235    */
236   $extrajs.= "//-->\n"
237     . "</script>\n"
238     . "<script src=\"js/check_me.js\" type=\"text/javascript\"></script>\n";
239
240
241   displayHtmlHeader(_("SquirrelSpell Results"),$extrajs);
242
243   echo "<body bgcolor=\"$color[4]\" text=\"$color[8]\" link=\"$color[7]\" "
244     . "alink=\"$color[7]\" vlink=\"$color[7]\" "
245     . "onload=\"populateSqspellForm()\">\n";
246   ?>
247   <table width="100%" border="0" cellpadding="2">
248    <tr>
249     <td bgcolor="<?php echo $color[9] ?>" align="center">
250      <b>
251       <?php printf( ngettext("Found %d error","Found %d errors",$errors), $errors ) ?>
252      </b>
253     </td>
254    </tr>
255    <tr>
256     <td>
257       <hr />
258     </td>
259    </tr>
260    <tr>
261     <td>
262      <form method="post">
263       <input type="hidden" name="MOD" value="forget_me_not" />
264       <input type="hidden" name="words" value="" />
265       <input type="hidden" name="sqspell_use_app"
266              value="<?php echo $sqspell_use_app ?>" />
267       <table border="0" width="100%">
268        <tr align="center">
269         <td colspan="4">
270          <?php
271           $sptag = "<span style=\"background-color: $color[9]\">";
272           echo $sptag . _("Line with an error:") . '</span>';
273          ?>
274          <br />
275          <textarea name="sqspell_line_area" cols="50" rows="3"
276                    onfocus="this.blur()"></textarea>
277         </td>
278        </tr>
279        <tr valign="middle">
280         <td align="right" width="25%">
281          <?php
282           echo $sptag . _("Error:") . '</span>';
283          ?>
284         </td>
285         <td align="left" width="25%">
286          <input name="sqspell_error" size="10" value=""
287                 onfocus="this.blur()" />
288         </td>
289         <td align="right" width="25%">
290          <?php
291           echo $sptag . _("Suggestions:") . '</span>';
292          ?>
293         </td>
294         <td align="left" width="25%">
295          <select name="sqspell_suggestion"
296                  onchange="if (this.options[this.selectedIndex].value != '_NONE') document.forms[0].sqspell_oruse.value=this.options[this.selectedIndex].value">
297           <?php
298            echo '<option>' . _("Suggestions") . '</option>';
299           ?>
300          </select>
301         </td>
302        </tr>
303        <tr>
304         <td align="right">
305          <?php
306           echo $sptag . _("Change to:") . '</span>';
307          ?>
308         </td>
309         <td align="left">
310          <input name="sqspell_oruse" size="15" value=""
311                 onfocus="if(!this.value) this.value=document.forms[0].sqspell_error.value" />
312         </td>
313         <td align="right">
314          <?php
315           echo $sptag . _("Occurs times:") . '</span>';
316          ?>
317         </td>
318         <td align="left">
319          <input name="sqspell_likethis" size=3 value="" onfocus="this.blur()" />
320         </td>
321        </tr>
322         <!-- hello? What is this? </td></tr> -->
323        <tr>
324         <td colspan="4"><hr /></td>
325        </tr>
326        <tr>
327         <td colspan="4">
328          <table border="0" cellpadding="0" cellspacing="3" width="100%">
329           <tr align="center" bgcolor="<?php echo $color[9] ?>">
330            <?php
331            SpellLink('sqspellChange()',
332                    _("Change this word"),
333                    _("Change"));
334          SpellLink('sqspellChangeAll()',
335                  _("Change ALL occurances of this word"),
336                  _("Change All"));
337          SpellLink('sqspellIgnore()',
338                  _("Ignore this word"),
339                  _("Ignore"));
340          SpellLink('sqspellIgnoreAll()',
341                  _("Ignore ALL occurances this word"),
342                  _("Ignore All"));
343          SpellLink('sqspellRemember()',
344                  _("Add this word to your personal dictionary"),
345                  _("Add to Dic"));
346            ?>
347           </tr>
348          </table>
349         </td>
350        </tr>
351        <tr>
352         <td colspan="4"><hr /></td>
353        </tr>
354        <tr>
355         <td colspan="4" align="center" bgcolor="<?php echo $color[9] ?>">
356          <?php
357              echo '<input type="button" value="  '
358                  . _("Close and Commit")
359                  . '  " onclick="if (confirm(\''
360                  . _("The spellcheck is not finished. Really close and commit changes?")
361                  . '\')) sqspellCommitChanges()" />'
362                  . ' <input type="button" value="  '
363                  . _("Close and Cancel")
364                  . '  " onclick="if (confirm(\''
365                  . _("The spellcheck is not finished. Really close and discard changes?")
366                  . '\')) self.close()" />';
367          ?>
368         </td>
369        </tr>
370       </table>
371      </form>
372     </td>
373    </tr>
374   </table>
375   </body></html>
376   <?php
377 } else {
378   /**
379    * AREN'T YOU SUCH A KNOW-IT-ALL!
380    */
381   $msg='<form onsubmit="return false"><div style="text-align: center;">' .
382        '<input type="submit" value="  ' . _("Close") .
383        '  " onclick="self.close()" /></div></form>';
384   sqspell_makeWindow(null, _("No errors found"), null, $msg);
385 }
386
387 /**
388  * For Emacs weenies:
389  * Local variables:
390  * mode: php
391  * End:
392  * vim: syntax=php et ts=4
393  */