1 | <?php
|
---|
2 | /*
|
---|
3 | Description: Companion file to translate <em>Easy AdSense</em>.
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | Copyright (C) 2008 www.thulasidas.com
|
---|
8 |
|
---|
9 | This program is free software; you can redistribute it and/or modify
|
---|
10 | it under the terms of the GNU General Public License as published by
|
---|
11 | the Free Software Foundation; either version 3 of the License, or
|
---|
12 | (at your option) any later version.
|
---|
13 |
|
---|
14 | This program is distributed in the hope that it will be useful,
|
---|
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
17 | GNU General Public License for more details.
|
---|
18 |
|
---|
19 | You should have received a copy of the GNU General Public License
|
---|
20 | along with this program. If not, see <http://www.gnu.org/licenses/>.
|
---|
21 | */
|
---|
22 |
|
---|
23 | define('minmatch', 89) ;
|
---|
24 |
|
---|
25 | if (!class_exists("ezTran") && !class_exists("PO")) {
|
---|
26 | class PO { // an id-str pair with attributes
|
---|
27 | var $num, $id, $str, $tranId, $tranVal, $keyId, $keyVal ;
|
---|
28 |
|
---|
29 | function PO($id, $str) {
|
---|
30 | $this->id = (string) $id ;
|
---|
31 | $this->str = (string) $str ;
|
---|
32 | $this->tranVal = minmatch ;
|
---|
33 | $this->keyVal = minmatch ;
|
---|
34 | }
|
---|
35 |
|
---|
36 | // Returns a text-area string of the Id
|
---|
37 | function textId() {
|
---|
38 | $ht = round(strlen($this->id)/52 + 1) * 25 ;
|
---|
39 | $col = 'background-color:#f5f5f5;' ;
|
---|
40 | if ($this->keyVal > minmatch+1) {
|
---|
41 | $col = "background-color:#ffc;border: solid 1px #f00" ;
|
---|
42 | $tit = 'onmouseover = "Tip(\'Another similar string: ' .
|
---|
43 | htmlspecialchars('<br /><em><b>' . addcslashes($this->keyId, "\n") .
|
---|
44 | '</b></em><br /> ', ENT_QUOTES) .
|
---|
45 | 'exists. Please alert the author.\',WIDTH, 300)" ' .
|
---|
46 | 'onmouseout="UnTip()"';
|
---|
47 | }
|
---|
48 | $s = '<textarea cols="50" rows="15" name="k' . $this->num .
|
---|
49 | '" style="width: 45%;height:' . $ht . 'px;' . $col . '" ' .
|
---|
50 | $tit . ' readonly="readonly">';
|
---|
51 | $s .= htmlspecialchars($this->id, ENT_QUOTES) ;
|
---|
52 | $s .= '</textarea> ' ;
|
---|
53 | return $s ;
|
---|
54 | }
|
---|
55 |
|
---|
56 | function textStr() {
|
---|
57 | $ht = round(strlen($this->id)/52 + 1) * 25 ;
|
---|
58 | if ($this->tranVal > minmatch+1){
|
---|
59 | $col = "background-color:#fdd;border: solid 1px #f00" ;
|
---|
60 | $tit = 'onmouseover = "Tip(\'Using the translation for a similar string: ' .
|
---|
61 | htmlspecialchars('<br /><em><b>' . addcslashes($this->tranId, "\n") .
|
---|
62 | '</b></em><br />', ENT_QUOTES) .
|
---|
63 | 'Please check carefully.\',WIDTH, 300)" ' .
|
---|
64 | 'onmouseout="UnTip()"';
|
---|
65 | }
|
---|
66 | $s = '<textarea cols="50" rows="15" name="' . $this->num .
|
---|
67 | '" style="width: 45%;height:' . $ht . 'px;' . $col. '" ' .
|
---|
68 | $tit . '>';
|
---|
69 | $s .= htmlspecialchars($this->str, ENT_QUOTES) ;
|
---|
70 | $s .= '</textarea><br />' ;
|
---|
71 | return $s ;
|
---|
72 | }
|
---|
73 | }
|
---|
74 |
|
---|
75 | class ezTran {
|
---|
76 | var $status, $error ;
|
---|
77 | function ezTran()
|
---|
78 | {
|
---|
79 | $this->status = '' ;
|
---|
80 | $this->error = '' ;
|
---|
81 | if ($_POST['savePot']) {
|
---|
82 | $file = $_POST['potFile'] ;
|
---|
83 | $str = $_POST['potStr'] ;
|
---|
84 | header('Content-Disposition: attachment; filename="' . $file .'"');
|
---|
85 | header("Content-Transfer-Encoding: ascii");
|
---|
86 | header('Expires: 0');
|
---|
87 | header('Pragma: no-cache');
|
---|
88 | ob_start() ;
|
---|
89 | print stripslashes(htmlspecialchars_decode($str, ENT_QUOTES)) ;
|
---|
90 | ob_end_flush() ;
|
---|
91 | $this->status = '<div class="updated">Pot file: ' . $file . ' was saved.</div> ' ;
|
---|
92 | exit(0) ;
|
---|
93 | }
|
---|
94 | if ($_POST['mailPot']) {
|
---|
95 | if (!class_exists("phpmailer")) {
|
---|
96 | require_once(ABSPATH.'wp-includes/class-phpmailer.php');
|
---|
97 | }
|
---|
98 | $mail = new PHPMailer();
|
---|
99 | $mail->From = get_bloginfo('admin_email') ;
|
---|
100 | $mail->FromName = get_bloginfo('name') ;
|
---|
101 | $mail->AddAddress('Manoj@Thulasidas.com', "Manoj Thulasidas") ;
|
---|
102 | $mail->CharSet = get_bloginfo('charset');
|
---|
103 | $mail->Mailer = 'php';
|
---|
104 | $mail->SMTPAuth = false;
|
---|
105 | $mail->Subject = $file;
|
---|
106 | $file = $_POST['potFile'] ;
|
---|
107 | $str = stripslashes($_POST['potStr']) ;
|
---|
108 | $str = str_replace("\'", "'", $str) ;
|
---|
109 | $mail->AddStringAttachment($str,$file) ;
|
---|
110 | $pos1 = strpos($str, "msgstr") ;
|
---|
111 | $pos2 = strpos($str, "msgid", $pos1) ;
|
---|
112 | $head = substr($str, 0, $pos2) ;
|
---|
113 | $mail->Body = $head ;
|
---|
114 | if ($mail->Send())
|
---|
115 | $this->status = '<div class="updated">Pot file: ' . $file . ' was sent.</div> ' ;
|
---|
116 | else
|
---|
117 | $this->error = '<div class="error">Error: ' . $mail->ErrorInfo . '</div>' ;
|
---|
118 | }
|
---|
119 | }
|
---|
120 |
|
---|
121 | // Return the contents of all PHP files in the dir specified
|
---|
122 | function getFileContents($dir="") {
|
---|
123 | if ($dir == "") $dir = dirname(__FILE__) ;
|
---|
124 | $files = glob($dir . '/*.php') ;
|
---|
125 | $page = "" ;
|
---|
126 | foreach ($files as $f) {
|
---|
127 | $page .= file_get_contents($f, FILE_IGNORE_NEW_LINES) ;
|
---|
128 | }
|
---|
129 | return $page ;
|
---|
130 | }
|
---|
131 |
|
---|
132 | // Percentage Levenshtein distance
|
---|
133 | function levDist(&$s1, &$s2) {
|
---|
134 | similar_text($s1, $s2, $p) ;
|
---|
135 | return round($p) ;
|
---|
136 | }
|
---|
137 |
|
---|
138 | // Get the closest existing translation keys, and the recursivley closest in the
|
---|
139 | // key set
|
---|
140 | function getClose(&$mo, &$POs){
|
---|
141 | foreach ($POs as $n => $po){
|
---|
142 | $s1 = $po->id ;
|
---|
143 | $l1 = strlen($s1);
|
---|
144 | if (strlen($po->str) == 0) {
|
---|
145 | if (!empty($mo)) foreach ($mo as $mn => $mk) {
|
---|
146 | $s2 = $mn ;
|
---|
147 | $result = $this->levDist($s1, $s2) ;
|
---|
148 | if ($result > $po->tranVal) {
|
---|
149 | $po->tranVal = $result ;
|
---|
150 | $po->tranId = $mn ;
|
---|
151 | $po->str = $mk->translations[0] ;
|
---|
152 | }
|
---|
153 | }
|
---|
154 | }
|
---|
155 | foreach ($POs as $n2 => $po2){
|
---|
156 | if ($n != $n2){
|
---|
157 | $s2 = $po2->id ;
|
---|
158 | $result = $this->levDist($s1, $s2) ;
|
---|
159 | if ($result > $po2->keyVal) {
|
---|
160 | $po->keyVal = $result ;
|
---|
161 | $po->keyId = $po2->id ;
|
---|
162 | $po2->keyVal = $result ;
|
---|
163 | $po2->keyId = $po->id ;
|
---|
164 | }
|
---|
165 | }
|
---|
166 | }
|
---|
167 | }
|
---|
168 | }
|
---|
169 |
|
---|
170 | // Get the strings that look like translation keys
|
---|
171 | function getTranPOs(&$contents, &$mo, $domain, &$POs) {
|
---|
172 | preg_match_all("#_[_e].*\([\'\"](.+)[\'\"]\s*,\s*[\'\"]" . $domain ."[\'\"]#",
|
---|
173 | $contents, $matches) ;
|
---|
174 | $keys = array_unique($matches[1]) ;
|
---|
175 | $keys = str_replace(array("\'", '\"', '\n'), array("'", '"', "\n"), $keys) ;
|
---|
176 | foreach ($keys as $n => $k) {
|
---|
177 | $v = $mo[$k] ;
|
---|
178 | $t = $v->translations[0] ;
|
---|
179 | $po = new PO($k, $t) ;
|
---|
180 | $po->num = $n ;
|
---|
181 | array_push($POs, $po) ;
|
---|
182 | }
|
---|
183 | $this->getClose($mo, $POs) ;
|
---|
184 | }
|
---|
185 |
|
---|
186 | // Make a POT string from ids and msgs
|
---|
187 | function mkPot(&$POs, $msg){
|
---|
188 | $pot = '' ;
|
---|
189 | $pot .=
|
---|
190 | '# This file was generated by Easy Translator -- a WordPress plugin translator
|
---|
191 | # Your Name: ' . $msg["name"] . '
|
---|
192 | # Your Email: ' . $msg["email"] . '
|
---|
193 | # Your Website: ' . $msg["blog"] . '
|
---|
194 | # Your URL: ' . $msg["url"] . '
|
---|
195 | # Your Locale: ' . $msg["locale"] . '
|
---|
196 | # Your Language: ' . $msg["lang"] . '
|
---|
197 | #, fuzzy
|
---|
198 | msgid ""
|
---|
199 | msgstr ""
|
---|
200 | "Project-Id-Version: Easy AdSenser\n"
|
---|
201 | "PO-Revision-Date: ' . current_time('mysql') . '\n"
|
---|
202 | "Last-Translator: ' . $msg['name'] . ' <' . $msg['email'] . '>\n"
|
---|
203 | "MIME-Version: 1.0\n"
|
---|
204 | "Content-Type: text/plain; charset=' . $msg['charset'] . '\n"
|
---|
205 | "Content-Transfer-Encoding: 8bit\n"
|
---|
206 |
|
---|
207 | ' ;
|
---|
208 | foreach ($POs as $n => $po) {
|
---|
209 | $pot .= "msgid " . '"' . addcslashes($po->id, "\n\r\"") . '"' . "\n" ;
|
---|
210 | $t = $msg[$po->num] ;
|
---|
211 | $pot .= "msgstr " . '"' . addcslashes($t, "\n\r") . '"' . "\n\n" ;
|
---|
212 | }
|
---|
213 | return $pot ;
|
---|
214 | }
|
---|
215 |
|
---|
216 | // Prints out the admin page
|
---|
217 | function printAdminPage() {
|
---|
218 | $locale = get_locale();
|
---|
219 | $made = isset($_POST['make']) ;
|
---|
220 | $saving = isset($_POST['save']) ;
|
---|
221 |
|
---|
222 | ?>
|
---|
223 | <h2>Easy Translator</h2>
|
---|
224 | <p>
|
---|
225 | <strong><a href="options-general.php?page=easy-adsenser.php"><em>Easy AdSense</em></a> Translation Interface</strong>
|
---|
226 | </p>
|
---|
227 | <?php
|
---|
228 |
|
---|
229 | global $l10n;
|
---|
230 | $domain = 'easy-adsenser' ;
|
---|
231 | $version = (float)get_bloginfo('version') ;
|
---|
232 | if ($version < 2.80) {
|
---|
233 | echo '<div class="error"><p><b>Error</b>:' .
|
---|
234 | 'Sorry, Easy Translator works only on WP2.8+</p></div>' ;
|
---|
235 | return ;
|
---|
236 | }
|
---|
237 |
|
---|
238 | $mo = array($l10n[$domain]->entries) ;
|
---|
239 |
|
---|
240 | $s = $this->getFileContents() ;
|
---|
241 | $parent = dirname(__FILE__) . '/..' ;
|
---|
242 | $s .= $this->getFileContents($parent) ;
|
---|
243 |
|
---|
244 | $POs = array() ;
|
---|
245 |
|
---|
246 | $this->getTranPOs($s, $mo[0], $domain, $POs) ;
|
---|
247 |
|
---|
248 | if ($made) {
|
---|
249 | $pot = htmlspecialchars($this->mkPot($POs, $_POST), ENT_QUOTES) ;
|
---|
250 | }
|
---|
251 | else {
|
---|
252 | global $current_user;
|
---|
253 | get_currentuserinfo();
|
---|
254 | $pot = '' ;
|
---|
255 | $pot .= '<div style="width: 15%; float:left">Your Name:</div>' .
|
---|
256 | '<input type="text" style="width: 30%" name="name" value="' .
|
---|
257 | $current_user->user_firstname . " " .
|
---|
258 | $current_user->user_lastname . '" /><br />' . "\n" ;
|
---|
259 | $pot .= '<div style="width: 15%; float:left">Your Email:</div>' .
|
---|
260 | '<input type="text" style="width: 30%" name="email" value="' .
|
---|
261 | $current_user->user_email . '" /><br />' . "\n" ;
|
---|
262 | $pot .= '<div style="width: 15%; float:left">Your Website:</div>' .
|
---|
263 | '<input type="text" style="width: 30%" name="blog" value="' .
|
---|
264 | get_bloginfo('blog') . '" />' . "\n<br />" ;
|
---|
265 | $pot .= '<div style="width: 15%; float:left">Your URL:</div>' .
|
---|
266 | '<input type="text" style="width: 30%" name="url" value="' .
|
---|
267 | get_bloginfo('url') . '" />' . "\n<br />" ;
|
---|
268 | $pot .= '<div style="width: 15%; float:left">Your Locale:</div>' .
|
---|
269 | '<input type="text" style="width: 30%" name="locale" value="' .
|
---|
270 | $locale . '" /><br />' . "\n" ;
|
---|
271 | $pot .= '<div style="width: 15%; float:left">Your Language:</div>' .
|
---|
272 | '<input type="text" style="width: 30%" name="lang" value="' .
|
---|
273 | get_bloginfo('language') . '" /><br />' . "\n" ;
|
---|
274 | $pot .= '<div style="width: 15%; float:left">Character Set:</div>' .
|
---|
275 | '<input type="text" style="width: 30%" name="charset" value="' .
|
---|
276 | get_bloginfo('charset') . '" />' . "\n<br /><br />" ;
|
---|
277 |
|
---|
278 | $pot .= '<div style="width:800px;padding:10px;padding-top:25px"></div>' ;
|
---|
279 | $pot .= '<div style="width:38%px;paddling:10px;padding-left:100px;float:left">' .
|
---|
280 | '<b>English (en_US)</b></div>' ;
|
---|
281 | $pot .= '<div style="width:38%;paddling:10px;padding-left:80px;float:right">' .
|
---|
282 | '<b>Your Language (' . $locale . ')</b></div>' ;
|
---|
283 | $pot .= '<div style="width:100%;padding:15px"></div>' ;
|
---|
284 |
|
---|
285 | foreach ($POs as $n => $po) {
|
---|
286 | $pot .= $po->textId() . "\n" . $po->textStr() . "\n\n" ;
|
---|
287 | }
|
---|
288 | }
|
---|
289 | $makeStr =
|
---|
290 | '<div class="submit">
|
---|
291 | <input type="submit" name="make" value="Display POT File" title="Make a POT file with the translation strings below and display it" />
|
---|
292 | </div>' . $this->status . $this->error ;
|
---|
293 | $saveStr =
|
---|
294 | '<div class="submit">
|
---|
295 | <input type="submit" name="savePot" value="Save POT file" title="Saves the strings shown below to your PC as a POT file" />
|
---|
296 | <input type="submit" name="mailPot" value="Mail POT file" title="Email the translation to the plugin autor" />
|
---|
297 | <input type="button" name="editMore" value="Edit More" title="If you are not happy with the strings, edit it further" onclick="history.go(-1)"/>
|
---|
298 | </div>' . $this->status . $this->error ;
|
---|
299 | if ($made) {
|
---|
300 | ?>
|
---|
301 | <div style="background-color:#eef;border: solid 1px #005;padding:5px">
|
---|
302 | If you are happy with the POT file as below, please save it or email it to the author.
|
---|
303 | If not, edit it further.
|
---|
304 | </div>
|
---|
305 | <?php
|
---|
306 | echo '<input type="hidden" name="potFile" value="' .
|
---|
307 | $domain . "-" . $locale . '.po" />' ;
|
---|
308 | echo '<input type="hidden" name="potStr" value="' . $pot . '" />' ;
|
---|
309 | echo $saveStr ;
|
---|
310 | echo "\n" . '<pre>' . $pot . '</pre>' ;
|
---|
311 | }
|
---|
312 | else
|
---|
313 | {
|
---|
314 | ?>
|
---|
315 | <div style="background-color:#eef;border: solid 1px #005;padding:5px">
|
---|
316 | Add or modify translation for your language <b><?php echo $locale ?></b>.
|
---|
317 | <br />
|
---|
318 | Enter the translated strings in the text boxes below and hit the "Display POT File" button.
|
---|
319 | </div>
|
---|
320 | <?php
|
---|
321 | echo $makeStr ;
|
---|
322 | echo $pot ;
|
---|
323 | }
|
---|
324 | } // End function printAdminPage()
|
---|
325 | }
|
---|
326 | } // End Class ezTran
|
---|
327 |
|
---|
328 | ?>
|
---|