alecpl
2010-06-24 2011bef155aacdfa8461a4d5c2cd3988d946d135
commit | author | age
4ca10b 1 <?php
T 2 /**
3  * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
4  *
5  * @author Moxiecode
6  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
7  */
8
9 class GoogleSpell extends SpellChecker {
10     /**
11      * Spellchecks an array of words.
12      *
13      * @param {String} $lang Language code like sv or en.
14      * @param {Array} $words Array of words to spellcheck.
15      * @return {Array} Array of misspelled words.
16      */
17     function &checkWords($lang, $words) {
18         $wordstr = implode(' ', $words);
19         $matches = $this->_getMatches($lang, $wordstr);
20         $words = array();
21
22         for ($i=0; $i<count($matches); $i++)
23             $words[] = $this->_unhtmlentities(mb_substr($wordstr, $matches[$i][1], $matches[$i][2], "UTF-8"));
24
25         return $words;
26     }
27
28     /**
29      * Returns suggestions of for a specific word.
30      *
31      * @param {String} $lang Language code like sv or en.
32      * @param {String} $word Specific word to get suggestions for.
33      * @return {Array} Array of suggestions for the specified word.
34      */
35     function &getSuggestions($lang, $word) {
36         $sug = array();
37         $osug = array();
38         $matches = $this->_getMatches($lang, $word);
39
40         if (count($matches) > 0)
b92a67 41             $sug = explode("\t", $this->_unhtmlentities($matches[0][4]));
4ca10b 42
T 43         // Remove empty
44         foreach ($sug as $item) {
45             if ($item)
46                 $osug[] = $item;
47         }
48
49         return $osug;
50     }
51
52     function &_getMatches($lang, $str) {
53         $server = "www.google.com";
54         $port = 443;
55         $path = "/tbproxy/spell?lang=" . $lang . "&hl=en";
ded713 56         $ssl = true;
T 57         
58         // spell check uri is configured (added by RoundCube)
59         if (!empty($this->_config['rpc_uri'])) {
60             $a_uri = parse_url($this->_config['rpc_uri']);
61             $ssl = ($a_uri['scheme']=='https' || $a_uri['scheme']=='ssl');
62             $port = $a_uri['port'] ? $a_uri['port'] : ($ssl ? 443 : 80);
63             $server = $a_uri['host'];
64             $path = $a_uri['path'] . ($a_uri['query'] ? '?'.$a_uri['query'] : '') . $lang;
65         }
4ca10b 66
T 67         // Setup XML request
2011be 68         $xml = '<?xml version="1.0" encoding="utf-8" ?>\
A 69         <spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1"><text>' . $str . '</text></spellrequest>';
4ca10b 70
T 71         $header  = "POST ".$path." HTTP/1.0 \r\n";
72         $header .= "MIME-Version: 1.0 \r\n";
73         $header .= "Content-type: application/PTI26 \r\n";
74         $header .= "Content-length: ".strlen($xml)." \r\n";
75         $header .= "Content-transfer-encoding: text \r\n";
76         $header .= "Request-number: 1 \r\n";
77         $header .= "Document-type: Request \r\n";
78         $header .= "Interface-Version: Test 1.4 \r\n";
79         $header .= "Connection: close \r\n\r\n";
80         $header .= $xml;
81
82         // Use curl if it exists
83         if (function_exists('curl_init')) {
84             // Use curl
85             $ch = curl_init();
ded713 86             curl_setopt($ch, CURLOPT_URL, ($ssl ? "https://" : "http://") . $server);
4ca10b 87             curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
T 88             curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $header);
89             curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
90             $xml = curl_exec($ch);
91             curl_close($ch);
92         } else {
93             // Use raw sockets
ded713 94             $fp = fsockopen(($ssl ? "ssl://" : "") . $server, $port, $errno, $errstr, 30);
4ca10b 95             if ($fp) {
T 96                 // Send request
97                 fwrite($fp, $header);
98
99                 // Read response
100                 $xml = "";
101                 while (!feof($fp))
102                     $xml .= fgets($fp, 128);
103
104                 fclose($fp);
105             } else
106                 echo "Could not open SSL connection to google.";
107         }
108
109         // Grab and parse content
110         $matches = array();
111         preg_match_all('/<c o="([^"]*)" l="([^"]*)" s="([^"]*)">([^<]*)<\/c>/', $xml, $matches, PREG_SET_ORDER);
112
113         return $matches;
114     }
115
116     function _unhtmlentities($string) {
117         $string = preg_replace('~&#x([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $string);
118         $string = preg_replace('~&#([0-9]+);~e', 'chr(\\1)', $string);
119
120         $trans_tbl = get_html_translation_table(HTML_ENTITIES);
121         $trans_tbl = array_flip($trans_tbl);
122
123         return strtr($string, $trans_tbl);
124     }
125 }
126
127 // Patch in multibyte support
128 if (!function_exists('mb_substr')) {
129     function mb_substr($str, $start, $len = '', $encoding="UTF-8"){
130         $limit = strlen($str);
131
132         for ($s = 0; $start > 0;--$start) {// found the real start
133             if ($s >= $limit)
134                 break;
135
136             if ($str[$s] <= "\x7F")
137                 ++$s;
138             else {
139                 ++$s; // skip length
140
141                 while ($str[$s] >= "\x80" && $str[$s] <= "\xBF")
142                     ++$s;
143             }
144         }
145
146         if ($len == '')
147             return substr($str, $s);
148         else
149             for ($e = $s; $len > 0; --$len) {//found the real end
150                 if ($e >= $limit)
151                     break;
152
153                 if ($str[$e] <= "\x7F")
154                     ++$e;
155                 else {
156                     ++$e;//skip length
157
158                     while ($str[$e] >= "\x80" && $str[$e] <= "\xBF" && $e < $limit)
159                         ++$e;
160                 }
161             }
162
163         return substr($str, $s, $e - $s);
164     }
165 }
166
167 ?>