Happy New Year
[squirrelmail.git] / plugins / squirrelspell / modules / check_me.mod
CommitLineData
849bdf42 1<?php
4b4abf93 2
d112ed5a 3/**
4 * check_me.mod
d112ed5a 5 *
4b4abf93 6 * Squirrelspell module.
d112ed5a 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 *
4b4abf93 12 * @author Konstantin Riabitsev <icon at duke.edu>
c997cbe6 13 * @copyright 1999-2021 The SquirrelMail Project Team
4b4abf93 14 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
44d661aa 15 * @version $Id$
16 * @package plugins
17 * @subpackage squirrelspell
d112ed5a 18 */
158d478f 19
d112ed5a 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 */
30function SpellLink($jscode, $title, $link) {
31 echo "<td><a href=\"javascript:$jscode\" "
4e37bc18 32 . "title=\"$title\">$link</a>"
d112ed5a 33 . '</td>';
158d478f 34}
35
d112ed5a 36/**
37 * Declaring globals for users with E_ALL set.
38 */
5d55011b 39global $SQSPELL_APP_DEFAULT, $SQSPELL_APP, $SQSPELL_SPELLCHECKER,
80b24263 40 $SQSPELL_FORCE_POPEN, $attachment_dir, $color;
d8aa9efe 41
7996c920 42if (! sqgetGlobalVar('sqspell_text',$sqspell_text,SQ_POST)) {
43 $sqspell_text = '';
44}
45if (! sqgetGlobalVar('sqspell_use_app',$sqspell_use_app,SQ_POST)) {
46 $sqspell_use_app = $SQSPELL_APP_DEFAULT;
47}
849bdf42 48
d112ed5a 49/**
80b24263 50 * Now we explode the lines for two reasons:
d112ed5a 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
d112ed5a 54 */
55$sqspell_raw_lines = explode("\n", $sqspell_text);
56for ($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) != '>'){
80b24263 70 $sqspell_new_lines[$i] = $sqspell_raw_lines[$i];
d112ed5a 71 } else {
80b24263 72 $sqspell_new_lines[$i] = '';
d112ed5a 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);
849bdf42 80
80b24263 81include_once(SM_PATH . 'plugins/squirrelspell/class/common.php');
3bb04c83 82
80b24263 83$aParams = array();
84$aParams['words'] = sqspell_getLang($sqspell_use_app);
3bb04c83 85
80b24263 86if ($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);
2fd96e6b 98 }
80b24263 99 $aParams['temp_dir'] = $attachment_dir;
100 $aParams['debug'] = false;
101 $check = new cmd_spell($aParams);
38c5802f 102}
849bdf42 103
d88c744e 104/**
80b24263 105 * Check for class constructor function errors
d88c744e 106 */
80b24263 107if (!empty($check->error)) {
0e271f86 108 $msg= '<div style="text-align: center;">'
3047e291 109 . nl2br(sm_encode_html_special_chars($check->error))
04fa3c41 110 . '<form onsubmit="return false">'
111 . '<input type="submit" value=" ' . _("Close")
112 . ' " onclick="self.close()" /></form></div>';
d88c744e 113 sqspell_makeWindow(null, _("SquirrelSpell is misconfigured."), null, $msg);
114 exit;
115}
116
d112ed5a 117$missed_words=Array();
118$misses = Array();
119$locations = Array();
120$errors=0;
80b24263 121$results = $check->check_text($sqspell_new_text);
122
d112ed5a 123/**
80b24263 124 * Check for execution errors
d112ed5a 125 */
80b24263 126if (!empty($check->error)) {
127 $msg= '<div style="text-align: center;">'
3047e291 128 . nl2br(sm_encode_html_special_chars($check->error))
80b24263 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
136if (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);
849bdf42 153 }
80b24263 154} else {
155 if (!empty($check->error)) {
3047e291 156 $error_msg = nl2br(sm_encode_html_special_chars($check->error));
80b24263 157 } else {
158 $error_msg = _("Unknown error");
849bdf42 159 }
80b24263 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;
d112ed5a 167}
158d478f 168
d112ed5a 169if ($errors){
d112ed5a 170 /**
171 * Load the spelling errors into JavaScript arrays
172 * (More dark magic!)
173 */
6ed7bbcb 174 $extrajs="<script type=\"text/javascript\">\n"
d112ed5a 175 . "<!--\n";
91e0dccc 176
d112ed5a 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 */
6ed7bbcb 182 $extrajs.= "var sqspell_lines=new Array();\n";
d112ed5a 183 for ($i=0; $i<sizeof($sqspell_lines); $i++){
7f5593a7 184 // use addcslashes for compatibility with magic_quotes_sybase
91e0dccc 185 $extrajs.= "sqspell_lines[$i] = \""
ce102fcc 186 . chop(addcslashes($sqspell_lines[$i], ">'\"\\\x0")) . "\";\n";
91e0dccc 187 }
6ed7bbcb 188 $extrajs.= "\n\n";
158d478f 189
d112ed5a 190 /**
191 * The javascript array misses[] contais all misspelled words.
192 */
6ed7bbcb 193 $extrajs.= "var misses=new Array();\n";
d112ed5a 194 for ($i=0; $i<sizeof($missed_words); $i++){
6ed7bbcb 195 $extrajs.= "misses[$i] = \"" . $missed_words[$i] . "\";\n";
d112ed5a 196 }
6ed7bbcb 197 $extrajs.= "\n\n";
91e0dccc 198
d112ed5a 199 /**
200 * Suggestions are (guess what!) suggestions for misspellings
201 */
6ed7bbcb 202 $extrajs.= "var suggestions = new Array();\n";
d112ed5a 203 $i=0;
c71c845c 204 foreach ($misses as $value){
d112ed5a 205 if ($value=='_NONE') $value='';
6ed7bbcb 206 $extrajs.= "suggestions[$i] = \"$value\";\n";
d112ed5a 207 $i++;
208 }
6ed7bbcb 209 $extrajs.= "\n\n";
849bdf42 210
d112ed5a 211 /**
212 * Locations are where those misspellings are located, line:symbol
213 */
6ed7bbcb 214 $extrajs.= "var locations= new Array();\n";
d112ed5a 215 $i=0;
c71c845c 216 foreach ($locations as $value){
6ed7bbcb 217 $extrajs.= "locations[$i] = \"$value\";\n";
d112ed5a 218 $i++;
219 }
849bdf42 220
91e0dccc 221 /**
d112ed5a 222 * Add some strings so they can be i18n'd.
223 */
6ed7bbcb 224 $extrajs.= "var ui_completed = \"" . _("Spellcheck completed. Commit changes?")
d112ed5a 225 . "\";\n";
6ed7bbcb 226 $extrajs.= "var ui_nochange = \"" . _("No changes were made.") . "\";\n";
91e0dccc 227 $extrajs.= "var ui_wait = \""
d112ed5a 228 . _("Now saving your personal dictionary... Please wait.")
229 . "\";\n";
91e0dccc 230
158d478f 231
d112ed5a 232 /**
5d55011b 233 * Did I mention that I hate dots on the end of concatenated lines?
d112ed5a 234 * Dots at the beginning make so much more sense!
235 */
6ed7bbcb 236 $extrajs.= "//-->\n"
d112ed5a 237 . "</script>\n"
6ed7bbcb 238 . "<script src=\"js/check_me.js\" type=\"text/javascript\"></script>\n";
91e0dccc 239
6ed7bbcb 240
241 displayHtmlHeader(_("SquirrelSpell Results"),$extrajs);
242
d112ed5a 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>
a0bce09f 251 <?php printf( ngettext("Found %d error","Found %d errors",$errors), $errors ) ?>
d112ed5a 252 </b>
253 </td>
254 </tr>
255 <tr>
256 <td>
04fa3c41 257 <hr />
d112ed5a 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="" />
91e0dccc 265 <input type="hidden" name="sqspell_use_app"
d112ed5a 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 />
91e0dccc 275 <textarea name="sqspell_line_area" cols="50" rows="3"
6f34ed5a 276 onfocus="this.blur()"></textarea>
d112ed5a 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%">
91e0dccc 286 <input name="sqspell_error" size="10" value=""
d112ed5a 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%">
91e0dccc 295 <select name="sqspell_suggestion"
d112ed5a 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=""
04fa3c41 311 onfocus="if(!this.value) this.value=document.forms[0].sqspell_error.value" />
d112ed5a 312 </td>
313 <td align="right">
314 <?php
315 echo $sptag . _("Occurs times:") . '</span>';
316 ?>
317 </td>
318 <td align="left">
04fa3c41 319 <input name="sqspell_likethis" size=3 value="" onfocus="this.blur()" />
d112ed5a 320 </td>
321 </tr>
322 <!-- hello? What is this? </td></tr> -->
323 <tr>
04fa3c41 324 <td colspan="4"><hr /></td>
d112ed5a 325 </tr>
326 <tr>
327 <td colspan="4">
328 <table border="0" cellpadding="0" cellspacing="3" width="100%">
90ad8cd1 329 <tr align="center" bgcolor="<?php echo $color[9] ?>">
d112ed5a 330 <?php
90ad8cd1 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"));
d112ed5a 346 ?>
347 </tr>
348 </table>
349 </td>
350 </tr>
351 <tr>
04fa3c41 352 <td colspan="4"><hr /></td>
d112ed5a 353 </tr>
354 <tr>
04fa3c41 355 <td colspan="4" align="center" bgcolor="<?php echo $color[9] ?>">
356 <?php
357 echo '<input type="button" value=" '
90ad8cd1 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()" />';
d112ed5a 367 ?>
368 </td>
849bdf42 369 </tr>
370 </table>
d112ed5a 371 </form>
372 </td>
373 </tr>
849bdf42 374 </table>
d112ed5a 375 </body></html>
849bdf42 376 <?php
d112ed5a 377} else {
378 /**
379 * AREN'T YOU SUCH A KNOW-IT-ALL!
380 */
0e271f86 381 $msg='<form onsubmit="return false"><div style="text-align: center;">' .
04fa3c41 382 '<input type="submit" value=" ' . _("Close") .
383 ' " onclick="self.close()" /></div></form>';
d112ed5a 384 sqspell_makeWindow(null, _("No errors found"), null, $msg);
385}
386
387/**
388 * For Emacs weenies:
389 * Local variables:
390 * mode: php
391 * End:
38c5802f 392 * vim: syntax=php et ts=4
d112ed5a 393 */