PluginProbe
Translation with DeepL API / 2.4.5
Translation with DeepL API v2.4.5
trunk 0.1.20180323 1.0 1.2.5.1 1.5.2.5 1.7.5 2.4.3.12 2.4.3.9 2.4.5
wpdeepl / client / deeplapi-translate.class.php

deeplapi-translate.class.php in Translation with DeepL API 2.4.5, at client/deeplapi-translate.class.php

473 lines 12.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class DeepLApiTranslate extends DeepLApi {
4 protected $endPoint = 'translate';
5
6 protected $langs = array( 'EN', 'DE', 'FR', 'ES', 'IT', 'NL', 'PL', 'RU' );
7 protected $syntaxes = array( 'xml', 'html' );
8
9 public $allow_cache = true;
10 protected $http_mode = 'POST';
11
12 protected $request = array(
13 'source_lang' => null,
14 'target_lang' => false,
15 'tag_handling' => 'html',
16 'ignore_tags' => 'x,code,pre',
17 'split_sentences' => 1,
18 'preserve_formatting' => 1,
19 'formality' => 'default',
20 //'glossary_id' => false,
21 'text' => array(),
22
23 );
24
25 public function getRequest() {
26 return $this->request;
27 }
28
29 protected function prepareString( $original_string, $index ) {
30 $string = $original_string;
31
32 $string = preg_replace_callback( '/\\\\u( [0-9a-fA-F]{4} )/', function ( $match ) {
33
34 $string = mb_convert_encoding( pack( 'H*', $match[1] ), 'UTF-8', 'UCS-2BE' );
35 }, $string );
36
37 $string = str_replace('&nbsp;', ' ', $string );
38 //$string = str_replace('&amp;', '&', $string );
39 $string = str_replace('&', '%26', $string );
40 //$string = str_replace( "\n", '<br class="98z4er98z4e968r4" />', $string );
41
42 if( $index == 'slug' ) {
43 $string = str_replace( '-' , ' ', $string );
44 }
45
46 //$string = addslashes( $string );
47
48 return apply_filters( __METHOD__, $string, $original_string );
49
50
51 $string = str_replace( '&nbsp;', ' ', $string );
52 // mandatory for POST requests
53 $string = urlencode($string);
54 //$string = htmlspecialchars($string);
55 $string = trim( $string );
56
57
58
59
60 //echo "\n ORIG $original_string \n = $string";
61
62 }
63
64 protected function splitString( $string, $length = 95000 ) {
65 $splitted_strings = array();
66
67 if( strpos( $string, '<!-- wp:') !== false ) {
68 $mode = 'blocks';
69 }
70 else {
71 $mode = 'lines';
72 }
73
74 //echo "\n mode $mode / $length / string = " . strlen( $string );
75
76 if( $mode == 'blocks' ) {
77
78 $bits = array();
79 while( strpos( $string, '<!-- /wp' ) !== false ) {
80 preg_match('#<!-- \/wp:([^>]+?)-->#ism', $string, $match );
81
82 $position = strpos( $string, $match[0] );
83 $bit = substr( $string, 0, $position + strlen( $match[0] ) );
84 $bits[] = $bit;
85 $string = substr( $string, strlen( $bit ) );
86 }
87 $bits[] = $string;
88
89
90 $current_string = '';
91 foreach( $bits as $index => $bit ) {
92 if( strlen( $current_string ) + strlen( $bit ) < $length ) {
93 $current_string .= $bit;
94 }
95 else {
96 $splitted_strings[] = $current_string;
97 $current_string = $bit;
98 }
99 }
100 $splitted_strings[] = $current_string;
101
102 }
103 else {
104 while( strlen( $string ) > $length ) {
105 $splitted_string = mb_substr( $string, 0, $length );
106 $position = mb_strrpos( $splitted_string, "\n\n" );
107 $real_split = mb_substr( $string, 0, $position );
108 $string = mb_substr( $string, $position );
109 $splitted_strings[] = $real_split;
110 }
111 $splitted_strings[] = $string;
112 }
113
114
115 foreach( $splitted_strings as $i => $string ) {
116 echo "\n #$i = " . strlen( $string );
117 }
118 return $splitted_strings;
119 }
120
121 public function getTranslations( $strings = array(), $return_originals = false ) {
122 if ( !is_array( $strings ) ) {
123 return new WP_Error( "wrong type", "Parameter is not an array" );
124 }
125
126 $debug = true;
127 $debug = false;
128
129 $this->finalPrepareRequest();
130
131 $response = array();
132 $translated = array();
133
134 //plouf( $strings , " zeirpejzirjzi" ); //die( 'okokok' );
135
136
137
138 $extra_strings = array();
139 $extra_prepared_strings = array();
140 $prepared_strings = array();
141
142 if( $debug ) plouf( $strings);
143 if( $debug ) die('ok');
144
145
146 foreach( $strings as $string_index => $string ) {
147 $prepared_string = $this->prepareString( $string, $string_index );
148
149 if( is_array( $prepared_string ) ) {
150 wpdeepl_log( array( __METHOD__, "is array", json_encode( $prepared_string ), json_encode( $_REQUEST) ), 'errors' );
151 return false;
152
153 }
154 // 2.2 20230502
155 elseif( strlen( $prepared_string ) > 105000 ) {
156 $splitted_strings = $this->splitString( $string );
157 //echo "\n avant = " . strlen( $string ) ." apres =" . strlen( implode("", $splitted_strings ) );
158
159 $real_index = $string_index;
160 $string_index = false;
161
162 foreach( $splitted_strings as $i => $splitted_string ) {
163 $prepared_string = $this->prepareString( $splitted_string, $string_index );
164 if( $i == 0) {
165 $extra_strings[$real_index .':0'] = $string;
166 $prepared_strings[$real_index .':0'] = $prepared_string;
167 }
168 else {
169 $extra_strings[$real_index . ':' . $i] = $string;
170 $extra_prepared_strings[$real_index . ':' . $i] = $prepared_string;
171
172 }
173 }
174
175
176 }
177 //echo "\n $string_index = " . strlen( $string ) ." / " . strlen( $prepared_string );
178 if( $string_index )
179 $prepared_strings[$string_index] = $prepared_string;
180 }
181
182 $need_multiple_requests = false;
183 if( count( $extra_prepared_strings ) ) {
184 $need_multiple_requests = true;
185 }
186
187 $strings_requests = array();
188 $strings_requests[] = $prepared_strings;
189 if( count( $extra_prepared_strings ) ) {
190 foreach( $extra_prepared_strings as $index => $string ) {
191 $strings_requests[] = array( $index => $string );
192 }
193 }
194 $translated = array();
195
196 //plouf( $strings_requests ); plouf( $this ); die('oazeazepùiprjk');
197
198
199
200 foreach( $strings_requests as $strings_request ) {
201 $translations = $this->requestTranslation( $strings_request, $return_originals );
202 if ( is_wp_error( $translations ) ) {
203 return $translations;
204 }
205 foreach( $translations as $key => $string ) {
206 $string = str_replace('<br class="98z4er98z4e968r4" />', "\n", $string );
207 $string = str_replace('%26', '&', $string );
208 $translations[$key] = $string;
209
210 }
211 //plouf( $translations ); die('zerepzijrpjr');
212 foreach( $translations as $index => $translation ) {
213
214 $real_index = $index;
215 if (count( $strings_requests ) > 1 ) {
216 $explode = explode(':', $index );
217 if( count( $explode ) > 1 ) {
218 $real_index = $explode[0];
219 }
220 }
221 if( isset( $translated[$real_index] ) ) {
222 $translated[$real_index] .= $translation;
223 }
224 else {
225 $translated[$real_index] = $translation;
226 }
227 }
228 }
229 if( isset( $translated['slug'] ) ) {
230 $translated['slug'] = str_replace( ' ', '-', $translated['slug'] );
231 }
232
233 //plouf( $this);
234 //plouf( $strings_requests , "strings reuqests"); plouf( $translated, " TRANSLATED" ); die('az54eaze684eaok');
235
236 return $translated;
237 }
238
239 protected function requestTranslation( $strings, $return_originals ) {
240 $this->resetTexts();
241 $translated = array();
242
243 //$this->allow_cache = false;
244
245 $string_indexes = array();
246 $i = 0;
247 $cache_id_strings = '';
248 //plouf( $strings) ;
249 foreach ( $strings as $string_index => $string ) {
250 if( empty( trim( $string ) ) ) {
251 unset( $strings[$string_index] );
252 }
253 }
254 foreach ( $strings as $string_index => $string ) {
255
256 $string_indexes[$i] = $string_index;
257 $i++;
258 $cache_id_strings .= $string;
259 $this->addText( $string );
260 if ( $return_originals ) {
261 $translated['_original_' . $string_index] = urldecode($string);
262 }
263 }
264
265 $cache_id = ( $this->request['source_lang'] ) ? $this->request['source_lang'] : 'AUTO';
266 $cache_id .= ':' . $this->request['target_lang'] . ':' . md5( $cache_id_strings );
267 $this->setCacheID( $cache_id );
268 // plouf( $strings, "strings donc cache id $cache_id");
269
270 //plouf($this); die('okaziejaiej');
271 if ( !$this->isValidRequest() ) {
272 $return = new WP_Error( "bad request", "Bof" );
273 return $return;
274 }
275
276
277 $response = $this->request();
278
279 if ( is_wp_error( $response ) ) {
280 return $response;
281 }
282 if ( !array_key_exists( 'translations', $response ) ) {
283 $return = new WP_Error( "bad response", $response );
284 }
285
286 foreach ( $response['translations'] as $index => $translation ) {
287 $string_index = $string_indexes[$index];
288 $translated_text = $translation->text;
289
290 // 2021 04 14
291 $translated_text = str_replace( '&lt;!--', '<!--', $translated_text );
292 $translated_text = str_replace( '--&gt;', '-->', $translated_text );
293 $translated_text = str_replace( '--&gt', '-->', $translated_text );
294
295 $translated_text = str_replace( '-->', "-->\n", $translated_text );
296 $translated[$string_index] = $translated_text;
297 }
298
299 //plouf( $response, "response" ); plouf( $string_indexes, "indexes"); plouf( $translated, "transalted");
300 // die('okokeroz');
301 //plouf( $translated, "translated");die('oizeeizjrirj');
302 return $translated;
303 }
304
305 public function buildBody( $mode = 'POST', $endPoint = '' ) {
306 $endPoint = $this->endPoint;
307 $body = array();
308
309 //if ( count( $this->headers ) ) $args['headers'] = $this->headers;
310
311 //$request = array( 'auth_key' => $this->authKey );
312
313 // plouf( $this->request); die(('ozeozrkzr'));
314
315
316 foreach( array( 'target_lang', 'source_lang', 'tag_handling', 'ignore_tags','split_sentences', 'preserve_formatting', 'formality' ) as $tag ) {
317 if( !empty( $this->request[$tag] ) ) {
318 $body[] = "$tag=" . $this->request[$tag];
319 }
320 }
321 $glossary_id = DeepLConfiguration::getActiveGlossaryFor( $this->request['source_lang'], $this->request['target_lang'] );
322 if( $glossary_id )
323 $body[] = "glossary_id=$glossary_id";
324
325 if ( $mode == 'POST' ) {
326 // fixed in 0.3 by schalipp https://wordpress.org/support/topic/translate-button-not-doing-anything/#post-10825822
327 // modified in 1.0 to send all strings in one request
328
329 foreach( $this->request['text'] as $string ) {
330 if( !empty( $string ) )
331 $body[] = "text=" . ( $string );
332 }
333
334 }
335 else {
336 }
337
338 $body = implode( '&', $body );
339 $this->final_request['body'] = $body;
340 //plouf($this);die('ezorozrk');
341 $this->saveRequest();
342 return $body;
343 }
344
345 /*
346 public function resetQuery() {
347 $this->request = array();
348 $this->headers = array();
349 }*/
350
351 private function finalPrepareRequest() {
352
353 /*
354 Sets whether the translated text should lean towards formal or informal language. This feature currently only works for target languages "DE" (German), "FR" (French), "IT" (Italian), "ES" (Spanish), "NL" (Dutch), "PL" (Polish), "PT-PT", "PT-BR" (Portuguese) and "RU" (Russian).
355 */
356
357 /*
358 no need to unset, just keep it useless
359 $target_lang = $this->request['target_lang'];
360 if ( !in_array( $target_lang, array('DE', 'FR', 'IT', 'ES', 'NL', 'PL', 'PT-PT', 'PT-BR', 'RU' ) ) ) {
361 unset( $this->request['formality'] );
362 }
363 */
364
365 return;
366 }
367
368 public function addText( $string ) {
369 $this->request['text'][] = $string;
370 return strlen( implode( '', $this->request['text'] ) );
371 }
372
373 protected function resetTexts() {
374 $this->request['text'] = array();
375 }
376
377 public function setLangFrom( $source_lang = false ) {
378 if ( !$source_lang ) {
379 return true;
380 }
381
382 $source = DeeplConfiguration::validateLang( $source_lang, 'assource' );
383 if ( $source ) {
384 $this->request['source_lang'] = $source;
385 return true;
386 }
387 else {
388 return true;
389 }
390 }
391
392 public function setLangTo( $target_lang ) {
393 if ( !$target_lang ) {
394 return false;
395 }
396
397 $target = DeeplConfiguration::validateLang( $target_lang, 'astarget' );
398 if ( !$target ) {
399 return false;
400 }
401 else {
402 $this->request['target_lang'] = $target;
403 return true;
404 }
405 }
406
407 public function setTagHandling( $tag_handling = 'html' ) {
408 if ( $tag_handling && in_array( $tag_handling, $this->syntaxes ) ) {
409 $this->request['tag_handling'] = $tag_handling;
410 return true;
411 }
412 }
413
414 public function setSplitSentences( $split_sentences = true ) {
415 if ( false === filter_var( $split_sentences, FILTER_VALIDATE_BOOLEAN ) ) {
416 $this->request['split_sentences'] = 0;
417 }
418 else {
419 $this->request['split_sentences'] = 1;
420 }
421 }
422
423 public function setFormality( $formality = 'default' ) {
424 if ( in_array( $formality, array('more', 'less', 'prefer_more', 'prefer_less', 'default' ) ) ) {
425 $this->request['formality'] = $formality;
426 }
427 else {
428 }
429 }
430
431 public function setGlossary( $glossary_id ) {
432
433 if( $glossary_id )
434 $this->request['glossary_id'] = $glossary_id;
435 }
436
437 public function setPreserveFormatting( $preserve_formatting = false ) {
438 if ( true === filter_var( $split_sentences, FILTER_VALIDATE_BOOLEAN ) ) {
439 $this->request['preserve_formatting'] = 1;
440 }
441 else {
442 $this->request['preserve_formatting'] = 0;
443 }
444 }
445
446 public function getRequestUniqueID() {
447 $this->uniqid = md5( implode( '',$this->request['text'] ) );
448 return $this->uniqid;
449 }
450
451 // RESPONSE
452 public function getDetectedLanguage() {
453 if ( !isset( $this->result ) || !array_key_exists( 'detected_source_language', $this->result ) ) {
454 return false;
455 }
456 return $this->result['detected_source_language'];
457 }
458
459 public function getMessage() {
460 if ( !isset( $this->result ) || !array_key_exists( 'message', $this->result ) ) {
461 return false;
462 }
463 return $this->result['message'];
464 }
465 public function getTranslatedText() {
466 if ( !isset( $this->result ) || !array_key_exists( 'text', $this->result ) ) {
467 return false;
468 }
469 return $this->result['text'];
470 }
471 }
472
473